class Reline::LineEditor - reline: Ruby Standard Library Documentation

# class Reline::LineEditor

### Constants

ARGUMENT_DIGIT_METHODS
CompletionJourneyState
DIALOG_DEFAULT_HEIGHT
MAX_INPUT_LINES
MINIMUM_SCROLLBAR_HEIGHT
NullActionState
RenderedScreen
VI_MOTIONS
VI_WAITING_ACCEPT_METHODS

### Attributes

auto_indent_proc[RW]
byte_pointer[R]

TODO: Use “private alias_method” idiom after drop Ruby 2.5.

completion_append_character[RW]
completion_proc[RW]
confirm_multiline_termination_proc[RW]
dig_perfect_match_proc[RW]
output_modifier_proc[RW]
prompt_proc[RW]

### Public Class Methods

new(config) click to toggle source

    # File reline/line_editor.rb, line 73
    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

add_dialog_proc(name, p, context = nil) click to toggle source

    # File reline/line_editor.rb, line 692
    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

backward_char(key, arg: 1)
Alias for: ed_prev_char
backward_delete_char(key, arg: 1)
Alias for: em_delete_prev_char
backward_kill_word(key)
Alias for: ed_delete_prev_word
backward_word(key)
Alias for: ed_prev_word
beginning_of_line(key)
Alias for: ed_move_to_beg
byte_pointer=(val) click to toggle source

    # File reline/line_editor.rb, line 1282
    def byte_pointer=(val)
      @byte_pointer = val
    end

calculate_overlay_levels(overlay_levels) click to toggle source

    # File reline/line_editor.rb, line 398
    def calculate_overlay_levels(overlay_levels)
      levels = []
      overlay_levels.each do |x, w, l|
        levels.fill(l, x, w)
      end
      levels
    end

call_completion_proc(pre, target, post, quote) click to toggle source

    # File reline/line_editor.rb, line 1122
    def call_completion_proc(pre, target, post, quote)
      Reline.core.instance_variable_set(:@completion_quote_character, quote)
      result = call_completion_proc_with_checking_args(pre, target, post)
      Reline.core.instance_variable_set(:@completion_quote_character, nil)
      result
    end

call_completion_proc_with_checking_args(pre, target, post) click to toggle source

    # File reline/line_editor.rb, line 1129
    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

capitalize_word(key)
Alias for: em_capitol_case
clear_dialogs() click to toggle source

    # File reline/line_editor.rb, line 446
    def clear_dialogs
      @dialogs.each do |dialog|
        dialog.contents = nil
        dialog.trap_key = nil
      end
    end

clear_screen(key)
Alias for: ed_clear_screen
confirm_multiline_termination() click to toggle source

    # File reline/line_editor.rb, line 1223
    def confirm_multiline_termination
      temp_buffer = @buffer_of_lines.dup
      @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
    end

current_byte_pointer_cursor() click to toggle source

    # File reline/line_editor.rb, line 304
    def current_byte_pointer_cursor
      calculate_width(current_line.byteslice(0, @byte_pointer))
    end

current_line() click to toggle source

    # File reline/line_editor.rb, line 1172
    def current_line
      @buffer_of_lines[@line_index]
    end

delete_char(key)
Alias for: em_delete
delete_char_or_list(key)
Alias for: em_delete_or_list
delete_text(start = nil, length = nil) click to toggle source

    # File reline/line_editor.rb, line 1248
    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

dialog_proc_scope_completion_journey_data() click to toggle source

    # File reline/line_editor.rb, line 874
    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

downcase_word(key)
Alias for: em_lower_case
ed_digit(str)
Alias for: ed_insert
editing_mode() click to toggle source

    # File reline/line_editor.rb, line 801
    def editing_mode
      @config.editing_mode
    end

encoding() click to toggle source

    # File reline/line_editor.rb, line 84
    def encoding
      io_gate.encoding
    end

end_of_line(key)
Alias for: ed_move_to_end
eof?() click to toggle source

    # File reline/line_editor.rb, line 220
    def eof?
      @eof
    end

exchange_point_and_mark(key)
Alias for: em_exchange_mark
finalize() click to toggle source

    # File reline/line_editor.rb, line 216
    def finalize
      Signal.trap('INT', @old_trap)
    end

finish() click to toggle source

    # File reline/line_editor.rb, line 1302
    def finish
      @finished = true
      @config.reset
    end

finished?() click to toggle source

    # File reline/line_editor.rb, line 1298
    def finished?
      @finished
    end

forward_char(key, arg: 1)
Alias for: ed_next_char
forward_search_history(key)
Alias for: vi_search_next
forward_word(key)
Alias for: em_next_word
handle_signal() click to toggle source

    # File reline/line_editor.rb, line 168
    def handle_signal
      handle_interrupted
      handle_resized
    end

history_search_backward(key, arg: 1)
Alias for: ed_search_prev_history
history_search_forward(key, arg: 1)
Alias for: ed_search_next_history
input_key(key) click to toggle source

    # File reline/line_editor.rb, line 1043
    def input_key(key)
      save_old_buffer
      @config.reset_oneshot_key_bindings
      if key.char.nil?
        process_insert(force: true)
        @eof = buffer_empty?
        finish
        return
      end
      @dialogs.each do |dialog|
        if key.method_symbol == dialog.name
          return
        end
      end
      @completion_occurs = false

      process_key(key.char, key.method_symbol)
      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

      @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 @restoring
      @restoring = 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

insert_multiline_text(text) click to toggle source

    # File reline/line_editor.rb, line 1228
    def insert_multiline_text(text)
      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
    end

insert_text(text) click to toggle source

    # File reline/line_editor.rb, line 1238
    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

io_gate() click to toggle source

    # File reline/line_editor.rb, line 80
    def io_gate
      Reline::IOGate
    end

kill_line(key)
Alias for: ed_kill_line
kill_whole_line(key)
Alias for: em_kill_line
kill_word(key)
Alias for: em_delete_next_word
line() click to toggle source

    # File reline/line_editor.rb, line 1168
    def line()
      @buffer_of_lines.join("\n") unless eof?
    end

modified_lines() click to toggle source

    # File reline/line_editor.rb, line 351
    def modified_lines
      with_cache(__method__, whole_lines, finished?) do |whole, complete|
        modify_lines(whole, complete)
      end
    end

multiline_off() click to toggle source

    # File reline/line_editor.rb, line 273
    def multiline_off
      @is_multiline = false
    end

multiline_on() click to toggle source

    # File reline/line_editor.rb, line 269
    def multiline_on
      @is_multiline = true
    end

next_history(key, arg: 1)
Alias for: ed_next_history
previous_history(key, arg: 1)
Alias for: ed_prev_history
print_nomultiline_prompt() click to toggle source

    # File reline/line_editor.rb, line 473
    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.
      Reline::IOGate.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

prompt_list() click to toggle source

    # File reline/line_editor.rb, line 357
    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

push_input_lines() click to toggle source

    # File reline/line_editor.rb, line 1093
    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

render() click to toggle source

    # File reline/line_editor.rb, line 481
    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

      Reline::IOGate.buffered_output do
        render_differential new_lines, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top
      end
    end

render_finished() click to toggle source

    # File reline/line_editor.rb, line 461
    def render_finished
      Reline::IOGate.buffered_output do
        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_line_by_width(line, screen_width)
          wrapped_lines.last.empty? ? "#{line} " : line
        end
        Reline::IOGate.write lines.map { |l| "#{l}\r\n" }.join
      end
    end

render_line_differential(old_items, new_items) click to toggle source

    # File reline/line_editor.rb, line 406
    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
          Reline::IOGate.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
          Reline::IOGate.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

rerender() click to toggle source

    # File reline/line_editor.rb, line 564
    def rerender
      render unless @in_pasting
    end

reset(prompt = '') click to toggle source

    # File reline/line_editor.rb, line 141
    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

reset_line() click to toggle source

    # File reline/line_editor.rb, line 261
    def reset_line
      @byte_pointer = 0
      @buffer_of_lines = [String.new(encoding: encoding)]
      @line_index = 0
      @cache.clear
      @line_backup_in_history = nil
    end

reset_variables(prompt = '') click to toggle source

    # File reline/line_editor.rb, line 224
    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
      @restoring = false
      @prev_action_state = NullActionState
      @next_action_state = NullActionState
      reset_line
    end

rest_height(wrapped_cursor_y) click to toggle source

    # File reline/line_editor.rb, line 560
    def rest_height(wrapped_cursor_y)
      screen_height - wrapped_cursor_y + screen_scroll_top - @rendered_screen.base_y - 1
    end

retrieve_completion_block() click to toggle source

    # File reline/line_editor.rb, line 1187
    def retrieve_completion_block
      quote_characters = Reline.completer_quote_characters
      before = current_line.byteslice(0, @byte_pointer).grapheme_clusters
      quote = nil
      # Calcualte closing quote when cursor is at the end of the line
      if current_line.bytesize == @byte_pointer && !quote_characters.empty?
        escaped = false
        before.each do |c|
          if escaped
            escaped = false
            next
          elsif c == '\\'
            escaped = true
          elsif quote
            quote = nil if c == quote
          elsif quote_characters.include?(c)
            quote = c
          end
        end
      end

      word_break_characters = quote_characters + Reline.completer_word_break_characters
      break_index = before.rindex { |c| word_break_characters.include?(c) || quote_characters.include?(c) } || -1
      preposing = before.take(break_index + 1).join
      target = before.drop(break_index + 1).join
      postposing = current_line.byteslice(@byte_pointer, current_line.bytesize - @byte_pointer)
      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), quote&.encode(encoding)]
    end

reverse_search_history(key)
Alias for: vi_search_prev
save_old_buffer() click to toggle source

    # File reline/line_editor.rb, line 1089
    def save_old_buffer
      @old_buffer_of_lines = @buffer_of_lines.dup
    end

screen_height() click to toggle source

    # File reline/line_editor.rb, line 363
    def screen_height
      @screen_size.first
    end

screen_scroll_top() click to toggle source

    # File reline/line_editor.rb, line 371
    def screen_scroll_top
      @scroll_partial_screen
    end

screen_width() click to toggle source

    # File reline/line_editor.rb, line 367
    def screen_width
      @screen_size.last
    end

scroll_into_view() click to toggle source

    # File reline/line_editor.rb, line 1112
    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

self_insert(str)
Alias for: ed_insert
set_current_line(line, byte_pointer = nil) click to toggle source

    # File reline/line_editor.rb, line 1176
    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

set_mark(key)
Alias for: em_set_mark
set_pasting_state(in_pasting) click to toggle source

    # File reline/line_editor.rb, line 88
    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

set_signal_handlers() click to toggle source

    # File reline/line_editor.rb, line 207
    def set_signal_handlers
      Reline::IOGate.set_winch_handler do
        @resized = true
      end
      @old_trap = Signal.trap('INT') do
        @interrupted = true
      end
    end

transpose_chars(key)
Alias for: ed_transpose_chars
transpose_words(key)
Alias for: ed_transpose_words
trim_input_lines() click to toggle source

    # File reline/line_editor.rb, line 1105
    def trim_input_lines
      if @input_lines.size > MAX_INPUT_LINES
        @input_lines.shift
        @input_lines_position -= 1
      end
    end

unix_line_discard(key)
Alias for: vi_kill_line_prev
unix_word_rubout(key)
Alias for: em_kill_region
upcase_word(key)
Alias for: em_upper_case
update(key) click to toggle source

    # File reline/line_editor.rb, line 1033
    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

update_dialogs(key = nil) click to toggle source

    # File reline/line_editor.rb, line 453
    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

upper_space_height(wrapped_cursor_y) click to toggle source

    # File reline/line_editor.rb, line 556
    def upper_space_height(wrapped_cursor_y)
      wrapped_cursor_y - screen_scroll_top
    end

vi_end_of_transmission(key)
Alias for: vi_list_or_eof
vi_eof_maybe(key)
Alias for: vi_list_or_eof
vi_movement_mode(key)
Alias for: vi_command_mode
vi_zero(key)
Alias for: ed_move_to_beg
whole_buffer() click to toggle source

    # File reline/line_editor.rb, line 1290
    def whole_buffer
      whole_lines.join("\n")
    end

whole_lines() click to toggle source

    # File reline/line_editor.rb, line 1286
    def whole_lines
      @buffer_of_lines.dup
    end

with_cache(key, *deps) { |*deps, cached_deps, value| ... } click to toggle source

    # File reline/line_editor.rb, line 343
    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

wrap_method_call(method_symbol, method_obj, key, with_operator = false) click to toggle source

    # File reline/line_editor.rb, line 948
    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

wrapped_cursor_position() click to toggle source

Calculate cursor position in word wrapped content.

    # File reline/line_editor.rb, line 437
    def wrapped_cursor_position
      prompt_width = calculate_width(prompt_list[@line_index], true)
      line_before_cursor = Reline::Unicode.escape_for_print(whole_lines[@line_index].byteslice(0, @byte_pointer))
      wrapped_line_before_cursor = split_line_by_width(' ' * prompt_width + line_before_cursor, screen_width)
      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

wrapped_prompt_and_input_lines() click to toggle source

    # File reline/line_editor.rb, line 375
    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_line_by_width(prompt, width)
          wrapped_lines = split_line_by_width(line, width, offset: calculate_width(code_line_prompt, true))
          wrapped_prompts.map { |p| [p, ''] } + [[code_line_prompt, wrapped_lines.first]] + wrapped_lines.drop(1).map { |c| ['', c] }
        end
      end
    end

yank(key)
Alias for: em_yank
yank_pop(key)
Alias for: em_yank_pop

### Private Instance Methods

argumentable?(method_obj) click to toggle source

    # File reline/line_editor.rb, line 938
            def argumentable?(method_obj)
      method_obj and method_obj.parameters.any? { |param| param[0] == :key and param[1] == :arg }
    end

buffer_empty?() click to toggle source

    # File reline/line_editor.rb, line 1294
            def buffer_empty?
      current_line.empty? and @buffer_of_lines.size == 1
    end

byteinsert(str, byte_pointer, other) click to toggle source

    # File reline/line_editor.rb, line 1313
            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

byteslice!(str, byte_pointer, size) click to toggle source

    # File reline/line_editor.rb, line 1307
            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

calculate_nearest_cursor(cursor) click to toggle source

    # File reline/line_editor.rb, line 308
            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

calculate_width(str, allow_escape_code = false) click to toggle source

    # File reline/line_editor.rb, line 1320
            def calculate_width(str, allow_escape_code = false)
      Reline::Unicode.calculate_width(str, allow_escape_code)
    end

check_mode_string() click to toggle source

    # File reline/line_editor.rb, line 95
            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

check_multiline_prompt(buffer, mode_string) click to toggle source

    # File reline/line_editor.rb, line 109
            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

cleanup_waiting() click to toggle source

    # File reline/line_editor.rb, line 968
            def cleanup_waiting
      @waiting_proc = nil
      @vi_waiting_operator = nil
      @vi_waiting_operator_arg = nil
      @searching_prompt = nil
      @drop_terminate_spaces = false
    end

clear_rendered_screen_cache() click to toggle source

    # File reline/line_editor.rb, line 551
            def clear_rendered_screen_cache
      @rendered_screen.lines = []
      @rendered_screen.cursor_y = 0
    end

complete(_key) click to toggle source

    # File reline/line_editor.rb, line 1340
            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
        pre, target, post, quote = retrieve_completion_block
        result = call_completion_proc(pre, target, post, quote)
        if result.is_a?(Array)
          @completion_occurs = true
          perform_completion(pre, target, post, quote, result)
        end
      end
    end

completion_journey_move(direction) click to toggle source

    # File reline/line_editor.rb, line 1358
            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

completion_journey_up(_key) click to toggle source

    # File reline/line_editor.rb, line 1374
            def completion_journey_up(_key)
      completion_journey_move(:up) if @config.autocompletion
    end

copy_for_vi(text) click to toggle source

    # File reline/line_editor.rb, line 1942
            def copy_for_vi(text)
      if @config.editing_mode_is?(:vi_insert) or @config.editing_mode_is?(:vi_command)
        @vi_clipboard = text
      end
    end

dialog_range(dialog, dialog_y) click to toggle source

    # File reline/line_editor.rb, line 703
            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

ed_argument_digit(key) click to toggle source

    # File reline/line_editor.rb, line 2195
            def ed_argument_digit(key)
      # key is expected to be `ESC digit` or `digit`
      num = key[/\d/].to_i
      @vi_arg = (@vi_arg || 0) * 10 + num
    end

ed_clear_screen(key) click to toggle source

    # File reline/line_editor.rb, line 1822
            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

Also aliased as: clear_screen
ed_delete_next_char(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 2141
            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

ed_delete_prev_char(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 2053
            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

ed_delete_prev_word(key) click to toggle source

    # File reline/line_editor.rb, line 1856
            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

Also aliased as: backward_kill_word
ed_insert(str) click to toggle source

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, call `ed-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.

    # File reline/line_editor.rb, line 1401
            def ed_insert(str)
      begin
        str.encode(Encoding::UTF_8)
      rescue Encoding::UndefinedConversionError
        return
      end
      if @in_pasting
        @continuous_insertion_buffer << str
        return
      elsif not @continuous_insertion_buffer.empty?
        process_insert
      end

      insert_text(str)
    end

Also aliased as: ed_digit, self_insert
ed_kill_line(key) click to toggle source

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.

    # File reline/line_editor.rb, line 1733
            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

Also aliased as: kill_line
ed_move_to_beg(key) click to toggle source

    # File reline/line_editor.rb, line 1460
            def ed_move_to_beg(key)
      @byte_pointer = 0
    end

Also aliased as: beginning_of_line, vi_zero
ed_move_to_end(key) click to toggle source

    # File reline/line_editor.rb, line 1466
            def ed_move_to_end(key)
      @byte_pointer = current_line.bytesize
    end

Also aliased as: end_of_line
ed_newline(key) click to toggle source

    # File reline/line_editor.rb, line 1683
            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

ed_next_char(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1430
            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

Also aliased as: forward_char
ed_next_history(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1666
            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

Also aliased as: next_history
ed_prev_char(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1443
            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

Also aliased as: backward_char
ed_prev_history(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1649
            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

Also aliased as: previous_history
ed_prev_word(key) click to toggle source

    # File reline/line_editor.rb, line 1838
            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

Also aliased as: backward_word
ed_search_next_history(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1612
            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

Also aliased as: history_search_forward
ed_search_prev_history(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1597
            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

Also aliased as: history_search_backward
ed_transpose_chars(key) click to toggle source

    # File reline/line_editor.rb, line 1866
            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

Also aliased as: transpose_chars
ed_transpose_words(key) click to toggle source

    # File reline/line_editor.rb, line 1883
            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

Also aliased as: transpose_words
ed_unassigned(key) click to toggle source

Editline

  `ed-unassigned` This editor command always results in an error.

GNU Readline

  There is no corresponding macro.

    # File reline/line_editor.rb, line 1380
    def ed_unassigned(key) end

em_capitol_case(key) click to toggle source

    # File reline/line_editor.rb, line 1896
            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

Also aliased as: capitalize_word
em_delete(key) click to toggle source

    # File reline/line_editor.rb, line 1777
            def em_delete(key)
      if buffer_empty? and key == "\C-d"
        @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

Also aliased as: delete_char
em_delete_next_word(key) click to toggle source

    # File reline/line_editor.rb, line 1846
            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

Also aliased as: kill_word
em_delete_or_list(key) click to toggle source

    # File reline/line_editor.rb, line 1792
            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
        pre, target, post, quote = retrieve_completion_block
        result = call_completion_proc(pre, target, post, quote)
        if result.is_a?(Array)
          candidates = filter_normalize_candidates(target, result)
          menu(candidates)
        end
      end
    end

Also aliased as: delete_char_or_list
em_delete_prev_char(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1712
            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

Also aliased as: backward_delete_char
em_exchange_mark(key) click to toggle source

    # File reline/line_editor.rb, line 2336
            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

Also aliased as: exchange_point_and_mark
em_kill_line(key) click to toggle source

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.

    # File reline/line_editor.rb, line 1769
            def em_kill_line(key)
      if current_line.size > 0
        @kill_ring.append(current_line.dup, true)
        set_current_line('', 0)
      end
    end

Also aliased as: kill_whole_line
em_kill_region(key) click to toggle source

    # File reline/line_editor.rb, line 1932
            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

Also aliased as: unix_word_rubout
em_lower_case(key) click to toggle source

    # File reline/line_editor.rb, line 1906
            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

Also aliased as: downcase_word
em_next_word(key) click to toggle source

    # File reline/line_editor.rb, line 1830
            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

Also aliased as: forward_word
em_set_mark(key) click to toggle source

    # File reline/line_editor.rb, line 2331
            def em_set_mark(key)
      @mark_pointer = [@byte_pointer, @line_index]
    end

Also aliased as: set_mark
em_upper_case(key) click to toggle source

    # File reline/line_editor.rb, line 1919
            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

Also aliased as: upcase_word
em_yank(key) click to toggle source

    # File reline/line_editor.rb, line 1806
            def em_yank(key)
      yanked = @kill_ring.yank
      insert_text(yanked) if yanked
    end

Also aliased as: yank
em_yank_pop(key) click to toggle source

    # File reline/line_editor.rb, line 1812
            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

Also aliased as: yank_pop
emacs_editing_mode(key) click to toggle source

    # File reline/line_editor.rb, line 2344
            def emacs_editing_mode(key)
      @config.editing_mode = :emacs
    end

filter_normalize_candidates(target, list) click to toggle source

    # File reline/line_editor.rb, line 809
            def filter_normalize_candidates(target, list)
      target = target.downcase if @config.completion_ignore_case
      list.select do |item|
        next unless item
        unless Encoding.compatible?(target.encoding, item.encoding)
          # Workaround for Readline test
          if defined?(::Readline) && ::Readline == ::Reline
            raise Encoding::CompatibilityError, "incompatible character encodings: #{target.encoding} and #{item.encoding}"
          end
        end

        if @config.completion_ignore_case
          item.downcase.start_with?(target)
        else
          item.start_with?(target)
        end
      end.map do |item|
        item.unicode_normalize
      rescue Encoding::CompatibilityError
        item
      end.uniq
    end

generate_searcher(search_key) click to toggle source

    # File reline/line_editor.rb, line 1471
            def generate_searcher(search_key)
      search_word = String.new(encoding: encoding)
      hit_pointer = nil
      lambda do |key|
        search_again = false
        case key
        when "\C-h", "\C-?"
          grapheme_clusters = search_word.grapheme_clusters
          if grapheme_clusters.size > 0
            grapheme_clusters.pop
            search_word = grapheme_clusters.join
          end
        when "\C-r", "\C-s"
          search_again = true if search_key == key
          search_key = key
        else
          search_word << key
        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"
                history_pointer_base = 0
                history = Reline::HISTORY[0..(@history_pointer - 1)]
              when "\C-s"
                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"
              history_pointer_base = 0
              history = Reline::HISTORY[0..@history_pointer]
            when "\C-s"
              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"
            hit_index = history.rindex { |item|
              item.include?(search_word)
            }
          when "\C-s"
            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"
          prompt_name = 'reverse-i-search'
        when "\C-s"
          prompt_name = 'i-search'
        end
        prompt_name = "failed #{prompt_name}" unless hit
        [search_word, prompt_name, hit_pointer]
      end
    end

handle_interrupted() click to toggle source

    # File reline/line_editor.rb, line 185
            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

handle_resized() click to toggle source

    # File reline/line_editor.rb, line 173
            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

inclusive?(method_obj) click to toggle source

    # File reline/line_editor.rb, line 942
            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

incremental_search_history(key) click to toggle source

    # File reline/line_editor.rb, line 1550
            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"]
      termination_keys.concat(@config.isearch_terminators.chars) if @config.isearch_terminators
      @waiting_proc = ->(k) {
        if k == "\C-g"
          # 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) && (k.match?(/[[:print:]]/) || k == "\C-h" || k == "\C-?" || k == "\C-r" || k == "\C-s")
          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

insert_new_line(cursor_line, next_line) click to toggle source

    # File reline/line_editor.rb, line 277
            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

insert_raw_char(str, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1419
            def insert_raw_char(str, arg: 1)
      arg.times do
        if str == "\C-j" or str == "\C-m"
          key_newline(str)
        elsif str != "\0"
          # Ignore NUL.
          ed_insert(str)
        end
      end
    end

key_delete(key) click to toggle source

    # File reline/line_editor.rb, line 1324
            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

key_newline(key) click to toggle source

    # File reline/line_editor.rb, line 1332
            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

modify_lines(before, complete) click to toggle source

    # File reline/line_editor.rb, line 793
            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

move_completed_list(direction) click to toggle source

    # File reline/line_editor.rb, line 887
            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

move_history(history_pointer, line:, cursor:) click to toggle source

    # File reline/line_editor.rb, line 1627
            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

move_undo_redo(direction) click to toggle source

    # File reline/line_editor.rb, line 2352
            def move_undo_redo(direction)
      @restoring = true
      return unless (0..@input_lines.size - 1).cover?(@input_lines_position + direction)

      @input_lines_position += direction
      buffer_of_lines, byte_pointer, line_index = @input_lines[@input_lines_position]
      @buffer_of_lines = buffer_of_lines.dup
      @line_index = line_index
      @byte_pointer = byte_pointer
    end

perform_completion(preposing, target, postposing, quote, list) click to toggle source

    # File reline/line_editor.rb, line 832
            def perform_completion(preposing, target, postposing, quote, list)
      candidates = filter_normalize_candidates(target, list)

      case @completion_state
      when CompletionState::PERFECT_MATCH
        if @dig_perfect_match_proc
          @dig_perfect_match_proc.call(@perfect_matched)
          return
        end
      when CompletionState::MENU
        menu(candidates)
        return
      when CompletionState::MENU_WITH_PERFECT_MATCH
        menu(candidates)
        @completion_state = CompletionState::PERFECT_MATCH
        return
      end

      completed = Reline::Unicode.common_prefix(candidates, ignore_case: @config.completion_ignore_case)
      return if completed.empty?

      append_character = ''
      if candidates.include?(completed)
        if candidates.one?
          append_character = quote || completion_append_character.to_s
          @completion_state = CompletionState::PERFECT_MATCH
        elsif @config.show_all_if_ambiguous
          menu(candidates)
          @completion_state = CompletionState::PERFECT_MATCH
        else
          @completion_state = CompletionState::MENU_WITH_PERFECT_MATCH
        end
        @perfect_matched = completed
      else
        @completion_state = CompletionState::MENU
        menu(candidates) if @config.show_all_if_ambiguous
      end
      @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

prev_action_state_value(type) click to toggle source

    # File reline/line_editor.rb, line 2371
            def prev_action_state_value(type)
      @prev_action_state[0] == type ? @prev_action_state[1] : nil
    end

process_auto_indent(line_index = @line_index, cursor_dependent: true, add_newline: false) click to toggle source

    # File reline/line_editor.rb, line 1151
            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

process_insert(force: false) click to toggle source

    # File reline/line_editor.rb, line 1382
            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

process_key(key, method_symbol) click to toggle source

    # File reline/line_editor.rb, line 979
            def process_key(key, method_symbol)
      if @waiting_proc
        cleanup_waiting unless key.size == 1
      end
      if @vi_waiting_operator
        cleanup_waiting unless VI_WAITING_ACCEPT_METHODS.include?(method_symbol) || VI_MOTIONS.include?(method_symbol)
      end

      if @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

      # Reject multibyte input (converted to ed_insert) in vi_command mode
      return if method_symbol == :ed_insert && @config.editing_mode_is?(:vi_command)

      if method_symbol and respond_to?(method_symbol, true)
        method_obj = method(method_symbol)
      end
      if @vi_arg
        if ARGUMENT_DIGIT_METHODS.include?(method_symbol)
          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)
          end
          @kill_ring.process
          @vi_arg = nil
        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
      end
    end

re_read_init_file(_key) click to toggle source

    # File reline/line_editor.rb, line 2379
            def re_read_init_file(_key)
      @config.reload
    end

redo(_key) click to toggle source

    # File reline/line_editor.rb, line 2367
            def redo(_key)
      move_undo_redo(+1)
    end

render_differential(new_lines, new_cursor_x, new_cursor_y) click to toggle source

Reflects lines to be rendered and new cursor position to the screen by calculating the difference from the previous render.

    # File reline/line_editor.rb, line 515
            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

retrieve_completion_journey_state() click to toggle source

    # File reline/line_editor.rb, line 899
            def retrieve_completion_journey_state
      preposing, target, postposing, quote = retrieve_completion_block
      list = call_completion_proc(preposing, target, postposing, quote)
      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

run_for_operators(key, method_symbol, &block) click to toggle source

    # File reline/line_editor.rb, line 914
            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

search_history(prefix, pointer_range) click to toggle source

    # File reline/line_editor.rb, line 1587
            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

search_next_char(key, arg, need_prev_char: false, inclusive: false) click to toggle source

    # File reline/line_editor.rb, line 2242
            def search_next_char(key, arg, need_prev_char: false, inclusive: false)
      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 key == 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

search_prev_char(key, arg, need_next_char = false) click to toggle source

    # File reline/line_editor.rb, line 2289
            def search_prev_char(key, arg, need_next_char = false)
      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 key == 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

set_next_action_state(type, value) click to toggle source

    # File reline/line_editor.rb, line 2375
            def set_next_action_state(type, value)
      @next_action_state = [type, value]
    end

split_line_by_width(str, max_width, offset: 0) click to toggle source

    # File reline/line_editor.rb, line 300
            def split_line_by_width(str, max_width, offset: 0)
      Reline::Unicode.split_line_by_width(str, max_width, encoding, offset: offset)
    end

undo(_key) click to toggle source

    # File reline/line_editor.rb, line 2363
            def undo(_key)
      move_undo_redo(-1)
    end

update_each_dialog(dialog, cursor_column, cursor_row, key = nil) click to toggle source

    # File reline/line_editor.rb, line 709
            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

vi_add(key) click to toggle source

    # File reline/line_editor.rb, line 1952
            def vi_add(key)
      @config.editing_mode = :vi_insert
      ed_next_char(key)
    end

vi_add_at_eol(key) click to toggle source

    # File reline/line_editor.rb, line 2048
            def vi_add_at_eol(key)
      ed_move_to_end(key)
      @config.editing_mode = :vi_insert
    end

vi_change_meta(key, arg: nil) click to toggle source

    # File reline/line_editor.rb, line 2067
            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

vi_change_meta_confirm(byte_pointer_diff) click to toggle source

    # File reline/line_editor.rb, line 2079
            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

vi_change_to_eol(key) click to toggle source

Editline

  `vi_change_to_eol` (vi command: `C`) + Kill and change from the cursor to the end of the line.

    # File reline/line_editor.rb, line 1745
            def vi_change_to_eol(key)
      ed_kill_line(key)

      @config.editing_mode = :vi_insert
    end

vi_command_mode(key) click to toggle source

    # File reline/line_editor.rb, line 1957
            def vi_command_mode(key)
      ed_prev_char(key)
      @config.editing_mode = :vi_command
    end

Also aliased as: vi_movement_mode
vi_delete_meta(key, arg: nil) click to toggle source

    # File reline/line_editor.rb, line 2085
            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

vi_delete_meta_confirm(byte_pointer_diff) click to toggle source

    # File reline/line_editor.rb, line 2096
            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

vi_delete_prev_char(key) click to toggle source

    # File reline/line_editor.rb, line 2029
            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

vi_editing_mode(key) click to toggle source

    # File reline/line_editor.rb, line 2348
            def vi_editing_mode(key)
      @config.editing_mode = :vi_insert
    end

vi_end_big_word(key, arg: 1, inclusive: false) click to toggle source

    # File reline/line_editor.rb, line 2014
            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

vi_end_word(key, arg: 1, inclusive: false) click to toggle source

    # File reline/line_editor.rb, line 1981
            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

vi_first_print(key) click to toggle source

    # File reline/line_editor.rb, line 1456
            def vi_first_print(key)
      @byte_pointer = Reline::Unicode.vi_first_print(current_line)
    end

vi_histedit(key) click to toggle source

    # File reline/line_editor.rb, line 2164
            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

vi_insert(key) click to toggle source

    # File reline/line_editor.rb, line 1948
            def vi_insert(key)
      @config.editing_mode = :vi_insert
    end

vi_insert_at_bol(key) click to toggle source

    # File reline/line_editor.rb, line 2043
            def vi_insert_at_bol(key)
      ed_move_to_beg(key)
      @config.editing_mode = :vi_insert
    end

vi_join_lines(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 2322
            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

vi_kill_line_prev(key) click to toggle source

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.

    # File reline/line_editor.rb, line 1756
            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

Also aliased as: unix_line_discard
vi_list_or_eof(key) click to toggle source

    # File reline/line_editor.rb, line 2130
            def vi_list_or_eof(key)
      if buffer_empty?
        @eof = true
        finish
      else
        ed_newline(key)
      end
    end

Also aliased as: vi_end_of_transmission, vi_eof_maybe
vi_next_big_word(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1996
            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

vi_next_char(key, arg: 1, inclusive: false) click to toggle source

    # File reline/line_editor.rb, line 2234
            def vi_next_char(key, arg: 1, inclusive: false)
      @waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg, inclusive: inclusive) }
    end

vi_next_word(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1963
            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

vi_paste_next(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 2185
            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

vi_paste_prev(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 2176
            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

vi_prev_big_word(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 2005
            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

vi_prev_char(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 2281
            def vi_prev_char(key, arg: 1)
      @waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg) }
    end

vi_prev_word(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 1972
            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

vi_replace_char(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 2210
            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 + 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 * arg
          set_current_line(before + replaced + after, @byte_pointer + replaced.bytesize)
          @waiting_proc = nil
        end
      }
    end

vi_search_next(key) click to toggle source

    # File reline/line_editor.rb, line 1582
            def vi_search_next(key)
      incremental_search_history(key)
    end

Also aliased as: forward_search_history
vi_search_prev(key) click to toggle source

    # File reline/line_editor.rb, line 1577
            def vi_search_prev(key)
      incremental_search_history(key)
    end

Also aliased as: reverse_search_history
vi_to_column(key, arg: 0) click to toggle source

    # File reline/line_editor.rb, line 2201
            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

vi_to_history_line(key) click to toggle source

    # File reline/line_editor.rb, line 2157
            def vi_to_history_line(key)
      if Reline::HISTORY.empty?
        return
      end
      move_history(0, line: :start, cursor: :start)
    end

vi_to_next_char(key, arg: 1, inclusive: false) click to toggle source

    # File reline/line_editor.rb, line 2238
            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

vi_to_prev_char(key, arg: 1) click to toggle source

    # File reline/line_editor.rb, line 2285
            def vi_to_prev_char(key, arg: 1)
      @waiting_proc = ->(key_for_proc) { search_prev_char(key_for_proc, arg, true) }
    end

vi_yank(key, arg: nil) click to toggle source

    # File reline/line_editor.rb, line 2108
            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

vi_yank_confirm(byte_pointer_diff) click to toggle source

    # File reline/line_editor.rb, line 2119
            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