diakonos 0.8.11 → 0.9.9

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.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +439 -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 +70 -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 +362 -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 +382 -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 +491 -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 +223 -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 +386 -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-2023 Pistos
10
+ #
11
+ # This software is released under the GNU GPL licence v3.
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.exist?( 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.exist? 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.exist? 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