123456789_123456789_123456789_123456789_123456789_

Class: Reline::LineEditor

Relationships & Source Files
Namespace Children
Modules:
Classes:
Inherits: Object
Defined in: lib/reline/line_editor.rb

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(config) ⇒ LineEditor

[ GitHub ]

  
# File 'lib/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

Instance Attribute Details

#auto_indent_proc (rw)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 14

attr_accessor :auto_indent_proc

#buffer_empty?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1328

private def buffer_empty?
  current_line.empty? and @buffer_of_lines.size == 1
end

#byte_pointer (rw)

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

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 8

attr_reader :byte_pointer

#byte_pointer=(val) (rw)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1316

def byte_pointer=(val)
  @byte_pointer = val
end

#completion_append_character (rw)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 11

attr_accessor :completion_append_character

#completion_proc (rw)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 10

attr_accessor :completion_proc

#confirm_multiline_termination_proc (rw)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 9

attr_accessor :confirm_multiline_termination_proc

#dig_perfect_match_proc (rw)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 15

attr_accessor :dig_perfect_match_proc

#eof?Boolean (readonly)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 220

def eof?
  @eof
end

#finished?Boolean (readonly)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1332

def finished?
  @finished
end

#output_modifier_proc (rw)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 12

attr_accessor :output_modifier_proc

#prompt_proc (rw)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 13

attr_accessor :prompt_proc

Instance Method Details

#add_dialog_proc(name, p, context = nil)

[ GitHub ]

  
# File 'lib/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

#argumentable?(method_obj) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 938

private def argumentable?(method_obj)
  method_obj and method_obj.parameters.any? { |param| param[0] == :key and param[1] == :arg }
end

#backward_char(key, arg: 1)

Alias for #ed_prev_char.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1503

alias_method :backward_char, :ed_prev_char

#backward_delete_char(key, arg: 1)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1776

alias_method :backward_delete_char, :em_delete_prev_char

#backward_kill_word(key)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1914

alias_method :backward_kill_word, :ed_delete_prev_word

#backward_word(key)

Alias for #ed_prev_word.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1894

alias_method :backward_word, :ed_prev_word

#beginning_of_line(key)

Alias for #ed_move_to_beg.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1512

alias_method :beginning_of_line, :ed_move_to_beg

#byteinsert(str, byte_pointer, other) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1347

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1341

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 308

private 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_overlay_levels(overlay_levels)

[ GitHub ]

  
# 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

#calculate_width(str, allow_escape_code = false) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1354

private def calculate_width(str, allow_escape_code = false)
  Reline::Unicode.calculate_width(str, allow_escape_code)
end

#call_completion_proc(pre, target, post, quote)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1142

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)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1149

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.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1954

alias_method :capitalize_word, :em_capitol_case

#check_mode_string (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 95

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 109

private 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 (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 968

private def cleanup_waiting
  @waiting_proc = nil
  @vi_waiting_operator = nil
  @vi_waiting_operator_arg = nil
  @searching_prompt = nil
  @drop_terminate_spaces = false
end

#clear_dialogs

[ GitHub ]

  
# 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_rendered_screen_cache (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 551

private def clear_rendered_screen_cache
  @rendered_screen.lines = []
  @rendered_screen.cursor_y = 0
end

#clear_screen(key)

Alias for #ed_clear_screen.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1878

alias_method :clear_screen, :ed_clear_screen

#complete(_key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1374

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1392

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1408

private def completion_journey_up(_key)
  completion_journey_move(:up) if @config.autocompletion
end

#confirm_multiline_termination

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1255

def confirm_multiline_termination
  temp_buffer = @buffer_of_lines.dup
  @confirm_multiline_termination_proc.(temp_buffer.join("\n") + "\n")
end

#copy_for_vi(text) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1992

private def copy_for_vi(text)
  if @config.editing_mode_is?(:vi_insert) or @config.editing_mode_is?(:vi_command)
    @vi_clipboard = text
  end
end

#current_byte_pointer_cursor

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 304

def current_byte_pointer_cursor
  calculate_width(current_line.byteslice(0, @byte_pointer))
end

#current_line

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1192

def current_line
  @buffer_of_lines[@line_index]
end

#delete_char(key)

Alias for #em_delete.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1840

alias_method :delete_char, :em_delete

#delete_char_or_list(key)

Alias for #em_delete_or_list.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1854

alias_method :delete_char_or_list, :em_delete_or_list

#delete_text(start = nil, length = nil)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1282

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

[ GitHub ]

  
# File 'lib/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

#dialog_range(dialog, dialog_y) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 703

private 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

#downcase_word(key)

Alias for #em_lower_case.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1967

alias_method :downcase_word, :em_lower_case

#ed_argument_digit(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2245

private def ed_argument_digit(key)
  if @vi_arg.nil?
    if key.chr.to_i.zero?
      if key.anybits?(0b10000000)
        unescaped_key = key ^ 0b10000000
        unless unescaped_key.chr.to_i.zero?
          @vi_arg = unescaped_key.chr.to_i
        end
      end
    else
      @vi_arg = key.chr.to_i
    end
  else
    @vi_arg = @vi_arg * 10 + key.chr.to_i
  end
end

#ed_clear_screen(key) (private) Also known as: #clear_screen

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1872

private 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

#ed_delete_next_char(key, arg: 1) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2191

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2103

private 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) (private) Also known as: #backward_kill_word

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1906

private 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

#ed_digit(key)

Alias for #ed_insert.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1460

alias_method :ed_digit, :ed_insert

#ed_insert(key) (private) Also known as: #ed_digit, #self_insert

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.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1435

private def ed_insert(key)
  if key.instance_of?(String)
    begin
      key.encode(Encoding::UTF_8)
    rescue Encoding::UndefinedConversionError
      return
    end
    str = key
  else
    begin
      key.chr.encode(Encoding::UTF_8)
    rescue Encoding::UndefinedConversionError
      return
    end
    str = key.chr
  end
  if @in_pasting
    @continuous_insertion_buffer << str
    return
  elsif not @continuous_insertion_buffer.empty?
    process_insert
  end

  insert_text(str)
end

#ed_kill_line(key) (private) Also known as: #kill_line

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.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1783

private 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

#ed_move_to_beg(key) (private) Also known as: #beginning_of_line, #vi_zero

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1509

private def ed_move_to_beg(key)
  @byte_pointer = 0
end

#ed_move_to_end(key) (private) Also known as: #end_of_line

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1515

private def ed_move_to_end(key)
  @byte_pointer = current_line.bytesize
end

#ed_newline(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1733

private 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) (private) Also known as: #forward_char

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1479

private 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

#ed_next_history(key, arg: 1) (private) Also known as: #next_history

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1716

private 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

#ed_prev_char(key, arg: 1) (private) Also known as: #backward_char

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1492

private 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

#ed_prev_history(key, arg: 1) (private) Also known as: #previous_history

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1699

private 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

#ed_prev_word(key) (private) Also known as: #backward_word

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1888

private 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

#ed_quoted_insert(str, arg: 1) (private) Also known as: #quoted_insert

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1463

private def ed_quoted_insert(str, arg: 1)
  @waiting_proc = proc { |key|
    arg.times do
      if key == "\C-j".ord or key == "\C-m".ord
        key_newline(key)
      elsif key == 0
        # Ignore NUL.
      else
        ed_insert(key)
      end
    end
    @waiting_proc = nil
  }
end

#ed_search_next_history(key, arg: 1) (private) Also known as: #history_search_forward

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1662

private 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

#ed_search_prev_history(key, arg: 1) (private) Also known as: #history_search_backward

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1647

private 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

#ed_transpose_chars(key) (private) Also known as: #transpose_chars

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1916

private 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

#ed_transpose_words(key) (private) Also known as: #transpose_words

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1933

private 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

#ed_unassigned(key) (private)

do nothing

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1414

private def ed_unassigned(key) end

#editing_mode

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 801

def editing_mode
  @config.editing_mode
end

#em_capitol_case(key) (private) Also known as: #capitalize_word

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1946

private 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

#em_delete(key) (private) Also known as: #delete_char

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1827

private def em_delete(key)
  if buffer_empty? and key == "\C-d".ord
    @eof = true
    finish
  elsif @byte_pointer < current_line.bytesize
    splitted_last = current_line.byteslice(@byte_pointer, current_line.bytesize)
    mbchar = splitted_last.grapheme_clusters.first
    line, = byteslice!(current_line, @byte_pointer, mbchar.bytesize)
    set_current_line(line)
  elsif @byte_pointer == current_line.bytesize and @buffer_of_lines.size > @line_index + 1
    set_current_line(current_line + @buffer_of_lines.delete_at(@line_index + 1), current_line.bytesize)
  end
end

#em_delete_next_word(key) (private) Also known as: #kill_word

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1896

private 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

#em_delete_or_list(key) (private) Also known as: #delete_char_or_list

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1842

private 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

#em_delete_prev_char(key, arg: 1) (private) Also known as: #backward_delete_char

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1762

private 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

#em_exchange_mark(key) (private) Also known as: #exchange_point_and_mark

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2407

private 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

#em_kill_line(key) (private) Also known as: #kill_whole_line

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.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1819

private def em_kill_line(key)
  if current_line.size > 0
    @kill_ring.append(current_line.dup, true)
    set_current_line('', 0)
  end
end

#em_kill_region(key) (private) Also known as: #unix_word_rubout

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1982

private 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

#em_lower_case(key) (private) Also known as: #downcase_word

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1956

private 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

#em_next_word(key) (private) Also known as: #forward_word

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1880

private 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

#em_set_mark(key) (private) Also known as: #set_mark

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2402

private def em_set_mark(key)
  @mark_pointer = [@byte_pointer, @line_index]
end

#em_upper_case(key) (private) Also known as: #upcase_word

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1969

private 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

#em_yank(key) (private) Also known as: #yank

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1856

private def em_yank(key)
  yanked = @kill_ring.yank
  insert_text(yanked) if yanked
end

#em_yank_pop(key) (private) Also known as: #yank_pop

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1862

private 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

#emacs_editing_mode(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2415

private def emacs_editing_mode(key)
  @config.editing_mode = :emacs
end

#encoding

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 84

def encoding
  io_gate.encoding
end

#end_of_line(key)

Alias for #ed_move_to_end.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1518

alias_method :end_of_line, :ed_move_to_end

#exchange_point_and_mark(key)

Alias for #em_exchange_mark.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2413

alias_method :exchange_point_and_mark, :em_exchange_mark

#filter_normalize_candidates(target, list) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 809

private 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

#finalize

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 216

def finalize
  Signal.trap('INT', @old_trap)
end

#finish

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1336

def finish
  @finished = true
  @config.reset
end

#forward_char(key, arg: 1)

Alias for #ed_next_char.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1490

alias_method :forward_char, :ed_next_char

#forward_search_history(key)

Alias for #vi_search_next.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1635

alias_method :forward_search_history, :vi_search_next

#forward_word(key)

Alias for #em_next_word.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1886

alias_method :forward_word, :em_next_word

#generate_searcher(search_key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1520

private 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".ord, "\C-?".ord
      grapheme_clusters = search_word.grapheme_clusters
      if grapheme_clusters.size > 0
        grapheme_clusters.pop
        search_word = grapheme_clusters.join
      end
    when "\C-r".ord, "\C-s".ord
      search_again = true if search_key == key
      search_key = key
    else
      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".ord
            history_pointer_base = 0
            history = Reline::HISTORY[0..(@history_pointer - 1)]
          when "\C-s".ord
            history_pointer_base = @history_pointer + 1
            history = Reline::HISTORY[(@history_pointer + 1)..-1]
          end
        else
          history_pointer_base = 0
          history = Reline::HISTORY
        end
      elsif @history_pointer
        case search_key
        when "\C-r".ord
          history_pointer_base = 0
          history = Reline::HISTORY[0..@history_pointer]
        when "\C-s".ord
          history_pointer_base = @history_pointer
          history = Reline::HISTORY[@history_pointer..-1]
        end
      else
        history_pointer_base = 0
        history = Reline::HISTORY
      end
      case search_key
      when "\C-r".ord
        hit_index = history.rindex { |item|
          item.include?(search_word)
        }
      when "\C-s".ord
        hit_index = history.index { |item|
          item.include?(search_word)
        }
      end
      if hit_index
        hit_pointer = history_pointer_base + hit_index
        hit = Reline::HISTORY[hit_pointer]
      end
    end
    case search_key
    when "\C-r".ord
      prompt_name = 'reverse-i-search'
    when "\C-s".ord
      prompt_name = 'i-search'
    end
    prompt_name = "failed #{prompt_name}" unless hit
    [search_word, prompt_name, hit_pointer]
  end
end

#handle_interrupted (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 185

private 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 (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 173

private 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

#handle_signal

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 168

def handle_signal
  handle_interrupted
  handle_resized
end

#history_search_backward(key, arg: 1)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1660

alias_method :history_search_backward, :ed_search_prev_history

#history_search_forward(key, arg: 1)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1675

alias_method :history_search_forward, :ed_search_next_history

#inclusive?(method_obj) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 942

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1599

private def incremental_search_history(key)
  backup = @buffer_of_lines.dup, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history
  searcher = generate_searcher(key)
  @searching_prompt = "(reverse-i-search)`': "
  termination_keys = ["\C-j".ord]
  termination_keys.concat(@config.isearch_terminators.chars.map(&:ord)) if @config.isearch_terminators
  @waiting_proc = ->(k) {
    chr = k.is_a?(String) ? k : k.chr(Encoding::ASCII_8BIT)
    if k == "\C-g".ord
      # cancel search and restore buffer
      @buffer_of_lines, @line_index, @byte_pointer, @history_pointer, @line_backup_in_history = backup
      @searching_prompt = nil
      @waiting_proc = nil
    elsif !termination_keys.include?(k) && (chr.match?(/[[:print:]]/) || k == "\C-h".ord || k == "\C-?".ord || k == "\C-r".ord || k == "\C-s".ord)
      search_word, prompt_name, hit_pointer = searcher.call(k)
      Reline.last_incremental_search = search_word
      @searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
      @searching_prompt += ': ' unless @is_multiline
      move_history(hit_pointer, line: :end, cursor: :end) if hit_pointer
    else
      # terminaton_keys and other keys will terminalte
      move_history(@history_pointer, line: :end, cursor: :start)
      @searching_prompt = nil
      @waiting_proc = nil
    end
  }
end

#input_key(key)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1063

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)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1260

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_new_line(cursor_line, next_line) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 277

private 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_text(text)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1272

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

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 80

def io_gate
  Reline::IOGate
end

#key_delete(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1358

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1366

private 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

#kill_line(key)

Alias for #ed_kill_line.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1792

alias_method :kill_line, :ed_kill_line

#kill_whole_line(key)

Alias for #em_kill_line.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1825

alias_method :kill_whole_line, :em_kill_line

#kill_word(key)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1904

alias_method :kill_word, :em_delete_next_word

#line

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1188

def line()
  @buffer_of_lines.join("\n") unless eof?
end

#modified_lines

[ GitHub ]

  
# 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

#modify_lines(before, complete) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 793

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 887

private 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:) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1677

private 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

#multiline_off

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 273

def multiline_off
  @is_multiline = false
end

#multiline_on

[ GitHub ]

  
# 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.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1731

alias_method :next_history, :ed_next_history

#normal_char(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1040

private def normal_char(key)
  if key.char < 0x80
    method_symbol = @config.editing_mode.get_method(key.combined_char)
    process_key(key.combined_char, method_symbol)
  else
    process_key(key.char.chr(encoding), nil)
  end
  if @config.editing_mode_is?(:vi_command) and @byte_pointer > 0 and @byte_pointer == current_line.bytesize
    byte_size = Reline::Unicode.get_prev_mbchar_size(@buffer_of_lines[@line_index], @byte_pointer)
    @byte_pointer -= byte_size
  end
end

#perform_completion(preposing, target, postposing, quote, list) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 832

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2443

private def prev_action_state_value(type)
  @prev_action_state[0] == type ? @prev_action_state[1] : nil
end

#previous_history(key, arg: 1)

Alias for #ed_prev_history.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1714

alias_method :previous_history, :ed_prev_history

#process_auto_indent(line_index = @line_index, cursor_dependent: true, add_newline: false) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1171

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1416

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 976

private def process_key(key, method_symbol)
  if key.is_a?(Symbol)
    cleanup_waiting
  elsif @waiting_proc
    old_byte_pointer = @byte_pointer
    @waiting_proc.call(key)
    if @vi_waiting_operator
      byte_pointer_diff = @byte_pointer - old_byte_pointer
      @byte_pointer = old_byte_pointer
      method_obj = method(@vi_waiting_operator)
      wrap_method_call(@vi_waiting_operator, method_obj, byte_pointer_diff)
      cleanup_waiting
    end
    @kill_ring.process
    return
  end

  if method_symbol and respond_to?(method_symbol, true)
    method_obj = method(method_symbol)
  end
  if method_symbol and key.is_a?(Symbol)
    if @vi_arg and argumentable?(method_obj)
      run_for_operators(key, method_symbol) do |with_operator|
        wrap_method_call(method_symbol, method_obj, key, with_operator)
      end
    else
      wrap_method_call(method_symbol, method_obj, key) if method_obj
    end
    @kill_ring.process
    if @vi_arg
      @vi_arg = nil
    end
  elsif @vi_arg
    if key.chr =~ /[0-9]/
      ed_argument_digit(key)
    else
      if argumentable?(method_obj)
        run_for_operators(key, method_symbol) do |with_operator|
          wrap_method_call(method_symbol, method_obj, key, with_operator)
        end
      elsif method_obj
        wrap_method_call(method_symbol, method_obj, key)
      else
        ed_insert(key) unless @config.editing_mode_is?(:vi_command)
      end
      @kill_ring.process
      if @vi_arg
        @vi_arg = nil
      end
    end
  elsif method_obj
    if method_symbol == :ed_argument_digit
      wrap_method_call(method_symbol, method_obj, key)
    else
      run_for_operators(key, method_symbol) do |with_operator|
        wrap_method_call(method_symbol, method_obj, key, with_operator)
      end
    end
    @kill_ring.process
  else
    ed_insert(key) unless @config.editing_mode_is?(:vi_command)
  end
end

#prompt_list

[ GitHub ]

  
# 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

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1113

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.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1477

alias_method :quoted_insert, :ed_quoted_insert

#re_read_init_file(_key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2451

private def re_read_init_file(_key)
  @config.reload
end

#redo(_key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2433

private def redo(_key)
  @undoing = true

  return if @input_lines_position >= @input_lines.size - 1

  @input_lines_position += 1
  target_lines, target_cursor_x, target_cursor_y = @input_lines[@input_lines_position]
  set_current_lines(target_lines.dup, target_cursor_x, target_cursor_y)
end

#render

[ GitHub ]

  
# File 'lib/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_differential(new_lines, new_cursor_x, new_cursor_y) (private)

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

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 515

private 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

#render_finished

[ GitHub ]

  
# File 'lib/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)

[ GitHub ]

  
# 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
      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

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 564

def rerender
  render unless @in_pasting
end

#reset(prompt = '')

[ GitHub ]

  
# File 'lib/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

[ GitHub ]

  
# File 'lib/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 = '')

[ GitHub ]

  
# File 'lib/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
  @undoing = false
  @prev_action_state = NullActionState
  @next_action_state = NullActionState
  reset_line
end

#rest_height(wrapped_cursor_y)

[ GitHub ]

  
# File 'lib/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

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1219

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

#retrieve_completion_journey_state (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 899

private 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

#reverse_search_history(key)

Alias for #vi_search_prev.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1630

alias_method :reverse_search_history, :vi_search_prev

#run_for_operators(key, method_symbol, &block) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 914

private 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

#save_old_buffer

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1109

def save_old_buffer
  @old_buffer_of_lines = @buffer_of_lines.dup
end

#screen_height

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 363

def screen_height
  @screen_size.first
end

#screen_scroll_top

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 371

def screen_scroll_top
  @scroll_partial_screen
end

#screen_width

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 367

def screen_width
  @screen_size.last
end

#scroll_into_view

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1132

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

#search_history(prefix, pointer_range) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1637

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2303

private def search_next_char(key, arg, need_prev_char: false, inclusive: false)
  if key.instance_of?(String)
    inputted_char = key
  else
    inputted_char = key.chr
  end
  prev_total = nil
  total = nil
  found = false
  current_line.byteslice(@byte_pointer..-1).grapheme_clusters.each do |mbchar|
    # total has [byte_size, cursor]
    unless total
      # skip cursor point
      width = Reline::Unicode.get_mbchar_width(mbchar)
      total = [mbchar.bytesize, width]
    else
      if inputted_char == mbchar
        arg -= 1
        if arg.zero?
          found = true
          break
        end
      end
      width = Reline::Unicode.get_mbchar_width(mbchar)
      prev_total = total
      total = [total.first + mbchar.bytesize, total.last + width]
    end
  end
  if not need_prev_char and found and total
    byte_size, _ = total
    @byte_pointer += byte_size
  elsif need_prev_char and found and prev_total
    byte_size, _ = prev_total
    @byte_pointer += byte_size
  end
  if inclusive
    byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
    if byte_size > 0
      @byte_pointer += byte_size
    end
  end
  @waiting_proc = nil
end

#search_prev_char(key, arg, need_next_char = false) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2355

private def search_prev_char(key, arg, need_next_char = false)
  if key.instance_of?(String)
    inputted_char = key
  else
    inputted_char = key.chr
  end
  prev_total = nil
  total = nil
  found = false
  current_line.byteslice(0..@byte_pointer).grapheme_clusters.reverse_each do |mbchar|
    # total has [byte_size, cursor]
    unless total
      # skip cursor point
      width = Reline::Unicode.get_mbchar_width(mbchar)
      total = [mbchar.bytesize, width]
    else
      if inputted_char == mbchar
        arg -= 1
        if arg.zero?
          found = true
          break
        end
      end
      width = Reline::Unicode.get_mbchar_width(mbchar)
      prev_total = total
      total = [total.first + mbchar.bytesize, total.last + width]
    end
  end
  if not need_next_char and found and total
    byte_size, _ = total
    @byte_pointer -= byte_size
  elsif need_next_char and found and prev_total
    byte_size, _ = prev_total
    @byte_pointer -= byte_size
  end
  @waiting_proc = nil
end

#self_insert(key)

Alias for #ed_insert.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1461

alias_method :self_insert, :ed_insert

#set_current_line(line, byte_pointer = nil)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1196

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)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1207

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.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2405

alias_method :set_mark, :em_set_mark

#set_next_action_state(type, value) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2447

private def set_next_action_state(type, value)
  @next_action_state = [type, value]
end

#set_pasting_state(in_pasting)

[ GitHub ]

  
# File 'lib/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

[ GitHub ]

  
# File 'lib/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

#split_line_by_width(str, max_width, offset: 0) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 300

private def split_line_by_width(str, max_width, offset: 0)
  Reline::Unicode.split_line_by_width(str, max_width, encoding, offset: offset)
end

#transpose_chars(key)

Alias for #ed_transpose_chars.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1931

alias_method :transpose_chars, :ed_transpose_chars

#transpose_words(key)

Alias for #ed_transpose_words.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1944

alias_method :transpose_words, :ed_transpose_words

#trim_input_lines

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1125

def trim_input_lines
  if @input_lines.size > MAX_INPUT_LINES
    @input_lines.shift
    @input_lines_position -= 1
  end
end

#undo(_key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2423

private def undo(_key)
  @undoing = true

  return if @input_lines_position <= 0

  @input_lines_position -= 1
  target_lines, target_cursor_x, target_cursor_y = @input_lines[@input_lines_position]
  set_current_lines(target_lines.dup, target_cursor_x, target_cursor_y)
end

#unix_line_discard(key)

Alias for #vi_kill_line_prev.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1813

alias_method :unix_line_discard, :vi_kill_line_prev

#unix_word_rubout(key)

Alias for #em_kill_region.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1990

alias_method :unix_word_rubout, :em_kill_region

#upcase_word(key)

Alias for #em_upper_case.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1980

alias_method :upcase_word, :em_upper_case

#update(key)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1053

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)

[ GitHub ]

  
# 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

#update_each_dialog(dialog, cursor_column, cursor_row, key = nil) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 709

private 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

#upper_space_height(wrapped_cursor_y)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 556

def upper_space_height(wrapped_cursor_y)
  wrapped_cursor_y - screen_scroll_top
end

#vi_add(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2002

private def vi_add(key)
  @config.editing_mode = :vi_insert
  ed_next_char(key)
end

#vi_add_at_eol(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2098

private def vi_add_at_eol(key)
  ed_move_to_end(key)
  @config.editing_mode = :vi_insert
end

#vi_change_meta(key, arg: nil) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2117

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2129

private 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) (private)

Editline

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

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1795

private def vi_change_to_eol(key)
  ed_kill_line(key)

  @config.editing_mode = :vi_insert
end

#vi_command_mode(key) (private) Also known as: #vi_movement_mode

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2007

private def vi_command_mode(key)
  ed_prev_char(key)
  @config.editing_mode = :vi_command
end

#vi_delete_meta(key, arg: nil) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2135

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2146

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2079

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2419

private def vi_editing_mode(key)
  @config.editing_mode = :vi_insert
end

#vi_end_big_word(key, arg: 1, inclusive: false) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2064

private 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_of_transmission(key)

Alias for #vi_list_or_eof.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2188

alias_method :vi_end_of_transmission, :vi_list_or_eof

#vi_end_word(key, arg: 1, inclusive: false) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2031

private 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_eof_maybe(key)

Alias for #vi_list_or_eof.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2189

alias_method :vi_eof_maybe, :vi_list_or_eof

#vi_first_print(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1505

private def vi_first_print(key)
  @byte_pointer = Reline::Unicode.vi_first_print(current_line)
end

#vi_histedit(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2214

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1998

private def vi_insert(key)
  @config.editing_mode = :vi_insert
end

#vi_insert_at_bol(key) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2093

private def vi_insert_at_bol(key)
  ed_move_to_beg(key)
  @config.editing_mode = :vi_insert
end

#vi_join_lines(key, arg: 1) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2393

private 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) (private) Also known as: #unix_line_discard

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.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1806

private 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

#vi_list_or_eof(key) (private) Also known as: #vi_end_of_transmission, #vi_eof_maybe

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2180

private def vi_list_or_eof(key)
  if buffer_empty?
    @eof = true
    finish
  else
    ed_newline(key)
  end
end

#vi_movement_mode(key)

Alias for #vi_command_mode.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2011

alias_method :vi_movement_mode, :vi_command_mode

#vi_next_big_word(key, arg: 1) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2046

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2295

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2013

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2235

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2226

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2055

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2347

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2022

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2271

private def vi_replace_char(key, arg: 1)
  @waiting_proc = ->(k) {
    if arg == 1
      byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
      before = current_line.byteslice(0, @byte_pointer)
      remaining_point = @byte_pointer + byte_size
      after = current_line.byteslice(remaining_point, current_line.bytesize - remaining_point)
      set_current_line(before + k.chr + after)
      @waiting_proc = nil
    elsif arg > 1
      byte_size = 0
      arg.times do
        byte_size += Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer + byte_size)
      end
      before = current_line.byteslice(0, @byte_pointer)
      remaining_point = @byte_pointer + byte_size
      after = current_line.byteslice(remaining_point, current_line.bytesize - remaining_point)
      replaced = k.chr * arg
      set_current_line(before + replaced + after, @byte_pointer + replaced.bytesize)
      @waiting_proc = nil
    end
  }
end

#vi_search_next(key) (private) Also known as: #forward_search_history

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1632

private def vi_search_next(key)
  incremental_search_history(key)
end

#vi_search_prev(key) (private) Also known as: #reverse_search_history

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1627

private def vi_search_prev(key)
  incremental_search_history(key)
end

#vi_to_column(key, arg: 0) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2262

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2207

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2299

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2351

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2158

private 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) (private)

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 2169

private 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

#vi_zero(key)

Alias for #ed_move_to_beg.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1513

alias_method :vi_zero, :ed_move_to_beg

#whole_buffer

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1324

def whole_buffer
  whole_lines.join("\n")
end

#whole_lines

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1320

def whole_lines
  @buffer_of_lines.dup
end

#with_cache(key, *deps)

[ GitHub ]

  
# 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)

[ GitHub ]

  
# File 'lib/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

Calculate cursor position in word wrapped content.

[ GitHub ]

  
# 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_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

[ GitHub ]

  
# 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_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.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1860

alias_method :yank, :em_yank

#yank_pop(key)

Alias for #em_yank_pop.

[ GitHub ]

  
# File 'lib/reline/line_editor.rb', line 1870

alias_method :yank_pop, :em_yank_pop