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.
- checksums.yaml +7 -0
- data/CHANGELOG +439 -0
- data/LICENCE.md +675 -0
- data/bin/diakonos +6 -0
- data/diakonos-256-colour.conf +220 -0
- data/diakonos.conf +1802 -0
- data/help/about-help.dhf +31 -0
- data/help/clipboard.dhf +45 -0
- data/help/close-file.dhf +6 -0
- data/help/code-block-navigation.dhf +16 -0
- data/help/column-markers.dhf +15 -0
- data/help/config.dhf +69 -0
- data/help/cursor-stack.dhf +19 -0
- data/help/delete.dhf +41 -0
- data/help/extensions.dhf +125 -0
- data/help/file-type.dhf +24 -0
- data/help/key-mapping.dhf +127 -0
- data/help/line-numbers.dhf +22 -0
- data/help/macros.dhf +27 -0
- data/help/new-file.dhf +6 -0
- data/help/open-file.dhf +21 -0
- data/help/quit.dhf +7 -0
- data/help/resizing.dhf +19 -0
- data/help/ruby.dhf +17 -0
- data/help/save-file.dhf +10 -0
- data/help/scripting.dhf +92 -0
- data/help/search.dhf +103 -0
- data/help/shell.dhf +60 -0
- data/help/speed.dhf +23 -0
- data/help/support.dhf +15 -0
- data/help/switch-buffers.dhf +15 -0
- data/help/tabs.dhf +36 -0
- data/help/undo.dhf +9 -0
- data/help/uninstall.dhf +18 -0
- data/help/welcome.dhf +32 -0
- data/help/word-wrap.dhf +17 -0
- data/lib/diakonos/about.rb +70 -0
- data/lib/diakonos/bookmark.rb +46 -0
- data/lib/diakonos/buffer/bookmarking.rb +47 -0
- data/lib/diakonos/buffer/cursor.rb +335 -0
- data/lib/diakonos/buffer/delete.rb +170 -0
- data/lib/diakonos/buffer/display.rb +362 -0
- data/lib/diakonos/buffer/file.rb +157 -0
- data/lib/diakonos/buffer/indentation.rb +175 -0
- data/lib/diakonos/buffer/searching.rb +552 -0
- data/lib/diakonos/buffer/selection.rb +360 -0
- data/lib/diakonos/buffer/undo.rb +73 -0
- data/lib/diakonos/buffer-hash.rb +60 -0
- data/lib/diakonos/buffer-management.rb +59 -0
- data/lib/diakonos/buffer.rb +698 -0
- data/lib/diakonos/clipboard-klipper-dbus.rb +62 -0
- data/lib/diakonos/clipboard-klipper.rb +62 -0
- data/lib/diakonos/clipboard-osx.rb +59 -0
- data/lib/diakonos/clipboard-xclip.rb +60 -0
- data/lib/diakonos/clipboard.rb +47 -0
- data/lib/diakonos/config-file.rb +67 -0
- data/lib/diakonos/config.rb +382 -0
- data/lib/diakonos/core-ext/enumerable.rb +15 -0
- data/lib/diakonos/core-ext/hash.rb +60 -0
- data/lib/diakonos/core-ext/object.rb +6 -0
- data/lib/diakonos/core-ext/regexp.rb +6 -0
- data/lib/diakonos/core-ext/string.rb +122 -0
- data/lib/diakonos/ctag.rb +28 -0
- data/lib/diakonos/cursor.rb +27 -0
- data/lib/diakonos/display/format.rb +75 -0
- data/lib/diakonos/display.rb +336 -0
- data/lib/diakonos/extension-set.rb +49 -0
- data/lib/diakonos/extension.rb +34 -0
- data/lib/diakonos/finding.rb +40 -0
- data/lib/diakonos/functions/basics.rb +34 -0
- data/lib/diakonos/functions/bookmarking.rb +61 -0
- data/lib/diakonos/functions/buffers.rb +491 -0
- data/lib/diakonos/functions/clipboard.rb +70 -0
- data/lib/diakonos/functions/cursor.rb +264 -0
- data/lib/diakonos/functions/grepping.rb +83 -0
- data/lib/diakonos/functions/indentation.rb +71 -0
- data/lib/diakonos/functions/readline.rb +93 -0
- data/lib/diakonos/functions/search.rb +179 -0
- data/lib/diakonos/functions/selection.rb +98 -0
- data/lib/diakonos/functions/sessions.rb +78 -0
- data/lib/diakonos/functions/shell.rb +250 -0
- data/lib/diakonos/functions/tags.rb +65 -0
- data/lib/diakonos/functions/text-manipulation.rb +196 -0
- data/lib/diakonos/functions-deprecated.rb +77 -0
- data/lib/diakonos/functions.rb +292 -0
- data/lib/diakonos/grep.rb +98 -0
- data/lib/diakonos/help.rb +47 -0
- data/lib/diakonos/hooks.rb +13 -0
- data/lib/diakonos/installation.rb +19 -0
- data/lib/diakonos/interaction-handler.rb +216 -0
- data/lib/diakonos/interaction.rb +52 -0
- data/lib/diakonos/key-map.rb +62 -0
- data/lib/diakonos/keying.rb +442 -0
- data/lib/diakonos/line-mover.rb +42 -0
- data/lib/diakonos/list.rb +59 -0
- data/lib/diakonos/logging.rb +27 -0
- data/lib/diakonos/mode.rb +17 -0
- data/lib/diakonos/mouse.rb +18 -0
- data/lib/diakonos/number-fitter.rb +11 -0
- data/lib/diakonos/range.rb +31 -0
- data/lib/diakonos/readline/functions.rb +82 -0
- data/lib/diakonos/readline.rb +223 -0
- data/lib/diakonos/search.rb +58 -0
- data/lib/diakonos/sessions.rb +257 -0
- data/lib/diakonos/sized-array.rb +48 -0
- data/lib/diakonos/text-mark.rb +19 -0
- data/lib/diakonos/vendor/fuzzy_file_finder.rb +386 -0
- data/lib/diakonos/version.rb +25 -0
- data/lib/diakonos/window.rb +43 -0
- data/lib/diakonos.rb +592 -0
- 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
|