Class: RuVim::Editor
- Inherits:
-
Object
- Object
- RuVim::Editor
- Defined in:
- lib/ruvim/editor.rb
Constant Summary collapse
- OPTION_DEFS =
{ "number" => { default_scope: :window, type: :bool, default: false }, "relativenumber" => { default_scope: :window, type: :bool, default: false }, "wrap" => { default_scope: :window, type: :bool, default: true }, "linebreak" => { default_scope: :window, type: :bool, default: false }, "breakindent" => { default_scope: :window, type: :bool, default: false }, "cursorline" => { default_scope: :window, type: :bool, default: false }, "scrolloff" => { default_scope: :window, type: :int, default: 0 }, "sidescrolloff" => { default_scope: :window, type: :int, default: 0 }, "numberwidth" => { default_scope: :window, type: :int, default: 4 }, "colorcolumn" => { default_scope: :window, type: :string, default: nil }, "signcolumn" => { default_scope: :window, type: :string, default: "auto" }, "list" => { default_scope: :window, type: :bool, default: false }, "listchars" => { default_scope: :window, type: :string, default: "tab:>-,trail:-,nbsp:+" }, "showbreak" => { default_scope: :window, type: :string, default: ">" }, "showmatch" => { default_scope: :global, type: :bool, default: false }, "matchtime" => { default_scope: :global, type: :int, default: 5 }, "whichwrap" => { default_scope: :global, type: :string, default: "" }, "virtualedit" => { default_scope: :global, type: :string, default: "" }, "ignorecase" => { default_scope: :global, type: :bool, default: false }, "smartcase" => { default_scope: :global, type: :bool, default: false }, "hlsearch" => { default_scope: :global, type: :bool, default: true }, "incsearch" => { default_scope: :global, type: :bool, default: false }, "splitbelow" => { default_scope: :global, type: :bool, default: false }, "splitright" => { default_scope: :global, type: :bool, default: false }, "hidden" => { default_scope: :global, type: :bool, default: false }, "autowrite" => { default_scope: :global, type: :bool, default: false }, "clipboard" => { default_scope: :global, type: :string, default: "" }, "timeoutlen" => { default_scope: :global, type: :int, default: 1000 }, "ttimeoutlen" => { default_scope: :global, type: :int, default: 50 }, "backspace" => { default_scope: :global, type: :string, default: "indent,eol,start" }, "completeopt" => { default_scope: :global, type: :string, default: "menu,menuone,noselect" }, "pumheight" => { default_scope: :global, type: :int, default: 10 }, "wildmode" => { default_scope: :global, type: :string, default: "full" }, "wildignore" => { default_scope: :global, type: :string, default: "" }, "wildignorecase" => { default_scope: :global, type: :bool, default: false }, "wildmenu" => { default_scope: :global, type: :bool, default: false }, "termguicolors" => { default_scope: :global, type: :bool, default: false }, "path" => { default_scope: :buffer, type: :string, default: nil }, "suffixesadd" => { default_scope: :buffer, type: :string, default: nil }, "textwidth" => { default_scope: :buffer, type: :int, default: 0 }, "formatoptions" => { default_scope: :buffer, type: :string, default: nil }, "expandtab" => { default_scope: :buffer, type: :bool, default: false }, "shiftwidth" => { default_scope: :buffer, type: :int, default: 2 }, "softtabstop" => { default_scope: :buffer, type: :int, default: 0 }, "autoindent" => { default_scope: :buffer, type: :bool, default: true }, "smartindent" => { default_scope: :buffer, type: :bool, default: true }, "iskeyword" => { default_scope: :buffer, type: :string, default: nil }, "tabstop" => { default_scope: :buffer, type: :int, default: 2 }, "filetype" => { default_scope: :buffer, type: :string, default: nil }, "onsavehook" => { default_scope: :buffer, type: :bool, default: true }, "grepprg" => { default_scope: :global, type: :string, default: "grep -nH" }, "grepformat" => { default_scope: :global, type: :string, default: "%f:%l:%m" }, "runprg" => { default_scope: :buffer, type: :string, default: nil } }.freeze
Instance Attribute Summary collapse
-
#alternate_buffer_id ⇒ Object
Returns the value of attribute alternate_buffer_id.
-
#app_action_handler ⇒ Object
Returns the value of attribute app_action_handler.
-
#buffers ⇒ Object
readonly
Returns the value of attribute buffers.
-
#current_window_id ⇒ Object
Returns the value of attribute current_window_id.
-
#current_window_view_height_hint ⇒ Object
Returns the value of attribute current_window_view_height_hint.
-
#git_stream_handler ⇒ Object
Returns the value of attribute git_stream_handler.
-
#git_stream_stop_handler ⇒ Object
Returns the value of attribute git_stream_stop_handler.
-
#keymap_manager ⇒ Object
Returns the value of attribute keymap_manager.
-
#layout_tree ⇒ Object
readonly
Returns the value of attribute layout_tree.
-
#message ⇒ Object
Returns the value of attribute message.
-
#mode ⇒ Object
Returns the value of attribute mode.
-
#open_path_handler ⇒ Object
Returns the value of attribute open_path_handler.
-
#pending_count ⇒ Object
Returns the value of attribute pending_count.
-
#restricted_mode ⇒ Object
Returns the value of attribute restricted_mode.
-
#run_stream_handler ⇒ Object
Returns the value of attribute run_stream_handler.
-
#shell_executor ⇒ Object
Returns the value of attribute shell_executor.
-
#windows ⇒ Object
readonly
Returns the value of attribute windows.
Instance Method Summary collapse
- #active_register_name ⇒ Object
- #add_buffer_from_file(path) ⇒ Object
- #add_empty_buffer(path: nil) ⇒ Object
- #add_virtual_buffer(kind:, name:, lines:, filetype: nil, readonly: true, modifiable: false) ⇒ Object
- #add_window(buffer_id:) ⇒ Object
- #apply_filetype_defaults(buffer, ft) ⇒ Object
- #arglist ⇒ Object
- #arglist_current ⇒ Object
- #arglist_first ⇒ Object
- #arglist_index ⇒ Object
- #arglist_last ⇒ Object
- #arglist_next(count = 1) ⇒ Object
- #arglist_prev(count = 1) ⇒ Object
- #assign_filetype(buffer, ft) ⇒ Object
- #buffer_ids ⇒ Object
- #cancel_command_line ⇒ Object
- #clear_expired_transient_message!(now: nil) ⇒ Object
- #clear_message ⇒ Object
- #clear_visual ⇒ Object
- #close_current_tabpage ⇒ Object
- #close_current_window ⇒ Object
- #close_window(id) ⇒ Object
- #command_area_active? ⇒ Boolean
- #command_line ⇒ Object
- #command_line_active? ⇒ Boolean
- #command_line_prefix ⇒ Object
- #consume_active_register(default = "\"") ⇒ Object
- #current_buffer ⇒ Object
- #current_location ⇒ Object
- #current_location_list_item(window_id = current_window_id) ⇒ Object
- #current_quickfix_item ⇒ Object
- #current_tabpage_index ⇒ Object
- #current_tabpage_number ⇒ Object
- #current_window ⇒ Object
- #delete_buffer(buffer_id) ⇒ Object
- #detect_filetype(path) ⇒ Object
- #echo(msg) ⇒ Object
- #echo_error(msg) ⇒ Object
- #echo_multiline(lines) ⇒ Object
- #echo_temporary(msg, duration_seconds:) ⇒ Object
- #effective_option(name, window: current_window, buffer: current_buffer) ⇒ Object
- #ensure_bootstrap_buffer! ⇒ Object
- #enter_command_line_mode(prefix = ":") ⇒ Object
- #enter_hit_enter_mode(lines) ⇒ Object
- #enter_insert_mode ⇒ Object
- #enter_normal_mode ⇒ Object
- #enter_rich_mode(format:, delimiter:) ⇒ Object
- #enter_visual(mode) ⇒ Object
- #exit_hit_enter_mode ⇒ Object
- #exit_rich_mode ⇒ Object
- #filetype_default_runprg(ft) ⇒ Object
- #find_window_ids_by_buffer_kind(kind) ⇒ Object
- #focus_next_window ⇒ Object
- #focus_prev_window ⇒ Object
- #focus_window(id) ⇒ Object
- #focus_window_direction(dir) ⇒ Object
- #get_option(name, scope: :effective, window: current_window, buffer: current_buffer) ⇒ Object
- #get_register(name = "\"") ⇒ Object
- #global_options ⇒ Object
-
#has_split_ancestor_on_axis?(dir) ⇒ Boolean
Check if the path from root to the current window passes through a split node matching the direction's axis.
- #hit_enter_active? ⇒ Boolean
- #hit_enter_lines ⇒ Object
- #hlsearch_suppressed? ⇒ Boolean
-
#initialize ⇒ Editor
constructor
A new instance of Editor.
- #invoke_app_action(name, **kwargs) ⇒ Object
- #jump_newer(linewise: false) ⇒ Object
- #jump_older(linewise: false) ⇒ Object
- #jump_to_location(loc, linewise: false) ⇒ Object
- #jump_to_mark(name, linewise: false) ⇒ Object
- #last_find ⇒ Object
- #last_search ⇒ Object
- #leave_command_line ⇒ Object
- #location_items(window_id = current_window_id) ⇒ Object
- #location_list(window_id = current_window_id) ⇒ Object
- #macro_keys(name) ⇒ Object
- #macro_recording? ⇒ Boolean
- #macro_recording_name ⇒ Object
- #macros ⇒ Object
- #mark_location(name, buffer_id: current_buffer.id) ⇒ Object
- #materialize_intro_buffer! ⇒ Object
- #message_error? ⇒ Boolean
- #move_location_list(step, window_id: current_window_id) ⇒ Object
- #move_quickfix(step) ⇒ Object
- #next_buffer_id_from(current_id, step = 1) ⇒ Object
- #open_path(path) ⇒ Object
- #open_path_sync(path) ⇒ Object
- #option_def(name) ⇒ Object
- #option_default_scope(name) ⇒ Object
- #option_snapshot(window: current_window, buffer: current_buffer) ⇒ Object
- #push_jump_location(location = current_location) ⇒ Object
- #quickfix_index ⇒ Object
- #quickfix_items ⇒ Object
- #record_macro_key(key) ⇒ Object
- #registers ⇒ Object
- #request_quit! ⇒ Object
- #restricted_mode? ⇒ Boolean
- #rich_mode? ⇒ Boolean
- #rich_state ⇒ Object
- #run_history ⇒ Object
- #run_output_buffer_id ⇒ Object
- #run_output_buffer_id=(id) ⇒ Object
- #running? ⇒ Boolean
- #select_location_list(index, window_id: current_window_id) ⇒ Object
- #select_quickfix(index) ⇒ Object
- #set_active_register(name) ⇒ Object
- #set_arglist(paths) ⇒ Object
- #set_last_find(char:, direction:, till:) ⇒ Object
- #set_last_search(pattern:, direction:) ⇒ Object
- #set_location_list(items, window_id: current_window_id) ⇒ Object
- #set_mark(name, window = current_window) ⇒ Object
- #set_option(name, value, scope: :auto, window: current_window, buffer: current_buffer) ⇒ Object
- #set_quickfix_list(items) ⇒ Object
- #set_register(name = "\"", text:, type: :charwise) ⇒ Object
- #show_help_buffer!(title:, lines:, filetype: "help") ⇒ Object
- #show_intro_buffer_if_applicable! ⇒ Object
- #split_current_window(layout: :horizontal, place: :after) ⇒ Object
- #start_macro_recording(name) ⇒ Object
- #stop_macro_recording ⇒ Object
- #store_operator_register(name = "\"", text:, type:, kind:) ⇒ Object
- #stream_stop_or_cancel! ⇒ Object
- #suppress_hlsearch! ⇒ Object
- #switch_to_buffer(buffer_id) ⇒ Object
- #tabnew(path: nil) ⇒ Object
- #tabnext(step = 1) ⇒ Object
- #tabpage_count ⇒ Object
- #tabpage_windows(tab) ⇒ Object
- #tabpages ⇒ Object
- #tabprev(step = 1) ⇒ Object
- #text_viewport_size(rows:, cols:) ⇒ Object
- #transient_message_timeout_seconds(now: nil) ⇒ Object
- #visual_active? ⇒ Boolean
- #visual_selection(window = current_window) ⇒ Object
- #visual_state ⇒ Object
- #window_count ⇒ Object
- #window_layout ⇒ Object
- #window_order ⇒ Object
Constructor Details
#initialize ⇒ Editor
Returns a new instance of Editor.
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 |
# File 'lib/ruvim/editor.rb', line 64 def initialize @buffers = {} @windows = {} @layout_tree = nil @tabpages = [] @current_tabpage_index = nil @next_tabpage_id = 1 @suspend_tab_autosave = false @next_buffer_id = 1 @next_window_id = 1 @current_window_id = nil @alternate_buffer_id = nil @mode = :normal @message = "" @message_kind = :info @message_deadline = nil @pending_count = nil @restricted_mode = false @current_window_view_height_hint = 1 @running = true @open_path_handler = nil @keymap_manager = nil @app_action_handler = nil @global_options = @command_line = CommandLine.new @last_search = nil @hlsearch_suppressed = false @last_find = nil @registers = {} @active_register_name = nil @local_marks = Hash.new { |h, k| h[k] = {} } @global_marks = {} @jumplist = [] @jump_index = nil @macros = {} @macro_recording = nil @visual_state = nil @rich_state = nil @quickfix_list = { items: [], index: nil } @location_lists = Hash.new { |h, k| h[k] = { items: [], index: nil } } @arglist = [] @arglist_index = 0 @hit_enter_lines = nil @run_history = {} # buffer_id => last run command (unexpanded) @run_output_buffer_id = nil end |
Instance Attribute Details
#alternate_buffer_id ⇒ Object
Returns the value of attribute alternate_buffer_id.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def alternate_buffer_id @alternate_buffer_id end |
#app_action_handler ⇒ Object
Returns the value of attribute app_action_handler.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def app_action_handler @app_action_handler end |
#buffers ⇒ Object (readonly)
Returns the value of attribute buffers.
61 62 63 |
# File 'lib/ruvim/editor.rb', line 61 def buffers @buffers end |
#current_window_id ⇒ Object
Returns the value of attribute current_window_id.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def current_window_id @current_window_id end |
#current_window_view_height_hint ⇒ Object
Returns the value of attribute current_window_view_height_hint.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def current_window_view_height_hint @current_window_view_height_hint end |
#git_stream_handler ⇒ Object
Returns the value of attribute git_stream_handler.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def git_stream_handler @git_stream_handler end |
#git_stream_stop_handler ⇒ Object
Returns the value of attribute git_stream_stop_handler.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def git_stream_stop_handler @git_stream_stop_handler end |
#keymap_manager ⇒ Object
Returns the value of attribute keymap_manager.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def keymap_manager @keymap_manager end |
#layout_tree ⇒ Object (readonly)
Returns the value of attribute layout_tree.
61 62 63 |
# File 'lib/ruvim/editor.rb', line 61 def layout_tree @layout_tree end |
#message ⇒ Object
Returns the value of attribute message.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def @message end |
#mode ⇒ Object
Returns the value of attribute mode.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def mode @mode end |
#open_path_handler ⇒ Object
Returns the value of attribute open_path_handler.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def open_path_handler @open_path_handler end |
#pending_count ⇒ Object
Returns the value of attribute pending_count.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def pending_count @pending_count end |
#restricted_mode ⇒ Object
Returns the value of attribute restricted_mode.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def restricted_mode @restricted_mode end |
#run_stream_handler ⇒ Object
Returns the value of attribute run_stream_handler.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def run_stream_handler @run_stream_handler end |
#shell_executor ⇒ Object
Returns the value of attribute shell_executor.
62 63 64 |
# File 'lib/ruvim/editor.rb', line 62 def shell_executor @shell_executor end |
#windows ⇒ Object (readonly)
Returns the value of attribute windows.
61 62 63 |
# File 'lib/ruvim/editor.rb', line 61 def windows @windows end |
Instance Method Details
#active_register_name ⇒ Object
334 335 336 |
# File 'lib/ruvim/editor.rb', line 334 def active_register_name @active_register_name end |
#add_buffer_from_file(path) ⇒ Object
586 587 588 589 590 591 592 |
# File 'lib/ruvim/editor.rb', line 586 def add_buffer_from_file(path) id = next_buffer_id buffer = Buffer.from_file(id:, path:) assign_detected_filetype(buffer) @buffers[id] = buffer buffer end |
#add_empty_buffer(path: nil) ⇒ Object
570 571 572 573 574 575 576 |
# File 'lib/ruvim/editor.rb', line 570 def add_empty_buffer(path: nil) id = next_buffer_id buffer = Buffer.new(id:, path:) assign_detected_filetype(buffer) @buffers[id] = buffer buffer end |
#add_virtual_buffer(kind:, name:, lines:, filetype: nil, readonly: true, modifiable: false) ⇒ Object
578 579 580 581 582 583 584 |
# File 'lib/ruvim/editor.rb', line 578 def add_virtual_buffer(kind:, name:, lines:, filetype: nil, readonly: true, modifiable: false) id = next_buffer_id buffer = Buffer.new(id:, lines:, kind:, name:, readonly:, modifiable:) assign_filetype(buffer, filetype) if filetype @buffers[id] = buffer buffer end |
#add_window(buffer_id:) ⇒ Object
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 |
# File 'lib/ruvim/editor.rb', line 594 def add_window(buffer_id:) id = next_window_id window = Window.new(id:, buffer_id:) @windows[id] = window leaf = { type: :window, id: id } if @layout_tree.nil? @layout_tree = leaf else # Append as sibling — used for initial bootstrap only if @layout_tree[:type] == :window @layout_tree = { type: :hsplit, children: [@layout_tree, leaf] } else @layout_tree[:children] << leaf end end @current_window_id ||= id ensure_initial_tabpage! save_current_tabpage_state! unless @suspend_tab_autosave window end |
#apply_filetype_defaults(buffer, ft) ⇒ Object
1148 1149 1150 1151 1152 1153 |
# File 'lib/ruvim/editor.rb', line 1148 def apply_filetype_defaults(buffer, ft) unless buffer..key?("runprg") runprg = filetype_default_runprg(ft) buffer.["runprg"] = runprg if runprg end end |
#arglist ⇒ Object
1305 1306 1307 |
# File 'lib/ruvim/editor.rb', line 1305 def arglist @arglist.dup end |
#arglist_current ⇒ Object
1318 1319 1320 |
# File 'lib/ruvim/editor.rb', line 1318 def arglist_current @arglist[@arglist_index] if @arglist_index < @arglist.length end |
#arglist_first ⇒ Object
1340 1341 1342 1343 |
# File 'lib/ruvim/editor.rb', line 1340 def arglist_first @arglist_index = 0 @arglist[@arglist_index] if @arglist.length > 0 end |
#arglist_index ⇒ Object
1309 1310 1311 |
# File 'lib/ruvim/editor.rb', line 1309 def arglist_index @arglist_index end |
#arglist_last ⇒ Object
1345 1346 1347 1348 |
# File 'lib/ruvim/editor.rb', line 1345 def arglist_last @arglist_index = [@arglist.length - 1, 0].max @arglist[@arglist_index] if @arglist.length > 0 end |
#arglist_next(count = 1) ⇒ Object
1322 1323 1324 1325 1326 1327 1328 1329 |
# File 'lib/ruvim/editor.rb', line 1322 def arglist_next(count = 1) new_index = @arglist_index + count if new_index >= @arglist.length raise RuVim::CommandError, "Already at last argument" end @arglist_index = new_index @arglist[@arglist_index] end |
#arglist_prev(count = 1) ⇒ Object
1331 1332 1333 1334 1335 1336 1337 1338 |
# File 'lib/ruvim/editor.rb', line 1331 def arglist_prev(count = 1) new_index = @arglist_index - count if new_index < 0 raise RuVim::CommandError, "Already at first argument" end @arglist_index = new_index @arglist[@arglist_index] end |
#assign_filetype(buffer, ft) ⇒ Object
1142 1143 1144 1145 1146 |
# File 'lib/ruvim/editor.rb', line 1142 def assign_filetype(buffer, ft) buffer.["filetype"] = ft buffer.lang_module = resolve_lang_module(ft) apply_filetype_defaults(buffer, ft) end |
#buffer_ids ⇒ Object
818 819 820 |
# File 'lib/ruvim/editor.rb', line 818 def buffer_ids @buffers.keys end |
#cancel_command_line ⇒ Object
1058 1059 1060 1061 |
# File 'lib/ruvim/editor.rb', line 1058 def cancel_command_line @command_line.clear leave_command_line end |
#clear_expired_transient_message!(now: nil) ⇒ Object
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 |
# File 'lib/ruvim/editor.rb', line 1114 def (now: nil) return false unless @message_deadline return false if return false if command_line_active? now ||= Process.clock_gettime(Process::CLOCK_MONOTONIC) return false if now < @message_deadline true rescue StandardError false end |
#clear_message ⇒ Object
1093 1094 1095 1096 1097 |
# File 'lib/ruvim/editor.rb', line 1093 def @message_kind = :info @message = "" @message_deadline = nil end |
#clear_visual ⇒ Object
476 477 478 |
# File 'lib/ruvim/editor.rb', line 476 def clear_visual @visual_state = nil end |
#close_current_tabpage ⇒ Object
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
# File 'lib/ruvim/editor.rb', line 661 def close_current_tabpage ensure_initial_tabpage! return nil if @tabpages.length <= 1 save_current_tabpage_state! removed = @tabpages.delete_at(@current_tabpage_index) removed_tree = removed && removed[:layout_tree] tree_leaves(removed_tree).each do |wid| @windows.delete(wid) @location_lists.delete(wid) end @current_tabpage_index = [@current_tabpage_index, @tabpages.length - 1].min load_tabpage_state!(@tabpages[@current_tabpage_index]) current_window end |
#close_current_window ⇒ Object
637 638 639 |
# File 'lib/ruvim/editor.rb', line 637 def close_current_window close_window(@current_window_id) end |
#close_window(id) ⇒ Object
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 |
# File 'lib/ruvim/editor.rb', line 641 def close_window(id) leaves = tree_leaves(@layout_tree) return nil if leaves.empty? return nil if leaves.length <= 1 return nil unless leaves.include?(id) save_current_tabpage_state! unless @suspend_tab_autosave idx = leaves.index(id) || 0 @windows.delete(id) @location_lists.delete(id) @layout_tree = tree_remove(@layout_tree, id) new_leaves = tree_leaves(@layout_tree) @current_window_id = new_leaves[[idx, new_leaves.length - 1].min] if @current_window_id == id @current_window_id ||= new_leaves.first save_current_tabpage_state! unless @suspend_tab_autosave current_window end |
#command_area_active? ⇒ Boolean
1138 1139 1140 |
# File 'lib/ruvim/editor.rb', line 1138 def command_area_active? command_line_active? || end |
#command_line ⇒ Object
135 136 137 |
# File 'lib/ruvim/editor.rb', line 135 def command_line @command_line end |
#command_line_active? ⇒ Boolean
1134 1135 1136 |
# File 'lib/ruvim/editor.rb', line 1134 def command_line_active? @mode == :command_line end |
#command_line_prefix ⇒ Object
143 144 145 |
# File 'lib/ruvim/editor.rb', line 143 def command_line_prefix @command_line.prefix end |
#consume_active_register(default = "\"") ⇒ Object
338 339 340 341 342 |
# File 'lib/ruvim/editor.rb', line 338 def consume_active_register(default = "\"") name = @active_register_name || default @active_register_name = nil name end |
#current_buffer ⇒ Object
176 177 178 |
# File 'lib/ruvim/editor.rb', line 176 def current_buffer @buffers.fetch(current_window.buffer_id) end |
#current_location ⇒ Object
394 395 396 |
# File 'lib/ruvim/editor.rb', line 394 def current_location { buffer_id: current_buffer.id, row: current_window.cursor_y, col: current_window.cursor_x } end |
#current_location_list_item(window_id = current_window_id) ⇒ Object
960 961 962 963 964 |
# File 'lib/ruvim/editor.rb', line 960 def current_location_list_item(window_id = current_window_id) list = location_list(window_id) idx = list[:index] idx ? list[:items][idx] : nil end |
#current_quickfix_item ⇒ Object
919 920 921 922 |
# File 'lib/ruvim/editor.rb', line 919 def current_quickfix_item idx = @quickfix_list[:index] idx ? @quickfix_list[:items][idx] : nil end |
#current_tabpage_index ⇒ Object
885 886 887 |
# File 'lib/ruvim/editor.rb', line 885 def current_tabpage_index @current_tabpage_index || 0 end |
#current_tabpage_number ⇒ Object
889 890 891 |
# File 'lib/ruvim/editor.rb', line 889 def current_tabpage_number current_tabpage_index + 1 end |
#current_window ⇒ Object
172 173 174 |
# File 'lib/ruvim/editor.rb', line 172 def current_window @windows.fetch(@current_window_id) end |
#delete_buffer(buffer_id) ⇒ Object
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 |
# File 'lib/ruvim/editor.rb', line 830 def delete_buffer(buffer_id) buffer = @buffers[buffer_id] return nil unless buffer if @buffers.length <= 1 replacement = add_empty_buffer else replacement = nil end fallback_id = if replacement replacement.id else candidates = @buffers.keys.reject { |bid| bid == buffer_id } alt = @alternate_buffer_id (alt && alt != buffer_id && @buffers.key?(alt)) ? alt : candidates.first end @windows.each_value do |win| next unless win.buffer_id == buffer_id next unless fallback_id win.buffer_id = fallback_id win.cursor_x = 0 win.cursor_y = 0 win.row_offset = 0 win.col_offset = 0 end @buffers.delete(buffer_id) @local_marks.delete(buffer_id) @alternate_buffer_id = nil if @alternate_buffer_id == buffer_id save_current_tabpage_state! unless @suspend_tab_autosave ensure_bootstrap_buffer! if @buffers.empty? true end |
#detect_filetype(path) ⇒ Object
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/ruvim/editor.rb', line 260 def detect_filetype(path) p = path.to_s return nil if p.empty? base = File.basename(p) # Basename-based detection (exact match, then prefix) base_ft = Lang::Registry.detect_by_basename(base) return base_ft if base_ft # Extension-based detection ext_ft = Lang::Registry.detect_by_extension(File.extname(base)) return ext_ft if ext_ft detect_filetype_from_shebang(p) end |
#echo(msg) ⇒ Object
1072 1073 1074 1075 1076 |
# File 'lib/ruvim/editor.rb', line 1072 def echo(msg) @message_kind = :info @message = msg.to_s @message_deadline = nil end |
#echo_error(msg) ⇒ Object
1087 1088 1089 1090 1091 |
# File 'lib/ruvim/editor.rb', line 1087 def echo_error(msg) @message_kind = :error @message = msg.to_s @message_deadline = nil end |
#echo_multiline(lines) ⇒ Object
561 562 563 564 565 566 567 568 |
# File 'lib/ruvim/editor.rb', line 561 def echo_multiline(lines) lines = Array(lines) if lines.length <= 1 echo(lines.first.to_s) else enter_hit_enter_mode(lines) end end |
#echo_temporary(msg, duration_seconds:) ⇒ Object
1078 1079 1080 1081 1082 1083 1084 1085 |
# File 'lib/ruvim/editor.rb', line 1078 def echo_temporary(msg, duration_seconds:) @message_kind = :info @message = msg.to_s dur = duration_seconds.to_f @message_deadline = dur.positive? ? (Process.clock_gettime(Process::CLOCK_MONOTONIC) + dur) : nil rescue StandardError @message_deadline = nil end |
#effective_option(name, window: current_window, buffer: current_buffer) ⇒ Object
203 204 205 206 207 208 209 210 211 212 |
# File 'lib/ruvim/editor.rb', line 203 def effective_option(name, window: current_window, buffer: current_buffer) key = name.to_s if window && window..key?(key) window.[key] elsif buffer && buffer..key?(key) buffer.[key] else @global_options[key] end end |
#ensure_bootstrap_buffer! ⇒ Object
765 766 767 768 769 770 771 |
# File 'lib/ruvim/editor.rb', line 765 def ensure_bootstrap_buffer! return unless @buffers.empty? buffer = add_empty_buffer add_window(buffer_id: buffer.id) ensure_initial_tabpage! end |
#enter_command_line_mode(prefix = ":") ⇒ Object
1052 1053 1054 1055 1056 |
# File 'lib/ruvim/editor.rb', line 1052 def enter_command_line_mode(prefix = ":") @mode = :command_line @command_line.reset(prefix:) @pending_count = nil end |
#enter_hit_enter_mode(lines) ⇒ Object
550 551 552 553 554 |
# File 'lib/ruvim/editor.rb', line 550 def enter_hit_enter_mode(lines) @mode = :hit_enter @hit_enter_lines = Array(lines) @pending_count = nil end |
#enter_insert_mode ⇒ Object
1047 1048 1049 1050 |
# File 'lib/ruvim/editor.rb', line 1047 def enter_insert_mode @mode = :insert @pending_count = nil end |
#enter_normal_mode ⇒ Object
1040 1041 1042 1043 1044 1045 |
# File 'lib/ruvim/editor.rb', line 1040 def enter_normal_mode @mode = :normal @pending_count = nil clear_visual @rich_state = nil end |
#enter_rich_mode(format:, delimiter:) ⇒ Object
531 532 533 534 535 |
# File 'lib/ruvim/editor.rb', line 531 def enter_rich_mode(format:, delimiter:) @mode = :rich @pending_count = nil @rich_state = { format: format, delimiter: delimiter } end |
#enter_visual(mode) ⇒ Object
466 467 468 469 470 471 472 473 474 |
# File 'lib/ruvim/editor.rb', line 466 def enter_visual(mode) @mode = mode @visual_state = { mode: mode, anchor_y: current_window.cursor_y, anchor_x: current_window.cursor_x } @pending_count = nil end |
#exit_hit_enter_mode ⇒ Object
556 557 558 559 |
# File 'lib/ruvim/editor.rb', line 556 def exit_hit_enter_mode @hit_enter_lines = nil enter_normal_mode end |
#exit_rich_mode ⇒ Object
537 538 539 540 |
# File 'lib/ruvim/editor.rb', line 537 def exit_rich_mode @rich_state = nil enter_normal_mode end |
#filetype_default_runprg(ft) ⇒ Object
1155 1156 1157 |
# File 'lib/ruvim/editor.rb', line 1155 def filetype_default_runprg(ft) Lang::Registry.runprg_for(ft) end |
#find_window_ids_by_buffer_kind(kind) ⇒ Object
1003 1004 1005 1006 1007 1008 1009 |
# File 'lib/ruvim/editor.rb', line 1003 def find_window_ids_by_buffer_kind(kind) window_order.select do |wid| win = @windows[wid] buf = win && @buffers[win.buffer_id] buf && buf.kind == kind end end |
#focus_next_window ⇒ Object
685 686 687 688 689 690 691 |
# File 'lib/ruvim/editor.rb', line 685 def focus_next_window order = window_order return current_window if order.length <= 1 idx = order.index(@current_window_id) || 0 focus_window(order[(idx + 1) % order.length]) end |
#focus_prev_window ⇒ Object
693 694 695 696 697 698 699 |
# File 'lib/ruvim/editor.rb', line 693 def focus_prev_window order = window_order return current_window if order.length <= 1 idx = order.index(@current_window_id) || 0 focus_window(order[(idx - 1) % order.length]) end |
#focus_window(id) ⇒ Object
677 678 679 680 681 682 683 |
# File 'lib/ruvim/editor.rb', line 677 def focus_window(id) return nil unless @windows.key?(id) @current_window_id = id save_current_tabpage_state! unless @suspend_tab_autosave current_window end |
#focus_window_direction(dir) ⇒ Object
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 |
# File 'lib/ruvim/editor.rb', line 701 def focus_window_direction(dir) leaves = tree_leaves(@layout_tree) return current_window if leaves.length <= 1 rects = tree_compute_rects(@layout_tree, top: 0.0, left: 0.0, height: 1.0, width: 1.0) cur = rects[@current_window_id] return current_window unless cur best_id = nil best_dist = Float::INFINITY cur_cx = cur[:left] + cur[:width] / 2.0 cur_cy = cur[:top] + cur[:height] / 2.0 rects.each do |wid, r| next if wid == @current_window_id rcx = r[:left] + r[:width] / 2.0 rcy = r[:top] + r[:height] / 2.0 in_direction = case dir when :left then rcx < cur_cx when :right then rcx > cur_cx when :up then rcy < cur_cy when :down then rcy > cur_cy end next unless in_direction dist = (rcx - cur_cx).abs + (rcy - cur_cy).abs if dist < best_dist best_dist = dist best_id = wid end end best_id ? focus_window(best_id) : current_window end |
#get_option(name, scope: :effective, window: current_window, buffer: current_buffer) ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/ruvim/editor.rb', line 214 def get_option(name, scope: :effective, window: current_window, buffer: current_buffer) key = name.to_s case scope when :global @global_options[key] when :buffer buffer&.&.[](key) when :window window&.&.[](key) else effective_option(key, window:, buffer:) end end |
#get_register(name = "\"") ⇒ Object
315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/ruvim/editor.rb', line 315 def get_register(name = "\"") key = name.to_s.downcase if key == "\"" if (default_clip = clipboard_default_register_key) if (payload = read_clipboard_register(default_clip)) @registers["\""] = dup_register_payload(payload) return @registers["\""] end end end return read_clipboard_register(key) if clipboard_register?(key) @registers[key] end |
#global_options ⇒ Object
139 140 141 |
# File 'lib/ruvim/editor.rb', line 139 def @global_options end |
#has_split_ancestor_on_axis?(dir) ⇒ Boolean
Check if the path from root to the current window passes through a split node matching the direction's axis. Used by focus_or_split to decide whether to split or stay put at edges. left/right → check for :vsplit ancestor up/down → check for :hsplit ancestor
995 996 997 998 999 1000 1001 |
# File 'lib/ruvim/editor.rb', line 995 def has_split_ancestor_on_axis?(dir) target_type = case dir when :left, :right then :vsplit when :up, :down then :hsplit end tree_path_has_split_type?(@layout_tree, @current_window_id, target_type) end |
#hit_enter_active? ⇒ Boolean
542 543 544 |
# File 'lib/ruvim/editor.rb', line 542 def hit_enter_active? @mode == :hit_enter end |
#hit_enter_lines ⇒ Object
546 547 548 |
# File 'lib/ruvim/editor.rb', line 546 def hit_enter_lines @hit_enter_lines end |
#hlsearch_suppressed? ⇒ Boolean
164 165 166 |
# File 'lib/ruvim/editor.rb', line 164 def hlsearch_suppressed? @hlsearch_suppressed end |
#invoke_app_action(name, **kwargs) ⇒ Object
187 188 189 190 191 192 193 |
# File 'lib/ruvim/editor.rb', line 187 def invoke_app_action(name, **kwargs) handler = @app_action_handler return false unless handler handler.call(name, **kwargs) true end |
#jump_newer(linewise: false) ⇒ Object
445 446 447 448 449 450 451 452 453 |
# File 'lib/ruvim/editor.rb', line 445 def jump_newer(linewise: false) return nil if @jumplist.empty? || @jump_index.nil? next_idx = @jump_index + 1 return nil if next_idx >= @jumplist.length @jump_index = next_idx jump_to_location(@jumplist[@jump_index], linewise:) end |
#jump_older(linewise: false) ⇒ Object
434 435 436 437 438 439 440 441 442 443 |
# File 'lib/ruvim/editor.rb', line 434 def jump_older(linewise: false) return nil if @jumplist.empty? if @jump_index.nil? push_jump_location(current_location) else @jump_index = [@jump_index - 1, 0].max end jump_to_location(@jumplist[@jump_index], linewise:) end |
#jump_to_location(loc, linewise: false) ⇒ Object
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 |
# File 'lib/ruvim/editor.rb', line 1291 def jump_to_location(loc, linewise: false) location = normalize_location(loc) return nil unless location return nil unless @buffers.key?(location[:buffer_id]) switch_to_buffer(location[:buffer_id]) if current_buffer.id != location[:buffer_id] current_window.cursor_y = location[:row] current_window.cursor_x = linewise ? 0 : location[:col] current_window.clamp_to_buffer(current_buffer) current_window.cursor_x = first_nonblank_col(current_buffer, current_window.cursor_y) if linewise current_window.clamp_to_buffer(current_buffer) current_location end |
#jump_to_mark(name, linewise: false) ⇒ Object
455 456 457 458 459 460 |
# File 'lib/ruvim/editor.rb', line 455 def jump_to_mark(name, linewise: false) loc = mark_location(name) return nil unless loc jump_to_location(loc, linewise:) end |
#last_find ⇒ Object
151 152 153 |
# File 'lib/ruvim/editor.rb', line 151 def last_find @last_find end |
#last_search ⇒ Object
147 148 149 |
# File 'lib/ruvim/editor.rb', line 147 def last_search @last_search end |
#leave_command_line ⇒ Object
1063 1064 1065 1066 1067 1068 1069 1070 |
# File 'lib/ruvim/editor.rb', line 1063 def leave_command_line if @rich_state @mode = :rich @pending_count = nil else enter_normal_mode end end |
#location_items(window_id = current_window_id) ⇒ Object
950 951 952 |
# File 'lib/ruvim/editor.rb', line 950 def location_items(window_id = current_window_id) location_list(window_id)[:items] end |
#location_list(window_id = current_window_id) ⇒ Object
946 947 948 |
# File 'lib/ruvim/editor.rb', line 946 def location_list(window_id = current_window_id) @location_lists[window_id] end |
#macro_keys(name) ⇒ Object
390 391 392 |
# File 'lib/ruvim/editor.rb', line 390 def macro_keys(name) @macros[name.to_s.downcase] end |
#macro_recording? ⇒ Boolean
352 353 354 |
# File 'lib/ruvim/editor.rb', line 352 def macro_recording? !@macro_recording.nil? end |
#macro_recording_name ⇒ Object
356 357 358 |
# File 'lib/ruvim/editor.rb', line 356 def macro_recording_name @macro_recording && @macro_recording[:name] end |
#macros ⇒ Object
348 349 350 |
# File 'lib/ruvim/editor.rb', line 348 def macros @macros end |
#mark_location(name, buffer_id: current_buffer.id) ⇒ Object
411 412 413 414 415 416 417 418 419 420 |
# File 'lib/ruvim/editor.rb', line 411 def mark_location(name, buffer_id: current_buffer.id) mark = name.to_s return nil unless mark.match?(/\A[A-Za-z]\z/) if mark.match?(/\A[a-z]\z/) @local_marks[buffer_id][mark] else @global_marks[mark] end end |
#materialize_intro_buffer! ⇒ Object
806 807 808 809 810 811 812 813 814 815 816 |
# File 'lib/ruvim/editor.rb', line 806 def materialize_intro_buffer! return false unless current_buffer.intro_buffer? current_buffer.become_normal_empty_buffer! assign_filetype(current_buffer, nil) current_window.cursor_x = 0 current_window.cursor_y = 0 current_window.row_offset = 0 current_window.col_offset = 0 true end |
#message_error? ⇒ Boolean
1099 1100 1101 |
# File 'lib/ruvim/editor.rb', line 1099 def !@message.to_s.empty? && @message_kind == :error end |
#move_location_list(step, window_id: current_window_id) ⇒ Object
966 967 968 969 970 971 972 973 974 975 976 977 978 |
# File 'lib/ruvim/editor.rb', line 966 def move_location_list(step, window_id: current_window_id) list = location_list(window_id) items = list[:items] return nil if items.empty? cur = list[:index] list[:index] = if cur.nil? step.to_i > 0 ? 0 : items.length - 1 else (cur + step.to_i) % items.length end current_location_list_item(window_id) end |
#move_quickfix(step) ⇒ Object
924 925 926 927 928 929 930 931 932 933 934 935 |
# File 'lib/ruvim/editor.rb', line 924 def move_quickfix(step) items = @quickfix_list[:items] return nil if items.empty? cur = @quickfix_list[:index] @quickfix_list[:index] = if cur.nil? step.to_i > 0 ? 0 : items.length - 1 else (cur + step.to_i) % items.length end current_quickfix_item end |
#next_buffer_id_from(current_id, step = 1) ⇒ Object
822 823 824 825 826 827 828 |
# File 'lib/ruvim/editor.rb', line 822 def next_buffer_id_from(current_id, step = 1) ids = buffer_ids return nil if ids.empty? idx = ids.index(current_id) || 0 ids[(idx + step) % ids.length] end |
#open_path(path) ⇒ Object
751 752 753 754 755 756 |
# File 'lib/ruvim/editor.rb', line 751 def open_path(path) handler = @open_path_handler return handler.call(path) if handler open_path_sync(path) end |
#open_path_sync(path) ⇒ Object
758 759 760 761 762 763 |
# File 'lib/ruvim/editor.rb', line 758 def open_path_sync(path) buffer = add_buffer_from_file(path) switch_to_buffer(buffer.id) echo("[New File]") unless path && File.exist?(path) buffer end |
#option_def(name) ⇒ Object
195 196 197 |
# File 'lib/ruvim/editor.rb', line 195 def option_def(name) OPTION_DEFS[name.to_s] end |
#option_default_scope(name) ⇒ Object
199 200 201 |
# File 'lib/ruvim/editor.rb', line 199 def option_default_scope(name) option_def(name)&.fetch(:default_scope, :global) || :global end |
#option_snapshot(window: current_window, buffer: current_buffer) ⇒ Object
247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/ruvim/editor.rb', line 247 def option_snapshot(window: current_window, buffer: current_buffer) keys = (OPTION_DEFS.keys + @global_options.keys + (buffer&.&.keys || []) + (window&.&.keys || [])).uniq.sort keys.map do |k| { name: k, effective: get_option(k, scope: :effective, window:, buffer:), global: get_option(k, scope: :global, window:, buffer:), buffer: get_option(k, scope: :buffer, window:, buffer:), window: get_option(k, scope: :window, window:, buffer:) } end end |
#push_jump_location(location = current_location) ⇒ Object
422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/ruvim/editor.rb', line 422 def push_jump_location(location = current_location) loc = normalize_location(location) return nil unless loc if @jump_index && @jump_index < @jumplist.length - 1 @jumplist = @jumplist[0..@jump_index] end @jumplist << loc unless same_location?(@jumplist.last, loc) @jump_index = @jumplist.length - 1 unless @jumplist.empty? loc end |
#quickfix_index ⇒ Object
909 910 911 |
# File 'lib/ruvim/editor.rb', line 909 def quickfix_index @quickfix_list[:index] end |
#quickfix_items ⇒ Object
905 906 907 |
# File 'lib/ruvim/editor.rb', line 905 def quickfix_items @quickfix_list[:items] end |
#record_macro_key(key) ⇒ Object
384 385 386 387 388 |
# File 'lib/ruvim/editor.rb', line 384 def record_macro_key(key) return unless @macro_recording @macro_recording[:keys] << dup_macro_key(key) end |
#registers ⇒ Object
277 278 279 |
# File 'lib/ruvim/editor.rb', line 277 def registers @registers end |
#request_quit! ⇒ Object
119 120 121 |
# File 'lib/ruvim/editor.rb', line 119 def request_quit! @running = false end |
#restricted_mode? ⇒ Boolean
115 116 117 |
# File 'lib/ruvim/editor.rb', line 115 def restricted_mode? !!@restricted_mode end |
#rich_mode? ⇒ Boolean
527 528 529 |
# File 'lib/ruvim/editor.rb', line 527 def rich_mode? @mode == :rich end |
#rich_state ⇒ Object
523 524 525 |
# File 'lib/ruvim/editor.rb', line 523 def rich_state @rich_state end |
#run_history ⇒ Object
123 124 125 |
# File 'lib/ruvim/editor.rb', line 123 def run_history @run_history end |
#run_output_buffer_id ⇒ Object
127 128 129 |
# File 'lib/ruvim/editor.rb', line 127 def run_output_buffer_id @run_output_buffer_id end |
#run_output_buffer_id=(id) ⇒ Object
131 132 133 |
# File 'lib/ruvim/editor.rb', line 131 def run_output_buffer_id=(id) @run_output_buffer_id = id end |
#running? ⇒ Boolean
111 112 113 |
# File 'lib/ruvim/editor.rb', line 111 def running? @running end |
#select_location_list(index, window_id: current_window_id) ⇒ Object
980 981 982 983 984 985 986 987 988 |
# File 'lib/ruvim/editor.rb', line 980 def select_location_list(index, window_id: current_window_id) list = location_list(window_id) items = list[:items] return nil if items.empty? i = [[index.to_i, 0].max, items.length - 1].min list[:index] = i current_location_list_item(window_id) end |
#select_quickfix(index) ⇒ Object
937 938 939 940 941 942 943 944 |
# File 'lib/ruvim/editor.rb', line 937 def select_quickfix(index) items = @quickfix_list[:items] return nil if items.empty? i = [[index.to_i, 0].max, items.length - 1].min @quickfix_list[:index] = i current_quickfix_item end |
#set_active_register(name) ⇒ Object
330 331 332 |
# File 'lib/ruvim/editor.rb', line 330 def set_active_register(name) @active_register_name = name.to_s end |
#set_arglist(paths) ⇒ Object
1313 1314 1315 1316 |
# File 'lib/ruvim/editor.rb', line 1313 def set_arglist(paths) @arglist = Array(paths).dup @arglist_index = 0 end |
#set_last_find(char:, direction:, till:) ⇒ Object
168 169 170 |
# File 'lib/ruvim/editor.rb', line 168 def set_last_find(char:, direction:, till:) @last_find = { char: char, direction: direction, till: !!till } end |
#set_last_search(pattern:, direction:) ⇒ Object
155 156 157 158 |
# File 'lib/ruvim/editor.rb', line 155 def set_last_search(pattern:, direction:) @last_search = { pattern: pattern, direction: direction } @hlsearch_suppressed = false end |
#set_location_list(items, window_id: current_window_id) ⇒ Object
954 955 956 957 958 |
# File 'lib/ruvim/editor.rb', line 954 def set_location_list(items, window_id: current_window_id) ary = Array(items).map { |it| normalize_location(it)&.merge(text: (it[:text] || it["text"]).to_s) }.compact @location_lists[window_id] = { items: ary, index: nil } @location_lists[window_id] end |
#set_mark(name, window = current_window) ⇒ Object
398 399 400 401 402 403 404 405 406 407 408 409 |
# File 'lib/ruvim/editor.rb', line 398 def set_mark(name, window = current_window) mark = name.to_s return false unless mark.match?(/\A[A-Za-z]\z/) loc = { buffer_id: window.buffer_id, row: window.cursor_y, col: window.cursor_x } if mark.match?(/\A[a-z]\z/) @local_marks[window.buffer_id][mark] = loc else @global_marks[mark] = loc end true end |
#set_option(name, value, scope: :auto, window: current_window, buffer: current_buffer) ⇒ Object
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/ruvim/editor.rb', line 228 def set_option(name, value, scope: :auto, window: current_window, buffer: current_buffer) key = name.to_s value = coerce_option_value(key, value) actual_scope = (scope == :auto ? option_default_scope(key) : scope) case actual_scope when :global @global_options[key] = value when :buffer raise RuVim::CommandError, "No current buffer" unless buffer buffer.[key] = value when :window raise RuVim::CommandError, "No current window" unless window window.[key] = value else raise RuVim::CommandError, "Unknown option scope: #{actual_scope}" end value end |
#set_quickfix_list(items) ⇒ Object
913 914 915 916 917 |
# File 'lib/ruvim/editor.rb', line 913 def set_quickfix_list(items) ary = Array(items).map { |it| normalize_location(it)&.merge(text: (it[:text] || it["text"]).to_s) }.compact @quickfix_list = { items: ary, index: nil } @quickfix_list end |
#set_register(name = "\"", text:, type: :charwise) ⇒ Object
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/ruvim/editor.rb', line 281 def set_register(name = "\"", text:, type: :charwise) key = name.to_s return { text: text, type: type } if key == "_" payload = write_register_payload(key, text: text, type: type) write_clipboard_register(key, payload) if key == "\"" if (default_clip = clipboard_default_register_key) mirror = write_register_payload(default_clip, text: payload[:text], type: payload[:type]) write_clipboard_register(default_clip, mirror) end end @registers["\""] = payload unless key == "\"" payload end |
#show_help_buffer!(title:, lines:, filetype: "help") ⇒ Object
773 774 775 776 777 778 779 780 781 782 783 784 785 |
# File 'lib/ruvim/editor.rb', line 773 def show_help_buffer!(title:, lines:, filetype: "help") buffer = add_virtual_buffer( kind: :help, name: title, lines: Array(lines), filetype: filetype, readonly: true, modifiable: false ) switch_to_buffer(buffer.id) echo(title) buffer end |
#show_intro_buffer_if_applicable! ⇒ Object
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 |
# File 'lib/ruvim/editor.rb', line 787 def show_intro_buffer_if_applicable! return unless @buffers.length == 1 return unless current_buffer.file_buffer? return unless current_buffer.path.nil? return unless current_buffer.lines == [""] return if current_buffer.modified? current_buffer.replace_all_lines!(intro_lines) current_buffer.configure_special!(kind: :intro, name: "[Intro]", readonly: true, modifiable: false) current_buffer.modified = false assign_filetype(current_buffer, "help") current_window.cursor_x = 0 current_window.cursor_y = 0 current_window.row_offset = 0 current_window.col_offset = 0 current_buffer end |
#split_current_window(layout: :horizontal, place: :after) ⇒ Object
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 |
# File 'lib/ruvim/editor.rb', line 615 def split_current_window(layout: :horizontal, place: :after) save_current_tabpage_state! unless @suspend_tab_autosave src = current_window id = next_window_id win = Window.new(id:, buffer_id: src.buffer_id) @windows[id] = win ensure_initial_tabpage! win.cursor_x = src.cursor_x win.cursor_y = src.cursor_y win.row_offset = src.row_offset win.col_offset = src.col_offset split_type = (layout == :vertical ? :vsplit : :hsplit) new_leaf = { type: :window, id: win.id } @layout_tree = tree_split_leaf(@layout_tree, src.id, split_type, new_leaf, place) @current_window_id = win.id save_current_tabpage_state! unless @suspend_tab_autosave win end |
#start_macro_recording(name) ⇒ Object
360 361 362 363 364 365 366 |
# File 'lib/ruvim/editor.rb', line 360 def start_macro_recording(name) reg = name.to_s return false unless reg.match?(/\A[A-Za-z0-9]\z/) @macro_recording = { name: reg, keys: [] } true end |
#stop_macro_recording ⇒ Object
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
# File 'lib/ruvim/editor.rb', line 368 def stop_macro_recording rec = @macro_recording @macro_recording = nil return nil unless rec name = rec[:name] keys = rec[:keys] if name.match?(/\A[A-Z]\z/) base = name.downcase @macros[base] = [*(@macros[base] || []), *keys] @macros[base] else @macros[name.downcase] = keys end end |
#store_operator_register(name = "\"", text:, type:, kind:) ⇒ Object
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/ruvim/editor.rb', line 297 def store_operator_register(name = "\"", text:, type:, kind:) key = (name || "\"") payload = { text: text, type: type } return payload if key == "_" written = set_register(key, text: payload[:text], type: payload[:type]) op_payload = dup_register_payload(written) case kind when :yank @registers["0"] = dup_register_payload(op_payload) when :delete, :change rotate_delete_registers!(op_payload) end written end |
#stream_stop_or_cancel! ⇒ Object
180 181 182 183 184 185 |
# File 'lib/ruvim/editor.rb', line 180 def stream_stop_or_cancel! handler = current_buffer&.stream&.stop_handler return false unless handler handler.call end |
#suppress_hlsearch! ⇒ Object
160 161 162 |
# File 'lib/ruvim/editor.rb', line 160 def suppress_hlsearch! @hlsearch_suppressed = true end |
#switch_to_buffer(buffer_id) ⇒ Object
737 738 739 740 741 742 743 744 745 746 747 748 749 |
# File 'lib/ruvim/editor.rb', line 737 def switch_to_buffer(buffer_id) prev_buffer_id = current_window&.buffer_id current_window.buffer_id = buffer_id current_window.cursor_x = 0 current_window.cursor_y = 0 current_window.row_offset = 0 current_window.col_offset = 0 if prev_buffer_id && prev_buffer_id != buffer_id @alternate_buffer_id = prev_buffer_id end save_current_tabpage_state! unless @suspend_tab_autosave current_window end |
#tabnew(path: nil) ⇒ Object
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 |
# File 'lib/ruvim/editor.rb', line 1011 def tabnew(path: nil) ensure_initial_tabpage! save_current_tabpage_state! with_tab_autosave_suspended do @layout_tree = nil @current_window_id = nil buffer = path ? add_buffer_from_file(path) : add_empty_buffer add_window(buffer_id: buffer.id) tab = new_tabpage_snapshot @tabpages << tab @current_tabpage_index = @tabpages.length - 1 load_tabpage_state!(tab) return tab end end |
#tabnext(step = 1) ⇒ Object
1029 1030 1031 1032 1033 1034 |
# File 'lib/ruvim/editor.rb', line 1029 def tabnext(step = 1) return nil if @tabpages.empty? save_current_tabpage_state! @current_tabpage_index = (@current_tabpage_index + step) % @tabpages.length load_tabpage_state!(@tabpages[@current_tabpage_index]) end |
#tabpage_count ⇒ Object
893 894 895 |
# File 'lib/ruvim/editor.rb', line 893 def tabpage_count @tabpages.length end |
#tabpage_windows(tab) ⇒ Object
897 898 899 |
# File 'lib/ruvim/editor.rb', line 897 def tabpage_windows(tab) tree_leaves(tab[:layout_tree]) end |
#tabpages ⇒ Object
881 882 883 |
# File 'lib/ruvim/editor.rb', line 881 def tabpages @tabpages end |
#tabprev(step = 1) ⇒ Object
1036 1037 1038 |
# File 'lib/ruvim/editor.rb', line 1036 def tabprev(step = 1) tabnext(-step) end |
#text_viewport_size(rows:, cols:) ⇒ Object
1128 1129 1130 1131 1132 |
# File 'lib/ruvim/editor.rb', line 1128 def (rows:, cols:) # Reserve one status row + one command/error row at the bottom. text_rows = rows - 2 [text_rows, cols] end |
#transient_message_timeout_seconds(now: nil) ⇒ Object
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 |
# File 'lib/ruvim/editor.rb', line 1103 def (now: nil) return nil unless @message_deadline return nil if return nil if command_line_active? now ||= Process.clock_gettime(Process::CLOCK_MONOTONIC) [@message_deadline - now, 0.0].max rescue StandardError nil end |
#visual_active? ⇒ Boolean
462 463 464 |
# File 'lib/ruvim/editor.rb', line 462 def visual_active? !@visual_state.nil? end |
#visual_selection(window = current_window) ⇒ Object
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 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
# File 'lib/ruvim/editor.rb', line 480 def visual_selection(window = current_window) return nil unless @visual_state ay = @visual_state[:anchor_y] ax = @visual_state[:anchor_x] cy = window.cursor_y cx = window.cursor_x case @visual_state[:mode] when :visual_line start_row, end_row = [ay, cy].minmax { mode: :linewise, start_row: start_row, start_col: 0, end_row: end_row, end_col: current_buffer.line_length(end_row) } when :visual_block start_row, end_row = [ay, cy].minmax start_col, end_col = [ax, cx].minmax { mode: :blockwise, start_row: start_row, start_col: start_col, end_row: end_row, end_col: end_col + 1 } else if ay < cy || (ay == cy && ax <= cx) s_row, s_col, e_row, e_col = [ay, ax, cy, cx] else s_row, s_col, e_row, e_col = [cy, cx, ay, ax] end { mode: :charwise, start_row: s_row, start_col: s_col, end_row: e_row, end_col: e_col + 1 } end end |
#visual_state ⇒ Object
344 345 346 |
# File 'lib/ruvim/editor.rb', line 344 def visual_state @visual_state end |
#window_count ⇒ Object
901 902 903 |
# File 'lib/ruvim/editor.rb', line 901 def window_count tree_leaves(@layout_tree).length end |
#window_layout ⇒ Object
872 873 874 875 876 877 878 879 |
# File 'lib/ruvim/editor.rb', line 872 def window_layout return :single if @layout_tree.nil? || @layout_tree[:type] == :window case @layout_tree[:type] when :vsplit then :vertical when :hsplit then :horizontal else :single end end |
#window_order ⇒ Object
868 869 870 |
# File 'lib/ruvim/editor.rb', line 868 def window_order tree_leaves(@layout_tree) end |