class Reline::LineEditor
Constants
- CompletionJourneyState
- DIALOG_DEFAULT_HEIGHT
- MAX_INPUT_LINES
- MINIMUM_SCROLLBAR_HEIGHT
- NullActionState
- RenderedScreen
- VI_MOTIONS
Attributes
TODO: Use “private alias_method” idiom after drop Ruby 2.5.
Public Class Methods
Source
# File lib/reline/line_editor.rb, line 75 def initialize(config) @config = config @completion_append_character = '' @screen_size = [0, 0] # Should be initialized with actual winsize in LineEditor#reset reset_variables end
Public Instance Methods
Source
# File lib/reline/line_editor.rb, line 690 def add_dialog_proc(name, p, context = nil) dialog = Dialog.new(name, @config, DialogProcScope.new(self, @config, p, context)) if index = @dialogs.find_index { |d| d.name == name } @dialogs[index] = dialog else @dialogs << dialog end end
Source
# File lib/reline/line_editor.rb, line 1396 def byte_pointer=(val) @byte_pointer = val end
Source
# File lib/reline/line_editor.rb, line 401 def calculate_overlay_levels(overlay_levels) levels = [] overlay_levels.each do |x, w, l| levels.fill(l, x, w) end levels end
Source
# File lib/reline/line_editor.rb, line 1181 def call_completion_proc result = retrieve_completion_block(true) pre, target, post = result result = call_completion_proc_with_checking_args(pre, target, post) Reline.core.instance_variable_set(:@completion_quote_character, nil) result end
Source
# File lib/reline/line_editor.rb, line 1189 def call_completion_proc_with_checking_args(pre, target, post) if @completion_proc and target argnum = @completion_proc.parameters.inject(0) { |result, item| case item.first when :req, :opt result + 1 when :rest break 3 end } case argnum when 1 result = @completion_proc.(target) when 2 result = @completion_proc.(target, pre) when 3..Float::INFINITY result = @completion_proc.(target, pre, post) end end result end
Source
# File lib/reline/line_editor.rb, line 449 def clear_dialogs @dialogs.each do |dialog| dialog.contents = nil dialog.trap_key = nil end end
Source
# File lib/reline/line_editor.rb, line 1335 def confirm_multiline_termination temp_buffer = @buffer_of_lines.dup @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n") end
Source
# File lib/reline/line_editor.rb, line 307 def current_byte_pointer_cursor calculate_width(current_line.byteslice(0, @byte_pointer)) end
Source
# File lib/reline/line_editor.rb, line 1232 def current_line @buffer_of_lines[@line_index] end
Source
# File lib/reline/line_editor.rb, line 1362 def delete_text(start = nil, length = nil) if start.nil? and length.nil? if @buffer_of_lines.size == 1 @buffer_of_lines[@line_index] = '' @byte_pointer = 0 elsif @line_index == (@buffer_of_lines.size - 1) and @line_index > 0 @buffer_of_lines.pop @line_index -= 1 @byte_pointer = 0 elsif @line_index < (@buffer_of_lines.size - 1) @buffer_of_lines.delete_at(@line_index) @byte_pointer = 0 end elsif not start.nil? and not length.nil? if current_line before = current_line.byteslice(0, start) after = current_line.byteslice(start + length, current_line.bytesize) set_current_line(before + after) end elsif start.is_a?(Range) range = start first = range.first last = range.last last = current_line.bytesize - 1 if last > current_line.bytesize last += current_line.bytesize if last < 0 first += current_line.bytesize if first < 0 range = range.exclude_end? ? first...last : first..last line = current_line.bytes.reject.with_index{ |c, i| range.include?(i) }.map{ |c| c.chr(Encoding::ASCII_8BIT) }.join.force_encoding(encoding) set_current_line(line) else set_current_line(current_line.byteslice(0, start)) end end
Source
# File lib/reline/line_editor.rb, line 904 def dialog_proc_scope_completion_journey_data return nil unless @completion_journey_state line_index = @completion_journey_state.line_index pre_lines = @buffer_of_lines[0...line_index].map { |line| line + "\n" } post_lines = @buffer_of_lines[(line_index + 1)..-1].map { |line| line + "\n" } DialogProcScope::CompletionJourneyData.new( pre_lines.join + @completion_journey_state.pre, @completion_journey_state.post + post_lines.join, @completion_journey_state.list, @completion_journey_state.pointer ) end
Source
# File lib/reline/line_editor.rb, line 799 def editing_mode @config.editing_mode end
Source
# File lib/reline/line_editor.rb, line 218 def finalize Signal.trap('INT', @old_trap) end
Source
# File lib/reline/line_editor.rb, line 1416 def finish @finished = true @config.reset end
Source
# File lib/reline/line_editor.rb, line 170 def handle_signal handle_interrupted handle_resized end
Source
# File lib/reline/line_editor.rb, line 1102 def input_key(key) save_old_buffer @config.reset_oneshot_key_bindings @dialogs.each do |dialog| if key.char.instance_of?(Symbol) and key.char == dialog.name return end end if key.char.nil? process_insert(force: true) @eof = buffer_empty? finish return end @completion_occurs = false if key.char.is_a?(Symbol) process_key(key.char, key.char) else normal_char(key) end @prev_action_state, @next_action_state = @next_action_state, NullActionState unless @completion_occurs @completion_state = CompletionState::NORMAL @completion_journey_state = nil end push_input_lines unless @undoing @undoing = false if @in_pasting clear_dialogs return end modified = @old_buffer_of_lines != @buffer_of_lines if !@completion_occurs && modified && !@config.disable_completion && @config.autocompletion # Auto complete starts only when edited process_insert(force: true) @completion_journey_state = retrieve_completion_journey_state end modified end
Source
# File lib/reline/line_editor.rb, line 1340 def insert_multiline_text(text) save_old_buffer pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer) post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..) lines = (pre + Reline::Unicode.safe_encode(text, encoding).gsub(/\r\n?/, "\n") + post).split("\n", -1) lines << '' if lines.empty? @buffer_of_lines[@line_index, 1] = lines @line_index += lines.size - 1 @byte_pointer = @buffer_of_lines[@line_index].bytesize - post.bytesize push_input_lines end
Source
# File lib/reline/line_editor.rb, line 1352 def insert_text(text) if @buffer_of_lines[@line_index].bytesize == @byte_pointer @buffer_of_lines[@line_index] += text else @buffer_of_lines[@line_index] = byteinsert(@buffer_of_lines[@line_index], @byte_pointer, text) end @byte_pointer += text.bytesize process_auto_indent end
Source
# File lib/reline/line_editor.rb, line 1228 def line() @buffer_of_lines.join("\n") unless eof? end
Source
# File lib/reline/line_editor.rb, line 354 def modified_lines with_cache(__method__, whole_lines, finished?) do |whole, complete| modify_lines(whole, complete) end end
Source
# File lib/reline/line_editor.rb, line 276 def multiline_off @is_multiline = false end
Source
# File lib/reline/line_editor.rb, line 272 def multiline_on @is_multiline = true end
Source
# File lib/reline/line_editor.rb, line 474 def print_nomultiline_prompt Reline::IOGate.disable_auto_linewrap(true) if Reline::IOGate.win? # Readline's test `TestRelineAsReadline#test_readline` requires first output to be prompt, not cursor reset escape sequence. @output.write Reline::Unicode.strip_non_printing_start_end(@prompt) if @prompt && !@is_multiline ensure Reline::IOGate.disable_auto_linewrap(false) if Reline::IOGate.win? end
Source
# File lib/reline/line_editor.rb, line 360 def prompt_list with_cache(__method__, whole_lines, check_mode_string, @vi_arg, @searching_prompt) do |lines, mode_string| check_multiline_prompt(lines, mode_string) end end
Source
# File lib/reline/line_editor.rb, line 1152 def push_input_lines if @old_buffer_of_lines == @buffer_of_lines @input_lines[@input_lines_position] = [@buffer_of_lines.dup, @byte_pointer, @line_index] else @input_lines = @input_lines[0..@input_lines_position] @input_lines_position += 1 @input_lines.push([@buffer_of_lines.dup, @byte_pointer, @line_index]) end trim_input_lines end
Source
# File lib/reline/line_editor.rb, line 482 def render wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line| prompt_width = Reline::Unicode.calculate_width(prompt, true) [[0, prompt_width, prompt], [prompt_width, Reline::Unicode.calculate_width(line, true), line]] end if @menu_info @menu_info.lines(screen_width).each do |item| new_lines << [[0, Reline::Unicode.calculate_width(item), item]] end @menu_info = nil # TODO: do not change state here end @dialogs.each_with_index do |dialog, index| next unless dialog.contents x_range, y_range = dialog_range dialog, wrapped_cursor_y - screen_scroll_top y_range.each do |row| next if row < 0 || row >= screen_height dialog_rows = new_lines[row] ||= [] # index 0 is for prompt, index 1 is for line, index 2.. is for dialog dialog_rows[index + 2] = [x_range.begin, dialog.width, dialog.contents[row - y_range.begin]] end end render_differential new_lines, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top end
Source
# File lib/reline/line_editor.rb, line 464 def render_finished render_differential([], 0, 0) lines = @buffer_of_lines.size.times.map do |i| line = Reline::Unicode.strip_non_printing_start_end(prompt_list[i]) + modified_lines[i] wrapped_lines, = split_by_width(line, screen_width) wrapped_lines.last.empty? ? "#{line} " : line end @output.puts lines.map { |l| "#{l}\r\n" }.join end
Source
# File lib/reline/line_editor.rb, line 409 def render_line_differential(old_items, new_items) old_levels = calculate_overlay_levels(old_items.zip(new_items).each_with_index.map {|((x, w, c), (nx, _nw, nc)), i| [x, w, c == nc && x == nx ? i : -1] if x }.compact) new_levels = calculate_overlay_levels(new_items.each_with_index.map { |(x, w), i| [x, w, i] if x }.compact).take(screen_width) base_x = 0 new_levels.zip(old_levels).chunk { |n, o| n == o ? :skip : n || :blank }.each do |level, chunk| width = chunk.size if level == :skip # do nothing elsif level == :blank Reline::IOGate.move_cursor_column base_x @output.write "#{Reline::IOGate.reset_color_sequence}#{' ' * width}" else x, w, content = new_items[level] cover_begin = base_x != 0 && new_levels[base_x - 1] == level cover_end = new_levels[base_x + width] == level pos = 0 unless x == base_x && w == width content, pos = Reline::Unicode.take_mbchar_range(content, base_x - x, width, cover_begin: cover_begin, cover_end: cover_end, padding: true) end Reline::IOGate.move_cursor_column x + pos @output.write "#{Reline::IOGate.reset_color_sequence}#{content}#{Reline::IOGate.reset_color_sequence}" end base_x += width end if old_levels.size > new_levels.size Reline::IOGate.move_cursor_column new_levels.size Reline::IOGate.erase_after_cursor end end
Source
# File lib/reline/line_editor.rb, line 563 def rerender render unless @in_pasting end
Source
# File lib/reline/line_editor.rb, line 143 def reset(prompt = '') @screen_size = Reline::IOGate.get_screen_size reset_variables(prompt) @rendered_screen.base_y = Reline::IOGate.cursor_pos.y if ENV.key?('RELINE_ALT_SCROLLBAR') @full_block = '::' @upper_half_block = "''" @lower_half_block = '..' @block_elem_width = 2 elsif Reline::IOGate.win? @full_block = '█' @upper_half_block = '▀' @lower_half_block = '▄' @block_elem_width = 1 elsif encoding == Encoding::UTF_8 @full_block = '█' @upper_half_block = '▀' @lower_half_block = '▄' @block_elem_width = Reline::Unicode.calculate_width('█') else @full_block = '::' @upper_half_block = "''" @lower_half_block = '..' @block_elem_width = 2 end end
Source
# File lib/reline/line_editor.rb, line 263 def reset_line @byte_pointer = 0 @buffer_of_lines = [String.new(encoding: encoding)] @line_index = 0 @cache.clear @line_backup_in_history = nil @multibyte_buffer = String.new(encoding: 'ASCII-8BIT') end
Source
# File lib/reline/line_editor.rb, line 226 def reset_variables(prompt = '') @prompt = prompt.gsub("\n", "\\n") @mark_pointer = nil @is_multiline = false @finished = false @history_pointer = nil @kill_ring ||= Reline::KillRing.new @vi_clipboard = '' @vi_arg = nil @waiting_proc = nil @vi_waiting_operator = nil @vi_waiting_operator_arg = nil @completion_journey_state = nil @completion_state = CompletionState::NORMAL @perfect_matched = nil @menu_info = nil @searching_prompt = nil @just_cursor_moving = false @eof = false @continuous_insertion_buffer = String.new(encoding: encoding) @scroll_partial_screen = 0 @drop_terminate_spaces = false @in_pasting = false @auto_indent_proc = nil @dialogs = [] @interrupted = false @resized = false @cache = {} @rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0) @input_lines = [[[""], 0, 0]] @input_lines_position = 0 @undoing = false @prev_action_state = NullActionState @next_action_state = NullActionState reset_line end
Source
# File lib/reline/line_editor.rb, line 559 def rest_height(wrapped_cursor_y) screen_height - wrapped_cursor_y + screen_scroll_top - @rendered_screen.base_y - 1 end
Source
# File lib/reline/line_editor.rb, line 1259 def retrieve_completion_block(set_completion_quote_character = false) if Reline.completer_word_break_characters.empty? word_break_regexp = nil else word_break_regexp = /\A[#{Regexp.escape(Reline.completer_word_break_characters)}]/ end if Reline.completer_quote_characters.empty? quote_characters_regexp = nil else quote_characters_regexp = /\A[#{Regexp.escape(Reline.completer_quote_characters)}]/ end before = current_line.byteslice(0, @byte_pointer) rest = nil break_pointer = nil quote = nil closing_quote = nil escaped_quote = nil i = 0 while i < @byte_pointer do slice = current_line.byteslice(i, @byte_pointer - i) unless slice.valid_encoding? i += 1 next end if quote and slice.start_with?(closing_quote) quote = nil i += 1 rest = nil elsif quote and slice.start_with?(escaped_quote) # skip i += 2 elsif quote_characters_regexp and slice =~ quote_characters_regexp # find new " rest = $' quote = $& closing_quote = /(?!\\)#{Regexp.escape(quote)}/ escaped_quote = /\\#{Regexp.escape(quote)}/ i += 1 break_pointer = i - 1 elsif word_break_regexp and not quote and slice =~ word_break_regexp rest = $' i += 1 before = current_line.byteslice(i, @byte_pointer - i) break_pointer = i else i += 1 end end postposing = current_line.byteslice(@byte_pointer, current_line.bytesize - @byte_pointer) if rest preposing = current_line.byteslice(0, break_pointer) target = rest if set_completion_quote_character and quote Reline.core.instance_variable_set(:@completion_quote_character, quote) if postposing !~ /(?!\\)#{Regexp.escape(quote)}/ # closing quote insert_text(quote) end end else preposing = '' if break_pointer preposing = current_line.byteslice(0, break_pointer) else preposing = '' end target = before end lines = whole_lines if @line_index > 0 preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing end if (lines.size - 1) > @line_index postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n") end [preposing.encode(encoding), target.encode(encoding), postposing.encode(encoding)] end
Source
# File lib/reline/line_editor.rb, line 1148 def save_old_buffer @old_buffer_of_lines = @buffer_of_lines.dup end
Source
# File lib/reline/line_editor.rb, line 366 def screen_height @screen_size.first end
Source
# File lib/reline/line_editor.rb, line 374 def screen_scroll_top @scroll_partial_screen end
Source
# File lib/reline/line_editor.rb, line 370 def screen_width @screen_size.last end
Source
# File lib/reline/line_editor.rb, line 1171 def scroll_into_view _wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position if wrapped_cursor_y < screen_scroll_top @scroll_partial_screen = wrapped_cursor_y end if wrapped_cursor_y >= screen_scroll_top + screen_height @scroll_partial_screen = wrapped_cursor_y - screen_height + 1 end end
Source
# File lib/reline/line_editor.rb, line 1236 def set_current_line(line, byte_pointer = nil) cursor = current_byte_pointer_cursor @buffer_of_lines[@line_index] = line if byte_pointer @byte_pointer = byte_pointer else calculate_nearest_cursor(cursor) end process_auto_indent end
Source
# File lib/reline/line_editor.rb, line 1247 def set_current_lines(lines, byte_pointer = nil, line_index = 0) cursor = current_byte_pointer_cursor @buffer_of_lines = lines @line_index = line_index if byte_pointer @byte_pointer = byte_pointer else calculate_nearest_cursor(cursor) end process_auto_indent end
Source
# File lib/reline/line_editor.rb, line 90 def set_pasting_state(in_pasting) # While pasting, text to be inserted is stored to @continuous_insertion_buffer. # After pasting, this buffer should be force inserted. process_insert(force: true) if @in_pasting && !in_pasting @in_pasting = in_pasting end
Source
# File lib/reline/line_editor.rb, line 209 def set_signal_handlers Reline::IOGate.set_winch_handler do @resized = true end @old_trap = Signal.trap('INT') do @interrupted = true end end
Source
# File lib/reline/line_editor.rb, line 1164 def trim_input_lines if @input_lines.size > MAX_INPUT_LINES @input_lines.shift @input_lines_position -= 1 end end
Source
# File lib/reline/line_editor.rb, line 1092 def update(key) modified = input_key(key) unless @in_pasting scroll_into_view @just_cursor_moving = !modified update_dialogs(key) @just_cursor_moving = false end end
Source
# File lib/reline/line_editor.rb, line 456 def update_dialogs(key = nil) wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position @dialogs.each do |dialog| dialog.trap_key = nil update_each_dialog(dialog, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top, key) end end
Source
# File lib/reline/line_editor.rb, line 555 def upper_space_height(wrapped_cursor_y) wrapped_cursor_y - screen_scroll_top end
Source
# File lib/reline/line_editor.rb, line 1404 def whole_buffer whole_lines.join("\n") end
Source
# File lib/reline/line_editor.rb, line 1400 def whole_lines @buffer_of_lines.dup end
Source
# File lib/reline/line_editor.rb, line 346 def with_cache(key, *deps) cached_deps, value = @cache[key] if cached_deps != deps @cache[key] = [deps, value = yield(*deps, cached_deps, value)] end value end
Source
# File lib/reline/line_editor.rb, line 978 def wrap_method_call(method_symbol, method_obj, key, with_operator = false) if @config.editing_mode_is?(:emacs, :vi_insert) and @vi_waiting_operator.nil? not_insertion = method_symbol != :ed_insert process_insert(force: not_insertion) end if @vi_arg and argumentable?(method_obj) if with_operator and inclusive?(method_obj) method_obj.(key, arg: @vi_arg, inclusive: true) else method_obj.(key, arg: @vi_arg) end else if with_operator and inclusive?(method_obj) method_obj.(key, inclusive: true) else method_obj.(key) end end end
Source
# File lib/reline/line_editor.rb, line 440 def wrapped_cursor_position prompt_width = calculate_width(prompt_list[@line_index], true) line_before_cursor = whole_lines[@line_index].byteslice(0, @byte_pointer) wrapped_line_before_cursor = split_by_width(' ' * prompt_width + line_before_cursor, screen_width).first.compact wrapped_cursor_y = wrapped_prompt_and_input_lines[0...@line_index].sum(&:size) + wrapped_line_before_cursor.size - 1 wrapped_cursor_x = calculate_width(wrapped_line_before_cursor.last) [wrapped_cursor_x, wrapped_cursor_y] end
Calculate cursor position in word wrapped content.
Source
# File lib/reline/line_editor.rb, line 378 def wrapped_prompt_and_input_lines with_cache(__method__, @buffer_of_lines.size, modified_lines, prompt_list, screen_width) do |n, lines, prompts, width, prev_cache_key, cached_value| prev_n, prev_lines, prev_prompts, prev_width = prev_cache_key cached_wraps = {} if prev_width == width prev_n.times do |i| cached_wraps[[prev_prompts[i], prev_lines[i]]] = cached_value[i] end end n.times.map do |i| prompt = prompts[i] || '' line = lines[i] || '' if (cached = cached_wraps[[prompt, line]]) next cached end *wrapped_prompts, code_line_prompt = split_by_width(prompt, width).first.compact wrapped_lines = split_by_width(line, width, offset: calculate_width(code_line_prompt, true)).first.compact wrapped_prompts.map { |p| [p, ''] } + [[code_line_prompt, wrapped_lines.first]] + wrapped_lines.drop(1).map { |c| ['', c] } end end end
Private Instance Methods
Source
# File lib/reline/line_editor.rb, line 968 def argumentable?(method_obj) method_obj and method_obj.parameters.any? { |param| param[0] == :key and param[1] == :arg } end
Source
# File lib/reline/line_editor.rb, line 1408 def buffer_empty? current_line.empty? and @buffer_of_lines.size == 1 end
Source
# File lib/reline/line_editor.rb, line 1427 def byteinsert(str, byte_pointer, other) new_str = str.byteslice(0, byte_pointer) new_str << other new_str << str.byteslice(byte_pointer, str.bytesize) new_str end
Source
# File lib/reline/line_editor.rb, line 1421 def byteslice!(str, byte_pointer, size) new_str = str.byteslice(0, byte_pointer) new_str << str.byteslice(byte_pointer + size, str.bytesize) [new_str, str.byteslice(byte_pointer, size)] end
Source
# File lib/reline/line_editor.rb, line 311 def calculate_nearest_cursor(cursor) line_to_calc = current_line new_cursor_max = calculate_width(line_to_calc) new_cursor = 0 new_byte_pointer = 0 height = 1 max_width = screen_width if @config.editing_mode_is?(:vi_command) last_byte_size = Reline::Unicode.get_prev_mbchar_size(line_to_calc, line_to_calc.bytesize) if last_byte_size > 0 last_mbchar = line_to_calc.byteslice(line_to_calc.bytesize - last_byte_size, last_byte_size) last_width = Reline::Unicode.get_mbchar_width(last_mbchar) end_of_line_cursor = new_cursor_max - last_width else end_of_line_cursor = new_cursor_max end else end_of_line_cursor = new_cursor_max end line_to_calc.grapheme_clusters.each do |gc| mbchar = gc.encode(Encoding::UTF_8) mbchar_width = Reline::Unicode.get_mbchar_width(mbchar) now = new_cursor + mbchar_width if now > end_of_line_cursor or now > cursor break end new_cursor += mbchar_width if new_cursor > max_width * height height += 1 end new_byte_pointer += gc.bytesize end @byte_pointer = new_byte_pointer end
Source
# File lib/reline/line_editor.rb, line 1434 def calculate_width(str, allow_escape_code = false) Reline::Unicode.calculate_width(str, allow_escape_code) end
Source
# File lib/reline/line_editor.rb, line 97 def check_mode_string if @config.show_mode_in_prompt if @config.editing_mode_is?(:vi_command) @config.vi_cmd_mode_string elsif @config.editing_mode_is?(:vi_insert) @config.vi_ins_mode_string elsif @config.editing_mode_is?(:emacs) @config.emacs_mode_string else '?' end end end
Source
# File lib/reline/line_editor.rb, line 111 def check_multiline_prompt(buffer, mode_string) if @vi_arg prompt = "(arg: #{@vi_arg}) " elsif @searching_prompt prompt = @searching_prompt else prompt = @prompt end if !@is_multiline mode_string = check_mode_string prompt = mode_string + prompt if mode_string [prompt] + [''] * (buffer.size - 1) elsif @prompt_proc prompt_list = @prompt_proc.(buffer).map { |pr| pr.gsub("\n", "\\n") } prompt_list.map!{ prompt } if @vi_arg or @searching_prompt prompt_list = [prompt] if prompt_list.empty? prompt_list = prompt_list.map{ |pr| mode_string + pr } if mode_string prompt = prompt_list[@line_index] prompt = prompt_list[0] if prompt.nil? prompt = prompt_list.last if prompt.nil? if buffer.size > prompt_list.size (buffer.size - prompt_list.size).times do prompt_list << prompt_list.last end end prompt_list else prompt = mode_string + prompt if mode_string [prompt] * buffer.size end end
Source
# File lib/reline/line_editor.rb, line 998 def cleanup_waiting @waiting_proc = nil @vi_waiting_operator = nil @vi_waiting_operator_arg = nil @searching_prompt = nil @drop_terminate_spaces = false end
Source
# File lib/reline/line_editor.rb, line 550 def clear_rendered_screen_cache @rendered_screen.lines = [] @rendered_screen.cursor_y = 0 end
Source
# File lib/reline/line_editor.rb, line 1454 def complete(_key) return if @config.disable_completion process_insert(force: true) if @config.autocompletion @completion_state = CompletionState::NORMAL @completion_occurs = move_completed_list(:down) else @completion_journey_state = nil result = call_completion_proc if result.is_a?(Array) @completion_occurs = true perform_completion(result, false) end end end
Source
# File lib/reline/line_editor.rb, line 807 def complete_internal_proc(list, is_menu) preposing, target, postposing = retrieve_completion_block candidates = list.select { |i| if i and not Encoding.compatible?(target.encoding, i.encoding) raise Encoding::CompatibilityError, "#{target.encoding.name} is not compatible with #{i.encoding.name}" end if @config.completion_ignore_case i&.downcase&.start_with?(target.downcase) else i&.start_with?(target) end }.uniq if is_menu menu(target, candidates) return nil end completed = candidates.inject { |memo, item| begin memo_mbchars = memo.unicode_normalize.grapheme_clusters item_mbchars = item.unicode_normalize.grapheme_clusters rescue Encoding::CompatibilityError memo_mbchars = memo.grapheme_clusters item_mbchars = item.grapheme_clusters end size = [memo_mbchars.size, item_mbchars.size].min result = +'' size.times do |i| if @config.completion_ignore_case if memo_mbchars[i].casecmp?(item_mbchars[i]) result << memo_mbchars[i] else break end else if memo_mbchars[i] == item_mbchars[i] result << memo_mbchars[i] else break end end end result } [target, preposing, completed, postposing, candidates] end
Source
# File lib/reline/line_editor.rb, line 1471 def completion_journey_move(direction) return if @config.disable_completion process_insert(force: true) @completion_state = CompletionState::NORMAL @completion_occurs = move_completed_list(direction) end
Source
# File lib/reline/line_editor.rb, line 1487 def completion_journey_up(_key) completion_journey_move(:up) if @config.autocompletion end
Source
# File lib/reline/line_editor.rb, line 2074 def copy_for_vi(text) if @config.editing_mode_is?(:vi_insert) or @config.editing_mode_is?(:vi_command) @vi_clipboard = text end end
Source
# File lib/reline/line_editor.rb, line 701 def dialog_range(dialog, dialog_y) x_range = dialog.column...dialog.column + dialog.width y_range = dialog_y + dialog.vertical_offset...dialog_y + dialog.vertical_offset + dialog.contents.size [x_range, y_range] end
Source
# File lib/reline/line_editor.rb, line 2327 def ed_argument_digit(key) if @vi_arg.nil? if key.chr.to_i.zero? if key.anybits?(0b10000000) unescaped_key = key ^ 0b10000000 unless unescaped_key.chr.to_i.zero? @vi_arg = unescaped_key.chr.to_i end end else @vi_arg = key.chr.to_i end else @vi_arg = @vi_arg * 10 + key.chr.to_i end end
Source
# File lib/reline/line_editor.rb, line 1954 def ed_clear_screen(key) Reline::IOGate.clear_screen @screen_size = Reline::IOGate.get_screen_size @rendered_screen.base_y = 0 clear_rendered_screen_cache end
Source
# File lib/reline/line_editor.rb, line 2273 def ed_delete_next_char(key, arg: 1) byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer) unless current_line.empty? || byte_size == 0 line, mbchar = byteslice!(current_line, @byte_pointer, byte_size) copy_for_vi(mbchar) if @byte_pointer > 0 && current_line.bytesize == @byte_pointer + byte_size byte_size = Reline::Unicode.get_prev_mbchar_size(line, @byte_pointer) set_current_line(line, @byte_pointer - byte_size) else set_current_line(line, @byte_pointer) end end arg -= 1 ed_delete_next_char(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 2185 def ed_delete_prev_char(key, arg: 1) deleted = +'' arg.times do if @byte_pointer > 0 byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer) @byte_pointer -= byte_size line, mbchar = byteslice!(current_line, @byte_pointer, byte_size) set_current_line(line) deleted.prepend(mbchar) end end copy_for_vi(deleted) end
Source
# File lib/reline/line_editor.rb, line 1988 def ed_delete_prev_word(key) if @byte_pointer > 0 byte_size, _ = Reline::Unicode.em_backward_word(current_line, @byte_pointer) line, word = byteslice!(current_line, @byte_pointer - byte_size, byte_size) set_current_line(line, @byte_pointer - byte_size) @kill_ring.append(word, true) end end
Source
# File lib/reline/line_editor.rb, line 1514 def ed_insert(key) if key.instance_of?(String) begin key.encode(Encoding::UTF_8) rescue Encoding::UndefinedConversionError return end str = key else begin key.chr.encode(Encoding::UTF_8) rescue Encoding::UndefinedConversionError return end str = key.chr end if @in_pasting @continuous_insertion_buffer << str return elsif not @continuous_insertion_buffer.empty? process_insert end insert_text(str) end
- Editline
-
ed-insert
(vi input: almost all; emacs: printable characters) In insert mode, insert the input character left of the cursor position. In replace mode, overwrite the character at the cursor and move the cursor to the right by one character position. Accept an argument to do this repeatedly. It is an error if the input character is the NUL character (Ctrl-@
). Failure to enlarge the edit buffer also results in an error. - Editline
-
ed-digit
(emacs: 0 to 9) If in argument input mode, append the input digit to the argument being read. Otherwise, called-insert
. It is an error if the input character is not a digit or if the existing argument is already greater than a million. - GNU
Readline
-
self-insert
(a, b, A, 1, !, …) Insert yourself.
Source
# File lib/reline/line_editor.rb, line 1867 def ed_kill_line(key) if current_line.bytesize > @byte_pointer line, deleted = byteslice!(current_line, @byte_pointer, current_line.bytesize - @byte_pointer) set_current_line(line, line.bytesize) @kill_ring.append(deleted) elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1 set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize) end end
- Editline
-
ed-kill-line
(vi command:D
,Ctrl-K
; emacs:Ctrl-K
,Ctrl-U
) + Kill from the cursor to the end of the line. - GNU
Readline
-
kill-line
(C-k
) Kill the text from point to the end of the line. With a negative numeric argument, kill backward from the cursor to the beginning of the current line.
Source
# File lib/reline/line_editor.rb, line 1588 def ed_move_to_beg(key) @byte_pointer = 0 end
Source
# File lib/reline/line_editor.rb, line 1594 def ed_move_to_end(key) @byte_pointer = current_line.bytesize end
Source
# File lib/reline/line_editor.rb, line 1817 def ed_newline(key) process_insert(force: true) if @is_multiline if @config.editing_mode_is?(:vi_command) if @line_index < (@buffer_of_lines.size - 1) ed_next_history(key) # means cursor down else # should check confirm_multiline_termination to finish? finish end else if @line_index == (@buffer_of_lines.size - 1) if confirm_multiline_termination finish else key_newline(key) end else # should check confirm_multiline_termination to finish? @line_index = @buffer_of_lines.size - 1 @byte_pointer = current_line.bytesize finish end end else finish end end
Source
# File lib/reline/line_editor.rb, line 1558 def ed_next_char(key, arg: 1) byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer) if (@byte_pointer < current_line.bytesize) @byte_pointer += byte_size elsif @config.editing_mode_is?(:emacs) and @byte_pointer == current_line.bytesize and @line_index < @buffer_of_lines.size - 1 @byte_pointer = 0 @line_index += 1 end arg -= 1 ed_next_char(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 1800 def ed_next_history(key, arg: 1) if @line_index < (@buffer_of_lines.size - 1) cursor = current_byte_pointer_cursor @line_index += 1 calculate_nearest_cursor(cursor) return end move_history( (@history_pointer || Reline::HISTORY.size) + 1, line: :start, cursor: @config.editing_mode_is?(:vi_command) ? :start : :end, ) arg -= 1 ed_next_history(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 1571 def ed_prev_char(key, arg: 1) if @byte_pointer > 0 byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer) @byte_pointer -= byte_size elsif @config.editing_mode_is?(:emacs) and @byte_pointer == 0 and @line_index > 0 @line_index -= 1 @byte_pointer = current_line.bytesize end arg -= 1 ed_prev_char(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 1783 def ed_prev_history(key, arg: 1) if @line_index > 0 cursor = current_byte_pointer_cursor @line_index -= 1 calculate_nearest_cursor(cursor) return end move_history( (@history_pointer || Reline::HISTORY.size) - 1, line: :end, cursor: @config.editing_mode_is?(:vi_command) ? :start : :end, ) arg -= 1 ed_prev_history(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 1970 def ed_prev_word(key) if @byte_pointer > 0 byte_size, _ = Reline::Unicode.em_backward_word(current_line, @byte_pointer) @byte_pointer -= byte_size end end
Source
# File lib/reline/line_editor.rb, line 1542 def ed_quoted_insert(str, arg: 1) @waiting_proc = proc { |key| arg.times do if key == "\C-j".ord or key == "\C-m".ord key_newline(key) elsif key == 0 # Ignore NUL. else ed_insert(key) end end @waiting_proc = nil } end
Source
# File lib/reline/line_editor.rb, line 1746 def ed_search_next_history(key, arg: 1) substr = prev_action_state_value(:search_history) == :empty ? '' : current_line.byteslice(0, @byte_pointer) return if @history_pointer.nil? history_range = @history_pointer + 1...Reline::HISTORY.size h_pointer, line_index = search_history(substr, history_range) return if h_pointer.nil? and not substr.empty? move_history(h_pointer, line: line_index || :start, cursor: substr.empty? ? :end : @byte_pointer) arg -= 1 set_next_action_state(:search_history, :empty) if substr.empty? ed_search_next_history(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 1731 def ed_search_prev_history(key, arg: 1) substr = prev_action_state_value(:search_history) == :empty ? '' : current_line.byteslice(0, @byte_pointer) return if @history_pointer == 0 return if @history_pointer.nil? && substr.empty? && !current_line.empty? history_range = 0...(@history_pointer || Reline::HISTORY.size) h_pointer, line_index = search_history(substr, history_range.reverse_each) return unless h_pointer move_history(h_pointer, line: line_index || :start, cursor: substr.empty? ? :end : @byte_pointer) arg -= 1 set_next_action_state(:search_history, :empty) if substr.empty? ed_search_prev_history(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 1998 def ed_transpose_chars(key) if @byte_pointer > 0 if @byte_pointer < current_line.bytesize byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer) @byte_pointer += byte_size end back1_byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer) if (@byte_pointer - back1_byte_size) > 0 back2_byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer - back1_byte_size) back2_pointer = @byte_pointer - back1_byte_size - back2_byte_size line, back2_mbchar = byteslice!(current_line, back2_pointer, back2_byte_size) set_current_line(byteinsert(line, @byte_pointer - back2_byte_size, back2_mbchar)) end end end
Source
# File lib/reline/line_editor.rb, line 2015 def ed_transpose_words(key) left_word_start, middle_start, right_word_start, after_start = Reline::Unicode.ed_transpose_words(current_line, @byte_pointer) before = current_line.byteslice(0, left_word_start) left_word = current_line.byteslice(left_word_start, middle_start - left_word_start) middle = current_line.byteslice(middle_start, right_word_start - middle_start) right_word = current_line.byteslice(right_word_start, after_start - right_word_start) after = current_line.byteslice(after_start, current_line.bytesize - after_start) return if left_word.empty? or right_word.empty? from_head_to_left_word = before + right_word + middle + left_word set_current_line(from_head_to_left_word + after, from_head_to_left_word.bytesize) end
Source
# File lib/reline/line_editor.rb, line 1493 def ed_unassigned(key) end
- Editline
-
ed-unassigned
This editor command always results in an error. - GNU
Readline
-
There is no corresponding macro.
Source
# File lib/reline/line_editor.rb, line 2028 def em_capitol_case(key) if current_line.bytesize > @byte_pointer byte_size, _, new_str = Reline::Unicode.em_forward_word_with_capitalization(current_line, @byte_pointer) before = current_line.byteslice(0, @byte_pointer) after = current_line.byteslice((@byte_pointer + byte_size)..-1) set_current_line(before + new_str + after, @byte_pointer + new_str.bytesize) end end
Source
# File lib/reline/line_editor.rb, line 1911 def em_delete(key) if buffer_empty? and key == "\C-d".ord @eof = true finish elsif @byte_pointer < current_line.bytesize splitted_last = current_line.byteslice(@byte_pointer, current_line.bytesize) mbchar = splitted_last.grapheme_clusters.first line, = byteslice!(current_line, @byte_pointer, mbchar.bytesize) set_current_line(line) elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1 set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize) end end
Source
# File lib/reline/line_editor.rb, line 1978 def em_delete_next_word(key) if current_line.bytesize > @byte_pointer byte_size, _ = Reline::Unicode.em_forward_word(current_line, @byte_pointer) line, word = byteslice!(current_line, @byte_pointer, byte_size) set_current_line(line) @kill_ring.append(word) end end
Source
# File lib/reline/line_editor.rb, line 1926 def em_delete_or_list(key) if current_line.empty? or @byte_pointer < current_line.bytesize em_delete(key) elsif !@config.autocompletion # show completed list result = call_completion_proc if result.is_a?(Array) perform_completion(result, true) end end end
Source
# File lib/reline/line_editor.rb, line 1846 def em_delete_prev_char(key, arg: 1) arg.times do if @byte_pointer == 0 and @line_index > 0 @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index) @line_index -= 1 elsif @byte_pointer > 0 byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer) line, = byteslice!(current_line, @byte_pointer - byte_size, byte_size) set_current_line(line, @byte_pointer - byte_size) end end process_auto_indent end
Source
# File lib/reline/line_editor.rb, line 2489 def em_exchange_mark(key) return unless @mark_pointer new_pointer = [@byte_pointer, @line_index] @byte_pointer, @line_index = @mark_pointer @mark_pointer = new_pointer end
Source
# File lib/reline/line_editor.rb, line 1903 def em_kill_line(key) if current_line.size > 0 @kill_ring.append(current_line.dup, true) set_current_line('', 0) end end
- Editline
-
em-kill-line
(not bound) Delete the entire contents of the edit buffer and save it to the cut buffer.vi-kill-line-prev
- GNU
Readline
-
kill-whole-line
(not bound) Kill all characters on the current line, no matter where point is.
Source
# File lib/reline/line_editor.rb, line 2064 def em_kill_region(key) if @byte_pointer > 0 byte_size, _ = Reline::Unicode.em_big_backward_word(current_line, @byte_pointer) line, deleted = byteslice!(current_line, @byte_pointer - byte_size, byte_size) set_current_line(line, @byte_pointer - byte_size) @kill_ring.append(deleted, true) end end
Source
# File lib/reline/line_editor.rb, line 2038 def em_lower_case(key) if current_line.bytesize > @byte_pointer byte_size, = Reline::Unicode.em_forward_word(current_line, @byte_pointer) part = current_line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar| mbchar =~ /[A-Z]/ ? mbchar.downcase : mbchar }.join rest = current_line.byteslice((@byte_pointer + byte_size)..-1) line = current_line.byteslice(0, @byte_pointer) + part set_current_line(line + rest, line.bytesize) end end
Source
# File lib/reline/line_editor.rb, line 1962 def em_next_word(key) if current_line.bytesize > @byte_pointer byte_size, _ = Reline::Unicode.em_forward_word(current_line, @byte_pointer) @byte_pointer += byte_size end end
Source
# File lib/reline/line_editor.rb, line 2484 def em_set_mark(key) @mark_pointer = [@byte_pointer, @line_index] end
Source
# File lib/reline/line_editor.rb, line 2051 def em_upper_case(key) if current_line.bytesize > @byte_pointer byte_size, = Reline::Unicode.em_forward_word(current_line, @byte_pointer) part = current_line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar| mbchar =~ /[a-z]/ ? mbchar.upcase : mbchar }.join rest = current_line.byteslice((@byte_pointer + byte_size)..-1) line = current_line.byteslice(0, @byte_pointer) + part set_current_line(line + rest, line.bytesize) end end
Source
# File lib/reline/line_editor.rb, line 1938 def em_yank(key) yanked = @kill_ring.yank insert_text(yanked) if yanked end
Source
# File lib/reline/line_editor.rb, line 1944 def em_yank_pop(key) yanked, prev_yank = @kill_ring.yank_pop if yanked line, = byteslice!(current_line, @byte_pointer - prev_yank.bytesize, prev_yank.bytesize) set_current_line(line, @byte_pointer - prev_yank.bytesize) insert_text(yanked) end end
Source
# File lib/reline/line_editor.rb, line 2497 def emacs_editing_mode(key) @config.editing_mode = :emacs end
Source
# File lib/reline/line_editor.rb, line 1599 def generate_searcher(search_key) search_word = String.new(encoding: encoding) multibyte_buf = String.new(encoding: 'ASCII-8BIT') hit_pointer = nil lambda do |key| search_again = false case key when "\C-h".ord, "\C-?".ord grapheme_clusters = search_word.grapheme_clusters if grapheme_clusters.size > 0 grapheme_clusters.pop search_word = grapheme_clusters.join end when "\C-r".ord, "\C-s".ord search_again = true if search_key == key search_key = key else multibyte_buf << key if multibyte_buf.dup.force_encoding(encoding).valid_encoding? search_word << multibyte_buf.dup.force_encoding(encoding) multibyte_buf.clear end end hit = nil if not search_word.empty? and @line_backup_in_history&.include?(search_word) hit_pointer = Reline::HISTORY.size hit = @line_backup_in_history else if search_again if search_word.empty? and Reline.last_incremental_search search_word = Reline.last_incremental_search end if @history_pointer case search_key when "\C-r".ord history_pointer_base = 0 history = Reline::HISTORY[0..(@history_pointer - 1)] when "\C-s".ord history_pointer_base = @history_pointer + 1 history = Reline::HISTORY[(@history_pointer + 1)..-1] end else history_pointer_base = 0 history = Reline::HISTORY end elsif @history_pointer case search_key when "\C-r".ord history_pointer_base = 0 history = Reline::HISTORY[0..@history_pointer] when "\C-s".ord history_pointer_base = @history_pointer history = Reline::HISTORY[@history_pointer..-1] end else history_pointer_base = 0 history = Reline::HISTORY end case search_key when "\C-r".ord hit_index = history.rindex { |item| item.include?(search_word) } when "\C-s".ord hit_index = history.index { |item| item.include?(search_word) } end if hit_index hit_pointer = history_pointer_base + hit_index hit = Reline::HISTORY[hit_pointer] end end case search_key when "\C-r".ord prompt_name = 'reverse-i-search' when "\C-s".ord prompt_name = 'i-search' end prompt_name = "failed #{prompt_name}" unless hit [search_word, prompt_name, hit_pointer] end end
Source
# File lib/reline/line_editor.rb, line 187 def handle_interrupted return unless @interrupted @interrupted = false clear_dialogs render cursor_to_bottom_offset = @rendered_screen.lines.size - @rendered_screen.cursor_y Reline::IOGate.scroll_down cursor_to_bottom_offset Reline::IOGate.move_cursor_column 0 clear_rendered_screen_cache case @old_trap when 'DEFAULT', 'SYSTEM_DEFAULT' raise Interrupt when 'IGNORE' # Do nothing when 'EXIT' exit else @old_trap.call if @old_trap.respond_to?(:call) end end
Source
# File lib/reline/line_editor.rb, line 175 def handle_resized return unless @resized @screen_size = Reline::IOGate.get_screen_size @resized = false scroll_into_view Reline::IOGate.move_cursor_up @rendered_screen.cursor_y @rendered_screen.base_y = Reline::IOGate.cursor_pos.y clear_rendered_screen_cache render end
Source
# File lib/reline/line_editor.rb, line 972 def inclusive?(method_obj) # If a motion method with the keyword argument "inclusive" follows the # operator, it must contain the character at the cursor position. method_obj and method_obj.parameters.any? { |param| param[0] == :key and param[1] == :inclusive } end
Source
# File lib/reline/line_editor.rb, line 1683 def incremental_search_history(key) backup = @buffer_of_lines.dup, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history searcher = generate_searcher(key) @searching_prompt = "(reverse-i-search)`': " termination_keys = ["\C-j".ord] termination_keys.concat(@config.isearch_terminators.chars.map(&:ord)) if @config.isearch_terminators @waiting_proc = ->(k) { chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT) if k == "\C-g".ord # cancel search and restore buffer @buffer_of_lines, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history = backup @searching_prompt = nil @waiting_proc = nil elsif !termination_keys.include?(k) && (chr.match?(/[[:print:]]/) || k == "\C-h".ord || k == "\C-?".ord || k == "\C-r".ord || k == "\C-s".ord) search_word, prompt_name, hit_pointer = searcher.call(k) Reline.last_incremental_search = search_word @searching_prompt = "(%s)`%s'" % [prompt_name, search_word] @searching_prompt += ': ' unless @is_multiline move_history(hit_pointer, line: :end, cursor: :end) if hit_pointer else # terminaton_keys and other keys will terminalte move_history(@history_pointer, line: :end, cursor: :start) @searching_prompt = nil @waiting_proc = nil end } end
Source
# File lib/reline/line_editor.rb, line 280 def insert_new_line(cursor_line, next_line) @buffer_of_lines.insert(@line_index + 1, String.new(next_line, encoding: encoding)) @buffer_of_lines[@line_index] = cursor_line @line_index += 1 @byte_pointer = 0 if @auto_indent_proc && !@in_pasting if next_line.empty? ( # For compatibility, use this calculation instead of just `process_auto_indent @line_index - 1, cursor_dependent: false` indent1 = @auto_indent_proc.(@buffer_of_lines.take(@line_index - 1).push(''), @line_index - 1, 0, true) indent2 = @auto_indent_proc.(@buffer_of_lines.take(@line_index), @line_index - 1, @buffer_of_lines[@line_index - 1].bytesize, false) indent = indent2 || indent1 @buffer_of_lines[@line_index - 1] = ' ' * indent + @buffer_of_lines[@line_index - 1].gsub(/\A\s*/, '') ) process_auto_indent @line_index, add_newline: true else process_auto_indent @line_index - 1, cursor_dependent: false process_auto_indent @line_index, add_newline: true # Need for compatibility process_auto_indent @line_index, cursor_dependent: false end end end
Source
# File lib/reline/line_editor.rb, line 1438 def key_delete(key) if @config.editing_mode_is?(:vi_insert) ed_delete_next_char(key) elsif @config.editing_mode_is?(:emacs) em_delete(key) end end
Source
# File lib/reline/line_editor.rb, line 1446 def key_newline(key) if @is_multiline next_line = current_line.byteslice(@byte_pointer, current_line.bytesize - @byte_pointer) cursor_line = current_line.byteslice(0, @byte_pointer) insert_new_line(cursor_line, next_line) end end
Source
# File lib/reline/line_editor.rb, line 791 def modify_lines(before, complete) if after = @output_modifier_proc&.call("#{before.join("\n")}\n", complete: complete) after.lines("\n").map { |l| l.chomp('') } else before.map { |l| Reline::Unicode.escape_for_print(l) } end end
Source
# File lib/reline/line_editor.rb, line 917 def move_completed_list(direction) @completion_journey_state ||= retrieve_completion_journey_state return false unless @completion_journey_state if (delta = { up: -1, down: +1 }[direction]) @completion_journey_state.pointer = (@completion_journey_state.pointer + delta) % @completion_journey_state.list.size end completed = @completion_journey_state.list[@completion_journey_state.pointer] set_current_line(@completion_journey_state.pre + completed + @completion_journey_state.post, @completion_journey_state.pre.bytesize + completed.bytesize) true end
Source
# File lib/reline/line_editor.rb, line 1761 def move_history(history_pointer, line:, cursor:) history_pointer ||= Reline::HISTORY.size return if history_pointer < 0 || history_pointer > Reline::HISTORY.size old_history_pointer = @history_pointer || Reline::HISTORY.size if old_history_pointer == Reline::HISTORY.size @line_backup_in_history = whole_buffer else Reline::HISTORY[old_history_pointer] = whole_buffer end if history_pointer == Reline::HISTORY.size buf = @line_backup_in_history @history_pointer = @line_backup_in_history = nil else buf = Reline::HISTORY[history_pointer] @history_pointer = history_pointer end @buffer_of_lines = buf.split("\n") @buffer_of_lines = [String.new(encoding: encoding)] if @buffer_of_lines.empty? @line_index = line == :start ? 0 : line == :end ? @buffer_of_lines.size - 1 : line @byte_pointer = cursor == :start ? 0 : cursor == :end ? current_line.bytesize : cursor end
Source
# File lib/reline/line_editor.rb, line 1070 def normal_char(key) @multibyte_buffer << key.combined_char if @multibyte_buffer.size > 1 if @multibyte_buffer.dup.force_encoding(encoding).valid_encoding? process_key(@multibyte_buffer.dup.force_encoding(encoding), nil) @multibyte_buffer.clear else # invalid return end else # single byte return if key.char >= 128 # maybe, first byte of multi byte method_symbol = @config.editing_mode.get_method(key.combined_char) process_key(key.combined_char, method_symbol) @multibyte_buffer.clear end if @config.editing_mode_is?(:vi_command) and @byte_pointer > 0 and @byte_pointer == current_line.bytesize byte_size = Reline::Unicode.get_prev_mbchar_size(@buffer_of_lines[@line_index], @byte_pointer) @byte_pointer -= byte_size end end
Source
# File lib/reline/line_editor.rb, line 854 def perform_completion(list, just_show_list) case @completion_state when CompletionState::NORMAL @completion_state = CompletionState::COMPLETION when CompletionState::PERFECT_MATCH if @dig_perfect_match_proc @dig_perfect_match_proc.(@perfect_matched) else @completion_state = CompletionState::COMPLETION end end if just_show_list is_menu = true elsif @completion_state == CompletionState::MENU is_menu = true elsif @completion_state == CompletionState::MENU_WITH_PERFECT_MATCH is_menu = true else is_menu = false end result = complete_internal_proc(list, is_menu) if @completion_state == CompletionState::MENU_WITH_PERFECT_MATCH @completion_state = CompletionState::PERFECT_MATCH end return if result.nil? target, preposing, completed, postposing, candidates = result return if completed.nil? if target <= completed and (@completion_state == CompletionState::COMPLETION) append_character = '' if candidates.include?(completed) if candidates.one? append_character = completion_append_character.to_s @completion_state = CompletionState::PERFECT_MATCH else @completion_state = CompletionState::MENU_WITH_PERFECT_MATCH perform_completion(candidates, true) if @config.show_all_if_ambiguous end @perfect_matched = completed else @completion_state = CompletionState::MENU perform_completion(candidates, true) if @config.show_all_if_ambiguous end unless just_show_list @buffer_of_lines[@line_index] = (preposing + completed + append_character + postposing).split("\n")[@line_index] || String.new(encoding: encoding) line_to_pointer = (preposing + completed + append_character).split("\n")[@line_index] || String.new(encoding: encoding) @byte_pointer = line_to_pointer.bytesize end end end
Source
# File lib/reline/line_editor.rb, line 2525 def prev_action_state_value(type) @prev_action_state[0] == type ? @prev_action_state[1] : nil end
Source
# File lib/reline/line_editor.rb, line 1211 def process_auto_indent(line_index = @line_index, cursor_dependent: true, add_newline: false) return if @in_pasting return unless @auto_indent_proc line = @buffer_of_lines[line_index] byte_pointer = cursor_dependent && @line_index == line_index ? @byte_pointer : line.bytesize new_indent = @auto_indent_proc.(@buffer_of_lines.take(line_index + 1).push(''), line_index, byte_pointer, add_newline) return unless new_indent new_line = ' ' * new_indent + line.lstrip @buffer_of_lines[line_index] = new_line if @line_index == line_index indent_diff = new_line.bytesize - line.bytesize @byte_pointer = [@byte_pointer + indent_diff, 0].max end end
Source
# File lib/reline/line_editor.rb, line 1495 def process_insert(force: false) return if @continuous_insertion_buffer.empty? or (@in_pasting and not force) insert_text(@continuous_insertion_buffer) @continuous_insertion_buffer.clear end
Source
# File lib/reline/line_editor.rb, line 1006 def process_key(key, method_symbol) if key.is_a?(Symbol) cleanup_waiting elsif @waiting_proc old_byte_pointer = @byte_pointer @waiting_proc.call(key) if @vi_waiting_operator byte_pointer_diff = @byte_pointer - old_byte_pointer @byte_pointer = old_byte_pointer method_obj = method(@vi_waiting_operator) wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff) cleanup_waiting end @kill_ring.process return end if method_symbol and respond_to?(method_symbol, true) method_obj = method(method_symbol) end if method_symbol and key.is_a?(Symbol) if @vi_arg and argumentable?(method_obj) run_for_operators(key, method_symbol) do |with_operator| wrap_method_call(method_symbol, method_obj, key, with_operator) end else wrap_method_call(method_symbol, method_obj, key) if method_obj end @kill_ring.process if @vi_arg @vi_arg = nil end elsif @vi_arg if key.chr =~ /[0-9]/ ed_argument_digit(key) else if argumentable?(method_obj) run_for_operators(key, method_symbol) do |with_operator| wrap_method_call(method_symbol, method_obj, key, with_operator) end elsif method_obj wrap_method_call(method_symbol, method_obj, key) else ed_insert(key) unless @config.editing_mode_is?(:vi_command) end @kill_ring.process if @vi_arg @vi_arg = nil end end elsif method_obj if method_symbol == :ed_argument_digit wrap_method_call(method_symbol, method_obj, key) else run_for_operators(key, method_symbol) do |with_operator| wrap_method_call(method_symbol, method_obj, key, with_operator) end end @kill_ring.process else ed_insert(key) unless @config.editing_mode_is?(:vi_command) end end
Source
# File lib/reline/line_editor.rb, line 2533 def re_read_init_file(_key) @config.reload end
Source
# File lib/reline/line_editor.rb, line 2515 def redo(_key) @undoing = true return if @input_lines_position >= @input_lines.size - 1 @input_lines_position += 1 target_lines, target_cursor_x, target_cursor_y = @input_lines[@input_lines_position] set_current_lines(target_lines.dup, target_cursor_x, target_cursor_y) end
Source
# File lib/reline/line_editor.rb, line 514 def render_differential(new_lines, new_cursor_x, new_cursor_y) Reline::IOGate.disable_auto_linewrap(true) if Reline::IOGate.win? rendered_lines = @rendered_screen.lines cursor_y = @rendered_screen.cursor_y if new_lines != rendered_lines # Hide cursor while rendering to avoid cursor flickering. Reline::IOGate.hide_cursor num_lines = [[new_lines.size, rendered_lines.size].max, screen_height].min if @rendered_screen.base_y + num_lines > screen_height Reline::IOGate.scroll_down(num_lines - cursor_y - 1) @rendered_screen.base_y = screen_height - num_lines cursor_y = num_lines - 1 end num_lines.times do |i| rendered_line = rendered_lines[i] || [] line_to_render = new_lines[i] || [] next if rendered_line == line_to_render Reline::IOGate.move_cursor_down i - cursor_y cursor_y = i unless rendered_lines[i] Reline::IOGate.move_cursor_column 0 Reline::IOGate.erase_after_cursor end render_line_differential(rendered_line, line_to_render) end @rendered_screen.lines = new_lines Reline::IOGate.show_cursor end Reline::IOGate.move_cursor_column new_cursor_x Reline::IOGate.move_cursor_down new_cursor_y - cursor_y @rendered_screen.cursor_y = new_cursor_y ensure Reline::IOGate.disable_auto_linewrap(false) if Reline::IOGate.win? end
Reflects lines to be rendered and new cursor position to the screen by calculating the difference from the previous render.
Source
# File lib/reline/line_editor.rb, line 929 def retrieve_completion_journey_state preposing, target, postposing = retrieve_completion_block list = call_completion_proc return unless list.is_a?(Array) candidates = list.select{ |item| item.start_with?(target) } return if candidates.empty? pre = preposing.split("\n", -1).last || '' post = postposing.split("\n", -1).first || '' CompletionJourneyState.new( @line_index, pre, target, post, [target] + candidates, 0 ) end
Source
# File lib/reline/line_editor.rb, line 944 def run_for_operators(key, method_symbol, &block) if @vi_waiting_operator if VI_MOTIONS.include?(method_symbol) old_byte_pointer = @byte_pointer @vi_arg = (@vi_arg || 1) * @vi_waiting_operator_arg block.(true) unless @waiting_proc byte_pointer_diff = @byte_pointer - old_byte_pointer @byte_pointer = old_byte_pointer method_obj = method(@vi_waiting_operator) wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff) cleanup_waiting end else # Ignores operator when not motion is given. block.(false) cleanup_waiting end @vi_arg = nil else block.(false) end end
Source
# File lib/reline/line_editor.rb, line 1721 def search_history(prefix, pointer_range) pointer_range.each do |pointer| lines = Reline::HISTORY[pointer].split("\n") lines.each_with_index do |line, index| return [pointer, index] if line.start_with?(prefix) end end nil end
Source
# File lib/reline/line_editor.rb, line 2385 def search_next_char(key, arg, need_prev_char: false, inclusive: false) if key.instance_of?(String) inputted_char = key else inputted_char = key.chr end prev_total = nil total = nil found = false current_line.byteslice(@byte_pointer..-1).grapheme_clusters.each do |mbchar| # total has [byte_size, cursor] unless total # skip cursor point width = Reline::Unicode.get_mbchar_width(mbchar) total = [mbchar.bytesize, width] else if inputted_char == mbchar arg -= 1 if arg.zero? found = true break end end width = Reline::Unicode.get_mbchar_width(mbchar) prev_total = total total = [total.first + mbchar.bytesize, total.last + width] end end if not need_prev_char and found and total byte_size, _ = total @byte_pointer += byte_size elsif need_prev_char and found and prev_total byte_size, _ = prev_total @byte_pointer += byte_size end if inclusive byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer) if byte_size > 0 @byte_pointer += byte_size end end @waiting_proc = nil end
Source
# File lib/reline/line_editor.rb, line 2437 def search_prev_char(key, arg, need_next_char = false) if key.instance_of?(String) inputted_char = key else inputted_char = key.chr end prev_total = nil total = nil found = false current_line.byteslice(0..@byte_pointer).grapheme_clusters.reverse_each do |mbchar| # total has [byte_size, cursor] unless total # skip cursor point width = Reline::Unicode.get_mbchar_width(mbchar) total = [mbchar.bytesize, width] else if inputted_char == mbchar arg -= 1 if arg.zero? found = true break end end width = Reline::Unicode.get_mbchar_width(mbchar) prev_total = total total = [total.first + mbchar.bytesize, total.last + width] end end if not need_next_char and found and total byte_size, _ = total @byte_pointer -= byte_size elsif need_next_char and found and prev_total byte_size, _ = prev_total @byte_pointer -= byte_size end @waiting_proc = nil end
Source
# File lib/reline/line_editor.rb, line 2529 def set_next_action_state(type, value) @next_action_state = [type, value] end
Source
# File lib/reline/line_editor.rb, line 303 def split_by_width(str, max_width, offset: 0) Reline::Unicode.split_by_width(str, max_width, encoding, offset: offset) end
Source
# File lib/reline/line_editor.rb, line 2505 def undo(_key) @undoing = true return if @input_lines_position <= 0 @input_lines_position -= 1 target_lines, target_cursor_x, target_cursor_y = @input_lines[@input_lines_position] set_current_lines(target_lines.dup, target_cursor_x, target_cursor_y) end
Source
# File lib/reline/line_editor.rb, line 707 def update_each_dialog(dialog, cursor_column, cursor_row, key = nil) dialog.set_cursor_pos(cursor_column, cursor_row) dialog_render_info = dialog.call(key) if dialog_render_info.nil? or dialog_render_info.contents.nil? or dialog_render_info.contents.empty? dialog.contents = nil dialog.trap_key = nil return end contents = dialog_render_info.contents pointer = dialog.pointer if dialog_render_info.width dialog.width = dialog_render_info.width else dialog.width = contents.map { |l| calculate_width(l, true) }.max end height = dialog_render_info.height || DIALOG_DEFAULT_HEIGHT height = contents.size if contents.size < height if contents.size > height if dialog.pointer if dialog.pointer < 0 dialog.scroll_top = 0 elsif (dialog.pointer - dialog.scroll_top) >= (height - 1) dialog.scroll_top = dialog.pointer - (height - 1) elsif (dialog.pointer - dialog.scroll_top) < 0 dialog.scroll_top = dialog.pointer end pointer = dialog.pointer - dialog.scroll_top else dialog.scroll_top = 0 end contents = contents[dialog.scroll_top, height] end if dialog_render_info.scrollbar and dialog_render_info.contents.size > height bar_max_height = height * 2 moving_distance = (dialog_render_info.contents.size - height) * 2 position_ratio = dialog.scroll_top.zero? ? 0.0 : ((dialog.scroll_top * 2).to_f / moving_distance) bar_height = (bar_max_height * ((contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i bar_height = MINIMUM_SCROLLBAR_HEIGHT if bar_height < MINIMUM_SCROLLBAR_HEIGHT scrollbar_pos = ((bar_max_height - bar_height) * position_ratio).floor.to_i else scrollbar_pos = nil end dialog.column = dialog_render_info.pos.x dialog.width += @block_elem_width if scrollbar_pos diff = (dialog.column + dialog.width) - screen_width if diff > 0 dialog.column -= diff end if rest_height(screen_scroll_top + cursor_row) - dialog_render_info.pos.y >= height dialog.vertical_offset = dialog_render_info.pos.y + 1 elsif cursor_row >= height dialog.vertical_offset = dialog_render_info.pos.y - height else dialog.vertical_offset = dialog_render_info.pos.y + 1 end if dialog.column < 0 dialog.column = 0 dialog.width = screen_width end face = Reline::Face[dialog_render_info.face || :default] scrollbar_sgr = face[:scrollbar] default_sgr = face[:default] enhanced_sgr = face[:enhanced] dialog.contents = contents.map.with_index do |item, i| line_sgr = i == pointer ? enhanced_sgr : default_sgr str_width = dialog.width - (scrollbar_pos.nil? ? 0 : @block_elem_width) str, = Reline::Unicode.take_mbchar_range(item, 0, str_width, padding: true) colored_content = "#{line_sgr}#{str}" if scrollbar_pos if scrollbar_pos <= (i * 2) and (i * 2 + 1) < (scrollbar_pos + bar_height) colored_content + scrollbar_sgr + @full_block elsif scrollbar_pos <= (i * 2) and (i * 2) < (scrollbar_pos + bar_height) colored_content + scrollbar_sgr + @upper_half_block elsif scrollbar_pos <= (i * 2 + 1) and (i * 2) < (scrollbar_pos + bar_height) colored_content + scrollbar_sgr + @lower_half_block else colored_content + scrollbar_sgr + ' ' * @block_elem_width end else colored_content end end end
Source
# File lib/reline/line_editor.rb, line 2084 def vi_add(key) @config.editing_mode = :vi_insert ed_next_char(key) end
Source
# File lib/reline/line_editor.rb, line 2180 def vi_add_at_eol(key) ed_move_to_end(key) @config.editing_mode = :vi_insert end
Source
# File lib/reline/line_editor.rb, line 2199 def vi_change_meta(key, arg: nil) if @vi_waiting_operator set_current_line('', 0) if @vi_waiting_operator == :vi_change_meta_confirm && arg.nil? @vi_waiting_operator = nil @vi_waiting_operator_arg = nil else @drop_terminate_spaces = true @vi_waiting_operator = :vi_change_meta_confirm @vi_waiting_operator_arg = arg || 1 end end
Source
# File lib/reline/line_editor.rb, line 2211 def vi_change_meta_confirm(byte_pointer_diff) vi_delete_meta_confirm(byte_pointer_diff) @config.editing_mode = :vi_insert @drop_terminate_spaces = false end
Source
# File lib/reline/line_editor.rb, line 1879 def vi_change_to_eol(key) ed_kill_line(key) @config.editing_mode = :vi_insert end
- Editline
-
vi_change_to_eol
(vi command:C
) + Kill and change from the cursor to the end of the line.
Source
# File lib/reline/line_editor.rb, line 2089 def vi_command_mode(key) ed_prev_char(key) @config.editing_mode = :vi_command end
Source
# File lib/reline/line_editor.rb, line 2217 def vi_delete_meta(key, arg: nil) if @vi_waiting_operator set_current_line('', 0) if @vi_waiting_operator == :vi_delete_meta_confirm && arg.nil? @vi_waiting_operator = nil @vi_waiting_operator_arg = nil else @vi_waiting_operator = :vi_delete_meta_confirm @vi_waiting_operator_arg = arg || 1 end end
Source
# File lib/reline/line_editor.rb, line 2228 def vi_delete_meta_confirm(byte_pointer_diff) if byte_pointer_diff > 0 line, cut = byteslice!(current_line, @byte_pointer, byte_pointer_diff) elsif byte_pointer_diff < 0 line, cut = byteslice!(current_line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff) else return end copy_for_vi(cut) set_current_line(line, @byte_pointer + (byte_pointer_diff < 0 ? byte_pointer_diff : 0)) end
Source
# File lib/reline/line_editor.rb, line 2161 def vi_delete_prev_char(key) if @byte_pointer == 0 and @line_index > 0 @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index) @line_index -= 1 process_auto_indent cursor_dependent: false elsif @byte_pointer > 0 byte_size = Reline::Unicode.get_prev_mbchar_size(current_line, @byte_pointer) @byte_pointer -= byte_size line, _ = byteslice!(current_line, @byte_pointer, byte_size) set_current_line(line) end end
Source
# File lib/reline/line_editor.rb, line 2501 def vi_editing_mode(key) @config.editing_mode = :vi_insert end
Source
# File lib/reline/line_editor.rb, line 2146 def vi_end_big_word(key, arg: 1, inclusive: false) if current_line.bytesize > @byte_pointer byte_size, _ = Reline::Unicode.vi_big_forward_end_word(current_line, @byte_pointer) @byte_pointer += byte_size end arg -= 1 if inclusive and arg.zero? byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer) if byte_size > 0 @byte_pointer += byte_size end end vi_end_big_word(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 2113 def vi_end_word(key, arg: 1, inclusive: false) if current_line.bytesize > @byte_pointer byte_size, _ = Reline::Unicode.vi_forward_end_word(current_line, @byte_pointer) @byte_pointer += byte_size end arg -= 1 if inclusive and arg.zero? byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer) if byte_size > 0 @byte_pointer += byte_size end end vi_end_word(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 1584 def vi_first_print(key) @byte_pointer, = Reline::Unicode.vi_first_print(current_line) end
Source
# File lib/reline/line_editor.rb, line 2296 def vi_histedit(key) path = Tempfile.open { |fp| fp.write whole_lines.join("\n") fp.path } system("#{ENV['EDITOR']} #{path}") @buffer_of_lines = File.read(path).split("\n") @buffer_of_lines = [String.new(encoding: encoding)] if @buffer_of_lines.empty? @line_index = 0 finish end
Source
# File lib/reline/line_editor.rb, line 2080 def vi_insert(key) @config.editing_mode = :vi_insert end
Source
# File lib/reline/line_editor.rb, line 2175 def vi_insert_at_bol(key) ed_move_to_beg(key) @config.editing_mode = :vi_insert end
Source
# File lib/reline/line_editor.rb, line 2475 def vi_join_lines(key, arg: 1) if @buffer_of_lines.size > @line_index + 1 next_line = @buffer_of_lines.delete_at(@line_index + 1).lstrip set_current_line(current_line + ' ' + next_line, current_line.bytesize) end arg -= 1 vi_join_lines(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 1890 def vi_kill_line_prev(key) if @byte_pointer > 0 line, deleted = byteslice!(current_line, 0, @byte_pointer) set_current_line(line, 0) @kill_ring.append(deleted, true) end end
- Editline
-
vi-kill-line-prev
(vi:Ctrl-U
) Delete the string from the beginning of the edit buffer to the cursor and save it to the cut buffer. - GNU
Readline
-
unix-line-discard
(C-u
) Kill backward from the cursor to the beginning of the current line.
Source
# File lib/reline/line_editor.rb, line 2262 def vi_list_or_eof(key) if buffer_empty? @eof = true finish else ed_newline(key) end end
Source
# File lib/reline/line_editor.rb, line 2128 def vi_next_big_word(key, arg: 1) if current_line.bytesize > @byte_pointer byte_size, _ = Reline::Unicode.vi_big_forward_word(current_line, @byte_pointer) @byte_pointer += byte_size end arg -= 1 vi_next_big_word(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 2377 def vi_next_char(key, arg: 1, inclusive: false) @waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg, inclusive: inclusive) } end
Source
# File lib/reline/line_editor.rb, line 2095 def vi_next_word(key, arg: 1) if current_line.bytesize > @byte_pointer byte_size, _ = Reline::Unicode.vi_forward_word(current_line, @byte_pointer, @drop_terminate_spaces) @byte_pointer += byte_size end arg -= 1 vi_next_word(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 2317 def vi_paste_next(key, arg: 1) if @vi_clipboard.size > 0 byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer) line = byteinsert(current_line, @byte_pointer + byte_size, @vi_clipboard) set_current_line(line, @byte_pointer + @vi_clipboard.bytesize) end arg -= 1 vi_paste_next(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 2308 def vi_paste_prev(key, arg: 1) if @vi_clipboard.size > 0 cursor_point = @vi_clipboard.grapheme_clusters[0..-2].join set_current_line(byteinsert(current_line, @byte_pointer, @vi_clipboard), @byte_pointer + cursor_point.bytesize) end arg -= 1 vi_paste_prev(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 2137 def vi_prev_big_word(key, arg: 1) if @byte_pointer > 0 byte_size, _ = Reline::Unicode.vi_big_backward_word(current_line, @byte_pointer) @byte_pointer -= byte_size end arg -= 1 vi_prev_big_word(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 2429 def vi_prev_char(key, arg: 1) @waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg) } end
Source
# File lib/reline/line_editor.rb, line 2104 def vi_prev_word(key, arg: 1) if @byte_pointer > 0 byte_size, _ = Reline::Unicode.vi_backward_word(current_line, @byte_pointer) @byte_pointer -= byte_size end arg -= 1 vi_prev_word(key, arg: arg) if arg > 0 end
Source
# File lib/reline/line_editor.rb, line 2353 def vi_replace_char(key, arg: 1) @waiting_proc = ->(k) { if arg == 1 byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer) before = current_line.byteslice(0, @byte_pointer) remaining_point = @byte_pointer + byte_size after = current_line.byteslice(remaining_point, current_line.bytesize - remaining_point) set_current_line(before + k.chr + after) @waiting_proc = nil elsif arg > 1 byte_size = 0 arg.times do byte_size += Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer + byte_size) end before = current_line.byteslice(0, @byte_pointer) remaining_point = @byte_pointer + byte_size after = current_line.byteslice(remaining_point, current_line.bytesize - remaining_point) replaced = k.chr * arg set_current_line(before + replaced + after, @byte_pointer + replaced.bytesize) @waiting_proc = nil end } end
Source
# File lib/reline/line_editor.rb, line 1716 def vi_search_next(key) incremental_search_history(key) end
Source
# File lib/reline/line_editor.rb, line 1711 def vi_search_prev(key) incremental_search_history(key) end
Source
# File lib/reline/line_editor.rb, line 2344 def vi_to_column(key, arg: 0) # Implementing behavior of vi, not Readline's vi-mode. @byte_pointer, = current_line.grapheme_clusters.inject([0, 0]) { |(total_byte_size, total_width), gc| mbchar_width = Reline::Unicode.get_mbchar_width(gc) break [total_byte_size, total_width] if (total_width + mbchar_width) >= arg [total_byte_size + gc.bytesize, total_width + mbchar_width] } end
Source
# File lib/reline/line_editor.rb, line 2289 def vi_to_history_line(key) if Reline::HISTORY.empty? return end move_history(0, line: :start, cursor: :start) end
Source
# File lib/reline/line_editor.rb, line 2381 def vi_to_next_char(key, arg: 1, inclusive: false) @waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg, need_prev_char: true, inclusive: inclusive) } end
Source
# File lib/reline/line_editor.rb, line 2433 def vi_to_prev_char(key, arg: 1) @waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg, true) } end
Source
# File lib/reline/line_editor.rb, line 2240 def vi_yank(key, arg: nil) if @vi_waiting_operator copy_for_vi(current_line) if @vi_waiting_operator == :vi_yank_confirm && arg.nil? @vi_waiting_operator = nil @vi_waiting_operator_arg = nil else @vi_waiting_operator = :vi_yank_confirm @vi_waiting_operator_arg = arg || 1 end end
Source
# File lib/reline/line_editor.rb, line 2251 def vi_yank_confirm(byte_pointer_diff) if byte_pointer_diff > 0 cut = current_line.byteslice(@byte_pointer, byte_pointer_diff) elsif byte_pointer_diff < 0 cut = current_line.byteslice(@byte_pointer + byte_pointer_diff, -byte_pointer_diff) else return end copy_for_vi(cut) end