class Reline::LineEditor

Constants

CompletionJourneyState
DIALOG_DEFAULT_HEIGHT
MAX_INPUT_LINES
MINIMUM_SCROLLBAR_HEIGHT
NullActionState
RenderedScreen
VI_MOTIONS

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 [W]
output_modifier_proc [RW]
prompt_proc [RW]

Public Class Methods

new (config, encoding)
# File lib/reline/line_editor.rb, line 75
def initialize(config, encoding)
  @config = config
  @completion_append_character = ''
  @screen_size = [0, 0] # Should be initialized with actual winsize in LineEditor#reset
  reset_variables(encoding: encoding)
end

Public Instance Methods

add_dialog_proc (name, p, context = nil)
# File lib/reline/line_editor.rb, line 681
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)
# File lib/reline/line_editor.rb, line 1380
def byte_pointer=(val)
  @byte_pointer = val
end
calculate_overlay_levels (overlay_levels)
# File lib/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 ()
# File lib/reline/line_editor.rb, line 1165
def call_completion_proc
  result = retrieve_completion_block(true)
  pre, target, post = result
  result = call_completion_proc_with_checking_args(pre, target, post)
  Reline.core.instance_variable_set(:@completion_quote_character, nil)
  result
end
call_completion_proc_with_checking_args (pre, target, post)
# File lib/reline/line_editor.rb, line 1173
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 ()
# File lib/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 ()
# File lib/reline/line_editor.rb, line 1319
def confirm_multiline_termination
  temp_buffer = @buffer_of_lines.dup
  @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
end
current_byte_pointer_cursor ()
# File lib/reline/line_editor.rb, line 304
def current_byte_pointer_cursor
  calculate_width(current_line.byteslice(0, @byte_pointer))
end
current_line ()
# File lib/reline/line_editor.rb, line 1216
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)
# File lib/reline/line_editor.rb, line 1346
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 ()
# File lib/reline/line_editor.rb, line 888
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 (key)
Alias for: ed_insert
editing_mode ()
# File lib/reline/line_editor.rb, line 790
def editing_mode
  @config.editing_mode
end
end_of_line (key)
Alias for: ed_move_to_end
eof? ()
# File lib/reline/line_editor.rb, line 218
def eof?
  @eof
end
exchange_point_and_mark (key)
Alias for: em_exchange_mark
finalize ()
# File lib/reline/line_editor.rb, line 214
def finalize
  Signal.trap('INT', @old_trap)
end
finish ()
# File lib/reline/line_editor.rb, line 1400
def finish
  @finished = true
  @config.reset
end
finished? ()
# File lib/reline/line_editor.rb, line 1396
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 ()
# File lib/reline/line_editor.rb, line 166
def handle_signal
  handle_interrupted
  handle_resized
end
history_search_backward (key, arg: 1)
history_search_forward (key, arg: 1)
input_key (key)
# File lib/reline/line_editor.rb, line 1086
def input_key(key)
  save_old_buffer
  @config.reset_oneshot_key_bindings
  @dialogs.each do |dialog|
    if key.char.instance_of?(Symbol) and key.char == dialog.name
      return
    end
  end
  if key.char.nil?
    process_insert(force: true)
    @eof = buffer_empty?
    finish
    return
  end
  @completion_occurs = false

  if key.char.is_a?(Symbol)
    process_key(key.char, key.char)
  else
    normal_char(key)
  end

  @prev_action_state, @next_action_state = @next_action_state, NullActionState

  unless @completion_occurs
    @completion_state = CompletionState::NORMAL
    @completion_journey_state = nil
  end

  push_input_lines unless @undoing
  @undoing = false

  if @in_pasting
    clear_dialogs
    return
  end

  modified = @old_buffer_of_lines != @buffer_of_lines
  if !@completion_occurs && modified && !@config.disable_completion && @config.autocompletion
    # Auto complete starts only when edited
    process_insert(force: true)
    @completion_journey_state = retrieve_completion_journey_state
  end
  modified
end
insert_multiline_text (text)
# File lib/reline/line_editor.rb, line 1324
def insert_multiline_text(text)
  save_old_buffer
  pre = @buffer_of_lines[@line_index].byteslice(0, @byte_pointer)
  post = @buffer_of_lines[@line_index].byteslice(@byte_pointer..)
  lines = (pre + Reline::Unicode.safe_encode(text, @encoding).gsub(/\r\n?/, "\n") + post).split("\n", -1)
  lines << '' if lines.empty?
  @buffer_of_lines[@line_index, 1] = lines
  @line_index += lines.size - 1
  @byte_pointer = @buffer_of_lines[@line_index].bytesize - post.bytesize
  push_input_lines
end
insert_text (text)
# File lib/reline/line_editor.rb, line 1336
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 ()
# File lib/reline/line_editor.rb, line 82
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 ()
# File lib/reline/line_editor.rb, line 1212
def line()
  @buffer_of_lines.join("\n") unless eof?
end
modified_lines ()
# File lib/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 ()
# File lib/reline/line_editor.rb, line 273
def multiline_off
  @is_multiline = false
end
multiline_on ()
# File lib/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 ()
prompt_list ()
# File lib/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 ()
# File lib/reline/line_editor.rb, line 1136
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
quoted_insert (str, arg: 1)
Alias for: ed_quoted_insert
render ()
# File lib/reline/line_editor.rb, line 476
def render
  wrapped_cursor_x, wrapped_cursor_y = wrapped_cursor_position
  new_lines = wrapped_prompt_and_input_lines.flatten(1)[screen_scroll_top, screen_height].map do |prompt, line|
    prompt_width = Reline::Unicode.calculate_width(prompt, true)
    [[0, prompt_width, prompt], [prompt_width, Reline::Unicode.calculate_width(line, true), line]]
  end
  if @menu_info
    @menu_info.lines(screen_width).each do |item|
      new_lines << [[0, Reline::Unicode.calculate_width(item), item]]
    end
    @menu_info = nil # TODO: do not change state here
  end

  @dialogs.each_with_index do |dialog, index|
    next unless dialog.contents

    x_range, y_range = dialog_range dialog, wrapped_cursor_y - screen_scroll_top
    y_range.each do |row|
      next if row < 0 || row >= screen_height

      dialog_rows = new_lines[row] ||= []
      # index 0 is for prompt, index 1 is for line, index 2.. is for dialog
      dialog_rows[index + 2] = [x_range.begin, dialog.width, dialog.contents[row - y_range.begin]]
    end
  end

  render_differential new_lines, wrapped_cursor_x, wrapped_cursor_y - screen_scroll_top
end
render_finished ()
# File lib/reline/line_editor.rb, line 461
def render_finished
  render_differential([], 0, 0)
  lines = @buffer_of_lines.size.times.map do |i|
    line = prompt_list[i] + modified_lines[i]
    wrapped_lines, = split_by_width(line, screen_width)
    wrapped_lines.last.empty? ? "#{line} " : line
  end
  @output.puts lines.map { |l| "#{l}\r\n" }.join
end
render_line_differential (old_items, new_items)
# File lib/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
      @output.write "#{Reline::IOGate.reset_color_sequence}#{' ' * width}"
    else
      x, w, content = new_items[level]
      cover_begin = base_x != 0 && new_levels[base_x - 1] == level
      cover_end = new_levels[base_x + width] == level
      pos = 0
      unless x == base_x && w == width
        content, pos = Reline::Unicode.take_mbchar_range(content, base_x - x, width, cover_begin: cover_begin, cover_end: cover_end, padding: true)
      end
      Reline::IOGate.move_cursor_column x + pos
      @output.write "#{Reline::IOGate.reset_color_sequence}#{content}#{Reline::IOGate.reset_color_sequence}"
    end
    base_x += width
  end
  if old_levels.size > new_levels.size
    Reline::IOGate.move_cursor_column new_levels.size
    Reline::IOGate.erase_after_cursor
  end
end
rerender ()
# File lib/reline/line_editor.rb, line 554
def rerender
  render unless @in_pasting
end
reset (prompt = '', encoding:)
# File lib/reline/line_editor.rb, line 139
def reset(prompt = '', encoding:)
  @screen_size = Reline::IOGate.get_screen_size
  reset_variables(prompt, encoding: encoding)
  @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 ()
# File lib/reline/line_editor.rb, line 260
def reset_line
  @byte_pointer = 0
  @buffer_of_lines = [String.new(encoding: @encoding)]
  @line_index = 0
  @cache.clear
  @line_backup_in_history = nil
  @multibyte_buffer = String.new(encoding: 'ASCII-8BIT')
end
reset_variables (prompt = '', encoding:)
# File lib/reline/line_editor.rb, line 222
def reset_variables(prompt = '', encoding:)
  @prompt = prompt.gsub("\n", "\\n")
  @mark_pointer = nil
  @encoding = encoding
  @is_multiline = false
  @finished = false
  @history_pointer = nil
  @kill_ring ||= Reline::KillRing.new
  @vi_clipboard = ''
  @vi_arg = nil
  @waiting_proc = nil
  @vi_waiting_operator = nil
  @vi_waiting_operator_arg = nil
  @completion_journey_state = nil
  @completion_state = CompletionState::NORMAL
  @perfect_matched = nil
  @menu_info = nil
  @searching_prompt = nil
  @just_cursor_moving = false
  @eof = false
  @continuous_insertion_buffer = String.new(encoding: @encoding)
  @scroll_partial_screen = 0
  @drop_terminate_spaces = false
  @in_pasting = false
  @auto_indent_proc = nil
  @dialogs = []
  @interrupted = false
  @resized = false
  @cache = {}
  @rendered_screen = RenderedScreen.new(base_y: 0, lines: [], cursor_y: 0)
  @input_lines = [[[""], 0, 0]]
  @input_lines_position = 0
  @undoing = false
  @prev_action_state = NullActionState
  @next_action_state = NullActionState
  reset_line
end
rest_height (wrapped_cursor_y)
# File lib/reline/line_editor.rb, line 550
def rest_height(wrapped_cursor_y)
  screen_height - wrapped_cursor_y + screen_scroll_top - @rendered_screen.base_y - 1
end
retrieve_completion_block (set_completion_quote_character = false)
# File lib/reline/line_editor.rb, line 1243
def retrieve_completion_block(set_completion_quote_character = false)
  if Reline.completer_word_break_characters.empty?
    word_break_regexp = nil
  else
    word_break_regexp = /\A[#{Regexp.escape(Reline.completer_word_break_characters)}]/
  end
  if Reline.completer_quote_characters.empty?
    quote_characters_regexp = nil
  else
    quote_characters_regexp = /\A[#{Regexp.escape(Reline.completer_quote_characters)}]/
  end
  before = current_line.byteslice(0, @byte_pointer)
  rest = nil
  break_pointer = nil
  quote = nil
  closing_quote = nil
  escaped_quote = nil
  i = 0
  while i < @byte_pointer do
    slice = current_line.byteslice(i, @byte_pointer - i)
    unless slice.valid_encoding?
      i += 1
      next
    end
    if quote and slice.start_with?(closing_quote)
      quote = nil
      i += 1
      rest = nil
    elsif quote and slice.start_with?(escaped_quote)
      # skip
      i += 2
    elsif quote_characters_regexp and slice =~ quote_characters_regexp # find new "
      rest = $'
      quote = $&
      closing_quote = /(?!\\)#{Regexp.escape(quote)}/
      escaped_quote = /\\#{Regexp.escape(quote)}/
      i += 1
      break_pointer = i - 1
    elsif word_break_regexp and not quote and slice =~ word_break_regexp
      rest = $'
      i += 1
      before = current_line.byteslice(i, @byte_pointer - i)
      break_pointer = i
    else
      i += 1
    end
  end
  postposing = current_line.byteslice(@byte_pointer, current_line.bytesize - @byte_pointer)
  if rest
    preposing = current_line.byteslice(0, break_pointer)
    target = rest
    if set_completion_quote_character and quote
      Reline.core.instance_variable_set(:@completion_quote_character, quote)
      if postposing !~ /(?!\\)#{Regexp.escape(quote)}/ # closing quote
        insert_text(quote)
      end
    end
  else
    preposing = ''
    if break_pointer
      preposing = current_line.byteslice(0, break_pointer)
    else
      preposing = ''
    end
    target = before
  end
  lines = whole_lines
  if @line_index > 0
    preposing = lines[0..(@line_index - 1)].join("\n") + "\n" + preposing
  end
  if (lines.size - 1) > @line_index
    postposing = postposing + "\n" + lines[(@line_index + 1)..-1].join("\n")
  end
  [preposing.encode(@encoding), target.encode(@encoding), postposing.encode(@encoding)]
end
reverse_search_history (key)
Alias for: vi_search_prev
save_old_buffer ()
# File lib/reline/line_editor.rb, line 1132
def save_old_buffer
  @old_buffer_of_lines = @buffer_of_lines.dup
end
screen_height ()
# File lib/reline/line_editor.rb, line 363
def screen_height
  @screen_size.first
end
screen_scroll_top ()
# File lib/reline/line_editor.rb, line 371
def screen_scroll_top
  @scroll_partial_screen
end
screen_width ()
# File lib/reline/line_editor.rb, line 367
def screen_width
  @screen_size.last
end
scroll_into_view ()
# File lib/reline/line_editor.rb, line 1155
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 (key)
Alias for: ed_insert
set_current_line (line, byte_pointer = nil)
# File lib/reline/line_editor.rb, line 1220
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_current_lines (lines, byte_pointer = nil, line_index = 0)
# File lib/reline/line_editor.rb, line 1231
def set_current_lines(lines, byte_pointer = nil, line_index = 0)
  cursor = current_byte_pointer_cursor
  @buffer_of_lines = lines
  @line_index = line_index
  if byte_pointer
    @byte_pointer = byte_pointer
  else
    calculate_nearest_cursor(cursor)
  end
  process_auto_indent
end
set_mark (key)
Alias for: em_set_mark
set_pasting_state (in_pasting)
# File lib/reline/line_editor.rb, line 86
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 ()
# File lib/reline/line_editor.rb, line 205
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 ()
# File lib/reline/line_editor.rb, line 1148
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)
# File lib/reline/line_editor.rb, line 1076
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)
# File lib/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)
# File lib/reline/line_editor.rb, line 546
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 ()
# File lib/reline/line_editor.rb, line 1388
def whole_buffer
  whole_lines.join("\n")
end
whole_lines ()
# File lib/reline/line_editor.rb, line 1384
def whole_lines
  @buffer_of_lines.dup
end
with_cache (key, *deps) { |*deps, cached_deps, value| ... }
# File lib/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)
# File lib/reline/line_editor.rb, line 962
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 ()

Calculate cursor position in word wrapped content.

# File lib/reline/line_editor.rb, line 437
def wrapped_cursor_position
  prompt_width = calculate_width(prompt_list[@line_index], true)
  line_before_cursor = whole_lines[@line_index].byteslice(0, @byte_pointer)
  wrapped_line_before_cursor = split_by_width(' ' * prompt_width + line_before_cursor, screen_width).first.compact
  wrapped_cursor_y = wrapped_prompt_and_input_lines[0...@line_index].sum(&:size) + wrapped_line_before_cursor.size - 1
  wrapped_cursor_x = calculate_width(wrapped_line_before_cursor.last)
  [wrapped_cursor_x, wrapped_cursor_y]
end
wrapped_prompt_and_input_lines ()
# File lib/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_by_width(prompt, width).first.compact
      wrapped_lines = split_by_width(line, width, offset: calculate_width(code_line_prompt, true)).first.compact
      wrapped_prompts.map { |p| [p, ''] } + [[code_line_prompt, wrapped_lines.first]] + wrapped_lines.drop(1).map { |c| ['', c] }
    end
  end
end
yank (key)
Alias for: em_yank
yank_pop (key)
Alias for: em_yank_pop