Class: Diakonos::Diakonos
- Inherits:
-
Object
show all
- Includes:
- Functions
- Defined in:
- lib/diakonos/functions-deprecated.rb,
lib/diakonos.rb,
lib/diakonos/grep.rb,
lib/diakonos/help.rb,
lib/diakonos/list.rb,
lib/diakonos/about.rb,
lib/diakonos/hooks.rb,
lib/diakonos/mouse.rb,
lib/diakonos/config.rb,
lib/diakonos/cursor.rb,
lib/diakonos/keying.rb,
lib/diakonos/search.rb,
lib/diakonos/display.rb,
lib/diakonos/logging.rb,
lib/diakonos/sessions.rb,
lib/diakonos/interaction.rb,
lib/diakonos/buffer-management.rb
Overview
These camel-cased method names are defined here to support legacy configuration files.
Constant Summary
collapse
- DOCK_SEPARATOR_CHAR =
'─'
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#about_write ⇒ Object
-
#actually_grep(regexp_source, *buffers) ⇒ Object
-
#buffer_number_to_name(buffer_number) ⇒ Object
Nil if no such buffer exists.
-
#buffer_to_number(buffer) ⇒ Integer
-
#capture_keychain(c, context) ⇒ Object
-
#capture_mapping(c, context) ⇒ Object
-
#cleanup_display ⇒ Object
-
#cleanup_session ⇒ Object
-
#clear_non_movement_flag ⇒ Object
-
#close_help_buffer ⇒ Object
-
#close_list_buffer(opts = {}) ⇒ Object
-
#create_buffers_from_files ⇒ Object
———————————————————————–.
-
#current_list_item ⇒ Object
-
#cursor_stack_remove_buffer(buffer) ⇒ Object
-
#debug_log(string) ⇒ Object
-
#decrease_grep_context ⇒ Object
-
#display_buffer(buffer) ⇒ Object
-
#escape_quotes(str) ⇒ Object
-
#find_(options = {}) ⇒ Integer
The number of replacements made.
-
#get_choice(*args) ⇒ Object
-
#get_language_from_name(name) ⇒ Object
-
#get_language_from_shabang(first_line) ⇒ Object
-
#get_token_regexp(hash, arg, match) ⇒ Object
-
#get_user_input(prompt, options = {}, &block) ⇒ Object
completion_array is the array of strings that tab completion can use.
-
#grep_(regexp_source, *buffers) ⇒ Object
-
#handle_gui_paste(mode) ⇒ Object
Handle paste from a GUI (like x.org).
-
#handle_mouse_event ⇒ Object
-
#handle_stale_session_files ⇒ Object
We have to do this separately and later (as opposed to inside #session_startup) because we have to wait for the display to get initialized in order to prompt the user for input, etc.
-
#handle_utf_8(c, mode) ⇒ Boolean
True iff c began a UTF-8 byte sequence.
-
#increase_grep_context ⇒ Object
-
#init_help ⇒ Object
-
#initialize(argv = []) ⇒ Diakonos
constructor
A new instance of Diakonos.
-
#initialize_display ⇒ Object
-
#initialize_session ⇒ Object
-
#keychain_str_for(array) ⇒ Object
-
#legitimize_config_filename!(prospective_filename, including_config_file) ⇒ ConfigFile, ConfigFileUnreadable
-
#list_item_selected? ⇒ Boolean
-
#load_configuration ⇒ Object
(also: #loadConfiguration)
-
#load_session(session_file) ⇒ Object
-
#load_tags ⇒ Object
-
#log(string) ⇒ Object
-
#log_backtrace ⇒ Object
-
#main_window_height ⇒ Object
-
#main_window_width ⇒ Object
-
#map_key(arg, keymap = @modes['edit'].keymap) ⇒ Object
-
#matching_help_documents(str) ⇒ Object
-
#mkdir(dir) ⇒ Object
-
#next_list_item ⇒ Object
-
#open_help_buffer ⇒ Object
-
#open_help_document(selected_string) ⇒ Object
-
#open_list_buffer ⇒ Object
-
#parse_configuration_file(filename, including_config_file = ConfigFileNull.new) ⇒ Object
-
#parse_options(argv) ⇒ Object
-
#previous_list_item ⇒ Object
-
#print_usage ⇒ Object
-
#process_async ⇒ Object
-
#process_keystroke(context = [], mode = 'edit', ch = nil) ⇒ Symbol
context is an array of characters (bytes) which are keystrokes previously typed (in a chain of keystrokes).
-
#push_cursor_state(top_line, row, col, clear_stack_pointer = CLEAR_STACK_POINTER) ⇒ Object
-
#redraw ⇒ Object
-
#refresh_all ⇒ Object
-
#register_proc(the_proc, hook_name, priority = 0) ⇒ Object
-
#run_hook_procs(hook_id, *args) ⇒ Object
-
#run_scripts ⇒ Object
-
#save_session(session_file = @session.filename) ⇒ Object
-
#select_list_item ⇒ Object
-
#session_filepath_for(session_id) ⇒ Object
-
#session_startup ⇒ Object
-
#set_iline(s = "") ⇒ Object
-
#set_iline_if_empty(s) ⇒ Object
-
#set_initial_iline ⇒ Object
-
#set_status_variable(identifier, value) ⇒ Object
-
#show_buffer_file_diff(buffer = @buffer_current) {|diff_buffer| ... } ⇒ Object
-
#show_dock(lines:) ⇒ Object
-
#show_exception(exception, probable_causes = ["Unknown"]) ⇒ Object
-
#showing_list? ⇒ Boolean
-
#start ⇒ Object
-
#start_recording_macro(name = nil) ⇒ Object
-
#stop_recording_macro ⇒ Object
-
#switch_to(buffer, opts = {}) ⇒ Boolean
True iff the buffer was successfully switched to.
-
#type_character(c, mode = 'edit') ⇒ Object
-
#typeable?(char) ⇒ Boolean
-
#uninstall(confirm: true) ⇒ Object
-
#update_context_line ⇒ Object
-
#update_status_line ⇒ Object
-
#utf_8_bytes_to_char(c, mode) ⇒ String
Nil if c is not the beginning of a multi-byte sequence.
-
#with_list_file ⇒ Object
Methods included from Functions
#about, #addNamedBookmark, #add_named_bookmark, #anchor_selection, #anchor_unanchored_selection, #backspace, #carriage_return, #change_session_setting, #chdir, #clear_matches, #close_buffer, #close_code, #collapseWhitespace, #collapse_whitespace, #columnize, #comment_out, #complete_word, #copy_selection, #cursor_bof, #cursor_bol, #cursor_bov, #cursor_down, #cursor_eof, #cursor_eol, #cursor_left, #cursor_return, #cursor_right, #cursor_tov, #cursor_up, #cut_selection, #delete, #delete_and_store_line, #delete_from, #delete_line, #delete_to, #delete_to_and_from, #delete_to_eol, #evaluate, #execute, #find, #find_again, #find_clip, #find_exact, #goToNamedBookmark, #goToNextBookmark, #goToPreviousBookmark, #go_block_inner, #go_block_next, #go_block_outer, #go_block_previous, #go_to_char, #go_to_char_previous, #go_to_definition, #go_to_line_ask, #go_to_named_bookmark, #go_to_next_bookmark, #go_to_pair_match, #go_to_previous_bookmark, #go_to_tag, #go_to_tag_under_cursor, #grep, #grep_buffers, #grep_dir, #grep_session_dir, #help, #hover, #indent, #insertSpaces, #insertTab, #insert_spaces, #insert_tab, #joinLines, #join_lines, #join_lines_upward, #list_buffers, #load_script, #merge_session_settings, #move_lines, #name_session, #open_file, #open_file_ask, #open_matching_files, #operateOnEachLine, #operateOnLines, #operateOnString, #operate_on_each_line, #operate_on_lines, #operate_on_string, #page_down, #page_up, #parsedIndent, #parsed_indent, #paste, #paste_shell_result, #play_macro, #pop_tag, #print_keychain, #print_mapped_function, #quit, #readline_abort, #readline_accept, #readline_backspace, #readline_complete_input, #readline_cursor_bol, #readline_cursor_down, #readline_cursor_eol, #readline_cursor_left, #readline_cursor_right, #readline_cursor_up, #readline_delete, #readline_delete_line, #readline_delete_word, #readline_grep_context_decrease, #readline_grep_context_increase, #readline_page_down, #readline_page_up, #removeNamedBookmark, #remove_named_bookmark, #remove_selection, #renumber_buffer, #repeat_last, #revert, #save_file, #save_file_as, #scroll_down, #scroll_up, #search_and_replace, #seek, #select_all, #select_block, #select_line, #select_word, #select_word_another, #select_wrapping_block, #selection_mode_block, #selection_mode_normal, #set_buffer_type, #set_read_only, #set_session_dir, #shell, #show_clips, #show_number_of_matches_found, #spawn, #sub_shell_variables, #surround_line, #surround_paragraph, #surround_selection, #surround_word, #suspend, #switch_to_buffer_number, #switch_to_next_buffer, #switch_to_previous_buffer, #toggleBookmark, #toggle_bookmark, #toggle_macro_recording, #toggle_selection, #toggle_session_setting, #uncomment, #undo, #unindent, #unundo, #wrap_paragraph
Constructor Details
#initialize(argv = []) ⇒ Diakonos
Returns a new instance of Diakonos.
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
# File 'lib/diakonos.rb', line 167
def initialize( argv = [] )
@diakonos_home = File.expand_path( ( ENV[ 'HOME' ] || '' ) + '/.diakonos' )
mkdir @diakonos_home
@script_dir = "#{@diakonos_home}/scripts"
mkdir @script_dir
@extensions = ExtensionSet.new( File.join( @diakonos_home, 'extensions' ) )
initialize_session
@files = Array.new
@read_only_files = Array.new
@config_filename = nil
parse_options argv
require 'diakonos/display'
require 'diakonos/display/format'
init_help
@debug = File.new( File.join( @diakonos_home, 'debug.log' ), 'w' )
@list_filename = File.join( @diakonos_home, 'listing.txt' )
@diff_filename = File.join( @diakonos_home, 'text.diff' )
@help_filename = File.join( @help_dir, 'about-help.dhf' )
@error_filename = File.join( @diakonos_home, 'diakonos.err' )
@about_filename = File.join( @diakonos_home, 'about.dhf' )
@win_main = nil
@win_context = nil
@win_status = nil
@win_interaction = nil
@win_line_numbers = nil
@buffers = Array.new
load_configuration
@quitting = false
@x = 0
@y = 0
@buffer_stack = Array.new
@buffer_current = nil
@cursor_stack = Array.new
@cursor_stack_pointer = nil
@bookmarks = Hash.new
@macro_history = nil
@macro_input_history = nil
@macros = Hash.new
@functions_last = SizedArray.new(2)
@playing_macro = false
@lsp_servers = Hash.new
@lsp_sessions = Hash.new
@display_mutex = Mutex.new
@display_queue_mutex = Mutex.new
@display_queue = nil
@do_display = true
@context_line_mutex = Mutex.new
@tag_stack = Array.new
@last_search_regexps = nil
@there_was_non_movement = false
@status_vars = Hash.new
@rlh_general = Array.new
@rlh_files = Array.new
@rlh_search = Array.new
@rlh_shell = Array.new
@rlh_help = Array.new
@rlh_sessions = Array.new
@hooks = {
after_buffer_switch: [],
after_open: [],
after_save: [],
after_startup: [],
}
end
|
Instance Attribute Details
#buffer_current ⇒ Object
Returns the value of attribute buffer_current.
3
4
5
|
# File 'lib/diakonos/buffer-management.rb', line 3
def buffer_current
@buffer_current
end
|
Returns the value of attribute buffers.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def buffers
@buffers
end
|
#clipboard ⇒ Object
Returns the value of attribute clipboard.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def clipboard
@clipboard
end
|
#close_token_regexps ⇒ Object
Returns the value of attribute close_token_regexps.
14
15
16
|
# File 'lib/diakonos/config.rb', line 14
def close_token_regexps
@close_token_regexps
end
|
Returns the value of attribute closers.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def closers
@closers
end
|
#column_markers ⇒ Object
Returns the value of attribute column_markers.
14
15
16
|
# File 'lib/diakonos/config.rb', line 14
def column_markers
@column_markers
end
|
#diakonos_conf ⇒ Object
Returns the value of attribute diakonos_conf.
14
15
16
|
# File 'lib/diakonos/config.rb', line 14
def diakonos_conf
@diakonos_conf
end
|
#diakonos_home ⇒ Object
Returns the value of attribute diakonos_home.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def diakonos_home
@diakonos_home
end
|
#display_mutex ⇒ Object
Returns the value of attribute display_mutex.
11
12
13
|
# File 'lib/diakonos/display.rb', line 11
def display_mutex
@display_mutex
end
|
#do_display ⇒ Object
Returns the value of attribute do_display.
148
149
150
|
# File 'lib/diakonos.rb', line 148
def do_display
@do_display
end
|
#functions_last ⇒ Object
Returns the value of attribute functions_last.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def functions_last
@functions_last
end
|
Returns the value of attribute hooks.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def hooks
@hooks
end
|
#indenters ⇒ Object
Returns the value of attribute indenters.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def indenters
@indenters
end
|
#indenters_next_line ⇒ Object
Returns the value of attribute indenters_next_line.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def indenters_next_line
@indenters_next_line
end
|
#list_buffer ⇒ Object
Returns the value of attribute list_buffer.
4
5
6
|
# File 'lib/diakonos/list.rb', line 4
def list_buffer
@list_buffer
end
|
#list_filename ⇒ Object
Returns the value of attribute list_filename.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def list_filename
@list_filename
end
|
Returns the value of attribute readline.
5
6
7
|
# File 'lib/diakonos/interaction.rb', line 5
def readline
@readline
end
|
#script_dir ⇒ Object
Returns the value of attribute script_dir.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def script_dir
@script_dir
end
|
Returns the value of attribute session.
135
136
137
|
# File 'lib/diakonos/sessions.rb', line 135
def session
@session
end
|
Returns the value of attribute settings.
14
15
16
|
# File 'lib/diakonos/config.rb', line 14
def settings
@settings
end
|
#surround_pairs ⇒ Object
Returns the value of attribute surround_pairs.
14
15
16
|
# File 'lib/diakonos/config.rb', line 14
def surround_pairs
@surround_pairs
end
|
Returns the value of attribute testing.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def testing
@testing
end
|
#there_was_non_movement ⇒ Object
Returns the value of attribute there_was_non_movement.
149
150
151
|
# File 'lib/diakonos.rb', line 149
def there_was_non_movement
@there_was_non_movement
end
|
Returns the value of attribute token_formats.
14
15
16
|
# File 'lib/diakonos/config.rb', line 14
def token_formats
@token_formats
end
|
Returns the value of attribute win_dock.
11
12
13
|
# File 'lib/diakonos/display.rb', line 11
def win_dock
@win_dock
end
|
#win_line_numbers ⇒ Object
Returns the value of attribute win_line_numbers.
11
12
13
|
# File 'lib/diakonos/display.rb', line 11
def win_line_numbers
@win_line_numbers
end
|
Returns the value of attribute win_main.
11
12
13
|
# File 'lib/diakonos/display.rb', line 11
def win_main
@win_main
end
|
Instance Method Details
#about_write ⇒ Object
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/diakonos/about.rb', line 4
def about_write
File.open( @about_filename, "w" ) do |f|
inst = ::Diakonos::INSTALL_SETTINGS
configs = @configs.map(&:to_s).join("\n")
ext_loaded = @extensions.loaded_extensions.sort_by { |e|
e.name.downcase
}.map { |e|
%{
### #{e.name} #{e.version}
#{e.description}
}.strip
}.join( "\n\n" )
ext_not_loaded = @extensions.not_loaded_extensions.sort.map { |e|
"### #{e} (NOT LOADED)"
}.join( "\n" )
installation_artifact = File.join(inst[:lib_dir], 'diakonos', 'installation.rb')
if File.exist?(installation_artifact)
install_time = File.mtime(installation_artifact)
else
install_time = "--"
end
f.puts %{
# About Diakonos
Licence: GNU GPL v3
Copyright: Copyright (c) 2004-#{ Time.now.year } Pistos
## Version
Version: #{ ::Diakonos::VERSION }
Code Date: #{ ::Diakonos::LAST_MODIFIED }
Install Time: #{ install_time }
Ruby Version: #{ ::RUBY_VERSION }
## Paths
Home dir: #{ @diakonos_home }
Session dir: #{ @session.dir }
### Installation
Prefix: #{ inst[ :prefix ] }
Executable dir: #{ inst[ :bin_dir ] }
Help dir: #{ inst[ :help_dir ] }
System config dir: #{ inst[ :conf_dir ] }
System library dir: #{ inst[ :lib_dir ] }
### Configuration Files
#{ configs }
## Extensions
#{ ext_loaded }
#{ ext_not_loaded }
}.strip
end
end
|
#actually_grep(regexp_source, *buffers) ⇒ Object
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
# File 'lib/diakonos/grep.rb', line 36
def actually_grep( regexp_source, *buffers )
regexp = Regexp.new( regexp_source, Regexp::IGNORECASE )
grep_results = buffers.map { |buffer| buffer.grep(regexp) }.flatten
if settings[ 'grep.context' ] == 0
join_str = "\n"
else
join_str = "\n---\n"
end
with_list_file do |list|
list.puts grep_results.join( join_str )
end
list_buffer = open_list_buffer
list_buffer.highlight_matches regexp
display_buffer list_buffer
rescue RegexpError
end
|
#buffer_number_to_name(buffer_number) ⇒ Object
Returns nil if no such buffer exists.
32
33
34
35
36
37
|
# File 'lib/diakonos/buffer-management.rb', line 32
def buffer_number_to_name( buffer_number )
return nil if buffer_number < 1
b = @buffers[ buffer_number - 1 ]
b&.name
end
|
#buffer_to_number(buffer) ⇒ Integer
41
42
43
44
45
46
|
# File 'lib/diakonos/buffer-management.rb', line 41
def buffer_to_number( buffer )
i = @buffers.index( buffer )
if i
i + 1
end
end
|
#capture_keychain(c, context) ⇒ Object
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
# File 'lib/diakonos/keying.rb', line 193
def capture_keychain( c, context )
if c == ENTER
@capturing_keychain = false
buffer_current.delete_selection
str = keychain_str_for( context )
buffer_current.insert_string str
cursor_right( Buffer::STILL_TYPING, str.length )
else
keychain_pressed = context.concat [ c ]
partial_keychain = @modes[ 'edit' ].keymap.get_node( keychain_pressed )
if partial_keychain
set_iline( "Part of existing keychain: " + keychain_str_for( keychain_pressed ) + "..." )
else
set_iline keychain_str_for( keychain_pressed ) + "..."
end
process_keystroke keychain_pressed
end
end
|
#capture_mapping(c, context) ⇒ Object
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
# File 'lib/diakonos/keying.rb', line 214
def capture_mapping( c, context )
if c == ENTER
@capturing_mapping = false
buffer_current.delete_selection
set_iline
else
keychain_pressed = context.concat [ c ]
function_and_args = @modes[ 'edit' ].keymap.get_leaf( keychain_pressed )
if function_and_args
function, args = function_and_args
set_iline "#{keychain_str_for( keychain_pressed )} -> #{function}( #{args} )"
else
partial_keychain = @modes[ 'edit' ].keymap.get_node( keychain_pressed )
if partial_keychain
set_iline( "Several mappings start with: " + keychain_str_for( keychain_pressed ) + "..." )
process_keystroke keychain_pressed
else
set_iline "There is no mapping for " + keychain_str_for( keychain_pressed )
end
end
end
end
|
#cleanup_display ⇒ Object
13
14
15
16
17
18
19
20
21
22
23
24
|
# File 'lib/diakonos/display.rb', line 13
def cleanup_display
return if @testing
@win_context&.close
@win_dock&.close
@win_interaction&.close
@win_line_numbers&.close
@win_main&.close
@win_status&.close
Curses.close_screen
end
|
#cleanup_session ⇒ Object
250
251
252
253
254
|
# File 'lib/diakonos/sessions.rb', line 250
def cleanup_session
if @session && Session.pid_session?(@session.filename) && File.exist?(@session.filename)
File.delete @session.filename
end
end
|
#clear_non_movement_flag ⇒ Object
394
395
396
|
# File 'lib/diakonos.rb', line 394
def clear_non_movement_flag
@there_was_non_movement = false
end
|
#close_help_buffer ⇒ Object
12
13
14
15
|
# File 'lib/diakonos/help.rb', line 12
def close_help_buffer
close_buffer @help_buffer
@help_buffer = nil
end
|
#close_list_buffer(opts = {}) ⇒ Object
10
11
12
13
|
# File 'lib/diakonos/list.rb', line 10
def close_list_buffer( opts = {} )
close_buffer @list_buffer, opts
@list_buffer = nil
end
|
#create_buffers_from_files ⇒ Object
400
401
402
403
404
|
# File 'lib/diakonos.rb', line 400
def create_buffers_from_files
@files.each do |file_info|
@buffers << Buffer.new(file_info)
end
end
|
#current_list_item ⇒ Object
23
24
25
|
# File 'lib/diakonos/list.rb', line 23
def current_list_item
@list_buffer&.set_selection_current_line
end
|
#cursor_stack_remove_buffer(buffer) ⇒ Object
4
5
6
7
8
|
# File 'lib/diakonos/cursor.rb', line 4
def cursor_stack_remove_buffer( buffer )
@cursor_stack.delete_if { |frame|
frame[ :buffer ] == buffer
}
end
|
#debug_log(string) ⇒ Object
10
11
12
13
|
# File 'lib/diakonos/logging.rb', line 10
def debug_log( string )
@debug.puts( Time.now.strftime( "[%a %H:%M:%S] #{string}" ) )
@debug.flush
end
|
#decrease_grep_context ⇒ Object
90
91
92
93
94
95
96
|
# File 'lib/diakonos/grep.rb', line 90
def decrease_grep_context
current = settings['grep.context']
if current > 0
@session.settings['grep.context'] = current - 1
merge_session_settings
end
end
|
#display_buffer(buffer) ⇒ Object
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
|
# File 'lib/diakonos/display.rb', line 308
def display_buffer( buffer )
return if @testing
return if ! @do_display
Thread.new do
if ! @display_mutex.try_lock
@display_queue_mutex.synchronize do
@display_queue = buffer
end
else
begin
Curses.curs_set 0
buffer.display
Curses.curs_set 1
rescue StandardError => e
$diakonos.log( "Display Exception:" )
$diakonos.log( e.message )
$diakonos.log( e.backtrace.join( "\n" ) )
show_exception e
end
@display_mutex.unlock
@display_queue_mutex.synchronize do
if @display_queue
b = @display_queue
@display_queue = nil
display_buffer b
end
end
end
end
end
|
#escape_quotes(str) ⇒ Object
653
654
655
656
657
658
659
660
661
662
663
664
|
# File 'lib/diakonos.rb', line 653
def escape_quotes( str )
temp = ''
str.each_byte do |b|
if b == 39
temp << 39
temp << 92
temp << 39
end
temp << b
end
temp
end
|
#find_(options = {}) ⇒ Integer
Returns the number of replacements made.
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
# File 'lib/diakonos/search.rb', line 5
def find_( options = {} )
regexp_source, replacement = options.values_at( :regexp_source, :replacement )
return if regexp_source.nil? || regexp_source.empty?
rs_array = regexp_source.newline_split
regexps = Array.new
exception_thrown = nil
rs_array.each do |source|
warning_verbosity = $VERBOSE
$VERBOSE = nil
regexps << Regexp.new(
source,
options[:case_sensitive] ? nil : Regexp::IGNORECASE
)
$VERBOSE = warning_verbosity
rescue RegexpError => e
if ! exception_thrown
exception_thrown = e
source = Regexp.escape( source )
retry
else
raise e
end
end
if replacement == ASK_REPLACEMENT
replacement = get_user_input( "Replace with: ", history: @rlh_search )
end
if exception_thrown && ! options[:quiet]
set_iline "Searching literally; #{exception_thrown.message}"
end
num_replacements = buffer_current.find(
regexps,
direction: options[:direction],
replacement:,
starting_row: options[:starting_row],
starting_col: options[:starting_col],
quiet: options[:quiet],
show_context_after: @settings[ 'find.show_context_after' ],
starting: true
)
@last_search_regexps = regexps
num_replacements
end
|
#get_choice(*args) ⇒ Object
48
49
50
|
# File 'lib/diakonos/interaction.rb', line 48
def get_choice(*args)
@interaction_handler.get_choice(*args)
end
|
#get_language_from_name(name) ⇒ Object
568
569
570
571
572
573
574
575
|
# File 'lib/diakonos.rb', line 568
def get_language_from_name( name )
@filemasks.each do |language,filemask|
if name =~ filemask
return language
end
end
nil
end
|
#get_language_from_shabang(first_line) ⇒ Object
577
578
579
580
581
582
583
584
|
# File 'lib/diakonos.rb', line 577
def get_language_from_shabang( first_line )
@bangmasks.each do |language,bangmask|
if first_line =~ bangmask
return language
end
end
nil
end
|
#get_token_regexp(hash, arg, match) ⇒ Object
125
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/diakonos/config.rb', line 125
def get_token_regexp( hash, arg, match )
language = match[ 1 ]
token_class = match[ 2 ]
case_insensitive = match[ 3 ]
hash[ language ] = ( hash[ language ] || Hash.new )
if case_insensitive
hash[ language ][ token_class ] = Regexp.new( arg, Regexp::IGNORECASE )
else
hash[ language ][ token_class ] = Regexp.new arg
end
end
|
completion_array is the array of strings that tab completion can use
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
# File 'lib/diakonos/interaction.rb', line 9
def get_user_input( prompt, options = {}, &block )
if @playing_macro
return @macro_input_history.shift
end
options[ :history ] ||= @rlh_general
options[ :initial_text ] ||= ""
options[ :do_complete ] ||= DONT_COMPLETE
options[ :on_dirs ] ||= :go_into_dirs
will_display_after_select = options.fetch( :will_display_after_select, false )
cursor_pos = set_iline( prompt )
@readline = Readline.new(
list_manager: self,
keystroke_processor: self,
testing: @testing,
window: @win_interaction,
start_pos: cursor_pos,
options:,
&block
)
retval = @readline.get_input
if will_display_after_select
close_list_buffer do_display: ! retval
else
close_list_buffer
end
options[ :history ][ -1 ] = @readline.input
@readline = nil
if @macro_history
@macro_input_history.push retval
end
set_iline
retval
end
|
#grep_(regexp_source, *buffers) ⇒ Object
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/diakonos/grep.rb', line 54
def grep_( regexp_source, *buffers )
original_buffer = buffer_current
if buffer_current.changing_selection
selected_text = buffer_current.copy_selection[ 0 ]
end
starting_row, starting_col = buffer_current.last_row, buffer_current.last_col
selected = get_user_input(
"Grep regexp: ",
history: @rlh_search,
initial_text: regexp_source || selected_text || "",
will_display_after_select: true
) { |input|
next if input.length < 2
actually_grep input, *buffers
}
if selected
spl = selected.split( "| " )
if spl.size > 1
open_file spl[-1]
else
original_buffer.cursor_to starting_row, starting_col
end
else
original_buffer.cursor_to starting_row, starting_col
end
end
|
#handle_gui_paste(mode) ⇒ Object
Handle paste from a GUI (like x.org). i.e. Shift-Insert
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
# File 'lib/diakonos/keying.rb', line 283
def handle_gui_paste(mode)
s = ""
ch = nil
loop do
ch = nil
begin
Timeout.timeout(0.02) do
ch = @modes[mode].window.getch
end
rescue Timeout::Error
break
end
break if ch.nil?
c = ch.ord
utf_8_char = self.utf_8_bytes_to_char(c, mode)
if utf_8_char
s << utf_8_char
elsif self.typeable?(c)
s << c
elsif c == ENTER && mode == 'edit'
s << "\n"
else
break
end
end
if ! s.empty?
case mode
when 'edit'
buffer_current.paste(s, typing: true)
when 'input'
@readline.paste s
end
end
if ch
process_keystroke( [], mode, ch )
end
end
|
#handle_mouse_event ⇒ Object
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# File 'lib/diakonos/mouse.rb', line 3
def handle_mouse_event
event = Curses.getmouse
return if event.nil?
if event.bstate & Curses::BUTTON1_CLICKED > 0
buffer_current.cursor_to(
buffer_current.top_line + event.y,
buffer_current.left_column + event.x,
Buffer::DO_DISPLAY
)
else
$diakonos.debug_log "button state = #{'0x%x' % event.bstate}, "
end
end
|
#handle_stale_session_files ⇒ Object
We have to do this separately and later (as opposed to inside #session_startup) because we have to wait for the display to get initialized in order to prompt the user for input, etc.
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
|
# File 'lib/diakonos/sessions.rb', line 211
def handle_stale_session_files
return if @testing
return if @stale_session_files.empty?
session_buffers = []
@stale_session_files.each_with_index do |session_file,index|
session_buffers << open_file( session_file )
choice = get_choice(
"#{@stale_session_files.size} unclosed session(s) found. " +
"Open the above files? (session #{index+1} of #{@stale_session_files.size})",
[ CHOICE_YES, CHOICE_NO, CHOICE_DELETE ],
index > 0 ? CHOICE_NO : nil
)
case choice
when CHOICE_YES
load_session session_file
if @session
File.delete session_file
break
end
when CHOICE_DELETE
File.delete session_file
end
end
if session_buffers.empty? && @files.empty? && @settings[ 'session.default_session' ]
session_file = session_filepath_for( @settings[ 'session.default_session' ] )
if File.exist? session_file
load_session session_file
end
end
session_buffers.each do |buffer|
close_buffer buffer
end
end
|
#handle_utf_8(c, mode) ⇒ Boolean
Returns true iff c began a UTF-8 byte sequence.
274
275
276
277
278
279
280
|
# File 'lib/diakonos/keying.rb', line 274
def handle_utf_8(c, mode)
utf_8_char = utf_8_bytes_to_char(c, mode)
if utf_8_char
self.type_character utf_8_char, mode
true
end
end
|
#increase_grep_context ⇒ Object
84
85
86
87
88
|
# File 'lib/diakonos/grep.rb', line 84
def increase_grep_context
current = settings['grep.context']
@session.settings['grep.context'] = current + 1
merge_session_settings
end
|
#init_help ⇒ Object
3
4
5
6
|
# File 'lib/diakonos/help.rb', line 3
def init_help
@help_dir = INSTALL_SETTINGS[ :help_dir ]
@help_tags = `grep -h Tags #{@help_dir}/* | cut -d ' ' -f 2-`.split.uniq
end
|
#initialize_display ⇒ Object
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/diakonos/display.rb', line 26
def initialize_display
if ! @testing
cleanup_display
Curses.init_screen
Curses.nonl
Curses.raw
Curses.noecho
if @settings['mouse']
Curses.mousemask(Curses::ALL_MOUSE_EVENTS)
end
if Curses.has_colors?
Curses.start_color
Curses.use_default_colors
background_colour = settings['colour.background'] || -1
Curses.init_pair( Curses::COLOR_BLACK, Curses::COLOR_BLACK, background_colour )
Curses.init_pair( Curses::COLOR_RED, Curses::COLOR_RED, background_colour )
Curses.init_pair( Curses::COLOR_GREEN, Curses::COLOR_GREEN, background_colour )
Curses.init_pair( Curses::COLOR_YELLOW, Curses::COLOR_YELLOW, background_colour )
Curses.init_pair( Curses::COLOR_BLUE, Curses::COLOR_BLUE, background_colour )
Curses.init_pair( Curses::COLOR_MAGENTA, Curses::COLOR_MAGENTA, background_colour )
Curses.init_pair( Curses::COLOR_CYAN, Curses::COLOR_CYAN, background_colour )
Curses.init_pair( Curses::COLOR_WHITE, Curses::COLOR_WHITE, background_colour )
@colour_pairs.each do |cp|
Curses.init_pair( cp[ :number ], cp[ :fg ], cp[ :bg ] )
end
end
end
if settings[ 'view.line_numbers' ]
line_numbers_width = settings[ 'view.line_numbers.width' ] + Buffer::COLUMNS_FOR_DIAGNOSTICS
@win_line_numbers = ::Diakonos::Window.new( main_window_height, line_numbers_width, 0, 0 )
@win_main = ::Diakonos::Window.new(
main_window_height,
Curses.cols - line_numbers_width,
0,
line_numbers_width
)
else
@win_main = ::Diakonos::Window.new( main_window_height, Curses.cols, 0, 0 )
@win_line_numbers = nil
end
if @dock_lines && ! @dock_lines.empty?
@win_dock = ::Diakonos::Window.new(dock_height, Curses.cols, main_window_height, 0)
else
@win_dock = nil
end
@win_status = ::Diakonos::Window.new( 1, Curses.cols, Curses.lines - 2, 0 )
@win_status.attrset @settings[ 'status.format' ]
@win_interaction = ::Diakonos::Window.new( 1, Curses.cols, Curses.lines - 1, 0 )
@interaction_handler = InteractionHandler.new(
win_main: @win_main,
win_interaction: @win_interaction,
cursor_manager: self,
testing: @testing,
choice_delay: @settings['interaction.choice_delay'],
blink_string: @settings['interaction.blink_string'],
blink_duration: @settings['interaction.blink_duration']
)
if @settings['context.visible']
if @settings['context.combined']
pos = 1
else
pos = 3
end
@win_context = ::Diakonos::Window.new( 1, Curses.cols, Curses.lines - pos, 0 )
else
@win_context = nil
end
if ! @testing
@win_main.keypad( true )
@win_status.keypad( true )
@win_interaction.keypad( true )
@win_line_numbers&.keypad( true )
@win_context&.keypad( true )
end
if ! @testing
@win_main.timeout = @settings['async_update_interval'] || 100
end
@modes[ 'edit' ].window = @win_main
@modes[ 'input' ].window = @win_interaction
@win_interaction.refresh
@win_main.refresh
@win_line_numbers&.refresh
@buffers&.each(&:reset_display)
end
|
#initialize_session ⇒ Object
137
138
139
140
141
|
# File 'lib/diakonos/sessions.rb', line 137
def initialize_session
@session_dir = "#{@diakonos_home}/sessions"
mkdir @session_dir
@session = Session.new("#{@session_dir}/#{Process.pid}")
end
|
#keychain_str_for(array) ⇒ Object
180
181
182
183
184
185
186
187
188
189
190
191
|
# File 'lib/diakonos/keying.rb', line 180
def keychain_str_for( array )
chain_str = ""
array.each do |key|
key_str = Keying.key_string_for( key )
if key_str
chain_str << key_str + " "
else
chain_str << key.to_s + " "
end
end
chain_str.strip
end
|
#legitimize_config_filename!(prospective_filename, including_config_file) ⇒ ConfigFile, ConfigFileUnreadable
168
169
170
171
172
173
174
175
176
177
|
# File 'lib/diakonos/config.rb', line 168
def legitimize_config_filename!(prospective_filename, including_config_file)
if File.exist?(prospective_filename)
ConfigFile.new(
File.realpath(prospective_filename),
including_config_file
)
else
ConfigFileUnreadable.new(prospective_filename, including_config_file)
end
end
|
#list_item_selected? ⇒ Boolean
19
20
21
|
# File 'lib/diakonos/list.rb', line 19
def list_item_selected?
@list_buffer&.selecting?
end
|
#load_configuration ⇒ Object
Also known as:
loadConfiguration
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/diakonos/config.rb', line 24
def load_configuration
conf_dir = INSTALL_SETTINGS[ :conf_dir ]
@global_diakonos_conf = "#{conf_dir}/diakonos.conf"
if ! @testing
@diakonos_conf = @config_filename || "#{@diakonos_home}/diakonos.conf"
if ! FileTest.exist?( @diakonos_conf )
if FileTest.exist?( @global_diakonos_conf )
puts "No personal configuration file found."
puts "Would you like to copy the system-wide configuration file (#{@global_diakonos_conf}) to use"
$stdout.print "as a basis for your personal configuration (recommended)? (y/n)"
$stdout.flush
answer = $stdin.gets
if answer =~ /^y/i
FileUtils.cp @global_diakonos_conf, @diakonos_conf
end
else
if @testing
File.open( @diakonos_conf, 'w' ) do |f|
f.puts File.read( './diakonos.conf' )
end
else
puts "diakonos.conf not found in any of:"
puts " #{conf_dir}"
puts " #{@diakonos_home}"
puts "At least one configuration file must exist."
puts "You download one from https://git.sr.ht/~pistos/diakonos/blob/master/diakonos.conf"
end
if ! FileTest.exist?( @diakonos_conf )
puts "Terminating due to lack of configuration file."
exit 1
end
end
end
end
@logfilename = @diakonos_home + "/diakonos.log"
@modes = {
'edit' => Mode.new,
'input' => Mode.new,
}
@token_regexps = Hash.new { |h,k| h[ k ] = Hash.new }
@close_token_regexps = Hash.new { |h,k| h[ k ] = Hash.new }
@token_formats = Hash.new { |h,k| h[ k ] = Hash.new }
@column_markers = Hash.new { |h,k| h[ k ] = Hash.new }
@indenters = Hash.new
@indenters_next_line = Hash.new
@unindenters = Hash.new
@indent_triggers = Hash.new
@filemasks = Hash.new
@bangmasks = Hash.new
@closers = Hash.new
@surround_pairs = Hash.new { |h,k| h[ k ] = Hash.new }
@fuzzy_ignores = Array.new
@settings = Hash.new
@setting_strings = Hash.new
@settings[ "context.format" ] = Curses::A_REVERSE
@settings['fuzzy_file_find.recursive'] = true
@modes[ 'edit' ].keymap[ Curses::KEY_RESIZE ] = [ "redraw", nil ]
@modes[ 'edit' ].keymap[ RESIZE2 ] = [ "redraw", nil ]
@colour_pairs = Array.new
@configs = Set.new
parse_configuration_file @global_diakonos_conf
parse_configuration_file @diakonos_conf if @diakonos_conf
languages = @surround_pairs.keys | @token_regexps.keys | @close_token_regexps.keys | @token_formats.keys
languages.each do |language|
@surround_pairs[ language ] = @surround_pairs[ 'all' ].merge( @surround_pairs[ language ] )
@token_regexps[ language ] = @token_regexps[ 'all' ].merge( @token_regexps[ language ] )
@close_token_regexps[ language ] = @close_token_regexps[ 'all' ].merge( @close_token_regexps[ language ] )
@token_formats[ language ] = @token_formats[ 'all' ].merge( @token_formats[ language ] )
end
merge_session_settings
case @settings[ 'clipboard.external' ]
when 'klipper', 'klipper-dcop'
@clipboard = ClipboardKlipper.new
when 'klipper-dbus'
@clipboard = ClipboardKlipperDBus.new
when 'xclip'
@clipboard = ClipboardXClip.new
when 'osx'
@clipboard = ClipboardOSX.new
else
@clipboard = Clipboard.new( @settings[ "max_clips" ] )
end
@log = File.open( @logfilename, "a" )
@buffers&.each(&:configure)
end
|
#load_session(session_file) ⇒ Object
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
# File 'lib/diakonos/sessions.rb', line 143
def load_session( session_file )
cleanup_session
@session = Session.from_yaml_file(session_file)
if @session
@files.concat @session.buffers
rlh = @session.readline_histories
if rlh
@rlh_general = rlh['general'] || @rlh_general
@rlh_files = rlh['files'] || @rlh_files
@rlh_search = rlh['search'] || @rlh_search
@rlh_shell = rlh['shell'] || @rlh_shell
@rlh_help = rlh['help'] || @rlh_help
@rlh_sessions = rlh['sessions'] || @rlh_sessions
end
merge_session_settings
end
end
|
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
|
# File 'lib/diakonos.rb', line 627
def load_tags
@tags = Hash.new
if buffer_current&.name
path = File.expand_path( File.dirname( buffer_current.name ) )
tagfile = path + "/tags"
else
tagfile = "./tags"
end
if ! FileTest.exist? tagfile
set_iline "(tags file not found)"
else
IO.foreach( tagfile ) do |line_|
line = line_.chomp
tag, file, command, kind, rest = line.split( /\t/ )
command.gsub!( /;"$/, "" )
if command =~ %r{^/.*/$}
command = command[ 1...-1 ]
end
@tags[ tag ] ||= Array.new
@tags[ tag ].push CTag.new( file, command, kind, rest )
end
end
end
|
#log(string) ⇒ Object
5
6
7
8
|
# File 'lib/diakonos/logging.rb', line 5
def log( string )
@log.puts string
@log.flush
end
|
#log_backtrace ⇒ Object
15
16
17
18
19
20
21
|
# File 'lib/diakonos/logging.rb', line 15
def log_backtrace
raise StandardError
rescue StandardError => e
e.backtrace[ 1.. ].each do |x|
debug_log x
end
end
|
#main_window_height ⇒ Object
132
133
134
135
136
137
138
139
140
|
# File 'lib/diakonos/display.rb', line 132
def main_window_height
retval = Curses.lines - (INPUT_LINE_HEIGHT + STATUS_LINE_HEIGHT)
if @settings['context.visible'] && ! @settings['context.combined']
retval -= CONTEXT_LINE_HEIGHT
end
retval -= dock_height
retval
end
|
#main_window_width ⇒ Object
142
143
144
|
# File 'lib/diakonos/display.rb', line 142
def main_window_width
Curses.cols
end
|
#map_key(arg, keymap = @modes['edit'].keymap) ⇒ Object
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
# File 'lib/diakonos/config.rb', line 137
def map_key( arg, keymap = @modes['edit'].keymap )
return if arg.nil?
if / / === arg
keystrings, function_and_args = arg.split( / {2,}/, 2 )
else
keystrings, function_and_args = arg.split( /;/, 2 )
end
keystrokes = Array.new
keystrings.split( /\s+/ ).each do |ks_str|
codes = Keying.keycodes_for( ks_str )
if codes.empty?
puts "Unknown keystring: #{ks_str}"
else
keystrokes.concat codes
end
end
if function_and_args.nil?
keymap.delete_key_path( keystrokes )
else
function, function_args = function_and_args.split( /\s+/, 2 )
keymap.set_key_path(
keystrokes,
[ function, function_args ]
)
end
end
|
#matching_help_documents(str) ⇒ Object
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/diakonos/help.rb', line 17
def matching_help_documents( str )
docs = []
if str =~ %r{^/(.+)$}
regexp = ::Regexp.last_match(1)
files = Dir[ "#{@help_dir}/*" ].select { |f|
File.open( f ) { |io| io.grep( /#{regexp}/i ) }.any?
}
else
terms = str.gsub( /[^a-zA-Z0-9-]/, ' ' ).split.join( '|' )
file_grep = `egrep -i -l '^Tags.*\\b(#{terms})\\b' #{@help_dir}/*`
files = file_grep.split( /\s+/ )
end
files.each do |file|
File.open( file ) do |f|
docs << ( "%-300s | %s" % [ f.gets.strip, file ] )
end
end
docs.sort { |a,b| a.gsub( /^# (?:an?|the) */i, '# ' ) <=> b.gsub( /^# (?:an?|the) */i, '# ' ) }
end
|
#mkdir(dir) ⇒ Object
253
254
255
256
257
|
# File 'lib/diakonos.rb', line 253
def mkdir( dir )
if ! FileTest.exist?( dir )
Dir.mkdir dir
end
end
|
#next_list_item ⇒ Object
42
43
44
45
46
47
|
# File 'lib/diakonos/list.rb', line 42
def next_list_item
if @list_buffer
cursor_down
@list_buffer[ @list_buffer.current_row ]
end
end
|
#open_help_buffer ⇒ Object
8
9
10
|
# File 'lib/diakonos/help.rb', line 8
def open_help_buffer
@help_buffer = open_file( @help_filename )
end
|
#open_help_document(selected_string) ⇒ Object
40
41
42
43
44
45
|
# File 'lib/diakonos/help.rb', line 40
def open_help_document( selected_string )
help_file = selected_string.split( "| " )[ -1 ]
if File.exist? help_file
open_file help_file
end
end
|
#open_list_buffer ⇒ Object
6
7
8
|
# File 'lib/diakonos/list.rb', line 6
def open_list_buffer
@list_buffer = open_file( @list_filename )
end
|
#parse_configuration_file(filename, including_config_file = ConfigFileNull.new) ⇒ Object
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
|
# File 'lib/diakonos/config.rb', line 181
def parse_configuration_file( filename, including_config_file = ConfigFileNull.new )
config_file = self.legitimize_config_filename!(filename, including_config_file)
@configs << config_file
config_file.each_line_with_index do |line, line_number|
if line =~ /^\s*(\S+)\s*=\s*(\S+)\s*$/
command, arg = ::Regexp.last_match(1), @setting_strings[ ::Regexp.last_match(2) ]
end
if arg.nil?
command, arg = line.split( /\s+/, 2 )
next if command.nil?
if arg.nil?
config_file.problems << "error on line #{line_number+1}"
next
end
end
command = command.downcase
@setting_strings[ command ] = arg
case command
when "include"
self.parse_configuration_file( File.expand_path( arg ), config_file )
when "load_extension"
@extensions.load( arg ).each do |conf_file|
parse_configuration_file conf_file
end
when /^lang\.(.+?)\.surround\.pair$/
language = ::Regexp.last_match(1)
args = arg.split( /"\s+"/ )
args.map! do |s|
s.gsub( /(?<!\\)"/, '' ).gsub( /\\"/, '"' )
end
pair_key = args.shift
if pair_key =~ %r{^/.+/$}
pair_key = Regexp.new( pair_key[ 1..-2 ] )
else
pair_key = Regexp.new( "^#{Regexp.escape(pair_key)}$" )
end
pair_parens = args
@surround_pairs[ language ][ pair_key ] = pair_parens
when 'key'
map_key arg
when 'mkey'
mode, arg_ = arg.split( /\s+/, 2 )
map_key arg_, @modes[mode].keymap
when 'key.after'
function, args = arg.split( /\s+/, 2 )
map_key args, @modes['edit'].keymap_after[function]
when /^lang\.(.+?)\.tokens\.([^.]+)(\.case_insensitive)?$/,
/^lang\.(.+?)\.tokens\.([^.]+)\.open(\.case_insensitive)?$/
get_token_regexp( @token_regexps, arg, Regexp.last_match )
when /^lang\.(.+?)\.tokens\.([^.]+)\.close(\.case_insensitive)?$/
get_token_regexp( @close_token_regexps, arg, Regexp.last_match )
when /^lang\.(.+?)\.tokens\.(.+?)\.format$/
language = ::Regexp.last_match(1)
token_class = ::Regexp.last_match(2)
@token_formats[ language ][ token_class ] = Display.to_formatting( arg )
when /^lang\.(.+?)\.format\..+$/
@settings[ command ] = Display.to_formatting( arg )
when /^colou?r$/
number, fg, bg = arg.split( /\s+/ )
number = number.to_i
fg = Display.to_colour_constant( fg )
bg = Display.to_colour_constant( bg )
@colour_pairs << {
number:,
fg:,
bg:,
}
when /^lang\.(.+?)\.indent\.indenters(\.case_insensitive)?$/
case_insensitive = ::Regexp.last_match(2)
if case_insensitive
@indenters[ ::Regexp.last_match(1) ] = Regexp.new( arg, Regexp::IGNORECASE )
else
@indenters[ ::Regexp.last_match(1) ] = Regexp.new arg
end
when /^lang\.(.+?)\.indent\.indenters_next_line(\.case_insensitive)?$/
case_insensitive = ::Regexp.last_match(2)
if case_insensitive
@indenters_next_line[ ::Regexp.last_match(1) ] = Regexp.new( arg, Regexp::IGNORECASE )
else
@indenters_next_line[ ::Regexp.last_match(1) ] = Regexp.new arg
end
when /^lang\.(.+?)\.indent\.unindenters(\.case_insensitive)?$/
case_insensitive = ::Regexp.last_match(2)
if case_insensitive
@unindenters[ ::Regexp.last_match(1) ] = Regexp.new( arg, Regexp::IGNORECASE )
else
@unindenters[ ::Regexp.last_match(1) ] = Regexp.new arg
end
when /^lang\.(.+?)\.indent\.(?:preventers|ignore|not_indented)(\.case_insensitive)?$/,
/^lang\.(.+?)\.context\.ignore(\.case_insensitive)?$/
case_insensitive = ::Regexp.last_match(2)
if case_insensitive
@settings[ command ] = Regexp.new( arg, Regexp::IGNORECASE )
else
@settings[ command ] = Regexp.new arg
end
when /^lang\.(.+?)\.indent\.triggers(\.case_insensitive)?$/
case_insensitive = ::Regexp.last_match(2)
if case_insensitive
@indent_triggers[::Regexp.last_match(1)] = Regexp.new( arg, Regexp::IGNORECASE )
else
@indent_triggers[::Regexp.last_match(1)] = Regexp.new arg
end
when /^lang\.(.+?)\.filemask$/
@filemasks[ ::Regexp.last_match(1) ] = Regexp.new arg
when /^lang\.(.+?)\.bangmask$/
@bangmasks[ ::Regexp.last_match(1) ] = Regexp.new arg
when /^lang\.(.+?)\.closers\.(.+?)\.(.+?)$/
@closers[ ::Regexp.last_match(1) ] ||= Hash.new
@closers[ ::Regexp.last_match(1) ][ ::Regexp.last_match(2) ] ||= Hash.new
@closers[ ::Regexp.last_match(1) ][ ::Regexp.last_match(2) ][ ::Regexp.last_match(3).to_sym ] = (
case ::Regexp.last_match(3)
when 'regexp'
Regexp.new arg
when 'closer'
begin
if arg =~ /^\{.+\}$/
eval("Proc.new " + arg) else
arg
end
rescue StandardError => e
show_exception(
e,
[ "Failed to process Proc for #{command}." ]
)
end
end
)
when "context.visible", "context.combined", "eof_newline", "view.nonfilelines.visible",
/^lang\.(.+?)\.indent\.(?:auto|roundup|using_tabs|closers)$/,
"found_cursor_start", "convert_tabs", 'delete_newline_on_delete_to_eol',
'suppress_welcome', 'strip_trailing_whitespace_on_save', 'save_backup_files',
'find.return_on_abort', 'fuzzy_file_find', 'fuzzy_file_find.recursive', 'view.line_numbers',
'find.show_context_after', 'view.pairs.highlight', 'open_as_first_buffer', 'mouse'
@settings[ command ] = arg.to_b
when "context.format", "context.separator.format", "status.format", 'view.line_numbers.format',
'view.non_search_area.format'
@settings[ command ] = Display.to_formatting( arg )
when /view\.column_markers\.(.+?)\.format/
@column_markers[ ::Regexp.last_match(1) ][ :format ] = Display.to_formatting( arg )
when "logfile"
@logfilename = File.expand_path( arg )
when "context.separator", /^lang\..+?\.indent\.ignore\.charset$/,
/^lang\.(.+?)\.tokens\.([^.]+)\.change_to$/,
/^lang\.(.+?)\.column_delimiters$/,
/^lang\..+?\.lsp\.command$/,
/^extension\.(.+?)\.(.+?)/,
"view.line_numbers.diagnostic_marker",
"view.nonfilelines.character",
'diff_command', 'session.default_session',
'clipboard.external'
@settings[ command ] = arg
when /^lang\..+?\.comment_(?:close_)?string$/, 'view.line_numbers.number_format',
"status.filler", "status.left", "status.right",
"status.modified_str", "status.unnamed_str", "status.selecting_str",
"status.read_only_str", 'interaction.blink_string'
@settings[ command ] = arg.gsub( /^["']|["']$/, '' )
when "status.vars"
@settings[ command ] = arg.split( /\s+/ )
when /^lang\.(.+?)\.indent\.size$/, /^lang\.(.+?)\.(?:tabsize|wrap_margin)$/,
"async_update_interval",
"context.max_levels", "context.max_segment_width", "max_clips", "max_undo_lines",
"view.margin.x", "view.margin.y", "view.scroll_amount", "view.lookback", 'grep.context',
'view.line_numbers.width', 'fuzzy_file_find.max_files', 'colour.background'
@settings[ command ] = arg.to_i
when "view.jump.x", "view.jump.y"
@settings[ command ] = [ arg.to_i, 1 ].max
when /view\.column_markers\.(.+?)\.column/
@column_markers[ ::Regexp.last_match(1) ][ :column ] = [ arg.to_i, 1 ].max
when "bol_behaviour", "bol_behavior"
case arg.downcase
when "zero"
@settings[ "bol_behaviour" ] = BOL_ZERO
when "first-char"
@settings[ "bol_behaviour" ] = BOL_FIRST_CHAR
when "alternating-zero"
@settings[ "bol_behaviour" ] = BOL_ALT_ZERO
else @settings[ "bol_behaviour" ] = BOL_ALT_FIRST_CHAR
end
when "eol_behaviour", "eol_behavior"
case arg.downcase
when "end"
@settings[ "eol_behaviour" ] = EOL_END
when "last-char"
@settings[ "eol_behaviour" ] = EOL_LAST_CHAR
when "alternating-last-char"
@settings[ "eol_behaviour" ] = EOL_ALT_FIRST_CHAR
else @settings[ "eol_behaviour" ] = EOL_ALT_END
end
when *[
'close_forgotten_buffers_after',
'context.delay',
'interaction.blink_duration',
'interaction.choice_delay',
]
@settings[ command ] = arg.to_f
when 'fuzzy_file_find.ignore'
@fuzzy_ignores << arg
end
end
end
|
#parse_options(argv) ⇒ Object
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
|
# File 'lib/diakonos.rb', line 259
def parse_options( argv )
@post_load_script = ""
while argv.any?
arg = argv.shift
case arg
when '-c', '--config'
@config_filename = argv.shift
if @config_filename.nil?
print_usage
exit 1
end
when '-e', '--execute'
post_load_script = argv.shift
if post_load_script.nil?
print_usage
exit 1
else
@post_load_script << "\n#{post_load_script}"
end
when '-h', '--help'
print_usage
exit 1
when '-m', '--open-matching'
regexp = argv.shift
files = `egrep -rl '#{regexp}' *`.split( /\n/ )
if files.any?
@files.concat( files.map { |f| Session.file_hash_for f } )
script = "\nfind '#{regexp}', case_sensitive: true"
@post_load_script << script
end
when '-ro'
filename = argv.shift
if filename.nil?
print_usage
exit 1
else
h = Session.file_hash_for( filename )
h[ 'read_only' ] = true
@read_only_files.push h
end
when '-s', '--load-session'
@session_to_load = session_filepath_for( argv.shift )
when '--test', '--testing'
@testing = true
when '--uninstall'
uninstall
when '--uninstall-without-confirmation'
uninstall(confirm: false)
when '--version'
puts "Diakonos #{::Diakonos::VERSION} (#{::Diakonos::LAST_MODIFIED})"
exit 0
else
@files.push Session.file_hash_for( arg )
end
end
end
|
#previous_list_item ⇒ Object
35
36
37
38
39
40
|
# File 'lib/diakonos/list.rb', line 35
def previous_list_item
if @list_buffer
cursor_up
@list_buffer[ @list_buffer.current_row ]
end
end
|
#print_usage ⇒ Object
383
384
385
386
387
388
389
390
391
392
|
# File 'lib/diakonos.rb', line 383
def print_usage
puts "Usage: #{$PROGRAM_NAME} [options] [file] [file...]"
puts "\t--help\tDisplay usage"
puts "\t-c <config file>\tLoad this config file instead of ~/.diakonos/diakonos.conf"
puts "\t-e, --execute <Ruby code>\tExecute Ruby code (such as Diakonos commands) after startup"
puts "\t-m, --open-matching <regular expression>\tOpen all matching files under current directory"
puts "\t-ro <file>\tLoad file as read-only"
puts "\t-s, --load-session <session identifier>\tLoad a session"
puts "\t--uninstall[-without-confirmation]\tUninstall Diakonos"
end
|
#process_async ⇒ Object
365
366
367
368
|
# File 'lib/diakonos.rb', line 365
def process_async
@lsp_sessions.each_value(&:process_queue)
show_lsp_diagnostic_for_current_line
end
|
#process_keystroke(context = [], mode = 'edit', ch = nil) ⇒ Symbol
context is an array of characters (bytes) which are keystrokes previously typed (in a chain of keystrokes)
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
|
# File 'lib/diakonos/keying.rb', line 329
def process_keystroke( context = [], mode = 'edit', ch = nil )
ch ||= @modes[ mode ].window.getch
if ch.nil?
return :waiting_for_keystroke
end
if ch == Curses::KEY_MOUSE
handle_mouse_event
return
end
if @dock_lines
hide_dock
end
c = ch.ord
self.handle_utf_8(c, mode) and return
if @capturing_keychain
capture_keychain c, context
elsif @capturing_mapping
capture_mapping c, context
else
if context.empty? && typeable?( c )
self.type_character ch, mode
self.handle_gui_paste(mode)
return
end
keychain_pressed = context.concat [ c ]
function_and_args = (
@modes[mode].keymap_after[@function_last].get_leaf( keychain_pressed ) ||
@modes[mode].keymap.get_leaf( keychain_pressed )
)
if function_and_args
function, args = function_and_args
@function_last = function
if mode != 'input' && ! @settings[ "context.combined" ]
set_iline
end
if args
to_eval = "#{function}( #{args} )"
else
to_eval = function
end
@macro_history&.push to_eval
begin
if buffer_current.search_area? && ! ( /^(?:find|readline)/ === to_eval )
buffer_current.clear_search_area
end
eval(to_eval, nil, "eval") @functions_last << to_eval unless to_eval == "repeat_last"
if ! @there_was_non_movement
@there_was_non_movement = !( /^((cursor|page|scroll)_?(up|down|left|right)|find|seek)/i === to_eval )
end
rescue StandardError => e
debug_log e.message
debug_log e.backtrace.join( "\n\t" )
show_exception e
end
else
partial_keychain = @modes[ mode ].keymap.get_node( keychain_pressed )
if partial_keychain
if mode != 'input'
set_iline( keychain_str_for( keychain_pressed ) + "..." )
end
waiting_for_keystroke = :waiting_for_keystroke
while waiting_for_keystroke == :waiting_for_keystroke
waiting_for_keystroke = process_keystroke(keychain_pressed, mode)
end
elsif mode != 'input'
set_iline "Nothing assigned to #{keychain_str_for( keychain_pressed )}"
end
end
end
end
|
#push_cursor_state(top_line, row, col, clear_stack_pointer = CLEAR_STACK_POINTER) ⇒ Object
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# File 'lib/diakonos/cursor.rb', line 10
def push_cursor_state( top_line, row, col, clear_stack_pointer = CLEAR_STACK_POINTER )
new_state = {
buffer: buffer_current,
top_line:,
row:,
col:,
}
if ! @cursor_stack.include? new_state
@cursor_stack << new_state
if clear_stack_pointer
@cursor_stack_pointer = nil
end
clear_non_movement_flag
end
end
|
124
125
126
127
128
129
130
|
# File 'lib/diakonos/display.rb', line 124
def redraw
load_configuration
initialize_display
update_status_line
update_context_line
display_buffer buffer_current
end
|
#refresh_all ⇒ Object
344
345
346
347
348
349
350
351
|
# File 'lib/diakonos/display.rb', line 344
def refresh_all
@win_main.refresh
@win_context&.refresh
@win_status.refresh
@win_interaction.refresh
@win_dock&.refresh
@win_line_numbers&.refresh
end
|
#register_proc(the_proc, hook_name, priority = 0) ⇒ Object
3
4
5
|
# File 'lib/diakonos/hooks.rb', line 3
def register_proc( the_proc, hook_name, priority = 0 )
@hooks[ hook_name ] << { proc: the_proc, priority: }
end
|
#run_hook_procs(hook_id, *args) ⇒ Object
7
8
9
10
11
|
# File 'lib/diakonos/hooks.rb', line 7
def run_hook_procs( hook_id, *args )
@hooks[ hook_id ].each do |hook_proc|
hook_proc[ :proc ].call( *args )
end
end
|
#run_scripts ⇒ Object
516
517
518
519
520
521
522
523
524
525
526
527
528
529
|
# File 'lib/diakonos.rb', line 516
def run_scripts
scripts = @extensions.scripts + Dir[ "#{@script_dir}/*" ]
scripts.each do |script|
require script
rescue StandardError => e
show_exception(
e,
[
"There is a syntax error in the script.",
"An invalid hook name was used.",
]
)
end
end
|
#save_session(session_file = @session.filename) ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
|
# File 'lib/diakonos/sessions.rb', line 161
def save_session( session_file = @session.filename )
return if session_file.nil?
return if @testing && Session.pid_session?(session_file)
@session.set_buffers(@buffers)
@session.set_readline_histories(@rlh_general, @rlh_files, @rlh_search, @rlh_shell, @rlh_help, @rlh_sessions)
File.open( session_file, 'w' ) do |f|
f.puts @session.to_yaml
end
end
|
#select_list_item ⇒ Object
27
28
29
30
31
32
33
|
# File 'lib/diakonos/list.rb', line 27
def select_list_item
if @list_buffer
line = @list_buffer.set_selection_current_line
display_buffer @list_buffer
line
end
end
|
#session_filepath_for(session_id) ⇒ Object
173
174
175
176
177
178
179
|
# File 'lib/diakonos/sessions.rb', line 173
def session_filepath_for( session_id )
if session_id && session_id !~ %r{/}
"#{@session_dir}/#{session_id}"
else
session_id
end
end
|
#session_startup ⇒ Object
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
# File 'lib/diakonos/sessions.rb', line 181
def session_startup
@stale_session_files = []
if @session_to_load
@session = nil
session_path = session_filepath_for( @session_to_load )
load_session session_path
if ! @session
@session = Session.new(session_path)
end
else
session_files = Dir[ "#{@session_dir}/*" ].grep( %r{/\d+$} )
session_files.each do |sf|
pid = sf[ %r{/(\d+)$}, 1 ].to_i
begin
Process.kill 0, pid
rescue Errno::ESRCH, Errno::EPERM
if Session.pid_session?(sf)
@stale_session_files << sf
end
end
end
end
end
|
#set_iline(s = "") ⇒ Object
161
162
163
|
# File 'lib/diakonos/display.rb', line 161
def set_iline(s = "")
@interaction_handler.set_iline s
end
|
#set_iline_if_empty(s) ⇒ Object
165
166
167
|
# File 'lib/diakonos/display.rb', line 165
def set_iline_if_empty(s)
@interaction_handler.set_iline_if_empty s
end
|
#set_initial_iline ⇒ Object
507
508
509
510
511
512
513
514
|
# File 'lib/diakonos.rb', line 507
def set_initial_iline
if ENV['COLORTERM'] == 'gnome-terminal'
help_key = 'Shift-F1'
else
help_key = 'F1'
end
set_iline "Diakonos #{VERSION} (#{LAST_MODIFIED}) #{help_key} for help F12 to configure Ctrl-Q to quit"
end
|
#set_status_variable(identifier, value) ⇒ Object
169
170
171
|
# File 'lib/diakonos/display.rb', line 169
def set_status_variable( identifier, value )
@status_vars[ identifier ] = value
end
|
#show_buffer_file_diff(buffer = @buffer_current) {|diff_buffer| ... } ⇒ Object
48
49
50
51
52
53
54
55
|
# File 'lib/diakonos/buffer-management.rb', line 48
def show_buffer_file_diff( buffer = @buffer_current )
current_text_file = @diakonos_home + '/current-buffer'
buffer.save_copy( current_text_file )
`#{@settings[ 'diff_command' ]} #{current_text_file} #{buffer.name} > #{@diff_filename}`
diff_buffer = open_file( @diff_filename )
yield diff_buffer
close_buffer diff_buffer
end
|
#show_dock(lines:) ⇒ Object
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
# File 'lib/diakonos/display.rb', line 146
def show_dock(lines:)
@dock_lines = lines
initialize_display
render_dock
update_status_line
update_context_line
buffer_current.cursor_to(
buffer_current.last_row,
buffer_current.last_col,
Buffer::DONT_DISPLAY,
)
display_buffer buffer_current
end
|
#show_exception(exception, probable_causes = ["Unknown"]) ⇒ Object
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
|
# File 'lib/diakonos.rb', line 586
def show_exception(exception, probable_causes = ["Unknown"])
File.open( @error_filename, "w" ) do |f|
f.puts "Diakonos Error:"
f.puts
f.puts "#{exception.class}: #{exception.message}"
f.puts
f.puts "Probable Causes:"
f.puts
probable_causes.each do |pc|
f.puts "- #{pc}"
end
f.puts
f.puts "----------------------------------------------------"
f.puts "If you can reproduce this error, please report it at"
f.puts "https://github.com/Pistos/diakonos/issues !"
f.puts "----------------------------------------------------"
f.puts exception.backtrace
end
open_file @error_filename
rescue StandardError => e
debug_log "EXCEPTION: #{e.message}"
debug_log "\t#{e.backtrace}"
end
|
#showing_list? ⇒ Boolean
15
16
17
|
# File 'lib/diakonos/list.rb', line 15
def showing_list?
@list_buffer
end
|
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
|
# File 'lib/diakonos.rb', line 406
def start
require 'diakonos/window'
create_buffers_from_files
@files = []
@read_only_files.each do |file|
@buffers << Buffer.new( file )
end
if ! @testing
session_startup
end
create_buffers_from_files
@files = []
if @buffers.empty?
@buffers << Buffer.new
end
initialize_display
@buffers.each(&:reset_display)
set_initial_iline
run_scripts
@hooks.each_value do |hook|
hook.sort { |a,b| a[ :priority ] <=> b[ :priority ] }
end
handle_stale_session_files
create_buffers_from_files
session_buffer_number = @session.buffer_current || 1
if ! switch_to_buffer_number( session_buffer_number )
debug_log "Failed to switch to buffer #{session_buffer_number.inspect}"
switch_to_buffer_number 1
end
run_hook_procs :after_startup
if @post_load_script
begin
eval @post_load_script rescue StandardError => e
show_exception(
e,
[ "There is an error in the post-load script:\n#{@post_load_script}" ]
)
end
end
@buffers.each do |b|
run_hook_procs :after_open, b
ensure_language_lsp(buffer: b, language: b.original_language)
b.cursor_to( b.last_row, b.last_col, Buffer::DONT_DISPLAY )
end
buffer_current.cursor_to( buffer_current.last_row, buffer_current.last_col, Buffer::DONT_DISPLAY )
if @configs.any? { |c| c.problems.any? }
File.open( @error_filename, "w" ) do |f|
f.puts "There are problems with the configuration file(s):"
@configs.each do |c|
next if c.problems.empty?
f.puts
f.print "#{c}:\n\t"
f.puts c.problems.join("\n\t")
end
end
open_file @error_filename
end
if ! @testing && ! @settings[ 'suppress_welcome' ]
open_file "#{@help_dir}/welcome.dhf"
else
conflict_regexp_source = '^<{4,}'
if seek(conflict_regexp_source)
find conflict_regexp_source
end
end
begin
while ! @quitting
process_keystroke
process_async
close_forgotten_buffers
@win_main.refresh
end
rescue SignalException => e
debug_log "Terminated by signal (#{e.message})"
end
@lsp_servers.each_value(&:stop)
cleanup_display
cleanup_session
@debug.close
end
|
#start_recording_macro(name = nil) ⇒ Object
610
611
612
613
614
615
616
617
|
# File 'lib/diakonos.rb', line 610
def start_recording_macro( name = nil )
return if @macro_history
@macro_name = name
@macro_history = Array.new
@macro_input_history = Array.new
set_iline "Started macro recording."
end
|
#stop_recording_macro ⇒ Object
619
620
621
622
623
624
625
|
# File 'lib/diakonos.rb', line 619
def stop_recording_macro
@macro_history.pop @macros[ @macro_name ] = [ @macro_history, @macro_input_history ]
@macro_history = nil
@macro_input_history = nil
set_iline "Stopped macro recording."
end
|
#switch_to(buffer, opts = {}) ⇒ Boolean
Returns true iff the buffer was successfully switched to.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# File 'lib/diakonos/buffer-management.rb', line 9
def switch_to( buffer, opts = {} )
return false if buffer.nil?
do_display = opts.fetch( :do_display, true )
@buffer_stack -= [ @buffer_current ]
if @buffer_current
@buffer_stack.push @buffer_current
end
@buffer_current = buffer
@session.buffer_current = buffer_to_number( buffer )
run_hook_procs( :after_buffer_switch, buffer )
if do_display
update_status_line
update_context_line
display_buffer buffer
end
true
end
|
#type_character(c, mode = 'edit') ⇒ Object
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
|
# File 'lib/diakonos/keying.rb', line 415
def type_character( c, mode = 'edit' )
@macro_history&.push "type_character #{c.inspect}, #{mode.inspect}"
@there_was_non_movement = true
case mode
when 'edit'
buffer_current.delete_selection Buffer::DONT_DISPLAY
buffer_current.insert_string c
cursor_right Buffer::STILL_TYPING
if c =~ @indent_triggers[buffer_current.language]
buffer_current.parsed_indent cursor_eol: true
end
when 'input'
if ! @readline.numbered_list?
@readline.paste c
elsif (
showing_list? &&
( (48..57).include?( c.ord ) || (97..122).include?( c.ord ) )
)
line = list_buffer.to_a.select { |l|
l =~ /^#{c} /
}[ 0 ]
if line
@readline.list_sync line
@readline.finish
end
end
end
end
|
#typeable?(char) ⇒ Boolean
239
240
241
|
# File 'lib/diakonos/keying.rb', line 239
def typeable?( char )
char > 31 && char < 255 && char != BACKSPACE
end
|
#uninstall(confirm: true) ⇒ Object
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
|
# File 'lib/diakonos.rb', line 531
def uninstall( confirm: true )
inst = ::Diakonos::INSTALL_SETTINGS[ :installed ]
if confirm
puts inst[ :files ].sort.join( "\n" )
puts
puts inst[ :dirs ].sort.map { |d| "#{d}/" }.join( "\n" )
puts
puts "The above files will be removed. The above directories will be removed if they are empty."
puts "Proceed? (y/n)"
answer = $stdin.gets
case answer
when /^y/i
puts "Deleting..."
else
puts "Uninstallation aborted."
exit 1
end
end
inst[ :files ].each do |f|
FileUtils.rm f
end
inst[ :dirs ].sort { |d1,d2| d2.length <=> d1.length }.each do |d|
begin
FileUtils.rmdir d
rescue Errno::ENOTEMPTY
end
if File.exist? d
warn "(#{d} not removed)"
end
end
exit 0
end
|
#update_context_line ⇒ Object
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
|
# File 'lib/diakonos/display.rb', line 261
def update_context_line
return if @testing
return if @win_context.nil?
@context_thread&.exit
@context_thread = Thread.new do
context = buffer_current.context
Curses.curs_set 0
@win_context.setpos( 0, 0 )
chars_printed = 0
if context.any?
truncation = [ @settings[ "context.max_levels" ], context.length ].min
max_length = [
( Curses.cols / truncation ) - @settings[ "context.separator" ].length,
( @settings[ "context.max_segment_width" ] || Curses.cols ),
].min
context_subset = context[ 0...truncation ]
context_subset = context_subset.collect { |line|
line.strip[ 0...max_length ]
}
context_subset.each do |line|
@win_context.attrset @settings[ "context.format" ]
@win_context.addstr line
chars_printed += line.length
@win_context.attrset @settings[ "context.separator.format" ]
@win_context.addstr @settings[ "context.separator" ]
chars_printed += @settings[ "context.separator" ].length
end
end
@context_line_mutex.synchronize do
@win_context.attrset @settings[ "context.format" ]
@win_context.addstr( " " * ( Curses.cols - chars_printed ) )
@win_context.refresh
end
@display_mutex.synchronize do
@win_main.setpos( buffer_current.last_screen_y, buffer_current.last_screen_x )
@win_main.refresh
end
Curses.curs_set 1
end
@context_thread.priority = -2
end
|
#update_status_line ⇒ Object
247
248
249
250
251
252
253
254
255
256
257
258
259
|
# File 'lib/diakonos/display.rb', line 247
def update_status_line
return if @testing
str = build_status_line
if str.length > Curses.cols
str = build_status_line( str.length - Curses.cols )
end
Curses.curs_set 0
@win_status.setpos( 0, 0 )
@win_status.addstr str
@win_status.refresh
Curses.curs_set 1
end
|
#utf_8_bytes_to_char(c, mode) ⇒ String
Returns nil if c is not the beginning of a multi-byte sequence.
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
|
# File 'lib/diakonos/keying.rb', line 245
def utf_8_bytes_to_char(c, mode)
if Keying::UTF_8_2_BYTE_BEGIN <= c && c <= Keying::UTF_8_2_BYTE_END
byte_array = [c, @modes[mode].window.getch.ord]
elsif Keying::UTF_8_3_BYTE_BEGIN <= c && c <= Keying::UTF_8_3_BYTE_END
byte_array = [
c,
@modes[mode].window.getch.ord,
@modes[mode].window.getch.ord,
]
elsif Keying::UTF_8_4_BYTE_BEGIN <= c && c <= Keying::UTF_8_4_BYTE_END
byte_array = [
c,
@modes[mode].window.getch.ord,
@modes[mode].window.getch.ord,
@modes[mode].window.getch.ord,
]
else
return nil
end
byte_array.pack('C*').force_encoding('utf-8')
end
|
#with_list_file ⇒ Object
49
50
51
52
53
|
# File 'lib/diakonos/list.rb', line 49
def with_list_file
File.open( @list_filename, "w" ) do |f|
yield f
end
end
|