diakonos 0.8.11 → 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 -68
data/lib/diakonos.rb ADDED
@@ -0,0 +1,592 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # == Diakonos
4
+ #
5
+ # A Linux console text editor for the masses.
6
+ # :title: Diakonos
7
+ #
8
+ # Author:: Pistos
9
+ # Copyright (c) 2004-2021 Pistos
10
+ #
11
+ # This software is released under the MIT licence.
12
+ # See the LICENCE file included with this program, or
13
+ # http://www.opensource.org/licenses/mit-license.php
14
+ #
15
+ require 'open3'
16
+ require 'thread'
17
+ require 'English'
18
+ require 'set'
19
+ require 'yaml'
20
+ require 'digest/md5'
21
+ require 'timeout'
22
+ require 'fileutils'
23
+
24
+ require 'diakonos/core-ext/object'
25
+ require 'diakonos/core-ext/enumerable'
26
+ require 'diakonos/core-ext/regexp'
27
+ require 'diakonos/core-ext/hash'
28
+ require 'diakonos/core-ext/string'
29
+ require 'diakonos/buffer-hash'
30
+ require 'diakonos/number-fitter'
31
+ require 'diakonos/sized-array'
32
+
33
+ require 'diakonos/version'
34
+ require 'diakonos/installation'
35
+
36
+ require 'diakonos/about'
37
+ require 'diakonos/buffer-management'
38
+ require 'diakonos/config'
39
+ require 'diakonos/config-file'
40
+ require 'diakonos/cursor'
41
+ require 'diakonos/functions'
42
+ require 'diakonos/functions/basics'
43
+ require 'diakonos/functions/bookmarking'
44
+ require 'diakonos/functions/buffers'
45
+ require 'diakonos/functions/clipboard'
46
+ require 'diakonos/functions/cursor'
47
+ require 'diakonos/functions/grepping'
48
+ require 'diakonos/functions/indentation'
49
+ require 'diakonos/functions/readline'
50
+ require 'diakonos/functions/search'
51
+ require 'diakonos/functions/selection'
52
+ require 'diakonos/functions/sessions'
53
+ require 'diakonos/functions/shell'
54
+ require 'diakonos/functions/tags'
55
+ require 'diakonos/functions/text-manipulation'
56
+ require 'diakonos/functions-deprecated'
57
+ require 'diakonos/help'
58
+ require 'diakonos/interaction-handler'
59
+ require 'diakonos/grep'
60
+ require 'diakonos/hooks'
61
+ require 'diakonos/interaction'
62
+ require 'diakonos/keying'
63
+ require 'diakonos/logging'
64
+ require 'diakonos/list'
65
+ require 'diakonos/mouse'
66
+ require 'diakonos/search'
67
+ require 'diakonos/sessions'
68
+
69
+ require 'diakonos/text-mark'
70
+ require 'diakonos/bookmark'
71
+ require 'diakonos/ctag'
72
+ require 'diakonos/finding'
73
+ require 'diakonos/buffer'
74
+ require 'diakonos/buffer/bookmarking'
75
+ require 'diakonos/buffer/cursor'
76
+ require 'diakonos/buffer/delete'
77
+ require 'diakonos/buffer/display'
78
+ require 'diakonos/buffer/indentation'
79
+ require 'diakonos/buffer/file'
80
+ require 'diakonos/buffer/searching'
81
+ require 'diakonos/buffer/selection'
82
+ require 'diakonos/buffer/undo'
83
+ require 'diakonos/clipboard'
84
+ require 'diakonos/clipboard-klipper'
85
+ require 'diakonos/clipboard-klipper-dbus'
86
+ require 'diakonos/clipboard-osx'
87
+ require 'diakonos/clipboard-xclip'
88
+ require 'diakonos/extension'
89
+ require 'diakonos/extension-set'
90
+ require 'diakonos/key-map'
91
+ require 'diakonos/mode'
92
+ require 'diakonos/range'
93
+ require 'diakonos/readline'
94
+ require 'diakonos/readline/functions'
95
+
96
+ require 'diakonos/vendor/fuzzy_file_finder'
97
+
98
+
99
+ module Diakonos
100
+
101
+ DONT_ADJUST_ROW = false
102
+ ADJUST_ROW = true
103
+ PROMPT_OVERWRITE = true
104
+ DONT_PROMPT_OVERWRITE = false
105
+ QUIET = true
106
+ NOISY = false
107
+ AFTER_CHAR = true
108
+ ON_CHAR = false
109
+ INCLUSIVE = true
110
+ NOT_INCLUSIVE = false
111
+
112
+ DEFAULT_TAB_SIZE = 8
113
+
114
+ FORCE_REVERT = true
115
+ ASK_REVERT = false
116
+
117
+ ASK_REPLACEMENT = true
118
+ NO_REPLACEMENT = nil
119
+
120
+ CASE_SENSITIVE = true
121
+ CASE_INSENSITIVE = false
122
+
123
+ LANG_TEXT = 'text'
124
+
125
+ # @return [Array] the filename and line number parsed
126
+ def self.parse_filename_and_line_number( s )
127
+ if(
128
+ # Ruby
129
+ s =~ /from (.+):(\d+)/ ||
130
+ # Python
131
+ s =~ /File "(.+)", line (\d+)/ ||
132
+ # Perl
133
+ s =~ /at (.+) line (\d+)/ ||
134
+ # generic
135
+ s =~ /^(.+):(\d+)/
136
+ )
137
+ [ $1, ( $2.to_i - 1 ) ]
138
+ else
139
+ [ s, nil ]
140
+ end
141
+ end
142
+
143
+ class Diakonos
144
+
145
+ attr_reader :diakonos_home, :script_dir, :clipboard,
146
+ :list_filename, :hooks, :indenters, :indenters_next_line, :unindenters, :closers,
147
+ :functions_last, :there_was_non_movement, :do_display, :testing, :buffers
148
+
149
+ # Temporarily a writer, so that collaborating classes can get at it
150
+ # TODO: Rewrite things so that this doesn't need to be a writer.
151
+ # e.g. pass do_display to methods as needed.
152
+ attr_writer :do_display
153
+
154
+ include ::Diakonos::Functions
155
+
156
+ def initialize( argv = [] )
157
+ @diakonos_home = File.expand_path( ( ENV[ 'HOME' ] || '' ) + '/.diakonos' )
158
+ mkdir @diakonos_home
159
+ @script_dir = "#{@diakonos_home}/scripts"
160
+ mkdir @script_dir
161
+ @extensions = ExtensionSet.new( File.join( @diakonos_home, 'extensions' ) )
162
+ initialize_session
163
+
164
+ @files = Array.new
165
+ @read_only_files = Array.new
166
+ @config_filename = nil
167
+ parse_options argv
168
+
169
+ # These requires are down here instead of up with the others so that
170
+ # uninstall can be done without needing the curses lib (which may not
171
+ # be installed).
172
+ require 'diakonos/display'
173
+ require 'diakonos/display/format'
174
+
175
+ init_help
176
+
177
+ @debug = File.new( File.join( @diakonos_home, 'debug.log' ), 'w' )
178
+ @list_filename = File.join( @diakonos_home, 'listing.txt' )
179
+ @diff_filename = File.join( @diakonos_home, 'text.diff' )
180
+ @help_filename = File.join( @help_dir, 'about-help.dhf' )
181
+ @error_filename = File.join( @diakonos_home, 'diakonos.err' )
182
+ @about_filename = File.join( @diakonos_home, 'about.dhf' )
183
+
184
+ @win_main = nil
185
+ @win_context = nil
186
+ @win_status = nil
187
+ @win_interaction = nil
188
+ @win_line_numbers = nil
189
+ @buffers = Array.new
190
+
191
+ load_configuration
192
+
193
+ @quitting = false
194
+
195
+ @x = 0
196
+ @y = 0
197
+
198
+ @buffer_stack = Array.new
199
+ @buffer_current = nil
200
+
201
+ @cursor_stack = Array.new
202
+ @cursor_stack_pointer = nil
203
+
204
+ @bookmarks = Hash.new
205
+
206
+ @macro_history = nil
207
+ @macro_input_history = nil
208
+ @macros = Hash.new
209
+ @functions_last = SizedArray.new(2)
210
+ @playing_macro = false
211
+
212
+ @display_mutex = Mutex.new
213
+ @display_queue_mutex = Mutex.new
214
+ @display_queue = nil
215
+ @do_display = true
216
+ @context_line_mutex = Mutex.new
217
+
218
+ @tag_stack = Array.new
219
+ @last_search_regexps = nil
220
+ @there_was_non_movement = false
221
+ @status_vars = Hash.new
222
+
223
+ # Readline histories
224
+ @rlh_general = Array.new
225
+ @rlh_files = Array.new
226
+ @rlh_search = Array.new
227
+ @rlh_shell = Array.new
228
+ @rlh_help = Array.new
229
+ @rlh_sessions = Array.new
230
+
231
+ @hooks = {
232
+ :after_buffer_switch => [],
233
+ :after_open => [],
234
+ :after_save => [],
235
+ :after_startup => [],
236
+ }
237
+ end
238
+
239
+ def mkdir( dir )
240
+ if ! FileTest.exists?( dir )
241
+ Dir.mkdir dir
242
+ end
243
+ end
244
+
245
+ def parse_options( argv )
246
+ @post_load_script = ""
247
+ while argv.length > 0
248
+ arg = argv.shift
249
+ case arg
250
+ when '-c', '--config'
251
+ @config_filename = argv.shift
252
+ if @config_filename.nil?
253
+ print_usage
254
+ exit 1
255
+ end
256
+ when '-e', '--execute'
257
+ post_load_script = argv.shift
258
+ if post_load_script.nil?
259
+ print_usage
260
+ exit 1
261
+ else
262
+ @post_load_script << "\n#{post_load_script}"
263
+ end
264
+ when '-h', '--help'
265
+ print_usage
266
+ exit 1
267
+ when '-m', '--open-matching'
268
+ regexp = argv.shift
269
+ files = `egrep -rl '#{regexp}' *`.split( /\n/ )
270
+ if files.any?
271
+ @files.concat( files.map { |f| Session.file_hash_for f } )
272
+ script = "\nfind '#{regexp}', case_sensitive: true"
273
+ @post_load_script << script
274
+ end
275
+ when '-ro'
276
+ filename = argv.shift
277
+ if filename.nil?
278
+ print_usage
279
+ exit 1
280
+ else
281
+ h = Session.file_hash_for( filename )
282
+ h[ 'read_only' ] = true
283
+ @read_only_files.push h
284
+ end
285
+ when '-s', '--load-session'
286
+ @session_to_load = session_filepath_for( argv.shift )
287
+ when '--test', '--testing'
288
+ @testing = true
289
+ when '--uninstall'
290
+ uninstall
291
+ when '--uninstall-without-confirmation'
292
+ uninstall false
293
+ when '--version'
294
+ puts "Diakonos #{::Diakonos::VERSION} (#{::Diakonos::LAST_MODIFIED})"
295
+ exit 0
296
+ else
297
+ # a name of a file to open
298
+ @files.push Session.file_hash_for( arg )
299
+ end
300
+ end
301
+ end
302
+
303
+ def print_usage
304
+ puts "Usage: #{$0} [options] [file] [file...]"
305
+ puts "\t--help\tDisplay usage"
306
+ puts "\t-c <config file>\tLoad this config file instead of ~/.diakonos/diakonos.conf"
307
+ puts "\t-e, --execute <Ruby code>\tExecute Ruby code (such as Diakonos commands) after startup"
308
+ puts "\t-m, --open-matching <regular expression>\tOpen all matching files under current directory"
309
+ puts "\t-ro <file>\tLoad file as read-only"
310
+ puts "\t-s, --load-session <session identifier>\tLoad a session"
311
+ puts "\t--uninstall[-without-confirmation]\tUninstall Diakonos"
312
+ end
313
+
314
+ def clear_non_movement_flag
315
+ @there_was_non_movement = false
316
+ end
317
+
318
+ # -----------------------------------------------------------------------
319
+
320
+ def create_buffers_from_files
321
+ @files.each do |file_info|
322
+ @buffers << Buffer.new(file_info)
323
+ end
324
+ end
325
+
326
+ def start
327
+ require 'diakonos/window'
328
+
329
+ create_buffers_from_files
330
+ @files = []
331
+ @read_only_files.each do |file|
332
+ @buffers << Buffer.new( file )
333
+ end
334
+ if ! @testing
335
+ session_startup
336
+ end
337
+ create_buffers_from_files
338
+ @files = []
339
+ if @buffers.empty?
340
+ @buffers << Buffer.new
341
+ end
342
+
343
+ initialize_display
344
+ @buffers.each do |buffer|
345
+ buffer.reset_display
346
+ end
347
+
348
+ set_initial_iline
349
+
350
+ run_scripts
351
+
352
+ @hooks.each do |hook_name, hook|
353
+ hook.sort { |a,b| a[ :priority ] <=> b[ :priority ] }
354
+ end
355
+
356
+ handle_stale_session_files
357
+
358
+ create_buffers_from_files
359
+
360
+ session_buffer_number = @session.buffer_current || 1
361
+ if ! switch_to_buffer_number( session_buffer_number )
362
+ debug_log "Failed to switch to buffer #{session_buffer_number.inspect}"
363
+ switch_to_buffer_number 1
364
+ end
365
+
366
+ run_hook_procs :after_startup
367
+ if @post_load_script
368
+ begin
369
+ eval @post_load_script
370
+ rescue Exception => e
371
+ show_exception(
372
+ e,
373
+ [ "There is an error in the post-load script:\n#{@post_load_script}" ]
374
+ )
375
+ end
376
+ end
377
+
378
+ @buffers.each do |b|
379
+ run_hook_procs :after_open, b
380
+ b.cursor_to( b.last_row, b.last_col, Buffer::DONT_DISPLAY )
381
+ end
382
+ buffer_current.cursor_to( buffer_current.last_row, buffer_current.last_col, Buffer::DONT_DISPLAY )
383
+
384
+ if @configs.any? { |c| c.problems.any? }
385
+ File.open( @error_filename, "w" ) do |f|
386
+ f.puts "There are problems with the configuration file(s):"
387
+ @configs.each do |c|
388
+ next if c.problems.empty?
389
+
390
+ f.puts
391
+ f.print "#{c}:\n\t"
392
+ f.puts c.problems.join("\n\t")
393
+ end
394
+ end
395
+ open_file @error_filename
396
+ end
397
+
398
+ if ! @testing && ! @settings[ 'suppress_welcome' ]
399
+ open_file "#{@help_dir}/welcome.dhf"
400
+ else
401
+ conflict_regexp_source = '^<{4,}'
402
+ if seek(conflict_regexp_source)
403
+ find conflict_regexp_source
404
+ end
405
+ end
406
+
407
+ begin
408
+ # Main keyboard loop.
409
+ while ! @quitting
410
+ process_keystroke
411
+ @win_main.refresh
412
+ end
413
+ rescue SignalException => e
414
+ debug_log "Terminated by signal (#{e.message})"
415
+ end
416
+
417
+ cleanup_display
418
+ cleanup_session
419
+
420
+ @debug.close
421
+ end
422
+
423
+ def set_initial_iline
424
+ if ENV['COLORTERM'] == 'gnome-terminal'
425
+ help_key = 'Shift-F1'
426
+ else
427
+ help_key = 'F1'
428
+ end
429
+ set_iline "Diakonos #{VERSION} (#{LAST_MODIFIED}) #{help_key} for help F12 to configure Ctrl-Q to quit"
430
+ end
431
+
432
+ def run_scripts
433
+ scripts = @extensions.scripts + Dir[ "#{@script_dir}/*" ]
434
+ scripts.each do |script|
435
+ begin
436
+ require script
437
+ rescue Exception => e
438
+ show_exception(
439
+ e,
440
+ [
441
+ "There is a syntax error in the script.",
442
+ "An invalid hook name was used."
443
+ ]
444
+ )
445
+ end
446
+ end
447
+ end
448
+
449
+ def uninstall( confirm = true )
450
+ inst = ::Diakonos::INSTALL_SETTINGS[ :installed ]
451
+
452
+ if confirm
453
+ puts inst[ :files ].sort.join( "\n" )
454
+ puts
455
+ puts inst[ :dirs ].sort.map { |d| "#{d}/" }.join( "\n" )
456
+ puts
457
+ puts "The above files will be removed. The above directories will be removed if they are empty. Proceed? (y/n)"
458
+ answer = $stdin.gets
459
+ case answer
460
+ when /^y/i
461
+ puts "Deleting..."
462
+ else
463
+ puts "Uninstallation aborted."
464
+ exit 1
465
+ end
466
+ end
467
+
468
+ inst[ :files ].each do |f|
469
+ FileUtils.rm f
470
+ end
471
+ inst[ :dirs ].sort { |d1,d2| d2.length <=> d1.length }.each do |d|
472
+ begin
473
+ FileUtils.rmdir d
474
+ rescue Errno::ENOTEMPTY
475
+ end
476
+ if File.exists? d
477
+ $stderr.puts "(#{d} not removed)"
478
+ end
479
+ end
480
+
481
+ exit 0
482
+ end
483
+
484
+ def get_language_from_name( name )
485
+ @filemasks.each do |language,filemask|
486
+ if name =~ filemask
487
+ return language
488
+ end
489
+ end
490
+ nil
491
+ end
492
+
493
+ def get_language_from_shabang( first_line )
494
+ @bangmasks.each do |language,bangmask|
495
+ if first_line =~ bangmask
496
+ return language
497
+ end
498
+ end
499
+ nil
500
+ end
501
+
502
+ def show_exception( e, probable_causes = [ "Unknown" ] )
503
+ begin
504
+ File.open( @error_filename, "w" ) do |f|
505
+ f.puts "Diakonos Error:"
506
+ f.puts
507
+ f.puts "#{e.class}: #{e.message}"
508
+ f.puts
509
+ f.puts "Probable Causes:"
510
+ f.puts
511
+ probable_causes.each do |pc|
512
+ f.puts "- #{pc}"
513
+ end
514
+ f.puts
515
+ f.puts "----------------------------------------------------"
516
+ f.puts "If you can reproduce this error, please report it at"
517
+ f.puts "https://github.com/Pistos/diakonos/issues !"
518
+ f.puts "----------------------------------------------------"
519
+ f.puts e.backtrace
520
+ end
521
+ open_file @error_filename
522
+ rescue Exception => e2
523
+ debug_log "EXCEPTION: #{e.message}"
524
+ debug_log "\t#{e.backtrace}"
525
+ end
526
+ end
527
+
528
+ def start_recording_macro( name = nil )
529
+ return if @macro_history
530
+ @macro_name = name
531
+ @macro_history = Array.new
532
+ @macro_input_history = Array.new
533
+ set_iline "Started macro recording."
534
+ end
535
+
536
+ def stop_recording_macro
537
+ @macro_history.pop # Remove the stop_recording_macro command itself
538
+ @macros[ @macro_name ] = [ @macro_history, @macro_input_history ]
539
+ @macro_history = nil
540
+ @macro_input_history = nil
541
+ set_iline "Stopped macro recording."
542
+ end
543
+
544
+ def load_tags
545
+ @tags = Hash.new
546
+ if buffer_current && buffer_current.name
547
+ path = File.expand_path( File.dirname( buffer_current.name ) )
548
+ tagfile = path + "/tags"
549
+ else
550
+ tagfile = "./tags"
551
+ end
552
+
553
+ if ! FileTest.exists? tagfile
554
+ set_iline "(tags file not found)"
555
+ else
556
+ IO.foreach( tagfile ) do |line_|
557
+ line = line_.chomp
558
+ # <tagname>\t<filepath>\t<line number or regexp>\t<kind of tag>
559
+ tag, file, command, kind, rest = line.split( /\t/ )
560
+ command.gsub!( /;"$/, "" )
561
+ if command =~ /^\/.*\/$/
562
+ command = command[ 1...-1 ]
563
+ end
564
+ @tags[ tag ] ||= Array.new
565
+ @tags[ tag ].push CTag.new( file, command, kind, rest )
566
+ end
567
+ end
568
+ end
569
+
570
+ def escape_quotes( str )
571
+ temp = ''
572
+ str.each_byte do |b|
573
+ if b == 39
574
+ temp << 39
575
+ temp << 92
576
+ temp << 39
577
+ end
578
+ temp << b
579
+ end
580
+ temp
581
+ end
582
+
583
+ end
584
+
585
+ end
586
+
587
+ ::Diakonos.check_ruby_version
588
+
589
+ if __FILE__ == $PROGRAM_NAME
590
+ $diakonos = Diakonos::Diakonos.new( ARGV )
591
+ $diakonos.start
592
+ end