diakonos 0.8.8 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +433 -0
  3. data/LICENCE.md +675 -0
  4. data/bin/diakonos +6 -0
  5. data/diakonos-256-colour.conf +220 -0
  6. data/diakonos.conf +1802 -0
  7. data/help/about-help.dhf +31 -0
  8. data/help/clipboard.dhf +45 -0
  9. data/help/close-file.dhf +6 -0
  10. data/help/code-block-navigation.dhf +16 -0
  11. data/help/column-markers.dhf +15 -0
  12. data/help/config.dhf +69 -0
  13. data/help/cursor-stack.dhf +19 -0
  14. data/help/delete.dhf +41 -0
  15. data/help/extensions.dhf +125 -0
  16. data/help/file-type.dhf +24 -0
  17. data/help/key-mapping.dhf +127 -0
  18. data/help/line-numbers.dhf +22 -0
  19. data/help/macros.dhf +27 -0
  20. data/help/new-file.dhf +6 -0
  21. data/help/open-file.dhf +21 -0
  22. data/help/quit.dhf +7 -0
  23. data/help/resizing.dhf +19 -0
  24. data/help/ruby.dhf +17 -0
  25. data/help/save-file.dhf +10 -0
  26. data/help/scripting.dhf +92 -0
  27. data/help/search.dhf +103 -0
  28. data/help/shell.dhf +60 -0
  29. data/help/speed.dhf +23 -0
  30. data/help/support.dhf +15 -0
  31. data/help/switch-buffers.dhf +15 -0
  32. data/help/tabs.dhf +36 -0
  33. data/help/undo.dhf +9 -0
  34. data/help/uninstall.dhf +18 -0
  35. data/help/welcome.dhf +32 -0
  36. data/help/word-wrap.dhf +17 -0
  37. data/lib/diakonos/about.rb +69 -0
  38. data/lib/diakonos/bookmark.rb +46 -0
  39. data/lib/diakonos/buffer/bookmarking.rb +47 -0
  40. data/lib/diakonos/buffer/cursor.rb +335 -0
  41. data/lib/diakonos/buffer/delete.rb +170 -0
  42. data/lib/diakonos/buffer/display.rb +356 -0
  43. data/lib/diakonos/buffer/file.rb +157 -0
  44. data/lib/diakonos/buffer/indentation.rb +175 -0
  45. data/lib/diakonos/buffer/searching.rb +552 -0
  46. data/lib/diakonos/buffer/selection.rb +360 -0
  47. data/lib/diakonos/buffer/undo.rb +73 -0
  48. data/lib/diakonos/buffer-hash.rb +60 -0
  49. data/lib/diakonos/buffer-management.rb +59 -0
  50. data/lib/diakonos/buffer.rb +698 -0
  51. data/lib/diakonos/clipboard-klipper-dbus.rb +62 -0
  52. data/lib/diakonos/clipboard-klipper.rb +62 -0
  53. data/lib/diakonos/clipboard-osx.rb +59 -0
  54. data/lib/diakonos/clipboard-xclip.rb +60 -0
  55. data/lib/diakonos/clipboard.rb +47 -0
  56. data/lib/diakonos/config-file.rb +67 -0
  57. data/lib/diakonos/config.rb +381 -0
  58. data/lib/diakonos/core-ext/enumerable.rb +15 -0
  59. data/lib/diakonos/core-ext/hash.rb +60 -0
  60. data/lib/diakonos/core-ext/object.rb +6 -0
  61. data/lib/diakonos/core-ext/regexp.rb +6 -0
  62. data/lib/diakonos/core-ext/string.rb +122 -0
  63. data/lib/diakonos/ctag.rb +28 -0
  64. data/lib/diakonos/cursor.rb +27 -0
  65. data/lib/diakonos/display/format.rb +75 -0
  66. data/lib/diakonos/display.rb +336 -0
  67. data/lib/diakonos/extension-set.rb +49 -0
  68. data/lib/diakonos/extension.rb +34 -0
  69. data/lib/diakonos/finding.rb +40 -0
  70. data/lib/diakonos/functions/basics.rb +34 -0
  71. data/lib/diakonos/functions/bookmarking.rb +61 -0
  72. data/lib/diakonos/functions/buffers.rb +489 -0
  73. data/lib/diakonos/functions/clipboard.rb +70 -0
  74. data/lib/diakonos/functions/cursor.rb +264 -0
  75. data/lib/diakonos/functions/grepping.rb +83 -0
  76. data/lib/diakonos/functions/indentation.rb +71 -0
  77. data/lib/diakonos/functions/readline.rb +93 -0
  78. data/lib/diakonos/functions/search.rb +179 -0
  79. data/lib/diakonos/functions/selection.rb +98 -0
  80. data/lib/diakonos/functions/sessions.rb +78 -0
  81. data/lib/diakonos/functions/shell.rb +250 -0
  82. data/lib/diakonos/functions/tags.rb +65 -0
  83. data/lib/diakonos/functions/text-manipulation.rb +196 -0
  84. data/lib/diakonos/functions-deprecated.rb +77 -0
  85. data/lib/diakonos/functions.rb +292 -0
  86. data/lib/diakonos/grep.rb +98 -0
  87. data/lib/diakonos/help.rb +47 -0
  88. data/lib/diakonos/hooks.rb +13 -0
  89. data/lib/diakonos/installation.rb +19 -0
  90. data/lib/diakonos/interaction-handler.rb +216 -0
  91. data/lib/diakonos/interaction.rb +52 -0
  92. data/lib/diakonos/key-map.rb +62 -0
  93. data/lib/diakonos/keying.rb +442 -0
  94. data/lib/diakonos/line-mover.rb +42 -0
  95. data/lib/diakonos/list.rb +59 -0
  96. data/lib/diakonos/logging.rb +27 -0
  97. data/lib/diakonos/mode.rb +17 -0
  98. data/lib/diakonos/mouse.rb +18 -0
  99. data/lib/diakonos/number-fitter.rb +11 -0
  100. data/lib/diakonos/range.rb +31 -0
  101. data/lib/diakonos/readline/functions.rb +82 -0
  102. data/lib/diakonos/readline.rb +222 -0
  103. data/lib/diakonos/search.rb +58 -0
  104. data/lib/diakonos/sessions.rb +257 -0
  105. data/lib/diakonos/sized-array.rb +48 -0
  106. data/lib/diakonos/text-mark.rb +19 -0
  107. data/lib/diakonos/vendor/fuzzy_file_finder.rb +365 -0
  108. data/lib/diakonos/version.rb +25 -0
  109. data/lib/diakonos/window.rb +43 -0
  110. data/lib/diakonos.rb +592 -0
  111. metadata +160 -66
@@ -0,0 +1,442 @@
1
+ module Diakonos
2
+ module Keying
3
+
4
+ KEYSTRINGS = [
5
+ "ctrl+space", # 0
6
+ "ctrl+a", # 1
7
+ "ctrl+b", # 2
8
+ "ctrl+c", # 3
9
+ "ctrl+d", # 4
10
+ "ctrl+e", # 5
11
+ "ctrl+f", # 6
12
+ "ctrl+g", # 7
13
+ nil, # 8
14
+ "tab", # 9
15
+ "ctrl+j", # 10
16
+ "ctrl+k", # 11
17
+ "ctrl+l", # 12
18
+ "enter", # 13
19
+ "ctrl+n", # 14
20
+ "ctrl+o", # 15
21
+ "ctrl+p", # 16
22
+ "ctrl+q", # 17
23
+ "ctrl+r", # 18
24
+ "ctrl+s", # 19
25
+ "ctrl+t", # 20
26
+ "ctrl+u", # 21
27
+ "ctrl+v", # 22
28
+ "ctrl+w", # 23
29
+ "ctrl+x", # 24
30
+ "ctrl+y", # 25
31
+ "ctrl+z", # 26
32
+ "esc", # 27
33
+ nil, # 28
34
+ nil, # 29
35
+ nil, # 30
36
+ nil, # 31
37
+ "space", # 32
38
+ ] + (33..126).map(&:chr) + [
39
+ "backspace" # 127
40
+ ]
41
+
42
+ def self.keycodes_for( str )
43
+ retval = case str.downcase
44
+ when "down"
45
+ Curses::KEY_DOWN
46
+ when "up"
47
+ Curses::KEY_UP
48
+ when "left"
49
+ Curses::KEY_LEFT
50
+ when "right"
51
+ Curses::KEY_RIGHT
52
+ when "home"
53
+ Curses::KEY_HOME
54
+ when "end"
55
+ Curses::KEY_END
56
+ when "insert", "ins"
57
+ Curses::KEY_IC
58
+ when "delete", "del"
59
+ Curses::KEY_DC
60
+ when "backspace"
61
+ ::Diakonos::BACKSPACE
62
+ when "tab"
63
+ 9
64
+ when "pageup", "page-up"
65
+ Curses::KEY_PPAGE
66
+ when "pagedown", "page-down"
67
+ Curses::KEY_NPAGE
68
+ when "enter", "return"
69
+ ::Diakonos::ENTER
70
+ when "numpad7", "keypad7", "kp-7"
71
+ Curses::KEY_A1
72
+ when "numpad9", "keypad9", "kp-9"
73
+ Curses::KEY_A3
74
+ when "numpad5", "keypad5", "kp-5"
75
+ Curses::KEY_B2
76
+ when "numpad1", "keypad1", "kp-1"
77
+ Curses::KEY_C1
78
+ when "numpad3", "keypad3", "kp-3"
79
+ Curses::KEY_C3
80
+ when "escape", "esc"
81
+ ::Diakonos::ESCAPE
82
+ when "space"
83
+ 32
84
+ when "ctrl+space"
85
+ 0
86
+ when "find"
87
+ Curses::KEY_FIND
88
+ when "select"
89
+ Curses::KEY_SELECT
90
+ when "suspend"
91
+ Curses::KEY_SUSPEND
92
+ when /^f(\d\d?)$/
93
+ Curses::KEY_F0 + $1.to_i
94
+ when /^ctrl\+[a-gi-z]$/
95
+ str.downcase[ -1 ].ord - 96
96
+ when /^ctrl\+h$/
97
+ ::Diakonos::CTRL_H
98
+ when /^alt\+(.)$/
99
+ [ ::Diakonos::ESCAPE, $1[ 0 ].ord ]
100
+ when /^ctrl\+alt\+(.)$/, /^alt\+ctrl\+(.)$/
101
+ [ ::Diakonos::ESCAPE, str.downcase[ -1 ].ord - 96 ]
102
+ when /^keycode(\d+)$/
103
+ $1.to_i
104
+ when /^.$/
105
+ str[ 0 ].ord
106
+ end
107
+ Array( retval )
108
+ end
109
+
110
+ def self.key_string_for( num )
111
+ retval = KEYSTRINGS[ num ]
112
+ if retval.nil?
113
+ retval = case num
114
+ when Curses::KEY_DOWN
115
+ "down"
116
+ when Curses::KEY_UP
117
+ "up"
118
+ when Curses::KEY_LEFT
119
+ "left"
120
+ when Curses::KEY_RIGHT
121
+ "right"
122
+ when Curses::KEY_HOME
123
+ "home"
124
+ when Curses::KEY_END
125
+ "end"
126
+ when Curses::KEY_IC
127
+ "insert"
128
+ when Curses::KEY_DC
129
+ "delete"
130
+ when Curses::KEY_PPAGE
131
+ "page-up"
132
+ when Curses::KEY_NPAGE
133
+ "page-down"
134
+ when Curses::KEY_A1
135
+ "numpad7"
136
+ when Curses::KEY_A3
137
+ "numpad9"
138
+ when Curses::KEY_B2
139
+ "numpad5"
140
+ when Curses::KEY_C1
141
+ "numpad1"
142
+ when Curses::KEY_C3
143
+ "numpad3"
144
+ when Curses::KEY_FIND
145
+ "find"
146
+ when Curses::KEY_SELECT
147
+ "select"
148
+ when Curses::KEY_SUSPEND
149
+ "suspend"
150
+ when Curses::KEY_F0..(Curses::KEY_F0 + 24)
151
+ "f" + ( num - Curses::KEY_F0 ).to_s
152
+ when CTRL_H
153
+ "ctrl+h"
154
+ when Curses::KEY_RESIZE
155
+ "resize"
156
+ when RESIZE2
157
+ "resize2"
158
+ end
159
+ end
160
+ if retval.nil? && num.class == Integer
161
+ retval = "keycode#{num}"
162
+ end
163
+ retval
164
+ end
165
+
166
+ UTF_8_2_BYTE_BEGIN = 0xc2
167
+ UTF_8_2_BYTE_END = 0xdf
168
+ UTF_8_3_BYTE_BEGIN = 0xe0
169
+ UTF_8_3_BYTE_END = 0xef
170
+ UTF_8_4_BYTE_BEGIN = 0xf0
171
+ UTF_8_4_BYTE_END = 0xf4
172
+ end
173
+
174
+ class Diakonos
175
+ def keychain_str_for( array )
176
+ chain_str = ""
177
+ array.each do |key|
178
+ key_str = Keying.key_string_for( key )
179
+ if key_str
180
+ chain_str << key_str + " "
181
+ else
182
+ chain_str << key.to_s + " "
183
+ end
184
+ end
185
+ chain_str.strip
186
+ end
187
+
188
+ def capture_keychain( c, context )
189
+ if c == ENTER
190
+ @capturing_keychain = false
191
+ buffer_current.delete_selection
192
+ str = keychain_str_for( context )
193
+ buffer_current.insert_string str
194
+ cursor_right( Buffer::STILL_TYPING, str.length )
195
+ else
196
+ keychain_pressed = context.concat [ c ]
197
+
198
+ function_and_args = @modes[ 'edit' ].keymap.get_leaf( keychain_pressed )
199
+
200
+ if function_and_args
201
+ function, args = function_and_args
202
+ end
203
+
204
+ partial_keychain = @modes[ 'edit' ].keymap.get_node( keychain_pressed )
205
+ if partial_keychain
206
+ set_iline( "Part of existing keychain: " + keychain_str_for( keychain_pressed ) + "..." )
207
+ else
208
+ set_iline keychain_str_for( keychain_pressed ) + "..."
209
+ end
210
+ process_keystroke keychain_pressed
211
+ end
212
+ end
213
+
214
+ def capture_mapping( c, context )
215
+ if c == ENTER
216
+ @capturing_mapping = false
217
+ buffer_current.delete_selection
218
+ set_iline
219
+ else
220
+ keychain_pressed = context.concat [ c ]
221
+
222
+ function_and_args = @modes[ 'edit' ].keymap.get_leaf( keychain_pressed )
223
+
224
+ if function_and_args
225
+ function, args = function_and_args
226
+ set_iline "#{keychain_str_for( keychain_pressed )} -> #{function}( #{args} )"
227
+ else
228
+ partial_keychain = @modes[ 'edit' ].keymap.get_node( keychain_pressed )
229
+ if partial_keychain
230
+ set_iline( "Several mappings start with: " + keychain_str_for( keychain_pressed ) + "..." )
231
+ process_keystroke keychain_pressed
232
+ else
233
+ set_iline "There is no mapping for " + keychain_str_for( keychain_pressed )
234
+ end
235
+ end
236
+ end
237
+ end
238
+
239
+ def typeable?( char )
240
+ char > 31 && char < 255 && char != BACKSPACE
241
+ end
242
+
243
+ # @param [Integer] c The first byte of a UTF-8 byte sequence
244
+ # @return [String] nil if c is not the beginning of a multi-byte sequence
245
+ def utf_8_bytes_to_char(c, mode)
246
+ if Keying::UTF_8_2_BYTE_BEGIN <= c && c <= Keying::UTF_8_2_BYTE_END
247
+ # 2-byte character
248
+ byte_array = [c, @modes[mode].window.getch.ord]
249
+ elsif Keying::UTF_8_3_BYTE_BEGIN <= c && c <= Keying::UTF_8_3_BYTE_END
250
+ # 3-byte character
251
+ byte_array = [
252
+ c,
253
+ @modes[mode].window.getch.ord,
254
+ @modes[mode].window.getch.ord,
255
+ ]
256
+ elsif Keying::UTF_8_4_BYTE_BEGIN <= c && c <= Keying::UTF_8_4_BYTE_END
257
+ # 4-byte character
258
+ byte_array = [
259
+ c,
260
+ @modes[mode].window.getch.ord,
261
+ @modes[mode].window.getch.ord,
262
+ @modes[mode].window.getch.ord,
263
+ ]
264
+ else
265
+ return nil
266
+ end
267
+
268
+ byte_array.pack('C*').force_encoding('utf-8')
269
+ end
270
+
271
+ # @param [Integer] c The ordinal (number) of a character
272
+ # @param [String] mode
273
+ # @return [Boolean] true iff c began a UTF-8 byte sequence
274
+ def handle_utf_8(c, mode)
275
+ utf_8_char = utf_8_bytes_to_char(c, mode)
276
+ if utf_8_char
277
+ self.type_character utf_8_char, mode
278
+ true
279
+ end
280
+ end
281
+
282
+ # Handle paste from a GUI (like x.org). i.e. Shift-Insert
283
+ def handle_gui_paste(mode)
284
+ s = ""
285
+ ch = nil
286
+
287
+ loop do
288
+ ch = nil
289
+ begin
290
+ Timeout::timeout(0.02) do
291
+ ch = @modes[mode].window.getch
292
+ end
293
+ rescue Timeout::Error => e
294
+ break
295
+ end
296
+ break if ch.nil?
297
+
298
+ c = ch.ord
299
+ utf_8_char = self.utf_8_bytes_to_char(c, mode)
300
+
301
+ if utf_8_char
302
+ s << utf_8_char
303
+ elsif self.typeable?(c)
304
+ s << c
305
+ elsif c == ENTER && mode == 'edit'
306
+ s << "\n"
307
+ else
308
+ break
309
+ end
310
+ end
311
+
312
+ if ! s.empty?
313
+ case mode
314
+ when 'edit'
315
+ buffer_current.paste s, Buffer::TYPING
316
+ when 'input'
317
+ @readline.paste s
318
+ end
319
+ end
320
+
321
+ if ch
322
+ process_keystroke( [], mode, ch )
323
+ end
324
+ end
325
+
326
+ # context is an array of characters (bytes) which are keystrokes previously
327
+ # typed (in a chain of keystrokes)
328
+ def process_keystroke( context = [], mode = 'edit', ch = nil )
329
+ ch ||= @modes[ mode ].window.getch
330
+ return if ch.nil?
331
+
332
+ if ch == Curses::KEY_MOUSE
333
+ handle_mouse_event
334
+ return
335
+ end
336
+
337
+ c = ch.ord
338
+
339
+ self.handle_utf_8(c, mode) and return
340
+
341
+ if @capturing_keychain
342
+ capture_keychain c, context
343
+ elsif @capturing_mapping
344
+ capture_mapping c, context
345
+ else
346
+
347
+ if context.empty? && typeable?( c )
348
+ self.type_character ch, mode
349
+ self.handle_gui_paste(mode)
350
+ return
351
+ end
352
+
353
+ keychain_pressed = context.concat [ c ]
354
+
355
+ function_and_args = (
356
+ @modes[mode].keymap_after[@function_last].get_leaf( keychain_pressed ) ||
357
+ @modes[mode].keymap.get_leaf( keychain_pressed )
358
+ )
359
+
360
+ if function_and_args
361
+ function, args = function_and_args
362
+ @function_last = function
363
+
364
+ if mode != 'input' && ! @settings[ "context.combined" ]
365
+ set_iline
366
+ end
367
+
368
+ if args
369
+ to_eval = "#{function}( #{args} )"
370
+ else
371
+ to_eval = function
372
+ end
373
+
374
+ if @macro_history
375
+ @macro_history.push to_eval
376
+ end
377
+
378
+ begin
379
+ if buffer_current.search_area? && ! ( /^(?:find|readline)/ === to_eval )
380
+ buffer_current.clear_search_area
381
+ end
382
+ eval to_eval, nil, "eval"
383
+ @functions_last << to_eval unless to_eval == "repeat_last"
384
+ if ! @there_was_non_movement
385
+ @there_was_non_movement = !( /^((cursor|page|scroll)_?(up|down|left|right)|find|seek)/i === to_eval )
386
+ end
387
+ rescue Exception => e
388
+ debug_log e.message
389
+ debug_log e.backtrace.join( "\n\t" )
390
+ show_exception e
391
+ end
392
+ else
393
+ partial_keychain = @modes[ mode ].keymap.get_node( keychain_pressed )
394
+ if partial_keychain
395
+ if mode != 'input'
396
+ set_iline( keychain_str_for( keychain_pressed ) + "..." )
397
+ end
398
+ process_keystroke keychain_pressed, mode
399
+ elsif mode != 'input'
400
+ set_iline "Nothing assigned to #{keychain_str_for( keychain_pressed )}"
401
+ end
402
+ end
403
+ end
404
+ end
405
+
406
+ def type_character( c, mode = 'edit' )
407
+ if @macro_history
408
+ @macro_history.push "type_character #{c.inspect}, #{mode.inspect}"
409
+ end
410
+ @there_was_non_movement = true
411
+
412
+ case mode
413
+ when 'edit'
414
+ buffer_current.delete_selection Buffer::DONT_DISPLAY
415
+ buffer_current.insert_string c
416
+ cursor_right Buffer::STILL_TYPING
417
+ if c =~ @indent_triggers[buffer_current.language]
418
+ buffer_current.parsed_indent cursor_eol: true
419
+ end
420
+ when 'input'
421
+ if ! @readline.numbered_list?
422
+ @readline.paste c
423
+ else
424
+ if(
425
+ showing_list? &&
426
+ ( (48..57).include?( c.ord ) || (97..122).include?( c.ord ) )
427
+ )
428
+ line = list_buffer.to_a.select { |l|
429
+ l =~ /^#{c} /
430
+ }[ 0 ]
431
+
432
+ if line
433
+ @readline.list_sync line
434
+ @readline.finish
435
+ end
436
+ end
437
+ end
438
+ end
439
+ end
440
+
441
+ end
442
+ end
@@ -0,0 +1,42 @@
1
+ module Diakonos
2
+ class LineMover
3
+ def initialize(buffer:)
4
+ @buffer = buffer
5
+ end
6
+
7
+ def move_selected_lines(direction:)
8
+ case direction
9
+ when :up
10
+ from_row = start_row-1
11
+ return if from_row < 0
12
+ to_row = end_row-1
13
+ selection_delta = 0
14
+ when :down
15
+ from_row = end_row
16
+ to_row = start_row
17
+ return if to_row > @buffer.lines.count - 2
18
+ selection_delta = @buffer.selecting? ? 1 : 0
19
+ end
20
+
21
+ @buffer.take_snapshot Buffer::TYPING
22
+ @buffer.lines.insert(
23
+ to_row,
24
+ @buffer.lines.delete_at(from_row)
25
+ )
26
+ if @buffer.selecting?
27
+ @buffer.set_selection to_row+selection_delta, 0, from_row+1+selection_delta, 0
28
+ @buffer.anchor_selection to_row+selection_delta
29
+ end
30
+ @buffer.go_to_line from_row+selection_delta
31
+ @buffer.set_modified
32
+ end
33
+
34
+ private def start_row
35
+ @buffer.selection_mark&.start_row || @buffer.current_row
36
+ end
37
+
38
+ private def end_row
39
+ @buffer.selection_mark&.end_row || @buffer.last_row+1
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,59 @@
1
+ module Diakonos
2
+
3
+ class Diakonos
4
+ attr_reader :list_buffer
5
+
6
+ def open_list_buffer
7
+ @list_buffer = open_file( @list_filename )
8
+ end
9
+
10
+ def close_list_buffer( opts = {} )
11
+ close_buffer @list_buffer, opts
12
+ @list_buffer = nil
13
+ end
14
+
15
+ def showing_list?
16
+ @list_buffer
17
+ end
18
+
19
+ def list_item_selected?
20
+ @list_buffer && @list_buffer.selecting?
21
+ end
22
+
23
+ def current_list_item
24
+ if @list_buffer
25
+ @list_buffer.set_selection_current_line
26
+ end
27
+ end
28
+
29
+ def select_list_item
30
+ if @list_buffer
31
+ line = @list_buffer.set_selection_current_line
32
+ display_buffer @list_buffer
33
+ line
34
+ end
35
+ end
36
+
37
+ def previous_list_item
38
+ if @list_buffer
39
+ cursor_up
40
+ @list_buffer[ @list_buffer.current_row ]
41
+ end
42
+ end
43
+
44
+ def next_list_item
45
+ if @list_buffer
46
+ cursor_down
47
+ @list_buffer[ @list_buffer.current_row ]
48
+ end
49
+ end
50
+
51
+ def with_list_file
52
+ File.open( @list_filename, "w" ) do |f|
53
+ yield f
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,27 @@
1
+ module Diakonos
2
+
3
+ class Diakonos
4
+
5
+ def log( string )
6
+ @log.puts string
7
+ @log.flush
8
+ end
9
+
10
+ def debug_log( string )
11
+ @debug.puts( Time.now.strftime( "[%a %H:%M:%S] #{string}" ) )
12
+ @debug.flush
13
+ end
14
+
15
+ def log_backtrace
16
+ begin
17
+ raise Exception
18
+ rescue Exception => e
19
+ e.backtrace[ 1..-1 ].each do |x|
20
+ debug_log x
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,17 @@
1
+ module Diakonos
2
+ class Mode
3
+ attr_reader :keymap, :keymap_after, :window
4
+
5
+ def initialize
6
+ @keymap = Hash.new.extend( KeyMap )
7
+ # keys of @keymap_after are Strings of Diakonos functions
8
+ @keymap_after = Hash.new { |h,k|
9
+ h[k] = Hash.new.extend( KeyMap )
10
+ }
11
+ end
12
+
13
+ def window=( w )
14
+ @window = w
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Diakonos
2
+ class Diakonos
3
+ def handle_mouse_event
4
+ event = Curses::getmouse
5
+ return if event.nil?
6
+
7
+ if event.bstate & Curses::BUTTON1_CLICKED > 0
8
+ buffer_current.cursor_to(
9
+ buffer_current.top_line + event.y,
10
+ buffer_current.left_column + event.x,
11
+ Buffer::DO_DISPLAY
12
+ )
13
+ else
14
+ $diakonos.debug_log "button state = #{'0x%x' % event.bstate}, "
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module Diakonos
2
+ class NumberFitter
3
+ def self.fit(number:, min:, max:)
4
+ return number if max < min
5
+ return min if number < min
6
+ return max if number > max
7
+ return number
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,31 @@
1
+ module Diakonos
2
+ class Range
3
+ attr_reader :start_row, :start_col, :end_row, :end_col
4
+ attr_writer :end_row, :end_col
5
+
6
+ def initialize( start_row, start_col, end_row, end_col )
7
+ @start_row, @start_col, @end_row, @end_col = start_row, start_col, end_row, end_col
8
+ end
9
+
10
+ def contains?(row, col)
11
+ if row == @start_row
12
+ @start_col <= col
13
+ elsif row == @end_row
14
+ col < @end_col
15
+ else
16
+ @start_row < row && row < @end_row
17
+ end
18
+ end
19
+ end
20
+
21
+ module RangeDelegator
22
+ def start_row; @range.start_row; end
23
+ def end_row; @range.end_row; end
24
+ def start_col; @range.start_col; end
25
+ def end_col; @range.end_col; end
26
+
27
+ def contains?(row, col)
28
+ @range.contains?(row, col)
29
+ end
30
+ end
31
+ end