Class: Kward::PromptInterface::EditorState
- Inherits:
-
Object
- Object
- Kward::PromptInterface::EditorState
- Defined in:
- lib/kward/prompt_interface/editor/state.rb
Overview
Mutable state for the built-in composer file editor.
Instance Attribute Summary collapse
-
#buffer ⇒ Object
Returns the value of attribute buffer.
-
#diff_view ⇒ Object
Returns the value of attribute diff_view.
-
#display_path ⇒ Object
readonly
Returns the value of attribute display_path.
-
#editor_mode ⇒ Object
Returns the value of attribute editor_mode.
-
#emacs_pending ⇒ Object
Returns the value of attribute emacs_pending.
-
#kill_buffer ⇒ Object
Returns the value of attribute kill_buffer.
-
#kill_ring ⇒ Object
Returns the value of attribute kill_ring.
-
#language ⇒ Object
readonly
Returns the value of attribute language.
-
#last_yank_index ⇒ Object
Returns the value of attribute last_yank_index.
-
#last_yank_range ⇒ Object
Returns the value of attribute last_yank_range.
-
#new_file ⇒ Object
Returns the value of attribute new_file.
-
#original_content ⇒ Object
readonly
Returns the value of attribute original_content.
-
#original_digest ⇒ Object
readonly
Returns the value of attribute original_digest.
-
#original_mtime ⇒ Object
readonly
Returns the value of attribute original_mtime.
-
#original_size ⇒ Object
readonly
Returns the value of attribute original_size.
-
#overwrite_confirmed ⇒ Object
Returns the value of attribute overwrite_confirmed.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#quit_confirmed ⇒ Object
Returns the value of attribute quit_confirmed.
-
#readonly ⇒ Object
Returns the value of attribute readonly.
-
#redo_stack ⇒ Object
Returns the value of attribute redo_stack.
-
#search_active ⇒ Object
Returns the value of attribute search_active.
-
#search_direction ⇒ Object
Returns the value of attribute search_direction.
-
#search_query ⇒ Object
Returns the value of attribute search_query.
-
#status ⇒ Object
Returns the value of attribute status.
-
#undo_stack ⇒ Object
Returns the value of attribute undo_stack.
-
#vibe_state ⇒ Object
readonly
Returns the value of attribute vibe_state.
-
#viewport_column ⇒ Object
Returns the value of attribute viewport_column.
-
#viewport_row ⇒ Object
Returns the value of attribute viewport_row.
Instance Method Summary collapse
- #add_next_occurrence_selection ⇒ Object
- #add_selection(anchor, cursor = anchor) ⇒ Object
- #add_vertical_cursor(direction) ⇒ Object
- #append_search(text) ⇒ Object
- #begin_search(direction = :forward) ⇒ Object
- #begin_selection ⇒ Object
- #bind_path(path) ⇒ Object
- #cancel_search ⇒ Object
- #clear_selection ⇒ Object
- #collapse_to_primary_selection ⇒ Object
- #confirm_search ⇒ Object
- #copy_for_kill_ring(start_index, end_index) ⇒ Object
- #copy_range(start_index, end_index) ⇒ Object
- #current_line_range ⇒ Object
- #cursor ⇒ Object
- #cursor=(value) ⇒ Object
- #cursor_line_and_column ⇒ Object
- #cursor_line_and_column_for(offset) ⇒ Object
- #cut_range(start_index, end_index) ⇒ Object
- #delete_at_cursor ⇒ Object
- #delete_at_selections ⇒ Object
- #delete_before_cursor ⇒ Object
- #delete_before_selections ⇒ Object
- #delete_search_character ⇒ Object
- #delete_word_after_cursor ⇒ Object
- #delete_word_before_cursor ⇒ Object
- #diff_view? ⇒ Boolean
- #dirty? ⇒ Boolean
- #emacs? ⇒ Boolean
- #extending_selections ⇒ Object
- #file_changed_on_disk? ⇒ Boolean
-
#initialize(path:, content:, new_file: false, editor_mode: "modern", readonly: false, diff_view: false, virtual: false, display_path: nil, language: nil) ⇒ EditorState
constructor
A new instance of EditorState.
- #initialize_copy(other) ⇒ Object
- #insert(text) ⇒ Object
- #kill_line_after_cursor ⇒ Object
- #kill_line_before_cursor ⇒ Object
- #line_range(line_index) ⇒ Object
- #line_start_offset(line_index) ⇒ Object
- #lines ⇒ Object
- #modern? ⇒ Boolean
- #move_down ⇒ Object
- #move_file_end ⇒ Object
- #move_file_start ⇒ Object
- #move_indentation_down ⇒ Object
- #move_indentation_right ⇒ Object
- #move_indentation_up ⇒ Object
- #move_left ⇒ Object
- #move_line_end ⇒ Object
- #move_line_first_non_blank ⇒ Object
- #move_line_start ⇒ Object
- #move_right ⇒ Object
- #move_to_line_first_non_blank(line_index) ⇒ Object
- #move_to_next_word ⇒ Object
- #move_to_previous_word ⇒ Object
- #move_to_word_end ⇒ Object
- #move_up ⇒ Object
- #multi_cursor? ⇒ Boolean
- #offset_for_line_and_column(line_index, column) ⇒ Object
- #page_down(rows) ⇒ Object
- #page_up(rows) ⇒ Object
- #push_kill(text) ⇒ Object
- #push_undo ⇒ Object
- #readonly? ⇒ Boolean
- #redo ⇒ Object
- #refresh_after_save(content) ⇒ Object
- #repeat_search(direction = @search_direction, query = @search_query) ⇒ Object
- #replace_range(start_index, end_index, text) ⇒ Object
- #replace_selections(text) ⇒ Object
- #secondary_cursor_offsets ⇒ Object
- #selected_text ⇒ Object
- #selection_active? ⇒ Boolean
- #selection_anchor ⇒ Object
- #selection_anchor=(value) ⇒ Object
- #selection_range ⇒ Object
- #selection_ranges ⇒ Object
- #selection_to_line_start_cursors ⇒ Object
- #selections ⇒ Object
- #set_cursor_line_and_column(line_index, column) ⇒ Object
- #set_selections(values) ⇒ Object
- #undo ⇒ Object
- #vibe? ⇒ Boolean
- #vibe_command ⇒ Object
- #vibe_command=(value) ⇒ Object
- #vibe_last_change ⇒ Object
- #vibe_last_change=(value) ⇒ Object
- #vibe_last_find ⇒ Object
- #vibe_last_find=(value) ⇒ Object
- #vibe_last_macro ⇒ Object
- #vibe_last_macro=(value) ⇒ Object
- #vibe_last_visual_selection ⇒ Object
- #vibe_last_visual_selection=(value) ⇒ Object
- #vibe_macros ⇒ Object
- #vibe_macros=(value) ⇒ Object
- #vibe_marks ⇒ Object
- #vibe_marks=(value) ⇒ Object
- #vibe_mode ⇒ Object
- #vibe_mode=(value) ⇒ Object
- #vibe_pending ⇒ Object
- #vibe_pending=(value) ⇒ Object
- #vibe_recording_macro ⇒ Object
- #vibe_recording_macro=(value) ⇒ Object
- #vibe_registers ⇒ Object
- #vibe_registers=(value) ⇒ Object
- #vibe_visual_block_insert ⇒ Object
- #vibe_visual_block_insert=(value) ⇒ Object
- #virtual? ⇒ Boolean
- #visual_block_selection_ranges ⇒ Object
- #visual_character_selection_range ⇒ Object
- #visual_line_selection_range ⇒ Object
- #word_range_at(offset) ⇒ Object
- #word_under_cursor ⇒ Object
- #yank_from_kill_ring ⇒ Object
- #yank_kill_buffer ⇒ Object
- #yank_pop ⇒ Object
Constructor Details
#initialize(path:, content:, new_file: false, editor_mode: "modern", readonly: false, diff_view: false, virtual: false, display_path: nil, language: nil) ⇒ EditorState
Returns a new instance of EditorState.
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 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 23 def initialize(path:, content:, new_file: false, editor_mode: "modern", readonly: false, diff_view: false, virtual: false, display_path: nil, language: nil) @path = virtual ? nil : path.to_s @display_path = display_path.to_s.empty? ? path.to_s : display_path.to_s @language = language&.to_sym @new_file = new_file @readonly = readonly @diff_view = diff_view @virtual = virtual == true @file_marker = EditorFileMarker.new(path: @path || @display_path, content: content, new_file: new_file || virtual?) @original_content = @file_marker.content @original_digest = @file_marker.digest @original_mtime = @file_marker.mtime @original_size = @file_marker.size @text_buffer = EditorBuffer.new(@original_content) @buffer = @text_buffer.text @cursor = 0 @viewport_row = 0 @viewport_column = 0 @status = nil @overwrite_confirmed = false @quit_confirmed = false @search = EditorSearch.new @search_active = @search.active? @search_query = @search.query @search_direction = @search.direction @kill_state = EditorKillRing.new @kill_buffer = @kill_state.kill_buffer @selections = EditorSelections.new(cursor: @cursor, buffer_length: @buffer.length) sync_selection_state @editor_mode = normalize_editor_mode(editor_mode) @emacs_pending = nil @kill_ring = @kill_state.kill_ring @last_yank_range = @kill_state.last_yank_range @last_yank_index = @kill_state.last_yank_index @vibe_state = VibeEditorState.new(editor_mode: @editor_mode) sync_vibe_state @undo_history = EditorUndoHistory.new @undo_stack = @undo_history.undo_stack @redo_stack = @undo_history.redo_stack @status = default_status end |
Instance Attribute Details
#buffer ⇒ Object
Returns the value of attribute buffer.
20 21 22 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 20 def buffer @buffer end |
#diff_view ⇒ Object
Returns the value of attribute diff_view.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def diff_view @diff_view end |
#display_path ⇒ Object (readonly)
Returns the value of attribute display_path.
19 20 21 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 19 def display_path @display_path end |
#editor_mode ⇒ Object
Returns the value of attribute editor_mode.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def editor_mode @editor_mode end |
#emacs_pending ⇒ Object
Returns the value of attribute emacs_pending.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def emacs_pending @emacs_pending end |
#kill_buffer ⇒ Object
Returns the value of attribute kill_buffer.
20 21 22 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 20 def kill_buffer @kill_buffer end |
#kill_ring ⇒ Object
Returns the value of attribute kill_ring.
20 21 22 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 20 def kill_ring @kill_ring end |
#language ⇒ Object (readonly)
Returns the value of attribute language.
19 20 21 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 19 def language @language end |
#last_yank_index ⇒ Object
Returns the value of attribute last_yank_index.
20 21 22 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 20 def last_yank_index @last_yank_index end |
#last_yank_range ⇒ Object
Returns the value of attribute last_yank_range.
20 21 22 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 20 def last_yank_range @last_yank_range end |
#new_file ⇒ Object
Returns the value of attribute new_file.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def new_file @new_file end |
#original_content ⇒ Object (readonly)
Returns the value of attribute original_content.
19 20 21 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 19 def original_content @original_content end |
#original_digest ⇒ Object (readonly)
Returns the value of attribute original_digest.
19 20 21 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 19 def original_digest @original_digest end |
#original_mtime ⇒ Object (readonly)
Returns the value of attribute original_mtime.
19 20 21 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 19 def original_mtime @original_mtime end |
#original_size ⇒ Object (readonly)
Returns the value of attribute original_size.
19 20 21 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 19 def original_size @original_size end |
#overwrite_confirmed ⇒ Object
Returns the value of attribute overwrite_confirmed.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def overwrite_confirmed @overwrite_confirmed end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
19 20 21 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 19 def path @path end |
#quit_confirmed ⇒ Object
Returns the value of attribute quit_confirmed.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def quit_confirmed @quit_confirmed end |
#readonly ⇒ Object
Returns the value of attribute readonly.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def readonly @readonly end |
#redo_stack ⇒ Object
Returns the value of attribute redo_stack.
20 21 22 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 20 def redo_stack @redo_stack end |
#search_active ⇒ Object
Returns the value of attribute search_active.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def search_active @search_active end |
#search_direction ⇒ Object
Returns the value of attribute search_direction.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def search_direction @search_direction end |
#search_query ⇒ Object
Returns the value of attribute search_query.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def search_query @search_query end |
#status ⇒ Object
Returns the value of attribute status.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def status @status end |
#undo_stack ⇒ Object
Returns the value of attribute undo_stack.
20 21 22 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 20 def undo_stack @undo_stack end |
#vibe_state ⇒ Object (readonly)
Returns the value of attribute vibe_state.
115 116 117 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 115 def vibe_state @vibe_state end |
#viewport_column ⇒ Object
Returns the value of attribute viewport_column.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def @viewport_column end |
#viewport_row ⇒ Object
Returns the value of attribute viewport_row.
21 22 23 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 21 def @viewport_row end |
Instance Method Details
#add_next_occurrence_selection ⇒ Object
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 867 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 836 def add_next_occurrence_selection range = selection_range || word_range_at(@cursor) unless range @status = "No word under cursor" return false end query = @buffer[range[0]...range[1]].to_s if query.empty? @status = "No word under cursor" return false end existing_ranges = selection_ranges existing_ranges = [range] if existing_ranges.empty? start_after = existing_ranges.map(&:last).max || range[1] if selection_range.nil? set_selections([{ anchor: range[0], cursor: range[1] }]) @status = "Selected: #{query}" return true end match = next_occurrence_range(query, start_after, existing_ranges) unless match @status = "No more matches: #{query}" return false end add_selection(match[0], match[1]) @status = "Added cursor for: #{query}" true end |
#add_selection(anchor, cursor = anchor) ⇒ Object
296 297 298 299 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 296 def add_selection(anchor, cursor = anchor) @selections.add(anchor, cursor) sync_selection_state end |
#add_vertical_cursor(direction) ⇒ Object
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 869 def add_vertical_cursor(direction) source = direction == :up ? selections.min_by { |selection| selection[:cursor] } : selections.max_by { |selection| selection[:cursor] } line, column = cursor_line_and_column_for(source[:cursor]) target_line = direction == :up ? line - 1 : line + 1 if target_line.negative? || target_line >= lines.length @status = direction == :up ? "No line above" : "No line below" return false end target_column = [column, lines[target_line].to_s.length].min offset = line_start_offset(target_line) + target_column add_selection(offset, offset) @status = direction == :up ? "Added cursor above" : "Added cursor below" true end |
#append_search(text) ⇒ Object
923 924 925 926 927 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 923 def append_search(text) @status = @search.append(text) sync_search_state true end |
#begin_search(direction = :forward) ⇒ Object
911 912 913 914 915 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 911 def begin_search(direction = :forward) @status = @search.begin(direction) sync_search_state true end |
#begin_selection ⇒ Object
665 666 667 668 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 665 def begin_selection self.selection_anchor = @cursor @status = "Selection started" end |
#bind_path(path) ⇒ Object
319 320 321 322 323 324 325 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 319 def bind_path(path) @path = path.to_s @display_path = @path @virtual = false @new_file = !File.exist?(@path) @file_marker = EditorFileMarker.new(path: @path, content: @original_content, new_file: true) end |
#cancel_search ⇒ Object
917 918 919 920 921 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 917 def cancel_search @status = @search.cancel sync_search_state true end |
#clear_selection ⇒ Object
670 671 672 673 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 670 def clear_selection @selections.clear sync_selection_state end |
#collapse_to_primary_selection ⇒ Object
301 302 303 304 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 301 def collapse_to_primary_selection @selections.collapse_to_primary sync_selection_state end |
#confirm_search ⇒ Object
935 936 937 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 935 def confirm_search apply_search_result(@search.confirm(buffer: @buffer, cursor: @cursor)) end |
#copy_for_kill_ring(start_index, end_index) ⇒ Object
827 828 829 830 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 827 def copy_for_kill_ring(start_index, end_index) start_index, end_index = [start_index, end_index].minmax push_kill(@buffer[start_index...end_index].to_s) end |
#copy_range(start_index, end_index) ⇒ Object
822 823 824 825 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 822 def copy_range(start_index, end_index) start_index, end_index = [start_index, end_index].minmax self.kill_buffer = @buffer[start_index...end_index].to_s end |
#current_line_range ⇒ Object
774 775 776 777 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 774 def current_line_range line, = cursor_line_and_column line_range(line) end |
#cursor ⇒ Object
261 262 263 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 261 def cursor @cursor end |
#cursor=(value) ⇒ Object
265 266 267 268 269 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 265 def cursor=(value) @cursor = clamp_offset(value) @selections.cursor = @cursor sync_selection_state end |
#cursor_line_and_column ⇒ Object
351 352 353 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 351 def cursor_line_and_column cursor_line_and_column_for(@cursor) end |
#cursor_line_and_column_for(offset) ⇒ Object
743 744 745 746 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 743 def cursor_line_and_column_for(offset) before_cursor = @buffer[0...offset].to_s [before_cursor.count("\n"), (before_cursor.split("\n", -1).last || "").length] end |
#cut_range(start_index, end_index) ⇒ Object
832 833 834 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 832 def cut_range(start_index, end_index) kill_range(start_index, end_index) end |
#delete_at_cursor ⇒ Object
417 418 419 420 421 422 423 424 425 426 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 417 def delete_at_cursor return delete_at_selections if multi_cursor? return false unless @cursor < @buffer.length @text_buffer.delete_range(@cursor, @cursor + 1) @buffer = @text_buffer.text sync_selection_state changed! true end |
#delete_at_selections ⇒ Object
810 811 812 813 814 815 816 817 818 819 820 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 810 def delete_at_selections apply_selection_edits do |selection| range = selection_range_for(selection) if range[0] != range[1] "" elsif range[1] < @buffer.length selection[:cursor] = range[1] + 1 "" end end end |
#delete_before_cursor ⇒ Object
405 406 407 408 409 410 411 412 413 414 415 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 405 def delete_before_cursor return delete_before_selections if multi_cursor? return false if @cursor.zero? @text_buffer.delete_range(@cursor - 1, @cursor) @cursor -= 1 @buffer = @text_buffer.text sync_selection_state changed! true end |
#delete_before_selections ⇒ Object
798 799 800 801 802 803 804 805 806 807 808 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 798 def delete_before_selections apply_selection_edits do |selection| range = selection_range_for(selection) if range[0] != range[1] "" elsif range[0].positive? selection[:anchor] = range[0] - 1 "" end end end |
#delete_search_character ⇒ Object
929 930 931 932 933 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 929 def delete_search_character @status = @search.delete_character sync_search_state true end |
#delete_word_after_cursor ⇒ Object
601 602 603 604 605 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 601 def delete_word_after_cursor return apply_selection_edits { |selection| selection[:cursor] = next_word_boundary(selection_range_for(selection)[1]); "" } if multi_cursor? kill_range(@cursor, next_word_boundary(@cursor)) end |
#delete_word_before_cursor ⇒ Object
595 596 597 598 599 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 595 def delete_word_before_cursor return apply_selection_edits { |selection| selection[:anchor] = previous_word_boundary(selection_range_for(selection)[0]); "" } if multi_cursor? kill_range(previous_word_boundary(@cursor), @cursor) end |
#diff_view? ⇒ Boolean
327 328 329 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 327 def diff_view? @diff_view == true end |
#dirty? ⇒ Boolean
343 344 345 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 343 def dirty? @buffer != @original_content end |
#emacs? ⇒ Boolean
335 336 337 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 335 def emacs? @editor_mode == "emacs" end |
#extending_selections ⇒ Object
903 904 905 906 907 908 909 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 903 def extending_selections previous = @extending_selections @extending_selections = true yield ensure @extending_selections = previous end |
#file_changed_on_disk? ⇒ Boolean
971 972 973 974 975 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 971 def file_changed_on_disk? return false if virtual? @file_marker.changed_on_disk?(new_file: new_file) end |
#initialize_copy(other) ⇒ Object
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 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 65 def initialize_copy(other) super @path = other.path&.dup @display_path = other.display_path.dup @language = other.language @virtual = other.virtual? @original_content = other.original_content.dup @file_marker = EditorFileMarker.new(path: @path || @display_path, content: @original_content, new_file: other.new_file || @virtual) @original_digest = other.original_digest.dup @original_mtime = other.original_mtime @original_size = other.original_size @text_buffer = EditorBuffer.new(other.buffer) @buffer = @text_buffer.text @status = other.status.dup @search = EditorSearch.new(direction: other.search_direction) @search_active = other.search_active @search_query = other.search_query.dup @search_direction = other.search_direction @kill_state = EditorKillRing.new( kill_buffer: other.kill_buffer.dup, kill_ring: other.kill_ring.map(&:dup), last_yank_range: other.last_yank_range&.dup, last_yank_index: other.last_yank_index ) @kill_buffer = @kill_state.kill_buffer @quit_confirmed = other.quit_confirmed @viewport_column = other. @selections = EditorSelections.new( cursor: @cursor, buffer_length: @buffer.length, anchor: other.selection_anchor, secondary: other.selections.drop(1).map(&:dup) ) sync_selection_state @editor_mode = other.editor_mode.dup @emacs_pending = other.emacs_pending&.dup @kill_ring = @kill_state.kill_ring @last_yank_range = @kill_state.last_yank_range @last_yank_index = @kill_state.last_yank_index @vibe_state = VibeEditorState.copy(other.vibe_state) sync_vibe_state @undo_history = EditorUndoHistory.new other.undo_stack.each { |entry| @undo_history.undo_stack << duplicate_editor_snapshot(entry) } other.redo_stack.each { |entry| @undo_history.redo_stack << duplicate_editor_snapshot(entry) } @undo_stack = @undo_history.undo_stack @redo_stack = @undo_history.redo_stack @readonly = other.readonly @diff_view = other.diff_view end |
#insert(text) ⇒ Object
393 394 395 396 397 398 399 400 401 402 403 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 393 def insert(text) text = text.to_s return if text.empty? return replace_selections(text) if multi_cursor? @text_buffer.insert(@cursor, text) @cursor += text.length @buffer = @text_buffer.text sync_selection_state changed! end |
#kill_line_after_cursor ⇒ Object
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 613 def kill_line_after_cursor if multi_cursor? return apply_selection_edits do |selection| range = selection_range_for(selection) selection[:cursor] = line_end_for_offset(range[1]) selection[:cursor] += 1 if range[0] == selection[:cursor] && selection[:cursor] < @buffer.length "" end end if current_line_empty? kill_range(empty_line_start, empty_line_end) else kill_range(@cursor, current_line_end) end end |
#kill_line_before_cursor ⇒ Object
607 608 609 610 611 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 607 def kill_line_before_cursor return apply_selection_edits { |selection| selection[:anchor] = line_start_for_offset(selection_range_for(selection)[0]); "" } if multi_cursor? kill_range(current_line_start, @cursor) end |
#line_range(line_index) ⇒ Object
754 755 756 757 758 759 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 754 def line_range(line_index) start_index = line_start_offset(line_index) end_index = start_index + lines[line_index].to_s.length end_index += 1 if end_index < @buffer.length [start_index, end_index] end |
#line_start_offset(line_index) ⇒ Object
748 749 750 751 752 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 748 def line_start_offset(line_index) values = lines line_index = [[line_index.to_i, 0].max, values.length - 1].min values.first(line_index).sum { |line| line.length + 1 } end |
#lines ⇒ Object
347 348 349 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 347 def lines @text_buffer.lines end |
#modern? ⇒ Boolean
331 332 333 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 331 def modern? @editor_mode == "modern" end |
#move_down ⇒ Object
459 460 461 462 463 464 465 466 467 468 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 459 def move_down if multi_cursor? return move_selection_cursors { |selection| move_offset_vertically(selection[:cursor], 1) } if extending_selections? return move_selections { |selection| move_offset_vertically(selection[:cursor], 1) } end line, column = cursor_line_and_column set_cursor_line_and_column(line + 1, column) end |
#move_file_end ⇒ Object
783 784 785 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 783 def move_file_end @cursor = @buffer.length end |
#move_file_start ⇒ Object
779 780 781 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 779 def move_file_start @cursor = 0 end |
#move_indentation_down ⇒ Object
567 568 569 570 571 572 573 574 575 576 577 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 567 def move_indentation_down if multi_cursor? return move_selection_cursors { |selection| indentation_offset_for(selection[:cursor], :down) } if extending_selections? return move_selections { |selection| indentation_offset_for(selection[:cursor], :down) } end line, column = cursor_line_and_column target_line = next_indentation_line(line, indentation_level_for_line(line)) move_to_indentation_line(target_line, column) end |
#move_indentation_right ⇒ Object
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 579 def move_indentation_right if multi_cursor? return move_selection_cursors { |selection| indentation_right_offset_for(selection[:cursor]) } if extending_selections? return move_selections { |selection| indentation_right_offset_for(selection[:cursor]) } end line, column = cursor_line_and_column indentation = indentation_level_for_line(line) if column < indentation set_cursor_line_and_column(line, indentation) else move_to_word_end end end |
#move_indentation_up ⇒ Object
555 556 557 558 559 560 561 562 563 564 565 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 555 def move_indentation_up if multi_cursor? return move_selection_cursors { |selection| indentation_offset_for(selection[:cursor], :up) } if extending_selections? return move_selections { |selection| indentation_offset_for(selection[:cursor], :up) } end line, column = cursor_line_and_column target_line = previous_indentation_line(line, indentation_level_for_line(line)) move_to_indentation_line(target_line, column) end |
#move_left ⇒ Object
428 429 430 431 432 433 434 435 436 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 428 def move_left if multi_cursor? return move_selection_cursors { |selection| [selection[:cursor] - 1, 0].max } if extending_selections? return move_selections { |selection| collapse_or_move_left(selection) } end @cursor -= 1 if @cursor.positive? end |
#move_line_end ⇒ Object
492 493 494 495 496 497 498 499 500 501 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 492 def move_line_end if multi_cursor? return move_selection_cursors { |selection| line_end_for_offset(selection[:cursor]) } if extending_selections? return move_selections { |selection| line_end_for_offset(selection[:cursor]) } end line, = cursor_line_and_column set_cursor_line_and_column(line, lines[line].length) end |
#move_line_first_non_blank ⇒ Object
481 482 483 484 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 481 def move_line_first_non_blank line, = cursor_line_and_column move_to_line_first_non_blank(line) end |
#move_line_start ⇒ Object
470 471 472 473 474 475 476 477 478 479 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 470 def move_line_start if multi_cursor? return move_selection_cursors { |selection| line_start_for_offset(selection[:cursor]) } if extending_selections? return move_selections { |selection| line_start_for_offset(selection[:cursor]) } end line, = cursor_line_and_column set_cursor_line_and_column(line, 0) end |
#move_right ⇒ Object
438 439 440 441 442 443 444 445 446 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 438 def move_right if multi_cursor? return move_selection_cursors { |selection| [selection[:cursor] + 1, @buffer.length].min } if extending_selections? return move_selections { |selection| collapse_or_move_right(selection) } end @cursor += 1 if @cursor < @buffer.length end |
#move_to_line_first_non_blank(line_index) ⇒ Object
486 487 488 489 490 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 486 def move_to_line_first_non_blank(line_index) line = [[line_index.to_i, 0].max, lines.length - 1].min column = lines[line].to_s.index(/\S/) || 0 set_cursor_line_and_column(line, column) end |
#move_to_next_word ⇒ Object
535 536 537 538 539 540 541 542 543 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 535 def move_to_next_word if multi_cursor? return move_selection_cursors { |selection| next_word_boundary(selection[:cursor]) } if extending_selections? return move_selections { |selection| next_word_boundary(selection[:cursor]) } end @cursor = next_word_boundary(@cursor) end |
#move_to_previous_word ⇒ Object
525 526 527 528 529 530 531 532 533 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 525 def move_to_previous_word if multi_cursor? return move_selection_cursors { |selection| previous_word_boundary(selection[:cursor]) } if extending_selections? return move_selections { |selection| previous_word_boundary(selection[:cursor]) } end @cursor = previous_word_boundary(@cursor) end |
#move_to_word_end ⇒ Object
545 546 547 548 549 550 551 552 553 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 545 def move_to_word_end if multi_cursor? return move_selection_cursors { |selection| next_word_end(selection[:cursor]) } if extending_selections? return move_selections { |selection| next_word_end(selection[:cursor]) } end @cursor = next_word_end(@cursor) end |
#move_up ⇒ Object
448 449 450 451 452 453 454 455 456 457 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 448 def move_up if multi_cursor? return move_selection_cursors { |selection| move_offset_vertically(selection[:cursor], -1) } if extending_selections? return move_selections { |selection| move_offset_vertically(selection[:cursor], -1) } end line, column = cursor_line_and_column set_cursor_line_and_column(line - 1, column) end |
#multi_cursor? ⇒ Boolean
285 286 287 288 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 285 def multi_cursor? sync_selection_state @selections.multi_cursor? end |
#offset_for_line_and_column(line_index, column) ⇒ Object
359 360 361 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 359 def offset_for_line_and_column(line_index, column) @text_buffer.offset_for_line_and_column(line_index, column) end |
#page_down(rows) ⇒ Object
514 515 516 517 518 519 520 521 522 523 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 514 def page_down(rows) if multi_cursor? return move_selection_cursors { |selection| move_offset_vertically(selection[:cursor], rows.to_i) } if extending_selections? return move_selections { |selection| move_offset_vertically(selection[:cursor], rows.to_i) } end line, column = cursor_line_and_column set_cursor_line_and_column(line + rows.to_i, column) end |
#page_up(rows) ⇒ Object
503 504 505 506 507 508 509 510 511 512 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 503 def page_up(rows) if multi_cursor? return move_selection_cursors { |selection| move_offset_vertically(selection[:cursor], -rows.to_i) } if extending_selections? return move_selections { |selection| move_offset_vertically(selection[:cursor], -rows.to_i) } end line, column = cursor_line_and_column set_cursor_line_and_column(line - rows.to_i, column) end |
#push_kill(text) ⇒ Object
634 635 636 637 638 639 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 634 def push_kill(text) return false unless @kill_state.push(text) sync_kill_state true end |
#push_undo ⇒ Object
363 364 365 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 363 def push_undo @undo_history.push(editor_snapshot) end |
#readonly? ⇒ Boolean
311 312 313 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 311 def readonly? @readonly == true end |
#redo ⇒ Object
380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 380 def redo snapshot = @undo_history.redo(editor_snapshot) unless snapshot @status = "Already at newest change" return false end restore_editor_snapshot(snapshot) changed!(clear_selections: false) @status = "Redo" true end |
#refresh_after_save(content) ⇒ Object
957 958 959 960 961 962 963 964 965 966 967 968 969 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 957 def refresh_after_save(content) @new_file = false @virtual = false @display_path = @path.to_s @file_marker.refresh(content) @original_content = @file_marker.content @original_digest = @file_marker.digest @original_mtime = @file_marker.mtime @original_size = @file_marker.size @overwrite_confirmed = false @quit_confirmed = false @status = "Saved #{@path}" end |
#repeat_search(direction = @search_direction, query = @search_query) ⇒ Object
939 940 941 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 939 def repeat_search(direction = @search_direction, query = @search_query) apply_search_result(@search.repeat(buffer: @buffer, cursor: @cursor, direction: direction, query: query)) end |
#replace_range(start_index, end_index, text) ⇒ Object
787 788 789 790 791 792 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 787 def replace_range(start_index, end_index, text) start_index, = @text_buffer.replace_range(start_index, end_index, text) @buffer = @text_buffer.text @cursor = [start_index, @buffer.length].min changed! end |
#replace_selections(text) ⇒ Object
794 795 796 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 794 def replace_selections(text) apply_selection_edits { |_selection| text.to_s } end |
#secondary_cursor_offsets ⇒ Object
306 307 308 309 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 306 def secondary_cursor_offsets sync_selection_state @selections.secondary_cursor_offsets end |
#selected_text ⇒ Object
732 733 734 735 736 737 738 739 740 741 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 732 def selected_text if vibe? && @vibe_mode == "visual_block" return selection_ranges.map { |range| @buffer[range[0]...range[1]].to_s }.join("\n") end ranges = selection_ranges return "" if ranges.empty? ranges.map { |range| @buffer[range[0]...range[1]].to_s }.join("\n") end |
#selection_active? ⇒ Boolean
675 676 677 678 679 680 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 675 def selection_active? return false if @selection_anchor.nil? return true if vibe? && %w[visual visual_line visual_block].include?(@vibe_mode) @selection_anchor != @cursor end |
#selection_anchor ⇒ Object
271 272 273 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 271 def selection_anchor @selection_anchor end |
#selection_anchor=(value) ⇒ Object
275 276 277 278 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 275 def selection_anchor=(value) @selections.anchor = value sync_selection_state end |
#selection_range ⇒ Object
682 683 684 685 686 687 688 689 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 682 def selection_range return visual_line_selection_range if vibe? && @vibe_mode == "visual_line" && selection_active? return visual_character_selection_range if vibe? && @vibe_mode == "visual" && selection_active? return visual_block_selection_ranges.first if vibe? && @vibe_mode == "visual_block" && selection_active? return nil unless primary_selection_active? [@selection_anchor, @cursor].minmax end |
#selection_ranges ⇒ Object
691 692 693 694 695 696 697 698 699 700 701 702 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 691 def selection_ranges if vibe? && %w[visual visual_line visual_block].include?(@vibe_mode) && selection_active? return visual_block_selection_ranges if @vibe_mode == "visual_block" return [selection_range] end selections.filter_map do |selection| range = selection_range_for(selection) range if range[0] != range[1] end end |
#selection_to_line_start_cursors ⇒ Object
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 885 def selection_to_line_start_cursors range = selection_range unless range @status = "No selection" return false end start_line, = cursor_line_and_column_for(range[0]) end_line, end_column = cursor_line_and_column_for(range[1]) end_line -= 1 if end_column.zero? && end_line > start_line set_selections((start_line..end_line).map do |line_index| offset = line_start_offset(line_index) { anchor: offset, cursor: offset } end) @status = "Created #{selections.length} cursors" true end |
#selections ⇒ Object
280 281 282 283 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 280 def selections sync_selection_state @selections.all end |
#set_cursor_line_and_column(line_index, column) ⇒ Object
355 356 357 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 355 def set_cursor_line_and_column(line_index, column) @cursor = offset_for_line_and_column(line_index, column) end |
#set_selections(values) ⇒ Object
290 291 292 293 294 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 290 def set_selections(values) @selections.set(values) @cursor = @selections.primary[:cursor] sync_selection_state end |
#undo ⇒ Object
367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 367 def undo snapshot = @undo_history.undo(editor_snapshot) unless snapshot @status = "Already at oldest change" return false end restore_editor_snapshot(snapshot) changed!(clear_selections: false) @status = "Undo" true end |
#vibe? ⇒ Boolean
339 340 341 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 339 def vibe? @editor_mode == "vibe" end |
#vibe_command ⇒ Object
171 172 173 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 171 def vibe_command @vibe_state.command end |
#vibe_command=(value) ⇒ Object
175 176 177 178 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 175 def vibe_command=(value) @vibe_state.command = value sync_vibe_state end |
#vibe_last_change ⇒ Object
180 181 182 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 180 def vibe_last_change @vibe_state.last_change end |
#vibe_last_change=(value) ⇒ Object
184 185 186 187 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 184 def vibe_last_change=(value) @vibe_state.last_change = value sync_vibe_state end |
#vibe_last_find ⇒ Object
189 190 191 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 189 def vibe_last_find @vibe_state.last_find end |
#vibe_last_find=(value) ⇒ Object
193 194 195 196 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 193 def vibe_last_find=(value) @vibe_state.last_find = value sync_vibe_state end |
#vibe_last_macro ⇒ Object
252 253 254 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 252 def vibe_last_macro @vibe_state.last_macro end |
#vibe_last_macro=(value) ⇒ Object
256 257 258 259 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 256 def vibe_last_macro=(value) @vibe_state.last_macro = value sync_vibe_state end |
#vibe_last_visual_selection ⇒ Object
198 199 200 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 198 def vibe_last_visual_selection @vibe_state.last_visual_selection end |
#vibe_last_visual_selection=(value) ⇒ Object
202 203 204 205 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 202 def vibe_last_visual_selection=(value) @vibe_state.last_visual_selection = value sync_vibe_state end |
#vibe_macros ⇒ Object
234 235 236 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 234 def vibe_macros @vibe_state.macros end |
#vibe_macros=(value) ⇒ Object
238 239 240 241 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 238 def vibe_macros=(value) @vibe_state.macros = value sync_vibe_state end |
#vibe_marks ⇒ Object
216 217 218 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 216 def vibe_marks @vibe_state.marks end |
#vibe_marks=(value) ⇒ Object
220 221 222 223 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 220 def vibe_marks=(value) @vibe_state.marks = value sync_vibe_state end |
#vibe_mode ⇒ Object
153 154 155 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 153 def vibe_mode @vibe_state.mode end |
#vibe_mode=(value) ⇒ Object
157 158 159 160 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 157 def vibe_mode=(value) @vibe_state.mode = value sync_vibe_state end |
#vibe_pending ⇒ Object
162 163 164 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 162 def vibe_pending @vibe_state.pending end |
#vibe_pending=(value) ⇒ Object
166 167 168 169 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 166 def vibe_pending=(value) @vibe_state.pending = value sync_vibe_state end |
#vibe_recording_macro ⇒ Object
243 244 245 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 243 def vibe_recording_macro @vibe_state.recording_macro end |
#vibe_recording_macro=(value) ⇒ Object
247 248 249 250 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 247 def vibe_recording_macro=(value) @vibe_state.recording_macro = value sync_vibe_state end |
#vibe_registers ⇒ Object
225 226 227 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 225 def vibe_registers @vibe_state.registers end |
#vibe_registers=(value) ⇒ Object
229 230 231 232 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 229 def vibe_registers=(value) @vibe_state.registers = value sync_vibe_state end |
#vibe_visual_block_insert ⇒ Object
207 208 209 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 207 def vibe_visual_block_insert @vibe_state.visual_block_insert end |
#vibe_visual_block_insert=(value) ⇒ Object
211 212 213 214 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 211 def vibe_visual_block_insert=(value) @vibe_state.visual_block_insert = value sync_vibe_state end |
#virtual? ⇒ Boolean
315 316 317 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 315 def virtual? @virtual == true end |
#visual_block_selection_ranges ⇒ Object
718 719 720 721 722 723 724 725 726 727 728 729 730 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 718 def visual_block_selection_ranges anchor_line, anchor_column = cursor_line_and_column_for(@selection_anchor) cursor_line, cursor_column = cursor_line_and_column start_line, end_line = [anchor_line, cursor_line].minmax start_column, end_column = [anchor_column, cursor_column].minmax (start_line..end_line).map do |line_index| line_start = line_start_offset(line_index) line_length = lines[line_index].to_s.length range_start = line_start + [start_column, line_length].min range_end = line_start + [end_column + 1, line_length].min [range_start, range_end] end end |
#visual_character_selection_range ⇒ Object
704 705 706 707 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 704 def visual_character_selection_range start_index, end_index = [@selection_anchor, @cursor].minmax [start_index, [end_index + 1, @buffer.length].min] end |
#visual_line_selection_range ⇒ Object
709 710 711 712 713 714 715 716 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 709 def visual_line_selection_range anchor_line, = cursor_line_and_column_for(@selection_anchor) cursor_line, = cursor_line_and_column start_line, end_line = [anchor_line, cursor_line].minmax start_index, = line_range(start_line) _, end_index = line_range(end_line) [start_index, end_index] end |
#word_range_at(offset) ⇒ Object
761 762 763 764 765 766 767 768 769 770 771 772 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 761 def word_range_at(offset) return nil if @buffer.empty? index = [[offset.to_i, 0].max, @buffer.length - 1].min return nil if word_separator?(@buffer[index]) start_index = index start_index -= 1 while start_index.positive? && !word_separator?(@buffer[start_index - 1]) end_index = index + 1 end_index += 1 while end_index < @buffer.length && !word_separator?(@buffer[end_index]) [start_index, end_index] end |
#word_under_cursor ⇒ Object
943 944 945 946 947 948 949 950 951 952 953 954 955 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 943 def word_under_cursor return "" if @buffer.empty? index = [[@cursor, 0].max, @buffer.length - 1].min index -= 1 while index.positive? && word_separator?(@buffer[index]) return "" if word_separator?(@buffer[index]) start_index = index start_index -= 1 while start_index.positive? && !word_separator?(@buffer[start_index - 1]) end_index = index + 1 end_index += 1 while end_index < @buffer.length && !word_separator?(@buffer[end_index]) @buffer[start_index...end_index].to_s end |
#yank_from_kill_ring ⇒ Object
641 642 643 644 645 646 647 648 649 650 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 641 def yank_from_kill_ring text = @kill_state.first_yank return false unless text start_index = @cursor insert(text) @kill_state.record_yank(start_index, @cursor) sync_kill_state true end |
#yank_kill_buffer ⇒ Object
630 631 632 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 630 def yank_kill_buffer replace_selections(@kill_buffer.to_s) unless @kill_buffer.to_s.empty? end |
#yank_pop ⇒ Object
652 653 654 655 656 657 658 659 660 661 662 663 |
# File 'lib/kward/prompt_interface/editor/state.rb', line 652 def yank_pop yank = @kill_state.next_yank_pop return false unless yank start_index, end_index = yank[:range] text = yank[:text] replace_range(start_index, end_index, text) @cursor = start_index + text.length @kill_state.record_yank_pop(start_index, @cursor) sync_kill_state true end |