jota 0.8.1 → 0.9.0dev2

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/INSTALL CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- $Id: INSTALL 39 2009-02-17 10:19:31Z dz $
2
+ $Id: INSTALL 248 2010-04-11 10:07:21Z dz $
3
3
 
4
4
  Jota is a written in the Ruby programming language and uses GTK+ Widgets.
5
5
 
@@ -13,9 +13,6 @@ following packages:
13
13
  - Ruby bindings for GTK+ and libglade
14
14
  - Ruby Gems the Ruby packet manager
15
15
 
16
- If you want to use the command line version of Jota, you will need the
17
- 'Cmd' gem: gem install cmd
18
-
19
16
 
20
17
  PREREQUISITES
21
18
  -------------
@@ -82,9 +79,11 @@ For the common operating systems you can use the following command:
82
79
  Go to http://ruby-gnome2.sourceforge.jp/hiki.cgi?Install+Guide+for+Windows
83
80
  and follow the three steps. In short:
84
81
 
85
- 1. install http://rubyforge.org/frs/download.php/17357/ruby185-22.exe
86
- (enable RubyGems). Install into default installation diectory.
87
- 2. install http://prdownloads.sourceforge.net/ruby-gnome2/ruby-gnome2-0.16.0-1-i386-mswin32.exe?download
82
+ 1. Install Ruby from
83
+ http://rubyforge.org/frs/download.php/47082/ruby186-27_rc2.exe
84
+ (enable RubyGems). Install into default installation directory.
85
+ 2. Install GTK+ Bindingf for Ruby from
86
+ http://prdownloads.sourceforge.net/ruby-gnome2/ruby-gnome2-0.16.0-1-i386-mswin32.exe?download
88
87
 
89
88
 
90
89
  INSTALLING
@@ -102,20 +101,6 @@ On Windows Vista you must execute gem as administrator. To do so enter
102
101
  "gem install jota" in the run box (Start menu, at the bottom) and hit
103
102
  Ctrl-Shift-Enter. Then accept the UAC dialog with "Continue".
104
103
 
105
- If you get the error "ERROR: While executing gem ... (RuntimeError)" and
106
- "jota requires cmd >= 0.7.2", you have an older version of gems that does not
107
- resolve dependencies on its own.
108
-
109
- So you have to
110
-
111
- gem install cmd
112
-
113
- before
114
-
115
- gem install jota
116
-
117
- (Only if you want to use joacli)
118
-
119
104
 
120
105
 
121
106
  RUNNING
@@ -147,3 +132,15 @@ gem uninstall jota
147
132
  gem install jota
148
133
  gem cleanup jota
149
134
 
135
+
136
+ DEVELOPMENT TOOLS
137
+ -----------------
138
+
139
+ If you want to contribute to the development of Jota you need the following
140
+ tools:
141
+
142
+ - rake "make" supplement with ruby syntax
143
+ - rdoc inline documentation generator
144
+ - rtags "tags" for ruby code
145
+
146
+
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+
2
+ Copyright (c) 2008-2010 Derik van Zuetphen <dz@426.ch>
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions
7
+ are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+ 3. The name of the author may not be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20
+ THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/bin/jota CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # $Id: jota 45 2009-05-08 09:27:26Z dz $
4
-
3
+ # $Id: jota 68 2010-01-04 14:23:45Z dz $
5
4
  begin
6
5
  require 'jota'
7
6
  rescue LoadError
data/bin/jota.bat ADDED
@@ -0,0 +1,7 @@
1
+ @echo off
2
+
3
+ rem $Id$
4
+
5
+ if "%1" == "-v" set ruby="ruby" else set ruby="rubyw"
6
+ %ruby% jota.rb %1 %2 %3 %4 %5 %6 %7 %8 %9
7
+ exit
data/lib/app_error.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- # $Id: app_error.rb 28 2009-01-22 09:20:48Z dz $
2
+ # $Id: app_error.rb 68 2010-01-04 14:23:45Z dz $
3
3
 
4
4
  class AppError < StandardError
5
5
  end
data/lib/clip.rb CHANGED
@@ -1,7 +1,5 @@
1
1
 
2
- # $Id: clip.rb 46 2009-05-08 09:27:55Z dz $
3
-
4
- # if you use vim and don't like folds type zR
2
+ # $Id: clip.rb 257 2010-05-02 19:47:26Z dz $
5
3
 
6
4
  require 'time'
7
5
  require 'version'
@@ -21,17 +19,15 @@ class Clip
21
19
  attr_accessor :wrap, :title, :created, :pos, :type, :data
22
20
 
23
21
  def initialize
24
- #{{{1
25
22
  @data = "" # no lines at all, "\n" would be 1 empty line
26
23
  @wrap = false
27
24
  @type = :text
28
25
  @title = ""
29
26
  @created = Time.now
30
27
  @pos = 0
31
- end #}}}1
28
+ end
32
29
 
33
30
  def Clip.from_mbox(str)
34
- #{{{1
35
31
  # "From_" line already removed
36
32
  cl = Clip.new
37
33
  in_header = true
@@ -68,10 +64,9 @@ def Clip.from_mbox(str)
68
64
  end
69
65
  end
70
66
  return cl
71
- end #}}}1
67
+ end
72
68
 
73
69
  def to_mbox
74
- #{{{1
75
70
  str = ""
76
71
  charset = "UTF-8"
77
72
 
@@ -97,10 +92,9 @@ def to_mbox
97
92
  str << @data
98
93
 
99
94
  return str
100
- end #}}}1
95
+ end
101
96
 
102
97
  def Clip.from_hash(hash)
103
- #{{{1
104
98
  cl = Clip.new
105
99
  case hash["type"]
106
100
  when :text
@@ -110,10 +104,9 @@ def Clip.from_hash(hash)
110
104
  cl.created = hash["created"]
111
105
  end
112
106
  return cl
113
- end #}}}1
107
+ end
114
108
 
115
109
  def to_hash
116
- #{{{1
117
110
  hash = Hash.new
118
111
  hash["type"] = @type
119
112
  hash["wrap"] = @wrap
@@ -121,43 +114,29 @@ def to_hash
121
114
  hash["title"] = @title
122
115
  hash["created"] = @created
123
116
  return hash
124
- end #}}}1
125
-
126
- def append_as_mbox(file_and_path)
127
- #{{{1
128
- print_verbose "append to mbox '#{file_and_path}'"
129
- File.open(file_and_path,"a") do | f |
130
- f.print "From %s@localhost %s\n" %
131
- [Version::PROGRAM_NAME, Time.now.ctime]
132
- f.print(to_mbox)
133
- end
134
- end #}}}1
117
+ end
118
+
135
119
 
136
120
  def empty?
137
- #{{{1
138
121
  # strip also removes LFs
139
122
  return @data.strip == "" && @title.strip == ""
140
- end #}}}1
123
+ end
141
124
 
142
125
  def ==(clip)
143
- #{{{1
144
126
  return self.to_hash == clip.to_hash
145
- end #}}}1
127
+ end
146
128
 
147
129
  # POSSIBLE CASES FOR TEXT <-> TITLE/DATA CONVERSION
148
- # # {{{1
149
- # # text title data
150
- # # a) "" 1) "" ""
151
- # # b) abc 2) abc ""
152
- # # c) abc\n 2) abc ""
153
- # # d) abc\n 3) abc def\n
154
- # # def
155
- # # e) abc\n 3) abc def\n
156
- # # def\n
157
- # # }}}1
130
+ # text title data
131
+ # a) "" 1) "" ""
132
+ # b) abc 2) abc ""
133
+ # c) abc\n 2) abc ""
134
+ # d) abc\n 3) abc def\n
135
+ # def
136
+ # e) abc\n 3) abc def\n
137
+ # def\n
158
138
 
159
139
  def text
160
- #{{{1
161
140
  if @title == "" and @data == "" then
162
141
  # map (1) to (a)
163
142
  return ""
@@ -165,10 +144,9 @@ def text
165
144
  # map (2) to (b) and (3) to (d)
166
145
  return "%s\n%s" % [@title,@data]
167
146
  end
168
- end #}}}1
147
+ end
169
148
 
170
149
  def text=(str)
171
- # {{{1
172
150
  # map (a),(b) to (c) and (d) to (e)
173
151
  str = str.chomp + "\n"
174
152
 
@@ -177,9 +155,15 @@ def text=(str)
177
155
  # the last elem is empty
178
156
  @title = arr[0] # first elem = first line
179
157
  @data = arr[1..-1].join("\n") # second to last elem
180
- end #}}}1
158
+ end
181
159
 
160
+ # Return modified title for easier readabiliy
161
+ def title!
162
+ if @title == "" then
163
+ return "..."
164
+ else
165
+ return @title
166
+ end
167
+ end
182
168
 
183
169
  end #class
184
-
185
- # vim: set foldmethod=marker:
data/lib/clip_array.rb CHANGED
@@ -1,7 +1,6 @@
1
1
 
2
- # $Id: clip_array.rb 53 2009-09-24 14:22:04Z dz $
2
+ # $Id: clip_array.rb 271 2010-07-29 18:56:41Z dz $
3
3
 
4
- # if you use vim and don't like folds type zR
5
4
 
6
5
 
7
6
  require 'app_error'
@@ -19,7 +18,6 @@ class ClipArray < Array
19
18
  # filename String ni name of current file
20
19
  # dirname String ni directory of current file
21
20
  # file File ni current File object
22
- # autosave_thread Thread nil thread for autosaving
23
21
 
24
22
 
25
23
  attr_reader :current_index, :file, :filename, :dirname, :file_and_path
@@ -27,49 +25,43 @@ attr_accessor :pref
27
25
 
28
26
  # Clear array and reset index
29
27
  def clear
30
- #{{{1
31
28
  super
32
29
  @current_index = -1
33
- end #}}}1
30
+ end
34
31
 
35
32
  # Clear array and create one empty clip
36
33
  def clear1
37
- #{{{1
38
34
  clear
39
35
  self << Clip.new
40
- end #}}}1
36
+ end
41
37
 
42
38
  def initialize
43
- #{{{1
44
39
  clear
45
40
  @file = nil
46
41
  @filename = nil
47
42
  @pref = Preferences.defaults
48
- @autosave_thread = nil
49
43
  print_verbose "initializing clip array"
50
- end #}}}1
44
+ end
51
45
 
52
46
  def <<(clip)
53
- #{{{1
54
47
  push(clip)
55
48
  @current_index = length-1
56
49
  return self
57
- end #}}}1
50
+ end
58
51
 
59
52
  def set_file(file,file_and_path)
60
- #{{{1
61
53
  @file = file
62
54
  @file_and_path = file_and_path
63
55
  @filename = File.basename(file_and_path)
64
56
  @dirname = File.dirname(file_and_path)
65
- end #}}}1
57
+ end
66
58
 
67
59
  #
68
60
  # Export
69
61
  #
70
62
 
71
63
  #def save_as_mbox(filename)
72
- ##{{{1
64
+ #
73
65
  # filename = get_filename(filename,:save)
74
66
  #
75
67
  # puts "# saving clips to '#{filename}', format mbox" if $VERBOSE
@@ -78,15 +70,15 @@ end #}}}1
78
70
  # write_mbox(f)
79
71
  # self.each do | clip |
80
72
  # f.print "From %s@localhost %s\n" %
81
- # [Version::PROGRAM_NAME, Time.now.ctime]
73
+ # [Version::PROGRAM_NAMELC, Time.now.ctime]
82
74
  # f.print(escape_from(clip.to_mbox.chomp))
83
75
  # f.print("\n")
84
76
  # end
85
77
  # f.close
86
- #end #}}}1
78
+ #end
87
79
  #
88
80
  #def save_as_yaml(filename)
89
- ##{{{1
81
+ #
90
82
  # filename = get_filename(filename,:save)
91
83
  #
92
84
  # arr = Array.new
@@ -99,34 +91,41 @@ end #}}}1
99
91
  # File.open(filename,"w") do | file |
100
92
  # YAML::dump(arr, file)
101
93
  # end
102
- #end #}}}1
94
+ #end
103
95
 
104
96
  #def ClipArray.load(filename,format)
105
- ##{{{1
97
+ #
106
98
  # case format
107
99
  # when :mbox
108
100
  # return ClipArray.load_from_mbox(filename)
109
101
  # when :yaml
110
102
  # return ClipArray.load_from_yaml(filename)
111
103
  # end
112
- #end #}}}1
104
+ #end
113
105
 
114
106
  def goto_regexp(re)
115
- #{{{1
116
- if re =~ /^\s*\d+\s*$/ then
117
- self.current_index = re.to_i-1
107
+ return nil if re.nil?
108
+
109
+ md = re.match(/^\s*#(\d+)\s*$/)
110
+ if md then
111
+ index = md[1].to_i
112
+ if index < 1 or index > length then
113
+ return nil
114
+ end
115
+ @current_index = index-1
116
+ return @current_index
118
117
  else
119
118
  self.each_index do | i |
120
119
  if self[i].title.match(re) then
121
120
  @current_index = i
122
- break
121
+ return @current_index
123
122
  end
124
123
  end
124
+ return nil
125
125
  end
126
- end #}}}1
126
+ end
127
127
 
128
128
  def current_index=(num)
129
- #{{{1
130
129
  if num < 0 then
131
130
  @current_index = 0
132
131
  elsif num >= length then
@@ -135,28 +134,25 @@ def current_index=(num)
135
134
  @current_index = num
136
135
  end
137
136
  print_verbose "going to clip #{@current_index+1}"
138
- end #}}}1
137
+ end
139
138
 
140
139
  def next
141
- #{{{1
142
140
  if @current_index < length-1 then
143
141
  @current_index += 1
144
142
  print_verbose "going to next clip #{@current_index+1}"
145
143
  end
146
144
  return self
147
- end #}}}1
145
+ end
148
146
 
149
147
  def prev
150
- #{{{1
151
148
  if @current_index > 0 then
152
149
  @current_index -= 1
153
150
  print_verbose "going to previous clip #{@current_index+1}"
154
151
  end
155
152
  return self
156
- end #}}}1
153
+ end
157
154
 
158
155
  def delete
159
- #{{{1
160
156
  if @current_index == length-1 then
161
157
  new_current_index = @current_index - 1
162
158
  else
@@ -172,23 +168,26 @@ def delete
172
168
  @current_index = new_current_index
173
169
  end
174
170
 
175
- end #}}}1
171
+ end
176
172
 
177
173
  def new
178
- #{{{1
179
- c = Clip.new
180
- push(c)
181
- @current_index = length-1
182
- print_verbose "creating new clip #{@current_index+1}"
183
- end #}}}1
174
+ if length > 0 and self[length-1].empty? then
175
+ @current_index = length-1
176
+ print_verbose "last clip alread empty, going to last clip"
177
+ else
178
+ c = Clip.new
179
+ push(c)
180
+ @current_index = length-1
181
+ print_verbose "creating new clip #{@current_index+1}"
182
+ end
183
+ end
184
184
 
185
185
  def current
186
- #{{{1
187
186
  return self[@current_index]
188
- end #}}}1
187
+ end
189
188
 
190
189
  #def ClipArray.load_from_yaml(filename)
191
- ##{{{1
190
+ #
192
191
  # filename = get_filename(filename,:open)
193
192
  # ca = self.new
194
193
  #
@@ -207,10 +206,10 @@ end #}}}1
207
206
  #
208
207
  # ca.current_index = ca.length - 1
209
208
  # return ca
210
- #end #}}}1
209
+ #end
211
210
  #
212
211
  #def ClipArray.load_from_mbox(filename)
213
- ##{{{1
212
+ #
214
213
  # ca = self.new
215
214
  # str = nil
216
215
  #
@@ -224,10 +223,40 @@ end #}}}1
224
223
  # end
225
224
  #
226
225
  # return ca
227
- #end #}}}1
226
+ #end
227
+
228
+ #
229
+ # Locking
230
+ #
231
+
232
+ def ClipArray.obtain_shared_lock(file)
233
+ release_lock(file) # necessary for win32
234
+
235
+ # a shared, non-blocking lock
236
+ print_debug "obtaining SHARED LOCK on '#{file.path}'"
237
+ if not file.flock(File::LOCK_SH|File::LOCK_NB) then
238
+ print_debug " cannot lock"
239
+ #file.flock(File::LOCK_SH) TODO
240
+ end
241
+ end
242
+
243
+ def ClipArray.obtain_exclusive_lock(file)
244
+ release_lock(file) # necessary for win32
245
+
246
+ # an exclusive, non-blocking lock
247
+ print_debug "obtaining EXCLUSIVE LOCK on '#{file.path}'"
248
+ if not file.flock(File::LOCK_EX|File::LOCK_NB) then
249
+ print_debug " cannot lock"
250
+ #file.flock(File::LOCK_EX) TODO
251
+ end
252
+ end
253
+
254
+ def ClipArray.release_lock(file)
255
+ print_debug "releasing LOCK from '#{file.path}'"
256
+ file.flock(File::LOCK_UN)
257
+ end
228
258
 
229
259
  def ClipArray.create(file_and_path)
230
- #{{{1
231
260
  print_verbose "creating file '#{file_and_path}'"
232
261
 
233
262
  if File.exists?(file_and_path) then
@@ -240,19 +269,18 @@ def ClipArray.create(file_and_path)
240
269
  ca.set_file(file,file_and_path)
241
270
 
242
271
  # test if writable
243
- obtain_exclusive_lock(file)
272
+ ClipArray.obtain_exclusive_lock(file)
244
273
 
245
- obtain_shared_lock(file)
274
+ ClipArray.obtain_shared_lock(file)
246
275
  rescue Exception
247
276
  file.close if file
248
277
  raise
249
278
  end
250
279
 
251
280
  return ca
252
- end #}}}1
281
+ end
253
282
 
254
283
  def ClipArray.open(file_and_path)
255
- #{{{1
256
284
  print_verbose "opening file '#{file_and_path}'"
257
285
 
258
286
  begin
@@ -261,77 +289,58 @@ def ClipArray.open(file_and_path)
261
289
  ca.set_file(file,file_and_path)
262
290
 
263
291
  # test if writable
264
- obtain_exclusive_lock(file)
292
+ ClipArray.obtain_exclusive_lock(file)
265
293
 
266
- obtain_shared_lock(file)
294
+ ClipArray.obtain_shared_lock(file)
267
295
  rescue Exception
268
296
  file.close if file
269
297
  raise
270
298
  end
271
299
 
272
300
  return ca
273
- end #}}}1
301
+ end
274
302
 
275
303
  def save
276
- #{{{1
277
304
  if @file.nil? then
278
305
  return
279
306
  end
280
307
 
281
308
  print_verbose "saving file '#{@filename}'"
282
309
 
283
- obtain_exclusive_lock(@file)
310
+ ClipArray.obtain_exclusive_lock(@file)
284
311
  @file.truncate(0)
285
312
  @file.rewind
286
313
  write_mbox(@file)
287
314
  @file.flush
288
- obtain_shared_lock(@file)
289
- end #}}}1
315
+ ClipArray.obtain_shared_lock(@file)
316
+ end
317
+
318
+ def append(file)
319
+ print_verbose "append to mbox '#{file}'"
320
+ File.open(file,"a") do | f |
321
+ f.print "From %s@localhost %s\n" %
322
+ [Version::PROGRAM_NAMELC, Time.now.ctime]
323
+ f.print(escape_from(self[@current_index].to_mbox.chomp))
324
+ f.print("\n")
325
+ end
326
+ end
290
327
 
291
328
  def close
292
- #{{{1
293
- autosave(0)
294
329
  save
295
330
  print_verbose "closing file '#{@filename}'"
296
331
  if @file then
297
- release_lock(@file)
332
+ ClipArray.release_lock(@file)
298
333
  @file.close
299
334
  end
300
335
  @file = nil
301
336
  @filename = nil
302
337
  clear
303
- end #}}}1
304
-
305
- def autosave(seconds)
306
- #{{{1
307
- print_debug "autosave(#{seconds}) called"
308
- if @autosave_thread then
309
- print_debug " killing old thread"
310
- @autosave_thread.kill
311
- @autosave_thread = nil
312
- end
313
-
314
- if seconds == 0 then
315
- print_debug " returning because seconds==0"
316
- return
317
- end
318
-
319
- print_verbose "starting autosave thread"
320
- @autosave_thread = Thread.new do
321
- while true
322
- print_verbose "autosaving at #{Time.now}"
323
- save
324
- sleep(seconds)
325
- end
326
- end
327
- end #}}}1
328
-
338
+ end
329
339
 
330
340
  private
331
341
 
332
342
 
333
343
  def ClipArray.read_mbox(file)
334
- #{{{1
335
344
  ca = self.new
336
345
  first_line = true
337
346
  str = ""
@@ -379,10 +388,9 @@ def ClipArray.read_mbox(file)
379
388
 
380
389
  ca.current_index = ca.length - 1
381
390
  return ca
382
- end #}}}1
391
+ end
383
392
 
384
393
  def write_mbox(file)
385
- #{{{1
386
394
  print_debug "writing clips, mbox format"
387
395
  i = 1
388
396
 
@@ -394,14 +402,12 @@ def write_mbox(file)
394
402
 
395
403
  ([pc]+self).each do | clip |
396
404
  file.print "From %s@localhost %s\n" %
397
- [Version::PROGRAM_NAME, Time.now.ctime]
405
+ [Version::PROGRAM_NAMELC, Time.now.ctime]
398
406
  file.print(escape_from(clip.to_mbox.chomp))
399
407
  file.print("\n")
400
408
  print_debug " #{i}: '#{clip.title}'"
401
409
  i += 1
402
410
  end
403
- end #}}}1
411
+ end
404
412
 
405
413
  end # class
406
-
407
- # vim: set foldmethod=marker: