jota 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/jota.rb ADDED
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # $Id: jota.rb 37 2009-02-09 10:06:02Z dz $
4
+
5
+ # if you use vim and don't like folds type zR
6
+
7
+
8
+ require 'getoptlong'
9
+ require 'helper'
10
+ require 'version'
11
+
12
+ class Jota
13
+
14
+ # from sysexits(3)
15
+ EX_OK = 0
16
+ EX_USAGE = 64
17
+ EX_SOFTWARE = 70
18
+
19
+ def usage
20
+ #{{{1
21
+ puts("%s Version %s, (C) %s %s" % [
22
+ Version::PROGRAM_NAME,
23
+ Version::STRING,
24
+ Version::YEARS,
25
+ Version::AUTHOR])
26
+ puts
27
+ puts("usage: #{$0} -dhv 'file' [ 'regular-expression' ]")
28
+ puts("\t-v\t\tset verbose mode")
29
+ puts("\t-d\t\tset debug mode")
30
+ puts("\t-h\t\tthis help")
31
+ end #}}}1
32
+
33
+
34
+ def parse_args
35
+ #{{{1
36
+ opts = GetoptLong.new(
37
+ [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
38
+ [ '--debug', '-d', GetoptLong::NO_ARGUMENT ],
39
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ]
40
+ )
41
+
42
+ begin
43
+ opts.each do |opt, arg|
44
+ case opt
45
+ when '--verbose'
46
+ $VERBOSE = true
47
+ when '--debug'
48
+ $VERBOSE = true
49
+ $DEBUG = true
50
+ when '--help'
51
+ usage
52
+ exit(EX_OK)
53
+ else
54
+ usage
55
+ exit(EX_USAGE)
56
+ end
57
+ end
58
+ rescue GetoptLong::InvalidOption
59
+ exit(EX_USAGE)
60
+ end
61
+
62
+ case ARGV.length
63
+ when 0
64
+ @filename = nil
65
+ @regexp = nil
66
+ when 1
67
+ @filename = ARGV[0]
68
+ @regexp = nil
69
+ when 2
70
+ @filename = ARGV[0]
71
+ @regexp = ARGV[1]
72
+ else
73
+ usage
74
+ exit(EX_USAGE)
75
+ end
76
+
77
+ if $VERBOSE then
78
+ print_verbose "running version #{Version::STRING}, build #{Version::build}"
79
+ print_verbose "verbose set to #{$VERBOSE}"
80
+ print_verbose "debug set to #{$DEBUG}"
81
+ print_verbose "filename set to '#{@filename}'"
82
+ print_verbose "regexp set to '#{@regexp}'"
83
+ end
84
+ end #}}}1
85
+
86
+
87
+ def run_gui
88
+ #{{{1
89
+ parse_args
90
+
91
+ # this 'require' must be after the command line is parsed, because
92
+ # 'require libglade2' parses the commandline too.
93
+ require 'gui'
94
+
95
+ glade = Gui.new
96
+
97
+ if @filename then
98
+ glade.open(@filename)
99
+ if @regexp
100
+ glade.set_current(@regexp)
101
+ end
102
+ end
103
+
104
+ glade.create_gui
105
+
106
+ print_verbose "entering main loop"
107
+
108
+ begin
109
+ Gtk.main
110
+ rescue Interrupt
111
+ glade.close
112
+ rescue Exception => e
113
+ print_verbose "crashing, #{e.class}: #{e.message}"
114
+ puts "#{e.class}: #{e.message}"
115
+ puts "#{e.backtrace}"
116
+
117
+ msgbox = Gtk::MessageDialog.new(@top_window,
118
+ Gtk::Dialog::MODAL,
119
+ Gtk::MessageDialog::ERROR,
120
+ Gtk::MessageDialog::BUTTONS_NONE,
121
+ "Oops! I am about to crash")
122
+ msgbox.title = "Internal Error"
123
+ msgbox.secondary_text = "You are strongly advised to save your data "+
124
+ "as soon as possible and restart the program."+
125
+ "\n\nDetails:\n#{e.class}: #{e.message}"
126
+ msgbox.add_button("Crash",Gtk::Dialog::RESPONSE_CANCEL)
127
+ msgbox.add_button("Recover",Gtk::Dialog::RESPONSE_OK)
128
+
129
+ msgbox.run do | response |
130
+ case response
131
+ when Gtk::Dialog::RESPONSE_OK
132
+ msgbox.destroy
133
+ sleep 2
134
+ print_verbose "recovering"
135
+ puts "recovering"
136
+ retry
137
+ when Gtk::Dialog::RESPONSE_CANCEL
138
+ msgbox.destroy
139
+ exit(EX_SOFTWARE)
140
+ end
141
+ end
142
+ end
143
+
144
+ end # run_gui }}}1
145
+
146
+
147
+ def run_cli
148
+ #{{{1
149
+ require 'cli'
150
+
151
+ parse_args
152
+
153
+ cli = JotaCli.new
154
+ if @filename then
155
+ cli.do_open(@filename)
156
+ if @regexp then
157
+ cli.do_edit(@regexp)
158
+ end
159
+ end
160
+
161
+ # If ARGV is empty, Cmd runs in a loop, otherwise it runs only once.
162
+
163
+ # in short: no arg -> loop
164
+ # only filename -> loop
165
+ # filename + re -> once
166
+
167
+ if @filename and @regexp.nil? then # i.e. only one arg
168
+ ARGV.clear
169
+ end
170
+
171
+ cli.run
172
+ end # run_cli }}}1
173
+
174
+ end # class Jota
175
+
176
+ # vim600: set foldmethod=marker:
@@ -0,0 +1,83 @@
1
+
2
+ # $Id: preferences.rb 37 2009-02-09 10:06:02Z dz $
3
+
4
+ # if you use vim and don't like folds type zR
5
+
6
+ require 'yaml'
7
+ require 'version'
8
+
9
+ class Preferences < Hash
10
+
11
+ # synonym for 'new'
12
+ def Preferences.defaults
13
+ #{{{1
14
+ return Preferences.new
15
+ end #}}}1
16
+
17
+ def Preferences.read(str)
18
+ #{{{1
19
+ p = Preferences.new
20
+
21
+ begin
22
+ print_debug "reading preferneces from string"
23
+ hash = YAML.load(str)
24
+ hash.each do | key, value |
25
+ p[key] = value
26
+ end
27
+ rescue SystemCallError
28
+ print_debug "# failed, setting default preferences'"
29
+ end
30
+
31
+ return p
32
+ end #}}}1
33
+
34
+ def write
35
+ #{{{1
36
+ print_debug "writing preferences to string"
37
+ return YAML.dump(self)
38
+ end #}}}1
39
+
40
+ def initialize
41
+ #{{{1
42
+ set_defaults
43
+ end #}}}1
44
+
45
+ def [](key)
46
+ #{{{1
47
+ if has_key?(key) then
48
+ return super(key)
49
+ else
50
+ raise "'#{key}' is not a valid preferences key"
51
+ end
52
+ end #}}}1
53
+
54
+ #def []=(key,value)
55
+ ##{{{1
56
+ # if has_key?(key) then
57
+ # return super(key)
58
+ # else
59
+ # raise "'#{key}' is not a valid preferences key"
60
+ # end
61
+ #end #}}}1
62
+
63
+
64
+ private
65
+
66
+ def set_defaults
67
+ #{{{1
68
+ clear
69
+ self["foreground"] = [65535, 65535, 65535]
70
+ self["background"] = [20316, 20316, 20316]
71
+ self["font"] = "Courier Bold 12"
72
+ self["text_wrap"] = true
73
+ self["deletesave_enable"] = true
74
+ self["deletesave_file"] = "$f.deleted-%Y%m"
75
+ self["confirm_delete"] = false
76
+ self["confirm_quit"] = false
77
+ self["autosave_enable"] = true
78
+ self["autosave_seconds"] = 600
79
+ end #}}}1
80
+
81
+ end # class
82
+
83
+ # vim600: set foldmethod=marker:
data/lib/svn_info.rb ADDED
@@ -0,0 +1,16 @@
1
+ # This file is creataed by './make_svn_info.rb'
2
+
3
+ module SVN_Info
4
+
5
+ SVN_PATH="."
6
+ SVN_URL="svn+ssh://solaria.426.ch/svn/jota/trunk"
7
+ SVN_REPOSITORY_ROOT="svn+ssh://solaria.426.ch/svn"
8
+ SVN_REPOSITORY_UUID="ff64bd42-7924-4c15-ba74-d98c4559417c"
9
+ SVN_REVISION="35"
10
+ SVN_NODE_KIND="directory"
11
+ SVN_SCHEDULE="normal"
12
+ SVN_LAST_CHANGED_AUTHOR="dz"
13
+ SVN_LAST_CHANGED_REV="35"
14
+ SVN_LAST_CHANGED_DATE="2009-01-26 10:30:05 +0100 (Mon, 26 Jan 2009)"
15
+
16
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,59 @@
1
+
2
+ # $Id: version.rb 35 2009-01-26 09:30:05Z dz $
3
+
4
+ require "svn_info"
5
+
6
+ class Version
7
+
8
+ include SVN_Info
9
+
10
+ MAJOR = 0
11
+ MINOR = 8
12
+ REVISION = 0
13
+
14
+ STRING = "%d.%d.%d" % [MAJOR, MINOR,REVISION]
15
+
16
+ PROGRAM_NAME = "jota"
17
+ YEARS = "2008-2009"
18
+
19
+ AUTHOR = "Derik van Zuetphen"
20
+ AUTHOR_EMAIL = "dz@426.ch"
21
+ AUTHOR_WEBSITE = "http://426.ch/jota"
22
+
23
+ LICENSE = "
24
+ Copyright (c) #{YEARS} #{AUTHOR} <#{AUTHOR_EMAIL}>
25
+ All rights reserved.
26
+
27
+ Redistribution and use in source and binary forms, with or without
28
+ modification, are permitted provided that the following conditions
29
+ are met:
30
+
31
+ 1. Redistributions of source code must retain the above copyright
32
+ notice, this list of conditions and the following disclaimer.
33
+ 2. Redistributions in binary form must reproduce the above copyright
34
+ notice, this list of conditions and the following disclaimer in the
35
+ documentation and/or other materials provided with the distribution.
36
+ 3. The name of the author may not be used to endorse or promote products
37
+ derived from this software without specific prior written permission.
38
+
39
+ THIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,
40
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
41
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
42
+ THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
43
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
44
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
45
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
46
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
47
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
48
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49
+ "
50
+
51
+ def Version.build
52
+ date,time = SVN_LAST_CHANGED_DATE.split(/ /)
53
+ date.gsub!(/[^0-9]/,"")
54
+ time.gsub!(/[^0-9]/,"")
55
+ rev = SVN_REVISION
56
+ return "#{rev}/#{date}T#{time}"
57
+ end
58
+
59
+ end # class
data/tests/test_all.rb ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # $Id: test_all.rb 28 2009-01-22 09:20:48Z dz $
4
+
5
+ # http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html
6
+
7
+ require 'test/unit'
8
+ require 'test_preferences'
9
+ require 'test_clip'
10
+ require 'test_clip_array'
@@ -0,0 +1,172 @@
1
+
2
+ # $Id: test_clip.rb 28 2009-01-22 09:20:48Z dz $
3
+
4
+ require 'test/unit'
5
+ require 'clip'
6
+
7
+ #$test_time = Time.now
8
+ # Time.now contains a usec value that cannot be saved
9
+ $test_time = Time.parse("2007-10-20 12:34:56")
10
+ $test_time_str = $test_time.ctime
11
+
12
+
13
+ def build_clip(title,data,type,wrap)
14
+ c = Clip.new
15
+ c.title = title
16
+ c.data = data # sets implicitly c.type
17
+ c.wrap = wrap
18
+ c.created = $test_time
19
+ return c
20
+ end
21
+
22
+ class TestClip < Test::Unit::TestCase
23
+
24
+ def test_new
25
+ c = Clip.new
26
+ assert_equal("",c.data)
27
+ assert_equal(:text,c.type)
28
+ assert_equal(false,c.wrap)
29
+ assert_equal("",c.title)
30
+ assert(c.empty?)
31
+ end
32
+
33
+ def test_data
34
+ c = Clip.new
35
+ c.data = "test"
36
+ assert_equal("test",c.data)
37
+ assert_equal("",c.title)
38
+ assert_equal(false,c.wrap)
39
+ assert_equal(:text,c.type)
40
+ assert(!c.empty?)
41
+ end
42
+
43
+ def test_title
44
+ c = Clip.new
45
+ c.title = "title"
46
+ assert_equal("",c.data)
47
+ assert_equal(false,c.wrap)
48
+ assert_equal("title",c.title)
49
+ assert_equal(:text,c.type)
50
+ assert(!c.empty?)
51
+ end
52
+
53
+ def test_wrap
54
+ c = Clip.new
55
+ c.data = "text"
56
+ c.title = "title"
57
+ c.wrap = true
58
+ assert_equal("text",c.data)
59
+ assert_equal(true,c.wrap)
60
+ assert_equal("title",c.title)
61
+ assert_equal(:text,c.type)
62
+ assert(!c.empty?)
63
+
64
+ c.wrap = false
65
+ assert_equal("text",c.data)
66
+ assert_equal(false,c.wrap)
67
+ assert_equal("title",c.title)
68
+ assert_equal(:text,c.type)
69
+ assert(!c.empty?)
70
+ end
71
+
72
+ def test_created
73
+ c = Clip.new
74
+ c.created = $test_time
75
+ assert_equal($test_time,c.created)
76
+ assert(c.empty?)
77
+ end
78
+
79
+ $sample = [
80
+ {
81
+ :clip => build_clip("title","text\n",:text,true),
82
+ :hash => {
83
+ "type" => :text,
84
+ "wrap" => true,
85
+ "data" => "text\n",
86
+ "title" => "title",
87
+ "created" => $test_time
88
+ },
89
+ :mbox => "Date: #{$test_time_str}
90
+ Subject: title
91
+ Content-Type: text/plain
92
+ X-Wrap: true
93
+ X-Saved-By: jota
94
+
95
+ text
96
+ "
97
+ },
98
+ {
99
+ :clip => build_clip(" title ","text\n",:text,false),
100
+ :hash => {
101
+ "type" => :text,
102
+ "wrap" => false,
103
+ "data" => "text\n",
104
+ "title" => " title ",
105
+ "created" => $test_time
106
+ },
107
+ :mbox => "Date: #{$test_time_str}
108
+ Subject: title
109
+ Content-Type: text/plain
110
+ X-Wrap: false
111
+ X-Saved-By: jota
112
+
113
+ text
114
+ "
115
+ },
116
+ {
117
+ :clip => build_clip("TITLE","text \n\n",:text,false),
118
+ :hash => {
119
+ "type" => :text,
120
+ "wrap" => false,
121
+ "data" => "text \n\n",
122
+ "title" => "TITLE",
123
+ "created" => $test_time
124
+ },
125
+ :mbox => "Date: #{$test_time_str}
126
+ Subject: TITLE
127
+ Content-Type: text/plain
128
+ X-Wrap: false
129
+ X-Saved-By: jota
130
+
131
+ text
132
+
133
+ "
134
+ }
135
+ ]
136
+
137
+ def test_to_hash
138
+ $sample.each do | sample |
139
+ c = sample[:clip]
140
+ h = c.to_hash
141
+ assert_equal(sample[:hash], h)
142
+ end
143
+ end
144
+
145
+ def test_from_hash
146
+ $sample.each do | sample |
147
+ h = sample[:hash]
148
+ c = Clip.from_hash(h)
149
+ assert_equal(sample[:clip], c)
150
+ end
151
+ end
152
+
153
+ def test_to_mbox
154
+ $sample.each do | sample |
155
+ c = sample[:clip]
156
+ r = c.to_mbox
157
+ assert_equal(sample[:mbox], r)
158
+ end
159
+ end
160
+
161
+ def test_from_mbox
162
+ $sample.each do | sample |
163
+ r = sample[:mbox]
164
+ c = Clip.from_mbox(r)
165
+ assert_equal(sample[:clip], c)
166
+ #assert_equal(sample[:clip].to_mbox, c.to_mbox)
167
+ #puts c.created.usec
168
+ #puts sample[:clip].created.usec
169
+ end
170
+ end
171
+
172
+ end # class
@@ -0,0 +1,177 @@
1
+
2
+ # $Id: test_clip_array.rb 28 2009-01-22 09:20:48Z dz $
3
+
4
+ require 'test/unit'
5
+
6
+ require 'clip'
7
+ require 'clip_array'
8
+
9
+
10
+
11
+ class TestClipArray < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @a = ClipArray.new.clear1
15
+ @c1 = Clip.new
16
+ @c1.data = "test1"
17
+ @c2 = Clip.new
18
+ @c2.data = "test2"
19
+ @c3 = Clip.new
20
+ @c3.data = "test3"
21
+ end
22
+
23
+ def test_initialized
24
+ assert_equal(0,@a.current_index)
25
+ assert_equal(1,@a.size)
26
+ assert_equal("",@a[0].data)
27
+ assert_equal(:text,@a[0].type)
28
+ end
29
+
30
+ def test_new
31
+ @a[0].data = "foo"
32
+ # [->"foo"]
33
+ assert_equal(0,@a.current_index)
34
+ assert_equal(1,@a.size)
35
+ assert_equal("foo",@a.current.data)
36
+
37
+ @a.new()
38
+ @a.current.data = "bar"
39
+ # ["foo", ->"bar"]
40
+ assert_equal(1,@a.current_index)
41
+ assert_equal(2,@a.size)
42
+ assert_equal("bar",@a.current.data)
43
+
44
+ @a.new()
45
+ # ["foo", "bar", ->""]
46
+ assert_equal(2,@a.current_index)
47
+ assert_equal(3,@a.size)
48
+ assert_equal("",@a.current.data)
49
+ end
50
+
51
+ def test_add
52
+ # [-> ""]
53
+
54
+ @a<<@c1
55
+ # ["", ->"test1"]
56
+ assert_equal(1,@a.current_index)
57
+ assert_equal(2,@a.size)
58
+ assert_equal("test1",@a[1].data)
59
+
60
+ @a<<@c2
61
+ # ["", "test1", ->"test2"]
62
+ assert_equal(2,@a.current_index)
63
+ assert_equal(3,@a.size)
64
+ assert_equal("test2",@a[2].data)
65
+
66
+ @a<<@c3
67
+ # ["", "test1", "test2", ->"test3"]
68
+ assert_equal(3,@a.current_index)
69
+ assert_equal(4,@a.size)
70
+ assert_equal("test3",@a[3].data)
71
+ end
72
+
73
+ def test_prev
74
+ @a<<@c1<<@c2<<@c3
75
+ # ["", "test1", "test2", ->"test3"]
76
+ assert_equal(3,@a.current_index)
77
+
78
+ @a.prev
79
+ # ["", "test1", ->"test2", "test3"]
80
+ assert_equal(2,@a.current_index)
81
+ assert_equal("test2",@a.current.data)
82
+
83
+ @a.prev
84
+ # ["", ->"test1", "test2", "test3"]
85
+ assert_equal(1,@a.current_index)
86
+ assert_equal("test1",@a.current.data)
87
+
88
+ @a.prev
89
+ # [->"", "test1", "test2", "test3"]
90
+ assert_equal(0,@a.current_index)
91
+ assert_equal("",@a.current.data)
92
+
93
+ @a.prev
94
+ # [->"", "test1", "test2", "test3"]
95
+ assert_equal(0,@a.current_index)
96
+ assert_equal("",@a.current.data)
97
+ end
98
+
99
+ def test_next
100
+ @a<<@c1<<@c2<<@c3
101
+ # ["", "test1", "test2", ->"test3"]
102
+
103
+ @a.next
104
+ # ["", "test1", "test2", ->"test3"]
105
+ assert_equal(3,@a.current_index)
106
+ assert_equal("test3",@a.current.data)
107
+
108
+ @a.prev.prev.prev
109
+ # [->"", "test1", "test2", "test3"]
110
+ assert_equal(0,@a.current_index)
111
+ assert_equal("",@a.current.data)
112
+
113
+ @a.next
114
+ # ["", ->"test1", "test2", "test3"]
115
+ assert_equal(1,@a.current_index)
116
+ assert_equal("test1",@a.current.data)
117
+
118
+ @a.next
119
+ # ["", "test1", ->"test2", "test3"]
120
+ assert_equal(2,@a.current_index)
121
+ assert_equal("test2",@a.current.data)
122
+ end
123
+
124
+ def test_delete
125
+ @a<<@c1<<@c2<<@c3
126
+ # ["", "test1", "test2", ->"test3"]
127
+
128
+ # delete at end
129
+ @a.delete
130
+ # ["", "test1", ->"test2"]
131
+ assert_equal(2,@a.current_index)
132
+ assert_equal(3,@a.size)
133
+ assert_equal("",@a[0].data)
134
+ assert_equal("test1",@a[1].data)
135
+ assert_equal("test2",@a[2].data)
136
+
137
+ # go back and forth, delete in the middle
138
+ @a.prev.next.prev
139
+ @a.delete
140
+ # ["", ->"test2"]
141
+ assert_equal(1,@a.current_index)
142
+ assert_equal(2,@a.size)
143
+ assert_equal("",@a[0].data)
144
+ assert_equal("test2",@a[1].data)
145
+
146
+ # go back, delete at front
147
+ @a.prev
148
+ @a.delete
149
+ # [->"test2"]
150
+ assert_equal(0,@a.current_index)
151
+ assert_equal(1,@a.size)
152
+ assert_equal("test2",@a[0].data)
153
+
154
+ # delete single
155
+ @a.delete
156
+ # [->""]
157
+ assert_equal(0,@a.current_index)
158
+ assert_equal(1,@a.size)
159
+ assert_equal("",@a[0].data)
160
+
161
+ # delete if empty
162
+ @a.delete
163
+ # [->""]
164
+ assert_equal(0,@a.current_index)
165
+ assert_equal(1,@a.size)
166
+ assert_equal("",@a[0].data)
167
+
168
+ end
169
+
170
+
171
+ def test_yaml
172
+ end
173
+
174
+ def test_mbox
175
+ end
176
+
177
+ end # class