mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Add Reline as a fallback library for Readline
* lib/reine.rb, lib/reline/*: Reline is a readline stdlib compatible library. * lib/readline.rb: Readline uses a fallback to Reline when ext/readline doesn't exist. * tool/sync_default_gems.rb: add ruby/reline as a default gem. * appveyor.yml: add "set RELINE_TEST_ENCODING=Windows-31J" for test suit of Reline, and add "--exclude readline" to "nmake test-all" on Visual Studio builds because of strange behavior. * spec/ruby/library/readline/spec_helper.rb: skip Reline as with RbReadline.
This commit is contained in:
parent
eb45ba6116
commit
17350c7e55
26 changed files with 8103 additions and 3 deletions
|
@ -63,9 +63,10 @@ for:
|
|||
- if not "%GEMS_FOR_TEST%" == "" \usr\bin\gem install --no-document %GEMS_FOR_TEST%
|
||||
test_script:
|
||||
- set /a JOBS=%NUMBER_OF_PROCESSORS%
|
||||
- set RELINE_TEST_ENCODING=Windows-31J
|
||||
- nmake -l "TESTOPTS=-v -q" btest
|
||||
- nmake -l "TESTOPTS=-v -q" test-basic
|
||||
- nmake -l "TESTOPTS=-q --subprocess-timeout-scale=3.0 --excludes=../test/excludes/_appveyor -j%JOBS% --exclude win32ole --exclude test_bignum --exclude test_syntax --exclude test_open-uri --exclude test_bundled_ca --exclude test_gc_compact" test-all
|
||||
- nmake -l "TESTOPTS=-q --subprocess-timeout-scale=3.0 --excludes=../test/excludes/_appveyor -j%JOBS% --exclude readline --exclude win32ole --exclude test_bignum --exclude test_syntax --exclude test_open-uri --exclude test_bundled_ca --exclude test_gc_compact" test-all
|
||||
# separately execute tests without -j which may crash worker with -j.
|
||||
- nmake -l "TESTOPTS=-v --subprocess-timeout-scale=3.0 --excludes=../test/excludes/_appveyor" test-all TESTS="../test/win32ole ../test/ruby/test_bignum.rb ../test/ruby/test_syntax.rb ../test/open-uri/test_open-uri.rb ../test/rubygems/test_bundled_ca.rb ../test/ruby/test_gc_compact.rb"
|
||||
- nmake -l test-spec MSPECOPT=-fs # not using `-j` because sometimes `mspec -j` silently dies on Windows
|
||||
|
@ -108,6 +109,7 @@ for:
|
|||
- mingw32-make DESTDIR=../install install-nodoc
|
||||
- if not "%GEMS_FOR_TEST%" == "" ..\install\bin\gem install --no-document %GEMS_FOR_TEST%
|
||||
test_script:
|
||||
- set RELINE_TEST_ENCODING=Windows-31J
|
||||
- mingw32-make test
|
||||
- mingw32-make test-all TESTOPTS="--retry --job-status=normal --show-skip --subprocess-timeout-scale=1.5 --excludes=../ruby/test/excludes/_appveyor -j %JOBS% --exclude win32ole --exclude test_open-uri --exclude test_gc_compact"
|
||||
# separately execute tests without -j which may crash worker with -j.
|
||||
|
|
6
lib/readline.rb
Normal file
6
lib/readline.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
begin
|
||||
require 'readline.so'
|
||||
rescue LoadError
|
||||
require 'reline'
|
||||
Readline = Reline
|
||||
end
|
197
lib/reline.rb
Normal file
197
lib/reline.rb
Normal file
|
@ -0,0 +1,197 @@
|
|||
require 'io/console'
|
||||
require 'reline/version'
|
||||
require 'reline/config'
|
||||
require 'reline/key_actor'
|
||||
require 'reline/key_stroke'
|
||||
require 'reline/line_editor'
|
||||
|
||||
module Reline
|
||||
extend self
|
||||
FILENAME_COMPLETION_PROC = nil
|
||||
USERNAME_COMPLETION_PROC = nil
|
||||
HISTORY = Array.new
|
||||
|
||||
if RUBY_PLATFORM =~ /mswin|mingw/
|
||||
IS_WINDOWS = true
|
||||
else
|
||||
IS_WINDOWS = false
|
||||
end
|
||||
|
||||
CursorPos = Struct.new(:x, :y)
|
||||
|
||||
class << self
|
||||
attr_accessor :basic_quote_characters
|
||||
attr_accessor :completer_quote_characters
|
||||
attr_accessor :completer_word_break_characters
|
||||
attr_reader :completion_append_character
|
||||
attr_accessor :completion_case_fold
|
||||
attr_accessor :filename_quote_characters
|
||||
attr_writer :input
|
||||
attr_writer :output
|
||||
end
|
||||
|
||||
@@ambiguous_width = nil
|
||||
@@config = nil
|
||||
|
||||
@basic_quote_characters = '"\''
|
||||
# TODO implement below
|
||||
#@completer_quote_characters
|
||||
#@completion_append_character
|
||||
#@completion_case_fold
|
||||
#@filename_quote_characters
|
||||
def self.completion_append_character=(val)
|
||||
if val.nil?
|
||||
@completion_append_character = nil
|
||||
elsif val.size == 1
|
||||
@completion_append_character = val
|
||||
elsif val.size > 1
|
||||
@completion_append_character = val[0]
|
||||
else
|
||||
@completion_append_character = val
|
||||
end
|
||||
end
|
||||
|
||||
@@basic_word_break_characters = " \t\n`><=;|&{("
|
||||
def self.basic_word_break_characters
|
||||
@@basic_word_break_characters
|
||||
end
|
||||
def self.basic_word_break_characters=(v)
|
||||
@@basic_word_break_characters = v
|
||||
end
|
||||
|
||||
@@completer_word_break_characters = @@basic_word_break_characters.dup
|
||||
|
||||
@@completion_proc = nil
|
||||
def self.completion_proc
|
||||
@@completion_proc
|
||||
end
|
||||
def self.completion_proc=(p)
|
||||
@@completion_proc = p
|
||||
end
|
||||
|
||||
@@dig_perfect_match_proc = nil
|
||||
def self.dig_perfect_match_proc
|
||||
@@dig_perfect_match_proc
|
||||
end
|
||||
def self.dig_perfect_match_proc=(p)
|
||||
@@dig_perfect_match_proc = p
|
||||
end
|
||||
|
||||
if IS_WINDOWS
|
||||
require 'reline/windows'
|
||||
else
|
||||
require 'reline/ansi'
|
||||
end
|
||||
|
||||
def retrieve_completion_block(line, byte_pointer)
|
||||
break_regexp = /[#{Regexp.escape(@@basic_word_break_characters)}]/
|
||||
before_pointer = line.byteslice(0, byte_pointer)
|
||||
break_point = before_pointer.rindex(break_regexp)
|
||||
if break_point
|
||||
preposing = before_pointer[0..(break_point)]
|
||||
block = before_pointer[(break_point + 1)..-1]
|
||||
else
|
||||
preposing = ''
|
||||
block = before_pointer
|
||||
end
|
||||
postposing = line.byteslice(byte_pointer, line.bytesize)
|
||||
[preposing, block, postposing]
|
||||
end
|
||||
|
||||
def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
|
||||
if block_given?
|
||||
inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
|
||||
else
|
||||
inner_readline(prompt, add_hist, true)
|
||||
end
|
||||
|
||||
if add_hist and @line_editor.whole_buffer and @line_editor.whole_buffer.chomp.size > 0
|
||||
Reline::HISTORY << @line_editor.whole_buffer
|
||||
end
|
||||
|
||||
@line_editor.whole_buffer
|
||||
end
|
||||
|
||||
def readline(prompt = '', add_hist = false)
|
||||
inner_readline(prompt, add_hist, false)
|
||||
|
||||
if add_hist and @line_editor.line and @line_editor.line.chomp.size > 0
|
||||
Reline::HISTORY << @line_editor.line.chomp
|
||||
end
|
||||
|
||||
@line_editor.line
|
||||
end
|
||||
|
||||
def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination)
|
||||
if @@config.nil?
|
||||
@@config = Reline::Config.new
|
||||
@@config.read
|
||||
end
|
||||
otio = prep
|
||||
|
||||
may_req_ambiguous_char_width
|
||||
@line_editor = Reline::LineEditor.new(@@config, prompt)
|
||||
if multiline
|
||||
@line_editor.multiline_on
|
||||
if block_given?
|
||||
@line_editor.confirm_multiline_termination_proc = confirm_multiline_termination
|
||||
end
|
||||
end
|
||||
@line_editor.completion_proc = @@completion_proc
|
||||
@line_editor.dig_perfect_match_proc = @@dig_perfect_match_proc
|
||||
@line_editor.retrieve_completion_block = method(:retrieve_completion_block)
|
||||
@line_editor.rerender
|
||||
|
||||
if IS_WINDOWS
|
||||
config = {
|
||||
key_mapping: {
|
||||
[224, 72] => :ed_prev_history, # ↑
|
||||
[224, 80] => :ed_next_history, # ↓
|
||||
[224, 77] => :ed_next_char, # →
|
||||
[224, 75] => :ed_prev_char # ←
|
||||
}
|
||||
}
|
||||
else
|
||||
config = {
|
||||
key_mapping: {
|
||||
[27, 91, 65] => :ed_prev_history, # ↑
|
||||
[27, 91, 66] => :ed_next_history, # ↓
|
||||
[27, 91, 67] => :ed_next_char, # →
|
||||
[27, 91, 68] => :ed_prev_char # ←
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
key_stroke = Reline::KeyStroke.new(config)
|
||||
begin
|
||||
while c = getc
|
||||
key_stroke.input_to!(c)&.then { |inputs|
|
||||
inputs.each { |c|
|
||||
@line_editor.input_key(c)
|
||||
@line_editor.rerender
|
||||
}
|
||||
}
|
||||
break if @line_editor.finished?
|
||||
end
|
||||
Reline.move_cursor_column(0)
|
||||
rescue StandardError => e
|
||||
deprep(otio)
|
||||
raise e
|
||||
end
|
||||
|
||||
deprep(otio)
|
||||
end
|
||||
|
||||
def may_req_ambiguous_char_width
|
||||
return if @@ambiguous_width
|
||||
Reline.move_cursor_column(0)
|
||||
print "\u{25bd}"
|
||||
@@ambiguous_width = Reline.cursor_pos.x
|
||||
Reline.move_cursor_column(0)
|
||||
Reline.erase_after_cursor
|
||||
end
|
||||
|
||||
def self.ambiguous_width
|
||||
@@ambiguous_width
|
||||
end
|
||||
end
|
87
lib/reline/ansi.rb
Normal file
87
lib/reline/ansi.rb
Normal file
|
@ -0,0 +1,87 @@
|
|||
module Reline
|
||||
def getc
|
||||
c = nil
|
||||
until c
|
||||
return nil if @line_editor.finished?
|
||||
result = select([$stdin], [], [], 0.1)
|
||||
next if result.nil?
|
||||
c = $stdin.read(1)
|
||||
end
|
||||
c.ord
|
||||
end
|
||||
|
||||
def self.get_screen_size
|
||||
$stdin.winsize
|
||||
end
|
||||
|
||||
def self.set_screen_size(rows, columns)
|
||||
$stdin.winsize = [rows, columns]
|
||||
self
|
||||
end
|
||||
|
||||
def self.cursor_pos
|
||||
res = ''
|
||||
$stdin.raw do |stdin|
|
||||
$stdout << "\e[6n"
|
||||
$stdout.flush
|
||||
while (c = stdin.getc) != 'R'
|
||||
res << c if c
|
||||
end
|
||||
end
|
||||
m = res.match(/(?<row>\d+);(?<column>\d+)/)
|
||||
CursorPos.new(m[:column].to_i - 1, m[:row].to_i - 1)
|
||||
end
|
||||
|
||||
def self.move_cursor_column(x)
|
||||
print "\e[#{x + 1}G"
|
||||
end
|
||||
|
||||
def self.move_cursor_up(x)
|
||||
if x > 0
|
||||
print "\e[#{x}A" if x > 0
|
||||
elsif x < 0
|
||||
move_cursor_down(-x)
|
||||
end
|
||||
end
|
||||
|
||||
def self.move_cursor_down(x)
|
||||
if x > 0
|
||||
print "\e[#{x}B" if x > 0
|
||||
elsif x < 0
|
||||
move_cursor_up(-x)
|
||||
end
|
||||
end
|
||||
|
||||
def self.erase_after_cursor
|
||||
print "\e[K"
|
||||
end
|
||||
|
||||
def self.scroll_down(x)
|
||||
return if x.zero?
|
||||
print "\e[#{x}S"
|
||||
end
|
||||
|
||||
def self.clear_screen
|
||||
print "\e[2J"
|
||||
print "\e[1;1H"
|
||||
end
|
||||
|
||||
def prep
|
||||
int_handle = Signal.trap('INT', 'IGNORE')
|
||||
otio = `stty -g`.chomp
|
||||
setting = ' -echo -icrnl cbreak'
|
||||
if (`stty -a`.scan(/-parenb\b/).first == '-parenb')
|
||||
setting << ' pass8'
|
||||
end
|
||||
setting << ' -ixoff'
|
||||
`stty #{setting}`
|
||||
Signal.trap('INT', int_handle)
|
||||
otio
|
||||
end
|
||||
|
||||
def deprep(otio)
|
||||
int_handle = Signal.trap('INT', 'IGNORE')
|
||||
`stty #{otio}`
|
||||
Signal.trap('INT', int_handle)
|
||||
end
|
||||
end
|
235
lib/reline/config.rb
Normal file
235
lib/reline/config.rb
Normal file
|
@ -0,0 +1,235 @@
|
|||
require 'pathname'
|
||||
|
||||
class Reline::Config
|
||||
DEFAULT_PATH = Pathname.new(Dir.home).join('.inputrc')
|
||||
|
||||
def initialize
|
||||
@skip_section = nil
|
||||
@if_stack = []
|
||||
@editing_mode_label = :emacs
|
||||
@keymap_label = :emacs
|
||||
@key_actors = {}
|
||||
@key_actors[:emacs] = Reline::KeyActor::Emacs.new
|
||||
@key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
|
||||
@key_actors[:vi_command] = Reline::KeyActor::ViCommand.new
|
||||
end
|
||||
|
||||
def reset
|
||||
if editing_mode_is?(:vi_command)
|
||||
@editing_mode_label = :vi_insert
|
||||
end
|
||||
end
|
||||
|
||||
def editing_mode
|
||||
@key_actors[@editing_mode_label]
|
||||
end
|
||||
|
||||
def editing_mode=(val)
|
||||
@editing_mode_label = val
|
||||
end
|
||||
|
||||
def editing_mode_is?(*val)
|
||||
(val.respond_to?(:any?) ? val : [val]).any?(@editing_mode_label)
|
||||
end
|
||||
|
||||
def keymap
|
||||
@key_actors[@keymap_label]
|
||||
end
|
||||
|
||||
def read(file = DEFAULT_PATH)
|
||||
begin
|
||||
if file.respond_to?(:readlines)
|
||||
lines = file.readlines
|
||||
else
|
||||
File.open(file, 'rt') do |f|
|
||||
lines = f.readlines
|
||||
end
|
||||
end
|
||||
rescue Errno::ENOENT
|
||||
$stderr.puts "no such file #{file}"
|
||||
return nil
|
||||
end
|
||||
|
||||
read_lines(lines)
|
||||
self
|
||||
end
|
||||
|
||||
def read_lines(lines)
|
||||
lines.each do |line|
|
||||
line = line.chomp.gsub(/^\s*/, '')
|
||||
if line[0, 1] == '$'
|
||||
handle_directive(line[1..-1])
|
||||
next
|
||||
end
|
||||
|
||||
next if @skip_section
|
||||
|
||||
if line.match(/^set +([^ ]+) +([^ ]+)/i)
|
||||
var, value = $1.downcase, $2.downcase
|
||||
bind_variable(var, value)
|
||||
next
|
||||
end
|
||||
|
||||
if line =~ /\s*(.*)\s*:\s*(.*)\s*$/
|
||||
key, func_name = $1, $2
|
||||
bind_key(key, func_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def handle_directive(directive)
|
||||
directive, args = directive.split(' ')
|
||||
case directive
|
||||
when 'if'
|
||||
condition = false
|
||||
case args # TODO: variables
|
||||
when 'mode'
|
||||
when 'term'
|
||||
when 'version'
|
||||
else # application name
|
||||
condition = true if args == 'Ruby'
|
||||
end
|
||||
unless @skip_section.nil?
|
||||
@if_stack << @skip_section
|
||||
end
|
||||
@skip_section = !condition
|
||||
when 'else'
|
||||
@skip_section = !@skip_section
|
||||
when 'endif'
|
||||
@skip_section = nil
|
||||
unless @if_stack.empty?
|
||||
@skip_section = @if_stack.pop
|
||||
end
|
||||
when 'include'
|
||||
read(args)
|
||||
end
|
||||
end
|
||||
|
||||
def bind_variable(name, value)
|
||||
case name
|
||||
when %w{
|
||||
bind-tty-special-chars
|
||||
blink-matching-paren
|
||||
byte-oriented
|
||||
completion-ignore-case
|
||||
convert-meta
|
||||
disable-completion
|
||||
enable-keypad
|
||||
expand-tilde
|
||||
history-preserve-point
|
||||
horizontal-scroll-mode
|
||||
input-meta
|
||||
mark-directories
|
||||
mark-modified-lines
|
||||
mark-symlinked-directories
|
||||
match-hidden-files
|
||||
meta-flag
|
||||
output-meta
|
||||
page-completions
|
||||
prefer-visible-bell
|
||||
print-completions-horizontally
|
||||
show-all-if-ambiguous
|
||||
show-all-if-unmodified
|
||||
visible-stats
|
||||
} then
|
||||
variable_name = :"@#{name.tr(?-, ?_)}"
|
||||
instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')
|
||||
when 'bell-style'
|
||||
@bell_style =
|
||||
case value
|
||||
when 'none', 'off'
|
||||
:none
|
||||
when 'audible', 'on'
|
||||
:audible
|
||||
when 'visible'
|
||||
:visible
|
||||
else
|
||||
:audible
|
||||
end
|
||||
when 'comment-begin'
|
||||
@comment_begin = value.dup
|
||||
when 'completion-query-items'
|
||||
@completion_query_items = value.to_i
|
||||
when 'isearch-terminators'
|
||||
@isearch_terminators = instance_eval(value)
|
||||
when 'editing-mode'
|
||||
case value
|
||||
when 'emacs'
|
||||
@editing_mode_label = :emacs
|
||||
@keymap_label = :emacs
|
||||
when 'vi'
|
||||
@editing_mode_label = :vi_insert
|
||||
@keymap_label = :vi_insert
|
||||
end
|
||||
when 'keymap'
|
||||
case value
|
||||
when 'emacs', 'emacs-standard', 'emacs-meta', 'emacs-ctlx'
|
||||
@keymap_label = :emacs
|
||||
when 'vi', 'vi-move', 'vi-command'
|
||||
@keymap_label = :vi_command
|
||||
when 'vi-insert'
|
||||
@keymap_label = :vi_insert
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def bind_key(key, func_name)
|
||||
if key =~ /"(.*)"/
|
||||
keyseq = parse_keyseq($1).force_encoding('ASCII-8BIT')
|
||||
else
|
||||
keyseq = nil
|
||||
end
|
||||
if func_name =~ /"(.*)"/
|
||||
func = parse_keyseq($1).force_encoding('ASCII-8BIT')
|
||||
else
|
||||
func = func_name.to_sym # It must be macro.
|
||||
end
|
||||
[keyseq, func]
|
||||
end
|
||||
|
||||
def key_notation_to_char(notation)
|
||||
case notation
|
||||
when /\\C-([A-Za-z_])/
|
||||
(1 + $1.downcase.ord - ?a.ord).chr('ASCII-8BIT')
|
||||
when /\\M-([0-9A-Za-z_])/
|
||||
modified_key = $1
|
||||
code =
|
||||
case $1
|
||||
when /[0-9]/
|
||||
?\M-0.bytes.first + (modified_key.ord - ?0.ord)
|
||||
when /[A-Z]/
|
||||
?\M-A.bytes.first + (modified_key.ord - ?A.ord)
|
||||
when /[a-z]/
|
||||
?\M-a.bytes.first + (modified_key.ord - ?a.ord)
|
||||
end
|
||||
code.chr('ASCII-8BIT')
|
||||
when /\\C-M-[A-Za-z_]/, /\\M-C-[A-Za-z_]/
|
||||
# 129 M-^A
|
||||
when /\\(\d{1,3})/ then $1.to_i(8).chr # octal
|
||||
when /\\x(\h{1,2})/ then $1.to_i(16).chr # hexadecimal
|
||||
when "\\e" then ?\e
|
||||
when "\\\\" then ?\\
|
||||
when "\\\"" then ?"
|
||||
when "\\'" then ?'
|
||||
when "\\a" then ?\a
|
||||
when "\\b" then ?\b
|
||||
when "\\d" then ?\d
|
||||
when "\\f" then ?\f
|
||||
when "\\n" then ?\n
|
||||
when "\\r" then ?\r
|
||||
when "\\t" then ?\t
|
||||
when "\\v" then ?\v
|
||||
else notation
|
||||
end
|
||||
end
|
||||
|
||||
def parse_keyseq(str)
|
||||
# TODO: Control- and Meta-
|
||||
ret = String.new(encoding: 'ASCII-8BIT')
|
||||
while str =~ /(\\C-[A-Za-z_]|\\M-[0-9A-Za-z_]|\\C-M-[A-Za-z_]|\\M-C-[A-Za-z_]|\\e|\\\\|\\"|\\'|\\a|\\b|\\d|\\f|\\n|\\r|\\t|\\v|\\\d{1,3}|\\x\h{1,2}|.)/
|
||||
ret << key_notation_to_char($&)
|
||||
str = $'
|
||||
end
|
||||
ret
|
||||
end
|
||||
end
|
7
lib/reline/key_actor.rb
Normal file
7
lib/reline/key_actor.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
module Reline::KeyActor
|
||||
end
|
||||
|
||||
require 'reline/key_actor/base'
|
||||
require 'reline/key_actor/emacs'
|
||||
require 'reline/key_actor/vi_command'
|
||||
require 'reline/key_actor/vi_insert'
|
7
lib/reline/key_actor/base.rb
Normal file
7
lib/reline/key_actor/base.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
class Reline::KeyActor::Base
|
||||
MAPPING = Array.new(256)
|
||||
|
||||
def get_method(key)
|
||||
self.class::MAPPING[key]
|
||||
end
|
||||
end
|
518
lib/reline/key_actor/emacs.rb
Normal file
518
lib/reline/key_actor/emacs.rb
Normal file
|
@ -0,0 +1,518 @@
|
|||
class Reline::KeyActor::Emacs < Reline::KeyActor::Base
|
||||
MAPPING = [
|
||||
# 0 ^@
|
||||
:em_set_mark,
|
||||
# 1 ^A
|
||||
:ed_move_to_beg,
|
||||
# 2 ^B
|
||||
:ed_prev_char,
|
||||
# 3 ^C
|
||||
:ed_ignore,
|
||||
# 4 ^D
|
||||
:em_delete_or_list,
|
||||
# 5 ^E
|
||||
:ed_move_to_end,
|
||||
# 6 ^F
|
||||
:ed_next_char,
|
||||
# 7 ^G
|
||||
:ed_unassigned,
|
||||
# 8 ^H
|
||||
:em_delete_prev_char,
|
||||
# 9 ^I
|
||||
:ed_unassigned,
|
||||
# 10 ^J
|
||||
:ed_newline,
|
||||
# 11 ^K
|
||||
:ed_kill_line,
|
||||
# 12 ^L
|
||||
:ed_clear_screen,
|
||||
# 13 ^M
|
||||
:ed_newline,
|
||||
# 14 ^N
|
||||
:ed_next_history,
|
||||
# 15 ^O
|
||||
:ed_ignore,
|
||||
# 16 ^P
|
||||
:ed_prev_history,
|
||||
# 17 ^Q
|
||||
:ed_ignore,
|
||||
# 18 ^R
|
||||
:ed_redisplay,
|
||||
# 19 ^S
|
||||
:ed_ignore,
|
||||
# 20 ^T
|
||||
:ed_transpose_chars,
|
||||
# 21 ^U
|
||||
:em_kill_line,
|
||||
# 22 ^V
|
||||
:ed_quoted_insert,
|
||||
# 23 ^W
|
||||
:em_kill_region,
|
||||
# 24 ^X
|
||||
:ed_sequence_lead_in,
|
||||
# 25 ^Y
|
||||
:em_yank,
|
||||
# 26 ^Z
|
||||
:ed_ignore,
|
||||
# 27 ^[
|
||||
:em_meta_next,
|
||||
# 28 ^\
|
||||
:ed_ignore,
|
||||
# 29 ^]
|
||||
:ed_ignore,
|
||||
# 30 ^^
|
||||
:ed_unassigned,
|
||||
# 31 ^_
|
||||
:ed_unassigned,
|
||||
# 32 SPACE
|
||||
:ed_insert,
|
||||
# 33 !
|
||||
:ed_insert,
|
||||
# 34 "
|
||||
:ed_insert,
|
||||
# 35 #
|
||||
:ed_insert,
|
||||
# 36 $
|
||||
:ed_insert,
|
||||
# 37 %
|
||||
:ed_insert,
|
||||
# 38 &
|
||||
:ed_insert,
|
||||
# 39 '
|
||||
:ed_insert,
|
||||
# 40 (
|
||||
:ed_insert,
|
||||
# 41 )
|
||||
:ed_insert,
|
||||
# 42 *
|
||||
:ed_insert,
|
||||
# 43 +
|
||||
:ed_insert,
|
||||
# 44 ,
|
||||
:ed_insert,
|
||||
# 45 -
|
||||
:ed_insert,
|
||||
# 46 .
|
||||
:ed_insert,
|
||||
# 47 /
|
||||
:ed_insert,
|
||||
# 48 0
|
||||
:ed_digit,
|
||||
# 49 1
|
||||
:ed_digit,
|
||||
# 50 2
|
||||
:ed_digit,
|
||||
# 51 3
|
||||
:ed_digit,
|
||||
# 52 4
|
||||
:ed_digit,
|
||||
# 53 5
|
||||
:ed_digit,
|
||||
# 54 6
|
||||
:ed_digit,
|
||||
# 55 7
|
||||
:ed_digit,
|
||||
# 56 8
|
||||
:ed_digit,
|
||||
# 57 9
|
||||
:ed_digit,
|
||||
# 58 :
|
||||
:ed_insert,
|
||||
# 59 ;
|
||||
:ed_insert,
|
||||
# 60 <
|
||||
:ed_insert,
|
||||
# 61 =
|
||||
:ed_insert,
|
||||
# 62 >
|
||||
:ed_insert,
|
||||
# 63 ?
|
||||
:ed_insert,
|
||||
# 64 @
|
||||
:ed_insert,
|
||||
# 65 A
|
||||
:ed_insert,
|
||||
# 66 B
|
||||
:ed_insert,
|
||||
# 67 C
|
||||
:ed_insert,
|
||||
# 68 D
|
||||
:ed_insert,
|
||||
# 69 E
|
||||
:ed_insert,
|
||||
# 70 F
|
||||
:ed_insert,
|
||||
# 71 G
|
||||
:ed_insert,
|
||||
# 72 H
|
||||
:ed_insert,
|
||||
# 73 I
|
||||
:ed_insert,
|
||||
# 74 J
|
||||
:ed_insert,
|
||||
# 75 K
|
||||
:ed_insert,
|
||||
# 76 L
|
||||
:ed_insert,
|
||||
# 77 M
|
||||
:ed_insert,
|
||||
# 78 N
|
||||
:ed_insert,
|
||||
# 79 O
|
||||
:ed_insert,
|
||||
# 80 P
|
||||
:ed_insert,
|
||||
# 81 Q
|
||||
:ed_insert,
|
||||
# 82 R
|
||||
:ed_insert,
|
||||
# 83 S
|
||||
:ed_insert,
|
||||
# 84 T
|
||||
:ed_insert,
|
||||
# 85 U
|
||||
:ed_insert,
|
||||
# 86 V
|
||||
:ed_insert,
|
||||
# 87 W
|
||||
:ed_insert,
|
||||
# 88 X
|
||||
:ed_insert,
|
||||
# 89 Y
|
||||
:ed_insert,
|
||||
# 90 Z
|
||||
:ed_insert,
|
||||
# 91 [
|
||||
:ed_insert,
|
||||
# 92 \
|
||||
:ed_insert,
|
||||
# 93 ]
|
||||
:ed_insert,
|
||||
# 94 ^
|
||||
:ed_insert,
|
||||
# 95 _
|
||||
:ed_insert,
|
||||
# 96 `
|
||||
:ed_insert,
|
||||
# 97 a
|
||||
:ed_insert,
|
||||
# 98 b
|
||||
:ed_insert,
|
||||
# 99 c
|
||||
:ed_insert,
|
||||
# 100 d
|
||||
:ed_insert,
|
||||
# 101 e
|
||||
:ed_insert,
|
||||
# 102 f
|
||||
:ed_insert,
|
||||
# 103 g
|
||||
:ed_insert,
|
||||
# 104 h
|
||||
:ed_insert,
|
||||
# 105 i
|
||||
:ed_insert,
|
||||
# 106 j
|
||||
:ed_insert,
|
||||
# 107 k
|
||||
:ed_insert,
|
||||
# 108 l
|
||||
:ed_insert,
|
||||
# 109 m
|
||||
:ed_insert,
|
||||
# 110 n
|
||||
:ed_insert,
|
||||
# 111 o
|
||||
:ed_insert,
|
||||
# 112 p
|
||||
:ed_insert,
|
||||
# 113 q
|
||||
:ed_insert,
|
||||
# 114 r
|
||||
:ed_insert,
|
||||
# 115 s
|
||||
:ed_insert,
|
||||
# 116 t
|
||||
:ed_insert,
|
||||
# 117 u
|
||||
:ed_insert,
|
||||
# 118 v
|
||||
:ed_insert,
|
||||
# 119 w
|
||||
:ed_insert,
|
||||
# 120 x
|
||||
:ed_insert,
|
||||
# 121 y
|
||||
:ed_insert,
|
||||
# 122 z
|
||||
:ed_insert,
|
||||
# 123 {
|
||||
:ed_insert,
|
||||
# 124 |
|
||||
:ed_insert,
|
||||
# 125 }
|
||||
:ed_insert,
|
||||
# 126 ~
|
||||
:ed_insert,
|
||||
# 127 ^?
|
||||
:em_delete_prev_char,
|
||||
# 128 M-^@
|
||||
:ed_unassigned,
|
||||
# 129 M-^A
|
||||
:ed_unassigned,
|
||||
# 130 M-^B
|
||||
:ed_unassigned,
|
||||
# 131 M-^C
|
||||
:ed_unassigned,
|
||||
# 132 M-^D
|
||||
:ed_unassigned,
|
||||
# 133 M-^E
|
||||
:ed_unassigned,
|
||||
# 134 M-^F
|
||||
:ed_unassigned,
|
||||
# 135 M-^G
|
||||
:ed_unassigned,
|
||||
# 136 M-^H
|
||||
:ed_delete_prev_word,
|
||||
# 137 M-^I
|
||||
:ed_unassigned,
|
||||
# 138 M-^J
|
||||
:ed_unassigned,
|
||||
# 139 M-^K
|
||||
:ed_unassigned,
|
||||
# 140 M-^L
|
||||
:ed_clear_screen,
|
||||
# 141 M-^M
|
||||
:ed_unassigned,
|
||||
# 142 M-^N
|
||||
:ed_unassigned,
|
||||
# 143 M-^O
|
||||
:ed_unassigned,
|
||||
# 144 M-^P
|
||||
:ed_unassigned,
|
||||
# 145 M-^Q
|
||||
:ed_unassigned,
|
||||
# 146 M-^R
|
||||
:ed_unassigned,
|
||||
# 147 M-^S
|
||||
:ed_unassigned,
|
||||
# 148 M-^T
|
||||
:ed_unassigned,
|
||||
# 149 M-^U
|
||||
:ed_unassigned,
|
||||
# 150 M-^V
|
||||
:ed_unassigned,
|
||||
# 151 M-^W
|
||||
:ed_unassigned,
|
||||
# 152 M-^X
|
||||
:ed_unassigned,
|
||||
# 153 M-^Y
|
||||
:ed_unassigned,
|
||||
# 154 M-^Z
|
||||
:ed_unassigned,
|
||||
# 155 M-^[
|
||||
:ed_unassigned,
|
||||
# 156 M-^\
|
||||
:ed_unassigned,
|
||||
# 157 M-^]
|
||||
:ed_unassigned,
|
||||
# 158 M-^^
|
||||
:ed_unassigned,
|
||||
# 159 M-^_
|
||||
:em_copy_prev_word,
|
||||
# 160 M-SPACE
|
||||
:ed_unassigned,
|
||||
# 161 M-!
|
||||
:ed_unassigned,
|
||||
# 162 M-"
|
||||
:ed_unassigned,
|
||||
# 163 M-#
|
||||
:ed_unassigned,
|
||||
# 164 M-$
|
||||
:ed_unassigned,
|
||||
# 165 M-%
|
||||
:ed_unassigned,
|
||||
# 166 M-&
|
||||
:ed_unassigned,
|
||||
# 167 M-'
|
||||
:ed_unassigned,
|
||||
# 168 M-(
|
||||
:ed_unassigned,
|
||||
# 169 M-)
|
||||
:ed_unassigned,
|
||||
# 170 M-*
|
||||
:ed_unassigned,
|
||||
# 171 M-+
|
||||
:ed_unassigned,
|
||||
# 172 M-,
|
||||
:ed_unassigned,
|
||||
# 173 M--
|
||||
:ed_unassigned,
|
||||
# 174 M-.
|
||||
:ed_unassigned,
|
||||
# 175 M-/
|
||||
:ed_unassigned,
|
||||
# 176 M-0
|
||||
:ed_argument_digit,
|
||||
# 177 M-1
|
||||
:ed_argument_digit,
|
||||
# 178 M-2
|
||||
:ed_argument_digit,
|
||||
# 179 M-3
|
||||
:ed_argument_digit,
|
||||
# 180 M-4
|
||||
:ed_argument_digit,
|
||||
# 181 M-5
|
||||
:ed_argument_digit,
|
||||
# 182 M-6
|
||||
:ed_argument_digit,
|
||||
# 183 M-7
|
||||
:ed_argument_digit,
|
||||
# 184 M-8
|
||||
:ed_argument_digit,
|
||||
# 185 M-9
|
||||
:ed_argument_digit,
|
||||
# 186 M-:
|
||||
:ed_unassigned,
|
||||
# 187 M-;
|
||||
:ed_unassigned,
|
||||
# 188 M-<
|
||||
:ed_unassigned,
|
||||
# 189 M-=
|
||||
:ed_unassigned,
|
||||
# 190 M->
|
||||
:ed_unassigned,
|
||||
# 191 M-?
|
||||
:ed_unassigned,
|
||||
# 192 M-@
|
||||
:ed_unassigned,
|
||||
# 193 M-A
|
||||
:ed_unassigned,
|
||||
# 194 M-B
|
||||
:ed_prev_word,
|
||||
# 195 M-C
|
||||
:em_capitol_case,
|
||||
# 196 M-D
|
||||
:em_delete_next_word,
|
||||
# 197 M-E
|
||||
:ed_unassigned,
|
||||
# 198 M-F
|
||||
:em_next_word,
|
||||
# 199 M-G
|
||||
:ed_unassigned,
|
||||
# 200 M-H
|
||||
:ed_unassigned,
|
||||
# 201 M-I
|
||||
:ed_unassigned,
|
||||
# 202 M-J
|
||||
:ed_unassigned,
|
||||
# 203 M-K
|
||||
:ed_unassigned,
|
||||
# 204 M-L
|
||||
:em_lower_case,
|
||||
# 205 M-M
|
||||
:ed_unassigned,
|
||||
# 206 M-N
|
||||
:ed_search_next_history,
|
||||
# 207 M-O
|
||||
:ed_sequence_lead_in,
|
||||
# 208 M-P
|
||||
:ed_search_prev_history,
|
||||
# 209 M-Q
|
||||
:ed_unassigned,
|
||||
# 210 M-R
|
||||
:ed_unassigned,
|
||||
# 211 M-S
|
||||
:ed_unassigned,
|
||||
# 212 M-T
|
||||
:ed_unassigned,
|
||||
# 213 M-U
|
||||
:em_upper_case,
|
||||
# 214 M-V
|
||||
:ed_unassigned,
|
||||
# 215 M-W
|
||||
:em_copy_region,
|
||||
# 216 M-X
|
||||
:ed_command,
|
||||
# 217 M-Y
|
||||
:ed_unassigned,
|
||||
# 218 M-Z
|
||||
:ed_unassigned,
|
||||
# 219 M-[
|
||||
:ed_sequence_lead_in,
|
||||
# 220 M-\
|
||||
:ed_unassigned,
|
||||
# 221 M-]
|
||||
:ed_unassigned,
|
||||
# 222 M-^
|
||||
:ed_unassigned,
|
||||
# 223 M-_
|
||||
:ed_unassigned,
|
||||
# 223 M-`
|
||||
:ed_unassigned,
|
||||
# 224 M-a
|
||||
:ed_unassigned,
|
||||
# 225 M-b
|
||||
:ed_prev_word,
|
||||
# 226 M-c
|
||||
:em_capitol_case,
|
||||
# 227 M-d
|
||||
:em_delete_next_word,
|
||||
# 228 M-e
|
||||
:ed_unassigned,
|
||||
# 229 M-f
|
||||
:em_next_word,
|
||||
# 230 M-g
|
||||
:ed_unassigned,
|
||||
# 231 M-h
|
||||
:ed_unassigned,
|
||||
# 232 M-i
|
||||
:ed_unassigned,
|
||||
# 233 M-j
|
||||
:ed_unassigned,
|
||||
# 234 M-k
|
||||
:ed_unassigned,
|
||||
# 235 M-l
|
||||
:em_lower_case,
|
||||
# 236 M-m
|
||||
:ed_unassigned,
|
||||
# 237 M-n
|
||||
:ed_search_next_history,
|
||||
# 238 M-o
|
||||
:ed_unassigned,
|
||||
# 239 M-p
|
||||
:ed_search_prev_history,
|
||||
# 240 M-q
|
||||
:ed_unassigned,
|
||||
# 241 M-r
|
||||
:ed_unassigned,
|
||||
# 242 M-s
|
||||
:ed_unassigned,
|
||||
# 243 M-t
|
||||
:ed_unassigned,
|
||||
# 244 M-u
|
||||
:em_upper_case,
|
||||
# 245 M-v
|
||||
:ed_unassigned,
|
||||
# 246 M-w
|
||||
:em_copy_region,
|
||||
# 247 M-x
|
||||
:ed_command,
|
||||
# 248 M-y
|
||||
:ed_unassigned,
|
||||
# 249 M-z
|
||||
:ed_unassigned,
|
||||
# 250 M-{
|
||||
:ed_unassigned,
|
||||
# 251 M-|
|
||||
:ed_unassigned,
|
||||
# 252 M-}
|
||||
:ed_unassigned,
|
||||
# 253 M-~
|
||||
:ed_unassigned,
|
||||
# 254 M-^?
|
||||
:ed_delete_prev_word
|
||||
# 255
|
||||
# EOF
|
||||
]
|
||||
end
|
519
lib/reline/key_actor/vi_command.rb
Normal file
519
lib/reline/key_actor/vi_command.rb
Normal file
|
@ -0,0 +1,519 @@
|
|||
class Reline::KeyActor::ViCommand < Reline::KeyActor::Base
|
||||
MAPPING = [
|
||||
# 0 ^@
|
||||
:ed_unassigned,
|
||||
# 1 ^A
|
||||
:ed_move_to_beg,
|
||||
# 2 ^B
|
||||
:ed_unassigned,
|
||||
# 3 ^C
|
||||
:ed_ignore,
|
||||
# 4 ^D
|
||||
:vi_end_of_transmission,
|
||||
# 5 ^E
|
||||
:ed_move_to_end,
|
||||
# 6 ^F
|
||||
:ed_unassigned,
|
||||
# 7 ^G
|
||||
:ed_unassigned,
|
||||
# 8 ^H
|
||||
:ed_delete_prev_char,
|
||||
# 9 ^I
|
||||
:ed_unassigned,
|
||||
# 10 ^J
|
||||
:ed_newline,
|
||||
# 11 ^K
|
||||
:ed_kill_line,
|
||||
# 12 ^L
|
||||
:ed_clear_screen,
|
||||
# 13 ^M
|
||||
:ed_newline,
|
||||
# 14 ^N
|
||||
:ed_next_history,
|
||||
# 15 ^O
|
||||
:ed_ignore,
|
||||
# 16 ^P
|
||||
:ed_prev_history,
|
||||
# 17 ^Q
|
||||
:ed_ignore,
|
||||
# 18 ^R
|
||||
:ed_redisplay,
|
||||
# 19 ^S
|
||||
:ed_ignore,
|
||||
# 20 ^T
|
||||
:ed_unassigned,
|
||||
# 21 ^U
|
||||
:vi_kill_line_prev,
|
||||
# 22 ^V
|
||||
:ed_quoted_insert,
|
||||
# 23 ^W
|
||||
:ed_delete_prev_word,
|
||||
# 24 ^X
|
||||
:ed_unassigned,
|
||||
# 25 ^Y
|
||||
:ed_unassigned,
|
||||
# 26 ^Z
|
||||
:ed_unassigned,
|
||||
# 27 ^[
|
||||
:em_meta_next,
|
||||
# 28 ^\
|
||||
:ed_ignore,
|
||||
# 29 ^]
|
||||
:ed_unassigned,
|
||||
# 30 ^^
|
||||
:ed_unassigned,
|
||||
# 31 ^_
|
||||
:ed_unassigned,
|
||||
# 32 SPACE
|
||||
:ed_next_char,
|
||||
# 33 !
|
||||
:ed_unassigned,
|
||||
# 34 "
|
||||
:ed_unassigned,
|
||||
# 35 #
|
||||
:vi_comment_out,
|
||||
# 36 $
|
||||
:ed_move_to_end,
|
||||
# 37 %
|
||||
:vi_match,
|
||||
# 38 &
|
||||
:ed_unassigned,
|
||||
# 39 '
|
||||
:ed_unassigned,
|
||||
# 40 (
|
||||
:ed_unassigned,
|
||||
# 41 )
|
||||
:ed_unassigned,
|
||||
# 42 *
|
||||
:ed_unassigned,
|
||||
# 43 +
|
||||
:ed_next_history,
|
||||
# 44 ,
|
||||
:vi_repeat_prev_char,
|
||||
# 45 -
|
||||
:ed_prev_history,
|
||||
# 46 .
|
||||
:vi_redo,
|
||||
# 47 /
|
||||
:vi_search_prev,
|
||||
# 48 0
|
||||
:vi_zero,
|
||||
# 49 1
|
||||
:ed_argument_digit,
|
||||
# 50 2
|
||||
:ed_argument_digit,
|
||||
# 51 3
|
||||
:ed_argument_digit,
|
||||
# 52 4
|
||||
:ed_argument_digit,
|
||||
# 53 5
|
||||
:ed_argument_digit,
|
||||
# 54 6
|
||||
:ed_argument_digit,
|
||||
# 55 7
|
||||
:ed_argument_digit,
|
||||
# 56 8
|
||||
:ed_argument_digit,
|
||||
# 57 9
|
||||
:ed_argument_digit,
|
||||
# 58 :
|
||||
:ed_command,
|
||||
# 59 ;
|
||||
:vi_repeat_next_char,
|
||||
# 60 <
|
||||
:ed_unassigned,
|
||||
# 61 =
|
||||
:ed_unassigned,
|
||||
# 62 >
|
||||
:ed_unassigned,
|
||||
# 63 ?
|
||||
:vi_search_next,
|
||||
# 64 @
|
||||
:vi_alias,
|
||||
# 65 A
|
||||
:vi_add_at_eol,
|
||||
# 66 B
|
||||
:vi_prev_big_word,
|
||||
# 67 C
|
||||
:vi_change_to_eol,
|
||||
# 68 D
|
||||
:ed_kill_line,
|
||||
# 69 E
|
||||
:vi_end_big_word,
|
||||
# 70 F
|
||||
:vi_prev_char,
|
||||
# 71 G
|
||||
:vi_to_history_line,
|
||||
# 72 H
|
||||
:ed_unassigned,
|
||||
# 73 I
|
||||
:vi_insert_at_bol,
|
||||
# 74 J
|
||||
:ed_search_next_history,
|
||||
# 75 K
|
||||
:ed_search_prev_history,
|
||||
# 76 L
|
||||
:ed_unassigned,
|
||||
# 77 M
|
||||
:ed_unassigned,
|
||||
# 78 N
|
||||
:vi_repeat_search_prev,
|
||||
# 79 O
|
||||
:ed_sequence_lead_in,
|
||||
# 80 P
|
||||
:vi_paste_prev,
|
||||
# 81 Q
|
||||
:ed_unassigned,
|
||||
# 82 R
|
||||
:vi_replace_mode,
|
||||
# 83 S
|
||||
:vi_substitute_line,
|
||||
# 84 T
|
||||
:vi_to_prev_char,
|
||||
# 85 U
|
||||
:vi_undo_line,
|
||||
# 86 V
|
||||
:ed_unassigned,
|
||||
# 87 W
|
||||
:vi_next_big_word,
|
||||
# 88 X
|
||||
:ed_delete_prev_char,
|
||||
# 89 Y
|
||||
:vi_yank_end,
|
||||
# 90 Z
|
||||
:ed_unassigned,
|
||||
# 91 [
|
||||
:ed_sequence_lead_in,
|
||||
# 92 \
|
||||
:ed_unassigned,
|
||||
# 93 ]
|
||||
:ed_unassigned,
|
||||
# 94 ^
|
||||
:ed_move_to_beg,
|
||||
# 95 _
|
||||
:vi_history_word,
|
||||
# 96 `
|
||||
:ed_unassigned,
|
||||
# 97 a
|
||||
:vi_add,
|
||||
# 98 b
|
||||
:vi_prev_word,
|
||||
# 99 c
|
||||
:vi_change_meta,
|
||||
# 100 d
|
||||
:vi_delete_meta,
|
||||
# 101 e
|
||||
:vi_end_word,
|
||||
# 102 f
|
||||
:vi_next_char,
|
||||
# 103 g
|
||||
:ed_unassigned,
|
||||
# 104 h
|
||||
:ed_prev_char,
|
||||
# 105 i
|
||||
:vi_insert,
|
||||
# 106 j
|
||||
:ed_next_history,
|
||||
# 107 k
|
||||
:ed_prev_history,
|
||||
# 108 l
|
||||
:ed_next_char,
|
||||
# 109 m
|
||||
:ed_unassigned,
|
||||
# 110 n
|
||||
:vi_repeat_search_next,
|
||||
# 111 o
|
||||
:ed_unassigned,
|
||||
# 112 p
|
||||
:vi_paste_next,
|
||||
# 113 q
|
||||
:ed_unassigned,
|
||||
# 114 r
|
||||
:vi_replace_char,
|
||||
# 115 s
|
||||
:vi_substitute_char,
|
||||
# 116 t
|
||||
:vi_to_next_char,
|
||||
# 117 u
|
||||
:vi_undo,
|
||||
# 118 v
|
||||
:vi_histedit,
|
||||
# 119 w
|
||||
:vi_next_word,
|
||||
# 120 x
|
||||
:ed_delete_next_char,
|
||||
# 121 y
|
||||
:vi_yank,
|
||||
# 122 z
|
||||
:ed_unassigned,
|
||||
# 123 {
|
||||
:ed_unassigned,
|
||||
# 124 |
|
||||
:vi_to_column,
|
||||
# 125 }
|
||||
:ed_unassigned,
|
||||
# 126 ~
|
||||
:vi_change_case,
|
||||
# 127 ^?
|
||||
:ed_delete_prev_char,
|
||||
# 128 M-^@
|
||||
:ed_unassigned,
|
||||
# 129 M-^A
|
||||
:ed_unassigned,
|
||||
# 130 M-^B
|
||||
:ed_unassigned,
|
||||
# 131 M-^C
|
||||
:ed_unassigned,
|
||||
# 132 M-^D
|
||||
:ed_unassigned,
|
||||
# 133 M-^E
|
||||
:ed_unassigned,
|
||||
# 134 M-^F
|
||||
:ed_unassigned,
|
||||
# 135 M-^G
|
||||
:ed_unassigned,
|
||||
# 136 M-^H
|
||||
:ed_unassigned,
|
||||
# 137 M-^I
|
||||
:ed_unassigned,
|
||||
# 138 M-^J
|
||||
:ed_unassigned,
|
||||
# 139 M-^K
|
||||
:ed_unassigned,
|
||||
# 140 M-^L
|
||||
:ed_unassigned,
|
||||
# 141 M-^M
|
||||
:ed_unassigned,
|
||||
# 142 M-^N
|
||||
:ed_unassigned,
|
||||
# 143 M-^O
|
||||
:ed_unassigned,
|
||||
# 144 M-^P
|
||||
:ed_unassigned,
|
||||
# 145 M-^Q
|
||||
:ed_unassigned,
|
||||
# 146 M-^R
|
||||
:ed_unassigned,
|
||||
# 147 M-^S
|
||||
:ed_unassigned,
|
||||
# 148 M-^T
|
||||
:ed_unassigned,
|
||||
# 149 M-^U
|
||||
:ed_unassigned,
|
||||
# 150 M-^V
|
||||
:ed_unassigned,
|
||||
# 151 M-^W
|
||||
:ed_unassigned,
|
||||
# 152 M-^X
|
||||
:ed_unassigned,
|
||||
# 153 M-^Y
|
||||
:ed_unassigned,
|
||||
# 154 M-^Z
|
||||
:ed_unassigned,
|
||||
# 155 M-^[
|
||||
:ed_unassigned,
|
||||
# 156 M-^\
|
||||
:ed_unassigned,
|
||||
# 157 M-^]
|
||||
:ed_unassigned,
|
||||
# 158 M-^^
|
||||
:ed_unassigned,
|
||||
# 159 M-^_
|
||||
:ed_unassigned,
|
||||
# 160 M-SPACE
|
||||
:ed_unassigned,
|
||||
# 161 M-!
|
||||
:ed_unassigned,
|
||||
# 162 M-"
|
||||
:ed_unassigned,
|
||||
# 163 M-#
|
||||
:ed_unassigned,
|
||||
# 164 M-$
|
||||
:ed_unassigned,
|
||||
# 165 M-%
|
||||
:ed_unassigned,
|
||||
# 166 M-&
|
||||
:ed_unassigned,
|
||||
# 167 M-'
|
||||
:ed_unassigned,
|
||||
# 168 M-(
|
||||
:ed_unassigned,
|
||||
# 169 M-)
|
||||
:ed_unassigned,
|
||||
# 170 M-*
|
||||
:ed_unassigned,
|
||||
# 171 M-+
|
||||
:ed_unassigned,
|
||||
# 172 M-,
|
||||
:ed_unassigned,
|
||||
# 173 M--
|
||||
:ed_unassigned,
|
||||
# 174 M-.
|
||||
:ed_unassigned,
|
||||
# 175 M-/
|
||||
:ed_unassigned,
|
||||
# 176 M-0
|
||||
:ed_unassigned,
|
||||
# 177 M-1
|
||||
:ed_unassigned,
|
||||
# 178 M-2
|
||||
:ed_unassigned,
|
||||
# 179 M-3
|
||||
:ed_unassigned,
|
||||
# 180 M-4
|
||||
:ed_unassigned,
|
||||
# 181 M-5
|
||||
:ed_unassigned,
|
||||
# 182 M-6
|
||||
:ed_unassigned,
|
||||
# 183 M-7
|
||||
:ed_unassigned,
|
||||
# 184 M-8
|
||||
:ed_unassigned,
|
||||
# 185 M-9
|
||||
:ed_unassigned,
|
||||
# 186 M-:
|
||||
:ed_unassigned,
|
||||
# 187 M-;
|
||||
:ed_unassigned,
|
||||
# 188 M-<
|
||||
:ed_unassigned,
|
||||
# 189 M-=
|
||||
:ed_unassigned,
|
||||
# 190 M->
|
||||
:ed_unassigned,
|
||||
# 191 M-?
|
||||
:ed_unassigned,
|
||||
# 192 M-@
|
||||
:ed_unassigned,
|
||||
# 193 M-A
|
||||
:ed_unassigned,
|
||||
# 194 M-B
|
||||
:ed_unassigned,
|
||||
# 195 M-C
|
||||
:ed_unassigned,
|
||||
# 196 M-D
|
||||
:ed_unassigned,
|
||||
# 197 M-E
|
||||
:ed_unassigned,
|
||||
# 198 M-F
|
||||
:ed_unassigned,
|
||||
# 199 M-G
|
||||
:ed_unassigned,
|
||||
# 200 M-H
|
||||
:ed_unassigned,
|
||||
# 201 M-I
|
||||
:ed_unassigned,
|
||||
# 202 M-J
|
||||
:ed_unassigned,
|
||||
# 203 M-K
|
||||
:ed_unassigned,
|
||||
# 204 M-L
|
||||
:ed_unassigned,
|
||||
# 205 M-M
|
||||
:ed_unassigned,
|
||||
# 206 M-N
|
||||
:ed_unassigned,
|
||||
# 207 M-O
|
||||
:ed_sequence_lead_in,
|
||||
# 208 M-P
|
||||
:ed_unassigned,
|
||||
# 209 M-Q
|
||||
:ed_unassigned,
|
||||
# 210 M-R
|
||||
:ed_unassigned,
|
||||
# 211 M-S
|
||||
:ed_unassigned,
|
||||
# 212 M-T
|
||||
:ed_unassigned,
|
||||
# 213 M-U
|
||||
:ed_unassigned,
|
||||
# 214 M-V
|
||||
:ed_unassigned,
|
||||
# 215 M-W
|
||||
:ed_unassigned,
|
||||
# 216 M-X
|
||||
:ed_unassigned,
|
||||
# 217 M-Y
|
||||
:ed_unassigned,
|
||||
# 218 M-Z
|
||||
:ed_unassigned,
|
||||
# 219 M-[
|
||||
:ed_sequence_lead_in,
|
||||
# 220 M-\
|
||||
:ed_unassigned,
|
||||
# 221 M-]
|
||||
:ed_unassigned,
|
||||
# 222 M-^
|
||||
:ed_unassigned,
|
||||
# 223 M-_
|
||||
:ed_unassigned,
|
||||
# 223 M-`
|
||||
:ed_unassigned,
|
||||
# 224 M-a
|
||||
:ed_unassigned,
|
||||
# 225 M-b
|
||||
:ed_unassigned,
|
||||
# 226 M-c
|
||||
:ed_unassigned,
|
||||
# 227 M-d
|
||||
:ed_unassigned,
|
||||
# 228 M-e
|
||||
:ed_unassigned,
|
||||
# 229 M-f
|
||||
:ed_unassigned,
|
||||
# 230 M-g
|
||||
:ed_unassigned,
|
||||
# 231 M-h
|
||||
:ed_unassigned,
|
||||
# 232 M-i
|
||||
:ed_unassigned,
|
||||
# 233 M-j
|
||||
:ed_unassigned,
|
||||
# 234 M-k
|
||||
:ed_unassigned,
|
||||
# 235 M-l
|
||||
:ed_unassigned,
|
||||
# 236 M-m
|
||||
:ed_unassigned,
|
||||
# 237 M-n
|
||||
:ed_unassigned,
|
||||
# 238 M-o
|
||||
:ed_unassigned,
|
||||
# 239 M-p
|
||||
:ed_unassigned,
|
||||
# 240 M-q
|
||||
:ed_unassigned,
|
||||
# 241 M-r
|
||||
:ed_unassigned,
|
||||
# 242 M-s
|
||||
:ed_unassigned,
|
||||
# 243 M-t
|
||||
:ed_unassigned,
|
||||
# 244 M-u
|
||||
:ed_unassigned,
|
||||
# 245 M-v
|
||||
:ed_unassigned,
|
||||
# 246 M-w
|
||||
:ed_unassigned,
|
||||
# 247 M-x
|
||||
:ed_unassigned,
|
||||
# 248 M-y
|
||||
:ed_unassigned,
|
||||
# 249 M-z
|
||||
:ed_unassigned,
|
||||
# 250 M-{
|
||||
:ed_unassigned,
|
||||
# 251 M-|
|
||||
:ed_unassigned,
|
||||
# 252 M-}
|
||||
:ed_unassigned,
|
||||
# 253 M-~
|
||||
:ed_unassigned,
|
||||
# 254 M-^?
|
||||
:ed_unassigned
|
||||
# 255
|
||||
# EOF
|
||||
]
|
||||
end
|
||||
|
518
lib/reline/key_actor/vi_insert.rb
Normal file
518
lib/reline/key_actor/vi_insert.rb
Normal file
|
@ -0,0 +1,518 @@
|
|||
class Reline::KeyActor::ViInsert < Reline::KeyActor::Base
|
||||
MAPPING = [
|
||||
# 0 ^@
|
||||
:ed_unassigned,
|
||||
# 1 ^A
|
||||
:ed_insert,
|
||||
# 2 ^B
|
||||
:ed_insert,
|
||||
# 3 ^C
|
||||
:ed_insert,
|
||||
# 4 ^D
|
||||
:vi_list_or_eof,
|
||||
# 5 ^E
|
||||
:ed_insert,
|
||||
# 6 ^F
|
||||
:ed_insert,
|
||||
# 7 ^G
|
||||
:ed_insert,
|
||||
# 8 ^H
|
||||
:vi_delete_prev_char,
|
||||
# 9 ^I
|
||||
:ed_insert,
|
||||
# 10 ^J
|
||||
:ed_newline,
|
||||
# 11 ^K
|
||||
:ed_insert,
|
||||
# 12 ^L
|
||||
:ed_insert,
|
||||
# 13 ^M
|
||||
:ed_newline,
|
||||
# 14 ^N
|
||||
:ed_insert,
|
||||
# 15 ^O
|
||||
:ed_insert,
|
||||
# 16 ^P
|
||||
:ed_insert,
|
||||
# 17 ^Q
|
||||
:ed_ignore,
|
||||
# 18 ^R
|
||||
:ed_insert,
|
||||
# 19 ^S
|
||||
:ed_ignore,
|
||||
# 20 ^T
|
||||
:ed_insert,
|
||||
# 21 ^U
|
||||
:vi_kill_line_prev,
|
||||
# 22 ^V
|
||||
:ed_quoted_insert,
|
||||
# 23 ^W
|
||||
:ed_delete_prev_word,
|
||||
# 24 ^X
|
||||
:ed_insert,
|
||||
# 25 ^Y
|
||||
:ed_insert,
|
||||
# 26 ^Z
|
||||
:ed_insert,
|
||||
# 27 ^[
|
||||
:vi_command_mode,
|
||||
# 28 ^\
|
||||
:ed_ignore,
|
||||
# 29 ^]
|
||||
:ed_insert,
|
||||
# 30 ^^
|
||||
:ed_insert,
|
||||
# 31 ^_
|
||||
:ed_insert,
|
||||
# 32 SPACE
|
||||
:ed_insert,
|
||||
# 33 !
|
||||
:ed_insert,
|
||||
# 34 "
|
||||
:ed_insert,
|
||||
# 35 #
|
||||
:ed_insert,
|
||||
# 36 $
|
||||
:ed_insert,
|
||||
# 37 %
|
||||
:ed_insert,
|
||||
# 38 &
|
||||
:ed_insert,
|
||||
# 39 '
|
||||
:ed_insert,
|
||||
# 40 (
|
||||
:ed_insert,
|
||||
# 41 )
|
||||
:ed_insert,
|
||||
# 42 *
|
||||
:ed_insert,
|
||||
# 43 +
|
||||
:ed_insert,
|
||||
# 44 ,
|
||||
:ed_insert,
|
||||
# 45 -
|
||||
:ed_insert,
|
||||
# 46 .
|
||||
:ed_insert,
|
||||
# 47 /
|
||||
:ed_insert,
|
||||
# 48 0
|
||||
:ed_insert,
|
||||
# 49 1
|
||||
:ed_insert,
|
||||
# 50 2
|
||||
:ed_insert,
|
||||
# 51 3
|
||||
:ed_insert,
|
||||
# 52 4
|
||||
:ed_insert,
|
||||
# 53 5
|
||||
:ed_insert,
|
||||
# 54 6
|
||||
:ed_insert,
|
||||
# 55 7
|
||||
:ed_insert,
|
||||
# 56 8
|
||||
:ed_insert,
|
||||
# 57 9
|
||||
:ed_insert,
|
||||
# 58 :
|
||||
:ed_insert,
|
||||
# 59 ;
|
||||
:ed_insert,
|
||||
# 60 <
|
||||
:ed_insert,
|
||||
# 61 =
|
||||
:ed_insert,
|
||||
# 62 >
|
||||
:ed_insert,
|
||||
# 63 ?
|
||||
:ed_insert,
|
||||
# 64 @
|
||||
:ed_insert,
|
||||
# 65 A
|
||||
:ed_insert,
|
||||
# 66 B
|
||||
:ed_insert,
|
||||
# 67 C
|
||||
:ed_insert,
|
||||
# 68 D
|
||||
:ed_insert,
|
||||
# 69 E
|
||||
:ed_insert,
|
||||
# 70 F
|
||||
:ed_insert,
|
||||
# 71 G
|
||||
:ed_insert,
|
||||
# 72 H
|
||||
:ed_insert,
|
||||
# 73 I
|
||||
:ed_insert,
|
||||
# 74 J
|
||||
:ed_insert,
|
||||
# 75 K
|
||||
:ed_insert,
|
||||
# 76 L
|
||||
:ed_insert,
|
||||
# 77 M
|
||||
:ed_insert,
|
||||
# 78 N
|
||||
:ed_insert,
|
||||
# 79 O
|
||||
:ed_insert,
|
||||
# 80 P
|
||||
:ed_insert,
|
||||
# 81 Q
|
||||
:ed_insert,
|
||||
# 82 R
|
||||
:ed_insert,
|
||||
# 83 S
|
||||
:ed_insert,
|
||||
# 84 T
|
||||
:ed_insert,
|
||||
# 85 U
|
||||
:ed_insert,
|
||||
# 86 V
|
||||
:ed_insert,
|
||||
# 87 W
|
||||
:ed_insert,
|
||||
# 88 X
|
||||
:ed_insert,
|
||||
# 89 Y
|
||||
:ed_insert,
|
||||
# 90 Z
|
||||
:ed_insert,
|
||||
# 91 [
|
||||
:ed_insert,
|
||||
# 92 \
|
||||
:ed_insert,
|
||||
# 93 ]
|
||||
:ed_insert,
|
||||
# 94 ^
|
||||
:ed_insert,
|
||||
# 95 _
|
||||
:ed_insert,
|
||||
# 96 `
|
||||
:ed_insert,
|
||||
# 97 a
|
||||
:ed_insert,
|
||||
# 98 b
|
||||
:ed_insert,
|
||||
# 99 c
|
||||
:ed_insert,
|
||||
# 100 d
|
||||
:ed_insert,
|
||||
# 101 e
|
||||
:ed_insert,
|
||||
# 102 f
|
||||
:ed_insert,
|
||||
# 103 g
|
||||
:ed_insert,
|
||||
# 104 h
|
||||
:ed_insert,
|
||||
# 105 i
|
||||
:ed_insert,
|
||||
# 106 j
|
||||
:ed_insert,
|
||||
# 107 k
|
||||
:ed_insert,
|
||||
# 108 l
|
||||
:ed_insert,
|
||||
# 109 m
|
||||
:ed_insert,
|
||||
# 110 n
|
||||
:ed_insert,
|
||||
# 111 o
|
||||
:ed_insert,
|
||||
# 112 p
|
||||
:ed_insert,
|
||||
# 113 q
|
||||
:ed_insert,
|
||||
# 114 r
|
||||
:ed_insert,
|
||||
# 115 s
|
||||
:ed_insert,
|
||||
# 116 t
|
||||
:ed_insert,
|
||||
# 117 u
|
||||
:ed_insert,
|
||||
# 118 v
|
||||
:ed_insert,
|
||||
# 119 w
|
||||
:ed_insert,
|
||||
# 120 x
|
||||
:ed_insert,
|
||||
# 121 y
|
||||
:ed_insert,
|
||||
# 122 z
|
||||
:ed_insert,
|
||||
# 123 {
|
||||
:ed_insert,
|
||||
# 124 |
|
||||
:ed_insert,
|
||||
# 125 }
|
||||
:ed_insert,
|
||||
# 126 ~
|
||||
:ed_insert,
|
||||
# 127 ^?
|
||||
:vi_delete_prev_char,
|
||||
# 128 M-^@
|
||||
:ed_insert,
|
||||
# 129 M-^A
|
||||
:ed_insert,
|
||||
# 130 M-^B
|
||||
:ed_insert,
|
||||
# 131 M-^C
|
||||
:ed_insert,
|
||||
# 132 M-^D
|
||||
:ed_insert,
|
||||
# 133 M-^E
|
||||
:ed_insert,
|
||||
# 134 M-^F
|
||||
:ed_insert,
|
||||
# 135 M-^G
|
||||
:ed_insert,
|
||||
# 136 M-^H
|
||||
:ed_insert,
|
||||
# 137 M-^I
|
||||
:ed_insert,
|
||||
# 138 M-^J
|
||||
:ed_insert,
|
||||
# 139 M-^K
|
||||
:ed_insert,
|
||||
# 140 M-^L
|
||||
:ed_insert,
|
||||
# 141 M-^M
|
||||
:ed_insert,
|
||||
# 142 M-^N
|
||||
:ed_insert,
|
||||
# 143 M-^O
|
||||
:ed_insert,
|
||||
# 144 M-^P
|
||||
:ed_insert,
|
||||
# 145 M-^Q
|
||||
:ed_insert,
|
||||
# 146 M-^R
|
||||
:ed_insert,
|
||||
# 147 M-^S
|
||||
:ed_insert,
|
||||
# 148 M-^T
|
||||
:ed_insert,
|
||||
# 149 M-^U
|
||||
:ed_insert,
|
||||
# 150 M-^V
|
||||
:ed_insert,
|
||||
# 151 M-^W
|
||||
:ed_insert,
|
||||
# 152 M-^X
|
||||
:ed_insert,
|
||||
# 153 M-^Y
|
||||
:ed_insert,
|
||||
# 154 M-^Z
|
||||
:ed_insert,
|
||||
# 155 M-^[
|
||||
:ed_insert,
|
||||
# 156 M-^\
|
||||
:ed_insert,
|
||||
# 157 M-^]
|
||||
:ed_insert,
|
||||
# 158 M-^^
|
||||
:ed_insert,
|
||||
# 159 M-^_
|
||||
:ed_insert,
|
||||
# 160 M-SPACE
|
||||
:ed_insert,
|
||||
# 161 M-!
|
||||
:ed_insert,
|
||||
# 162 M-"
|
||||
:ed_insert,
|
||||
# 163 M-#
|
||||
:ed_insert,
|
||||
# 164 M-$
|
||||
:ed_insert,
|
||||
# 165 M-%
|
||||
:ed_insert,
|
||||
# 166 M-&
|
||||
:ed_insert,
|
||||
# 167 M-'
|
||||
:ed_insert,
|
||||
# 168 M-(
|
||||
:ed_insert,
|
||||
# 169 M-)
|
||||
:ed_insert,
|
||||
# 170 M-*
|
||||
:ed_insert,
|
||||
# 171 M-+
|
||||
:ed_insert,
|
||||
# 172 M-,
|
||||
:ed_insert,
|
||||
# 173 M--
|
||||
:ed_insert,
|
||||
# 174 M-.
|
||||
:ed_insert,
|
||||
# 175 M-/
|
||||
:ed_insert,
|
||||
# 176 M-0
|
||||
:ed_insert,
|
||||
# 177 M-1
|
||||
:ed_insert,
|
||||
# 178 M-2
|
||||
:ed_insert,
|
||||
# 179 M-3
|
||||
:ed_insert,
|
||||
# 180 M-4
|
||||
:ed_insert,
|
||||
# 181 M-5
|
||||
:ed_insert,
|
||||
# 182 M-6
|
||||
:ed_insert,
|
||||
# 183 M-7
|
||||
:ed_insert,
|
||||
# 184 M-8
|
||||
:ed_insert,
|
||||
# 185 M-9
|
||||
:ed_insert,
|
||||
# 186 M-:
|
||||
:ed_insert,
|
||||
# 187 M-;
|
||||
:ed_insert,
|
||||
# 188 M-<
|
||||
:ed_insert,
|
||||
# 189 M-=
|
||||
:ed_insert,
|
||||
# 190 M->
|
||||
:ed_insert,
|
||||
# 191 M-?
|
||||
:ed_insert,
|
||||
# 192 M-@
|
||||
:ed_insert,
|
||||
# 193 M-A
|
||||
:ed_insert,
|
||||
# 194 M-B
|
||||
:ed_insert,
|
||||
# 195 M-C
|
||||
:ed_insert,
|
||||
# 196 M-D
|
||||
:ed_insert,
|
||||
# 197 M-E
|
||||
:ed_insert,
|
||||
# 198 M-F
|
||||
:ed_insert,
|
||||
# 199 M-G
|
||||
:ed_insert,
|
||||
# 200 M-H
|
||||
:ed_insert,
|
||||
# 201 M-I
|
||||
:ed_insert,
|
||||
# 202 M-J
|
||||
:ed_insert,
|
||||
# 203 M-K
|
||||
:ed_insert,
|
||||
# 204 M-L
|
||||
:ed_insert,
|
||||
# 205 M-M
|
||||
:ed_insert,
|
||||
# 206 M-N
|
||||
:ed_insert,
|
||||
# 207 M-O
|
||||
:ed_insert,
|
||||
# 208 M-P
|
||||
:ed_insert,
|
||||
# 209 M-Q
|
||||
:ed_insert,
|
||||
# 210 M-R
|
||||
:ed_insert,
|
||||
# 211 M-S
|
||||
:ed_insert,
|
||||
# 212 M-T
|
||||
:ed_insert,
|
||||
# 213 M-U
|
||||
:ed_insert,
|
||||
# 214 M-V
|
||||
:ed_insert,
|
||||
# 215 M-W
|
||||
:ed_insert,
|
||||
# 216 M-X
|
||||
:ed_insert,
|
||||
# 217 M-Y
|
||||
:ed_insert,
|
||||
# 218 M-Z
|
||||
:ed_insert,
|
||||
# 219 M-[
|
||||
:ed_insert,
|
||||
# 220 M-\
|
||||
:ed_insert,
|
||||
# 221 M-]
|
||||
:ed_insert,
|
||||
# 222 M-^
|
||||
:ed_insert,
|
||||
# 223 M-_
|
||||
:ed_insert,
|
||||
# 223 M-`
|
||||
:ed_insert,
|
||||
# 224 M-a
|
||||
:ed_insert,
|
||||
# 225 M-b
|
||||
:ed_insert,
|
||||
# 226 M-c
|
||||
:ed_insert,
|
||||
# 227 M-d
|
||||
:ed_insert,
|
||||
# 228 M-e
|
||||
:ed_insert,
|
||||
# 229 M-f
|
||||
:ed_insert,
|
||||
# 230 M-g
|
||||
:ed_insert,
|
||||
# 231 M-h
|
||||
:ed_insert,
|
||||
# 232 M-i
|
||||
:ed_insert,
|
||||
# 233 M-j
|
||||
:ed_insert,
|
||||
# 234 M-k
|
||||
:ed_insert,
|
||||
# 235 M-l
|
||||
:ed_insert,
|
||||
# 236 M-m
|
||||
:ed_insert,
|
||||
# 237 M-n
|
||||
:ed_insert,
|
||||
# 238 M-o
|
||||
:ed_insert,
|
||||
# 239 M-p
|
||||
:ed_insert,
|
||||
# 240 M-q
|
||||
:ed_insert,
|
||||
# 241 M-r
|
||||
:ed_insert,
|
||||
# 242 M-s
|
||||
:ed_insert,
|
||||
# 243 M-t
|
||||
:ed_insert,
|
||||
# 244 M-u
|
||||
:ed_insert,
|
||||
# 245 M-v
|
||||
:ed_insert,
|
||||
# 246 M-w
|
||||
:ed_insert,
|
||||
# 247 M-x
|
||||
:ed_insert,
|
||||
# 248 M-y
|
||||
:ed_insert,
|
||||
# 249 M-z
|
||||
:ed_insert,
|
||||
# 250 M-{
|
||||
:ed_insert,
|
||||
# 251 M-|
|
||||
:ed_insert,
|
||||
# 252 M-}
|
||||
:ed_insert,
|
||||
# 253 M-~
|
||||
:ed_insert,
|
||||
# 254 M-^?
|
||||
:ed_insert
|
||||
# 255
|
||||
# EOF
|
||||
]
|
||||
end
|
74
lib/reline/key_stroke.rb
Normal file
74
lib/reline/key_stroke.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
class Reline::KeyStroke
|
||||
using Module.new {
|
||||
refine Array do
|
||||
def start_with?(other)
|
||||
other.size <= size && other == self.take(other.size)
|
||||
end
|
||||
|
||||
def bytes
|
||||
self
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
def initialize(config)
|
||||
@config = config
|
||||
@buffer = []
|
||||
end
|
||||
|
||||
def input_to(bytes)
|
||||
case match_status(bytes)
|
||||
when :matching
|
||||
nil
|
||||
when :matched
|
||||
expand(bytes)
|
||||
when :unmatched
|
||||
bytes
|
||||
end
|
||||
end
|
||||
|
||||
def input_to!(bytes)
|
||||
@buffer.concat Array(bytes)
|
||||
input_to(@buffer)&.tap { clear }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def match_status(input)
|
||||
key_mapping.keys.select { |lhs|
|
||||
lhs.start_with? input
|
||||
}.tap { |it|
|
||||
return :matched if it.size == 1 && (it.max_by(&:size)&.size&.== input.size)
|
||||
return :matching if it.size == 1 && (it.max_by(&:size)&.size&.!= input.size)
|
||||
return :matched if it.max_by(&:size)&.size&.< input.size
|
||||
return :matching if it.size > 1
|
||||
}
|
||||
key_mapping.keys.select { |lhs|
|
||||
input.start_with? lhs
|
||||
}.tap { |it|
|
||||
return it.size > 0 ? :matched : :unmatched
|
||||
}
|
||||
end
|
||||
|
||||
def expand(input)
|
||||
lhs = key_mapping.keys.select { |lhs| input.start_with? lhs }.sort_by(&:size).reverse.first
|
||||
return input unless lhs
|
||||
rhs = key_mapping[lhs]
|
||||
|
||||
case rhs
|
||||
when String
|
||||
rhs_bytes = rhs.bytes
|
||||
expand(expand(rhs_bytes) + expand(input.drop(lhs.size)))
|
||||
when Symbol
|
||||
[rhs] + expand(input.drop(lhs.size))
|
||||
end
|
||||
end
|
||||
|
||||
def key_mapping
|
||||
@config[:key_mapping].transform_keys(&:bytes)
|
||||
end
|
||||
|
||||
def clear
|
||||
@buffer = []
|
||||
end
|
||||
end
|
113
lib/reline/kill_ring.rb
Normal file
113
lib/reline/kill_ring.rb
Normal file
|
@ -0,0 +1,113 @@
|
|||
class Reline::KillRing
|
||||
module State
|
||||
FRESH = :fresh
|
||||
CONTINUED = :continued
|
||||
PROCESSED = :processed
|
||||
YANK = :yank
|
||||
end
|
||||
|
||||
RingPoint = Struct.new(:backward, :forward, :str) do
|
||||
def initialize(str)
|
||||
super(nil, nil, str)
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
object_id == other.object_id
|
||||
end
|
||||
end
|
||||
|
||||
class RingBuffer
|
||||
attr_reader :size
|
||||
attr_reader :head
|
||||
|
||||
def initialize(max = 1024)
|
||||
@max = max
|
||||
@size = 0
|
||||
@head = nil # reading head of ring-shaped tape
|
||||
end
|
||||
|
||||
def <<(point)
|
||||
if @size.zero?
|
||||
@head = point
|
||||
@head.backward = @head
|
||||
@head.forward = @head
|
||||
@size = 1
|
||||
elsif @size >= @max
|
||||
tail = @head.forward
|
||||
new_tail = tail.forward
|
||||
@head.forward = point
|
||||
point.backward = @head
|
||||
new_tail.backward = point
|
||||
point.forward = new_tail
|
||||
@head = point
|
||||
else
|
||||
tail = @head.forward
|
||||
@head.forward = point
|
||||
point.backward = @head
|
||||
tail.backward = point
|
||||
point.forward = tail
|
||||
@head = point
|
||||
@size += 1
|
||||
end
|
||||
end
|
||||
|
||||
def empty?
|
||||
@size.zero?
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(max = 1024)
|
||||
@ring = RingBuffer.new(max)
|
||||
@ring_pointer = nil
|
||||
@buffer = nil
|
||||
@state = State::FRESH
|
||||
end
|
||||
|
||||
def append(string, before_p = false)
|
||||
case @state
|
||||
when State::FRESH, State::YANK
|
||||
@ring << RingPoint.new(string)
|
||||
@state = State::CONTINUED
|
||||
when State::CONTINUED, State::PROCESSED
|
||||
if before_p
|
||||
@ring.head.str.prepend(string)
|
||||
else
|
||||
@ring.head.str.concat(string)
|
||||
end
|
||||
@state = State::CONTINUED
|
||||
end
|
||||
end
|
||||
|
||||
def process
|
||||
case @state
|
||||
when State::FRESH
|
||||
# nothing to do
|
||||
when State::CONTINUED
|
||||
@state = State::PROCESSED
|
||||
when State::PROCESSED
|
||||
@state = State::FRESH
|
||||
when State::YANK
|
||||
# nothing to do
|
||||
end
|
||||
end
|
||||
|
||||
def yank
|
||||
unless @ring.empty?
|
||||
@state = State::YANK
|
||||
@ring_pointer = @ring.head
|
||||
@ring_pointer.str
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def yank_pop
|
||||
if @state == State::YANK
|
||||
prev_yank = @ring_pointer.str
|
||||
@ring_pointer = @ring_pointer.backward
|
||||
[@ring_pointer.str, prev_yank]
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
1358
lib/reline/line_editor.rb
Normal file
1358
lib/reline/line_editor.rb
Normal file
File diff suppressed because it is too large
Load diff
25
lib/reline/reline.gemspec
Normal file
25
lib/reline/reline.gemspec
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
lib = File.expand_path('../lib', __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
require 'reline/version'
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = 'reline'
|
||||
spec.version = Reline::VERSION
|
||||
spec.authors = ['aycabta']
|
||||
spec.email = ['aycabta@gmail.com']
|
||||
|
||||
spec.summary = %q{Alternative GNU Readline or Editline implementation by pure Ruby.}
|
||||
spec.description = %q{Alternative GNU Readline or Editline implementation by pure Ruby.}
|
||||
spec.homepage = 'https://github.com/ruby/reline'
|
||||
spec.license = 'Ruby License'
|
||||
|
||||
spec.files = Dir['BSDL', 'COPYING', 'README.md', 'lib/**/*']
|
||||
spec.bindir = 'exe'
|
||||
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
||||
spec.require_paths = ['lib']
|
||||
|
||||
spec.add_development_dependency 'bundler'
|
||||
spec.add_development_dependency 'rake'
|
||||
spec.add_development_dependency 'test-unit'
|
||||
end
|
415
lib/reline/unicode.rb
Normal file
415
lib/reline/unicode.rb
Normal file
|
@ -0,0 +1,415 @@
|
|||
class Reline::Unicode
|
||||
EscapedPairs = {
|
||||
0x00 => '^@',
|
||||
0x01 => '^A', # C-a
|
||||
0x02 => '^B',
|
||||
0x03 => '^C',
|
||||
0x04 => '^D',
|
||||
0x05 => '^E',
|
||||
0x06 => '^F',
|
||||
0x07 => '^G',
|
||||
0x08 => '^H', # Backspace
|
||||
0x09 => '^I',
|
||||
0x0A => '^J',
|
||||
0x0B => '^K',
|
||||
0x0C => '^L',
|
||||
0x0D => '^M', # Enter
|
||||
0x0E => '^N',
|
||||
0x0F => '^O',
|
||||
0x10 => '^P',
|
||||
0x11 => '^Q',
|
||||
0x12 => '^R',
|
||||
0x13 => '^S',
|
||||
0x14 => '^T',
|
||||
0x15 => '^U',
|
||||
0x16 => '^V',
|
||||
0x17 => '^W',
|
||||
0x18 => '^X',
|
||||
0x19 => '^Y',
|
||||
0x1A => '^Z', # C-z
|
||||
0x1B => '^[', # C-[ C-3
|
||||
0x1D => '^]', # C-]
|
||||
0x1E => '^^', # C-~ C-6
|
||||
0x1F => '^_', # C-_ C-7
|
||||
0x7F => '^?', # C-? C-8
|
||||
}
|
||||
EscapedChars = EscapedPairs.keys.map(&:chr)
|
||||
|
||||
def self.get_mbchar_byte_size_by_first_char(c)
|
||||
# Checks UTF-8 character byte size
|
||||
case c.ord
|
||||
# 0b0xxxxxxx
|
||||
when ->(code) { (code ^ 0b10000000).allbits?(0b10000000) } then 1
|
||||
# 0b110xxxxx
|
||||
when ->(code) { (code ^ 0b00100000).allbits?(0b11100000) } then 2
|
||||
# 0b1110xxxx
|
||||
when ->(code) { (code ^ 0b00010000).allbits?(0b11110000) } then 3
|
||||
# 0b11110xxx
|
||||
when ->(code) { (code ^ 0b00001000).allbits?(0b11111000) } then 4
|
||||
# 0b111110xx
|
||||
when ->(code) { (code ^ 0b00000100).allbits?(0b11111100) } then 5
|
||||
# 0b1111110x
|
||||
when ->(code) { (code ^ 0b00000010).allbits?(0b11111110) } then 6
|
||||
# successor of mbchar
|
||||
else 0
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_mbchar_width(mbchar)
|
||||
case mbchar.encode(Encoding::UTF_8)
|
||||
when *EscapedChars # ^ + char, such as ^M, ^H, ^[, ...
|
||||
2
|
||||
when /^\u{2E3B}/ # THREE-EM DASH
|
||||
3
|
||||
when /^\p{M}/
|
||||
0
|
||||
when EastAsianWidth::TYPE_A
|
||||
Reline.ambiguous_width
|
||||
when EastAsianWidth::TYPE_F, EastAsianWidth::TYPE_W
|
||||
2
|
||||
when EastAsianWidth::TYPE_H, EastAsianWidth::TYPE_NA, EastAsianWidth::TYPE_N
|
||||
1
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_next_mbchar_size(line, byte_pointer)
|
||||
grapheme = line.byteslice(byte_pointer..-1).grapheme_clusters.first
|
||||
grapheme ? grapheme.bytesize : 0
|
||||
end
|
||||
|
||||
def self.get_prev_mbchar_size(line, byte_pointer)
|
||||
if byte_pointer.zero?
|
||||
0
|
||||
else
|
||||
grapheme = line.byteslice(0..(byte_pointer - 1)).grapheme_clusters.last
|
||||
grapheme ? grapheme.bytesize : 0
|
||||
end
|
||||
end
|
||||
|
||||
def self.em_forward_word(line, byte_pointer)
|
||||
width = 0
|
||||
byte_size = 0
|
||||
while line.bytesize > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
while line.bytesize > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[byte_size, width]
|
||||
end
|
||||
|
||||
def self.em_forward_word_with_capitalization(line, byte_pointer)
|
||||
width = 0
|
||||
byte_size = 0
|
||||
new_str = String.new
|
||||
while line.bytesize > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
|
||||
new_str += mbchar
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
first = true
|
||||
while line.bytesize > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
if first
|
||||
new_str += mbchar.upcase
|
||||
first = false
|
||||
else
|
||||
new_str += mbchar.downcase
|
||||
end
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[byte_size, width, new_str]
|
||||
end
|
||||
|
||||
def self.em_backward_word(line, byte_pointer)
|
||||
width = 0
|
||||
byte_size = 0
|
||||
while 0 < (byte_pointer - byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer - byte_size)
|
||||
mbchar = line.byteslice(byte_pointer - byte_size - size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
while 0 < (byte_pointer - byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer - byte_size)
|
||||
mbchar = line.byteslice(byte_pointer - byte_size - size, size)
|
||||
break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[byte_size, width]
|
||||
end
|
||||
|
||||
def self.em_big_backward_word(line, byte_pointer)
|
||||
width = 0
|
||||
byte_size = 0
|
||||
while 0 < (byte_pointer - byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer - byte_size)
|
||||
mbchar = line.byteslice(byte_pointer - byte_size - size, size)
|
||||
break if mbchar =~ /\S/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
while 0 < (byte_pointer - byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer - byte_size)
|
||||
mbchar = line.byteslice(byte_pointer - byte_size - size, size)
|
||||
break if mbchar =~ /\s/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[byte_size, width]
|
||||
end
|
||||
|
||||
def self.vi_big_forward_word(line, byte_pointer)
|
||||
width = 0
|
||||
byte_size = 0
|
||||
while (line.bytesize - 1) > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar =~ /\s/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
while (line.bytesize - 1) > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar =~ /\S/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[byte_size, width]
|
||||
end
|
||||
|
||||
def self.vi_big_forward_end_word(line, byte_pointer)
|
||||
if (line.bytesize - 1) > byte_pointer
|
||||
size = get_next_mbchar_size(line, byte_pointer)
|
||||
mbchar = line.byteslice(byte_pointer, size)
|
||||
width = get_mbchar_width(mbchar)
|
||||
byte_size = size
|
||||
else
|
||||
return [0, 0]
|
||||
end
|
||||
while (line.bytesize - 1) > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar =~ /\S/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
prev_width = width
|
||||
prev_byte_size = byte_size
|
||||
while line.bytesize > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar =~ /\s/
|
||||
prev_width = width
|
||||
prev_byte_size = byte_size
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[prev_byte_size, prev_width]
|
||||
end
|
||||
|
||||
def self.vi_big_backward_word(line, byte_pointer)
|
||||
width = 0
|
||||
byte_size = 0
|
||||
while 0 < (byte_pointer - byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer - byte_size)
|
||||
mbchar = line.byteslice(byte_pointer - byte_size - size, size)
|
||||
break if mbchar =~ /\S/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
while 0 < (byte_pointer - byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer - byte_size)
|
||||
mbchar = line.byteslice(byte_pointer - byte_size - size, size)
|
||||
break if mbchar =~ /\s/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[byte_size, width]
|
||||
end
|
||||
|
||||
def self.vi_forward_word(line, byte_pointer)
|
||||
if (line.bytesize - 1) > byte_pointer
|
||||
size = get_next_mbchar_size(line, byte_pointer)
|
||||
mbchar = line.byteslice(byte_pointer, size)
|
||||
if mbchar =~ /\w/
|
||||
started_by = :word
|
||||
elsif mbchar =~ /\s/
|
||||
started_by = :space
|
||||
else
|
||||
started_by = :non_word_printable
|
||||
end
|
||||
width = get_mbchar_width(mbchar)
|
||||
byte_size = size
|
||||
else
|
||||
return [0, 0]
|
||||
end
|
||||
while (line.bytesize - 1) > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
case started_by
|
||||
when :word
|
||||
break if mbchar =~ /\W/
|
||||
when :space
|
||||
break if mbchar =~ /\S/
|
||||
when :non_word_printable
|
||||
break if mbchar =~ /\w|\s/
|
||||
end
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
while (line.bytesize - 1) > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
break if mbchar =~ /\S/
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[byte_size, width]
|
||||
end
|
||||
|
||||
def self.vi_forward_end_word(line, byte_pointer)
|
||||
if (line.bytesize - 1) > byte_pointer
|
||||
size = get_next_mbchar_size(line, byte_pointer)
|
||||
mbchar = line.byteslice(byte_pointer, size)
|
||||
if mbchar =~ /\w/
|
||||
started_by = :word
|
||||
elsif mbchar =~ /\s/
|
||||
started_by = :space
|
||||
else
|
||||
started_by = :non_word_printable
|
||||
end
|
||||
width = get_mbchar_width(mbchar)
|
||||
byte_size = size
|
||||
else
|
||||
return [0, 0]
|
||||
end
|
||||
if (line.bytesize - 1) > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
if mbchar =~ /\w/
|
||||
second = :word
|
||||
elsif mbchar =~ /\s/
|
||||
second = :space
|
||||
else
|
||||
second = :non_word_printable
|
||||
end
|
||||
second_width = get_mbchar_width(mbchar)
|
||||
second_byte_size = size
|
||||
else
|
||||
return [byte_size, width]
|
||||
end
|
||||
if second == :space
|
||||
width += second_width
|
||||
byte_size += second_byte_size
|
||||
while (line.bytesize - 1) > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
if mbchar =~ /\S/
|
||||
if mbchar =~ /\w/
|
||||
started_by = :word
|
||||
else
|
||||
started_by = :non_word_printable
|
||||
end
|
||||
break
|
||||
end
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
else
|
||||
case [started_by, second]
|
||||
when [:word, :non_word_printable], [:non_word_printable, :word]
|
||||
started_by = second
|
||||
else
|
||||
width += second_width
|
||||
byte_size += second_byte_size
|
||||
started_by = second
|
||||
end
|
||||
end
|
||||
prev_width = width
|
||||
prev_byte_size = byte_size
|
||||
while line.bytesize > (byte_pointer + byte_size)
|
||||
size = get_next_mbchar_size(line, byte_pointer + byte_size)
|
||||
mbchar = line.byteslice(byte_pointer + byte_size, size)
|
||||
case started_by
|
||||
when :word
|
||||
break if mbchar =~ /\W/
|
||||
when :non_word_printable
|
||||
break if mbchar =~ /[\w\s]/
|
||||
end
|
||||
prev_width = width
|
||||
prev_byte_size = byte_size
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[prev_byte_size, prev_width]
|
||||
end
|
||||
|
||||
def self.vi_backward_word(line, byte_pointer)
|
||||
width = 0
|
||||
byte_size = 0
|
||||
while 0 < (byte_pointer - byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer - byte_size)
|
||||
mbchar = line.byteslice(byte_pointer - byte_size - size, size)
|
||||
if mbchar =~ /\S/
|
||||
if mbchar =~ /\w/
|
||||
started_by = :word
|
||||
else
|
||||
started_by = :non_word_printable
|
||||
end
|
||||
break
|
||||
end
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
while 0 < (byte_pointer - byte_size)
|
||||
size = get_prev_mbchar_size(line, byte_pointer - byte_size)
|
||||
mbchar = line.byteslice(byte_pointer - byte_size - size, size)
|
||||
case started_by
|
||||
when :word
|
||||
break if mbchar =~ /\W/
|
||||
when :non_word_printable
|
||||
break if mbchar =~ /[\w\s]/
|
||||
end
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[byte_size, width]
|
||||
end
|
||||
|
||||
def self.ed_move_to_begin(line)
|
||||
width = 0
|
||||
byte_size = 0
|
||||
while (line.bytesize - 1) > byte_size
|
||||
size = get_next_mbchar_size(line, byte_size)
|
||||
mbchar = line.byteslice(byte_size, size)
|
||||
if mbchar =~ /\S/
|
||||
break
|
||||
end
|
||||
width += get_mbchar_width(mbchar)
|
||||
byte_size += size
|
||||
end
|
||||
[byte_size, width]
|
||||
end
|
||||
end
|
||||
|
||||
require 'reline/unicode/east_asian_width'
|
1145
lib/reline/unicode/east_asian_width.rb
Normal file
1145
lib/reline/unicode/east_asian_width.rb
Normal file
File diff suppressed because it is too large
Load diff
3
lib/reline/version.rb
Normal file
3
lib/reline/version.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
module Reline
|
||||
VERSION = '0.0.0'
|
||||
end
|
174
lib/reline/windows.rb
Normal file
174
lib/reline/windows.rb
Normal file
|
@ -0,0 +1,174 @@
|
|||
require 'fiddle/import'
|
||||
|
||||
class Win32API
|
||||
DLL = {}
|
||||
TYPEMAP = {"0" => Fiddle::TYPE_VOID, "S" => Fiddle::TYPE_VOIDP, "I" => Fiddle::TYPE_LONG}
|
||||
POINTER_TYPE = Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG ? 'q*' : 'l!*'
|
||||
|
||||
WIN32_TYPES = "VPpNnLlIi"
|
||||
DL_TYPES = "0SSI"
|
||||
|
||||
def initialize(dllname, func, import, export = "0", calltype = :stdcall)
|
||||
@proto = [import].join.tr(WIN32_TYPES, DL_TYPES).sub(/^(.)0*$/, '\1')
|
||||
import = @proto.chars.map {|win_type| TYPEMAP[win_type.tr(WIN32_TYPES, DL_TYPES)]}
|
||||
export = TYPEMAP[export.tr(WIN32_TYPES, DL_TYPES)]
|
||||
calltype = Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[calltype]
|
||||
|
||||
handle = DLL[dllname] ||=
|
||||
begin
|
||||
Fiddle.dlopen(dllname)
|
||||
rescue Fiddle::DLError
|
||||
raise unless File.extname(dllname).empty?
|
||||
Fiddle.dlopen(dllname + ".dll")
|
||||
end
|
||||
|
||||
@func = Fiddle::Function.new(handle[func], import, export, calltype)
|
||||
rescue Fiddle::DLError => e
|
||||
raise LoadError, e.message, e.backtrace
|
||||
end
|
||||
|
||||
def call(*args)
|
||||
import = @proto.split("")
|
||||
args.each_with_index do |x, i|
|
||||
args[i], = [x == 0 ? nil : x].pack("p").unpack(POINTER_TYPE) if import[i] == "S"
|
||||
args[i], = [x].pack("I").unpack("i") if import[i] == "I"
|
||||
end
|
||||
ret, = @func.call(*args)
|
||||
return ret || 0
|
||||
end
|
||||
|
||||
alias Call call
|
||||
end
|
||||
|
||||
module Reline
|
||||
VK_LMENU = 0xA4
|
||||
STD_OUTPUT_HANDLE = -11
|
||||
@@getwch = Win32API.new('msvcrt', '_getwch', [], 'I')
|
||||
@@kbhit = Win32API.new('msvcrt', '_kbhit', [], 'I')
|
||||
@@GetKeyState = Win32API.new('user32', 'GetKeyState', ['L'], 'L')
|
||||
@@GetConsoleScreenBufferInfo = Win32API.new('kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L')
|
||||
@@SetConsoleCursorPosition = Win32API.new('kernel32', 'SetConsoleCursorPosition', ['L', 'L'], 'L')
|
||||
@@GetStdHandle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L')
|
||||
@@FillConsoleOutputCharacter = Win32API.new('kernel32', 'FillConsoleOutputCharacter', ['L', 'L', 'L', 'L', 'P'], 'L')
|
||||
@@ScrollConsoleScreenBuffer = Win32API.new('kernel32', 'ScrollConsoleScreenBuffer', ['L', 'P', 'P', 'L', 'P'], 'L')
|
||||
@@hConsoleHandle = @@GetStdHandle.call(STD_OUTPUT_HANDLE)
|
||||
@@buf = []
|
||||
|
||||
def getwch
|
||||
while @@kbhit.call == 0
|
||||
sleep(0.001)
|
||||
end
|
||||
result = []
|
||||
until @@kbhit.call == 0
|
||||
ret = @@getwch.call
|
||||
begin
|
||||
result.concat(ret.chr(Encoding::UTF_8).encode(Encoding.default_external).bytes)
|
||||
rescue Encoding::UndefinedConversionError
|
||||
result << ret
|
||||
result << @@getwch.call if ret == 224
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def getc
|
||||
unless @@buf.empty?
|
||||
return @@buf.shift
|
||||
end
|
||||
input = getwch
|
||||
alt = (@@GetKeyState.call(VK_LMENU) & 0x80) != 0
|
||||
if input.size > 1
|
||||
@@buf.concat(input)
|
||||
else # single byte
|
||||
case input[0]
|
||||
when 0x00
|
||||
getwch
|
||||
alt = false
|
||||
input = getwch
|
||||
@@buf.concat(input)
|
||||
when 0xE0
|
||||
@@buf.concat(input)
|
||||
input = getwch
|
||||
@@buf.concat(input)
|
||||
when 0x03
|
||||
@@buf.concat(input)
|
||||
else
|
||||
@@buf.concat(input)
|
||||
end
|
||||
end
|
||||
if alt
|
||||
"\e".ord
|
||||
else
|
||||
@@buf.shift
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_screen_size
|
||||
csbi = 0.chr * 24
|
||||
@@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
|
||||
csbi[0, 4].unpack('SS')
|
||||
end
|
||||
|
||||
def self.cursor_pos
|
||||
csbi = 0.chr * 24
|
||||
@@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
|
||||
x = csbi[4, 2].unpack('s*').first
|
||||
y = csbi[6, 4].unpack('s*').first
|
||||
CursorPos.new(x, y)
|
||||
end
|
||||
|
||||
def self.move_cursor_column(val)
|
||||
@@SetConsoleCursorPosition.call(@@hConsoleHandle, cursor_pos.y * 65536 + val)
|
||||
end
|
||||
|
||||
def self.move_cursor_up(val)
|
||||
if val > 0
|
||||
@@SetConsoleCursorPosition.call(@@hConsoleHandle, (cursor_pos.y - val) * 65536 + cursor_pos.x)
|
||||
elsif val < 0
|
||||
move_cursor_down(-val)
|
||||
end
|
||||
end
|
||||
|
||||
def self.move_cursor_down(val)
|
||||
if val > 0
|
||||
@@SetConsoleCursorPosition.call(@@hConsoleHandle, (cursor_pos.y + val) * 65536 + cursor_pos.x)
|
||||
elsif val < 0
|
||||
move_cursor_up(-val)
|
||||
end
|
||||
end
|
||||
|
||||
def self.erase_after_cursor
|
||||
csbi = 0.chr * 24
|
||||
@@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
|
||||
cursor = csbi[4, 4].unpack('L').first
|
||||
written = 0.chr * 4
|
||||
@@FillConsoleOutputCharacter.call(@@hConsoleHandle, 0x20, get_screen_size.first - cursor_pos.x, cursor, written)
|
||||
end
|
||||
|
||||
def self.scroll_down(val)
|
||||
return if val.zero?
|
||||
scroll_rectangle = [0, val, get_screen_size.last, get_screen_size.first].pack('s4')
|
||||
destination_origin = 0 # y * 65536 + x
|
||||
fill = [' '.ord, 0].pack('SS')
|
||||
@@ScrollConsoleScreenBuffer.call(@@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill)
|
||||
end
|
||||
|
||||
def self.clear_screen
|
||||
# TODO: Use FillConsoleOutputCharacter and FillConsoleOutputAttribute
|
||||
print "\e[2J"
|
||||
print "\e[1;1H"
|
||||
end
|
||||
|
||||
def self.set_screen_size(rows, columns)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def prep
|
||||
# do nothing
|
||||
nil
|
||||
end
|
||||
|
||||
def deprep(otio)
|
||||
# do nothing
|
||||
end
|
||||
end
|
|
@ -4,8 +4,8 @@ begin
|
|||
require 'readline'
|
||||
rescue LoadError
|
||||
else
|
||||
# rb-readline behaves quite differently
|
||||
unless defined?(RbReadline)
|
||||
# rb-readline and reline behave quite differently
|
||||
unless defined?(RbReadline) or defined?(Reline)
|
||||
MSpec.enable_feature :readline
|
||||
end
|
||||
end
|
||||
|
|
73
test/reline/helper.rb
Normal file
73
test/reline/helper.rb
Normal file
|
@ -0,0 +1,73 @@
|
|||
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
||||
require 'reline'
|
||||
require 'test/unit'
|
||||
|
||||
RELINE_TEST_ENCODING ||=
|
||||
if ENV['RELINE_TEST_ENCODING']
|
||||
Encoding.find(ENV['RELINE_TEST_ENCODING'])
|
||||
else
|
||||
Encoding.default_external
|
||||
end
|
||||
|
||||
class Reline::TestCase < Test::Unit::TestCase
|
||||
puts "Test encoding is #{RELINE_TEST_ENCODING}"
|
||||
|
||||
private def convert_str(input, options = {}, normalized = nil)
|
||||
return nil if input.nil?
|
||||
input.chars.map { |c|
|
||||
if Reline::Unicode::EscapedChars.include?(c.ord)
|
||||
c
|
||||
else
|
||||
c.encode(@line_editor.instance_variable_get(:@encoding), Encoding::UTF_8, options)
|
||||
end
|
||||
}.join
|
||||
rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
|
||||
input.unicode_normalize!(:nfc)
|
||||
if normalized
|
||||
options[:undef] = :replace
|
||||
options[:replace] = '?'
|
||||
end
|
||||
normalized = true
|
||||
retry
|
||||
end
|
||||
|
||||
def input_keys(input, convert = true)
|
||||
input = convert_str(input) if convert
|
||||
input.chars.each do |c|
|
||||
if c.bytesize == 1
|
||||
eighth_bit = 0b10000000
|
||||
byte = c.bytes.first
|
||||
if byte.allbits?(eighth_bit)
|
||||
@line_editor.input_key("\e".ord)
|
||||
byte ^= eighth_bit
|
||||
end
|
||||
@line_editor.input_key(byte)
|
||||
else
|
||||
c.bytes.each do |b|
|
||||
@line_editor.input_key(b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_line(expected)
|
||||
expected = convert_str(expected)
|
||||
assert_equal(expected, @line_editor.line)
|
||||
end
|
||||
|
||||
def assert_byte_pointer_size(expected)
|
||||
expected = convert_str(expected)
|
||||
byte_pointer = @line_editor.instance_variable_get(:@byte_pointer)
|
||||
assert_equal(
|
||||
expected.bytesize, byte_pointer,
|
||||
"<#{expected.inspect}> expected but was\n<#{@line_editor.line.byteslice(0, byte_pointer).inspect}>")
|
||||
end
|
||||
|
||||
def assert_cursor(expected)
|
||||
assert_equal(expected, @line_editor.instance_variable_get(:@cursor))
|
||||
end
|
||||
|
||||
def assert_cursor_max(expected)
|
||||
assert_equal(expected, @line_editor.instance_variable_get(:@cursor_max))
|
||||
end
|
||||
end
|
118
test/reline/test_config.rb
Normal file
118
test/reline/test_config.rb
Normal file
|
@ -0,0 +1,118 @@
|
|||
require_relative 'helper'
|
||||
|
||||
class Reline::Config::Test < Reline::TestCase
|
||||
def setup
|
||||
@pwd = Dir.pwd
|
||||
@tmpdir = File.join(Dir.tmpdir, "test_reline_config_#{$$}")
|
||||
begin
|
||||
Dir.mkdir(@tmpdir)
|
||||
rescue Errno::EEXIST
|
||||
FileUtils.rm_rf(@tmpdir)
|
||||
Dir.mkdir(@tmpdir)
|
||||
end
|
||||
Dir.chdir(@tmpdir)
|
||||
@config = Reline::Config.new
|
||||
end
|
||||
|
||||
def teardown
|
||||
Dir.chdir(@pwd)
|
||||
FileUtils.rm_rf(@tmpdir)
|
||||
end
|
||||
|
||||
def test_read_lines
|
||||
@config.read_lines(<<~LINES.split(/(?<=\n)/))
|
||||
set bell-style on
|
||||
LINES
|
||||
|
||||
assert_equal :audible, @config.instance_variable_get(:@bell_style)
|
||||
end
|
||||
|
||||
def test_bind_key
|
||||
key, func = @config.bind_key('"input"', '"abcde"')
|
||||
|
||||
assert_equal 'input', key
|
||||
assert_equal 'abcde', func
|
||||
end
|
||||
|
||||
def test_bind_key_with_macro
|
||||
key, func = @config.bind_key('"input"', 'abcde')
|
||||
|
||||
assert_equal 'input', key
|
||||
assert_equal :abcde, func
|
||||
end
|
||||
|
||||
def test_bind_key_with_escaped_chars
|
||||
assert_equal ['input', "\e \\ \" ' \a \b \d \f \n \r \t \v"], @config.bind_key('"input"', '"\\e \\\\ \\" \\\' \\a \\b \\d \\f \\n \\r \\t \\v"')
|
||||
end
|
||||
|
||||
def test_bind_key_with_ctrl_chars
|
||||
assert_equal ['input', "\C-h\C-h"], @config.bind_key('"input"', '"\C-h\C-H"')
|
||||
end
|
||||
|
||||
def test_bind_key_with_meta_chars
|
||||
assert_equal ['input', "\M-h\M-H".force_encoding('ASCII-8BIT')], @config.bind_key('"input"', '"\M-h\M-H"')
|
||||
end
|
||||
|
||||
def test_bind_key_with_octal_number
|
||||
assert_equal ['input', "\1"], @config.bind_key('"input"', '"\1"')
|
||||
assert_equal ['input', "\12"], @config.bind_key('"input"', '"\12"')
|
||||
assert_equal ['input', "\123"], @config.bind_key('"input"', '"\123"')
|
||||
assert_equal ['input', ["\123", '4'].join], @config.bind_key('"input"', '"\1234"')
|
||||
end
|
||||
|
||||
def test_bind_key_with_hexadecimal_number
|
||||
assert_equal ['input', "\x4"], @config.bind_key('"input"', '"\x4"')
|
||||
assert_equal ['input', "\x45"], @config.bind_key('"input"', '"\x45"')
|
||||
assert_equal ['input', ["\x45", '6'].join], @config.bind_key('"input"', '"\x456"')
|
||||
end
|
||||
|
||||
def test_include
|
||||
File.open('included_partial', 'wt') do |f|
|
||||
f.write(<<~PARTIAL_LINES)
|
||||
set bell-style on
|
||||
PARTIAL_LINES
|
||||
end
|
||||
@config.read_lines(<<~LINES.split(/(?<=\n)/))
|
||||
$include included_partial
|
||||
LINES
|
||||
|
||||
assert_equal :audible, @config.instance_variable_get(:@bell_style)
|
||||
end
|
||||
|
||||
def test_if
|
||||
@config.read_lines(<<~LINES.split(/(?<=\n)/))
|
||||
$if Ruby
|
||||
set bell-style audible
|
||||
$else
|
||||
set bell-style visible
|
||||
$endif
|
||||
LINES
|
||||
|
||||
assert_equal :audible, @config.instance_variable_get(:@bell_style)
|
||||
end
|
||||
|
||||
def test_if_with_false
|
||||
@config.read_lines(<<~LINES.split(/(?<=\n)/))
|
||||
$if Python
|
||||
set bell-style audible
|
||||
$else
|
||||
set bell-style visible
|
||||
$endif
|
||||
LINES
|
||||
|
||||
assert_equal :visible, @config.instance_variable_get(:@bell_style)
|
||||
end
|
||||
|
||||
def test_if_with_indent
|
||||
@config.read_lines(<<~LINES.split(/(?<=\n)/))
|
||||
set bell-style none
|
||||
$if Ruby
|
||||
set bell-style audible
|
||||
$else
|
||||
set bell-style visible
|
||||
$endif
|
||||
LINES
|
||||
|
||||
assert_equal :audible, @config.instance_variable_get(:@bell_style)
|
||||
end
|
||||
end
|
1166
test/reline/test_key_actor_emacs.rb
Normal file
1166
test/reline/test_key_actor_emacs.rb
Normal file
File diff suppressed because it is too large
Load diff
51
test/reline/test_key_stroke.rb
Normal file
51
test/reline/test_key_stroke.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
require_relative 'helper'
|
||||
|
||||
class Reline::KeyStroke::Test < Reline::TestCase
|
||||
using Module.new {
|
||||
refine Array do
|
||||
def as_s
|
||||
map(&:chr).join
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
def test_input_to!
|
||||
config = {
|
||||
key_mapping: {
|
||||
"a" => "xx",
|
||||
"ab" => "y",
|
||||
"abc" => "z",
|
||||
"x" => "rr"
|
||||
}
|
||||
}
|
||||
stroke = Reline::KeyStroke.new(config)
|
||||
result = ("abzwabk".bytes).map { |char|
|
||||
stroke.input_to!(char)&.then { |result|
|
||||
"#{result.as_s}"
|
||||
}
|
||||
}
|
||||
assert_equal(result, [nil, nil, "yz", "w", nil, nil, "yk"])
|
||||
end
|
||||
|
||||
def test_input_to
|
||||
config = {
|
||||
key_mapping: {
|
||||
"a" => "xx",
|
||||
"ab" => "y",
|
||||
"abc" => "z",
|
||||
"x" => "rr"
|
||||
}
|
||||
}
|
||||
stroke = Reline::KeyStroke.new(config)
|
||||
assert_equal(stroke.input_to("a".bytes)&.as_s, nil)
|
||||
assert_equal(stroke.input_to("ab".bytes)&.as_s, nil)
|
||||
assert_equal(stroke.input_to("abc".bytes)&.as_s, "z")
|
||||
assert_equal(stroke.input_to("abz".bytes)&.as_s, "yz")
|
||||
assert_equal(stroke.input_to("abx".bytes)&.as_s, "yrr")
|
||||
assert_equal(stroke.input_to("ac".bytes)&.as_s, "rrrrc")
|
||||
assert_equal(stroke.input_to("aa".bytes)&.as_s, "rrrrrrrr")
|
||||
assert_equal(stroke.input_to("x".bytes)&.as_s, "rr")
|
||||
assert_equal(stroke.input_to("m".bytes)&.as_s, "m")
|
||||
assert_equal(stroke.input_to("abzwabk".bytes)&.as_s, "yzwabk")
|
||||
end
|
||||
end
|
1026
test/reline/test_key_vi_emacs.rb
Normal file
1026
test/reline/test_key_vi_emacs.rb
Normal file
File diff suppressed because it is too large
Load diff
256
test/reline/test_kill_ring.rb
Normal file
256
test/reline/test_kill_ring.rb
Normal file
|
@ -0,0 +1,256 @@
|
|||
require_relative 'helper'
|
||||
|
||||
class Reline::KillRing::Test < Reline::TestCase
|
||||
def setup
|
||||
@prompt = '> '
|
||||
@kill_ring = Reline::KillRing.new
|
||||
end
|
||||
|
||||
def test_append_one
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('a')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('a', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('a', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['a', 'a'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['a', 'a'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
end
|
||||
|
||||
def test_append_two
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('a')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('b')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('b', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('b', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['a', 'b'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['b', 'a'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
end
|
||||
|
||||
def test_append_three
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('a')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('b')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('c')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('c', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('c', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['b', 'c'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['a', 'b'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['c', 'a'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
end
|
||||
|
||||
def test_append_three_with_max_two
|
||||
@kill_ring = Reline::KillRing.new(2)
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('a')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('b')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('c')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('c', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('c', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['b', 'c'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['c', 'b'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['b', 'c'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
end
|
||||
|
||||
def test_append_four_with_max_two
|
||||
@kill_ring = Reline::KillRing.new(2)
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('a')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('b')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('c')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('d')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('d', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('d', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['c', 'd'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['d', 'c'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['c', 'd'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
end
|
||||
|
||||
def test_append_after
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('a')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('b')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('ab', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('ab', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['ab', 'ab'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['ab', 'ab'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
end
|
||||
|
||||
def test_append_before
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('a')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('b', true)
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('ba', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('ba', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['ba', 'ba'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['ba', 'ba'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
end
|
||||
|
||||
def test_append_chain_two
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('a')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('b')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('c')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('d')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('cd', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('cd', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['ab', 'cd'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['cd', 'ab'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
end
|
||||
|
||||
def test_append_complex_chain
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('c')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('d')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('b', true)
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('e')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('a', true)
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('A')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.append('B')
|
||||
assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state))
|
||||
@kill_ring.process
|
||||
assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('AB', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal('AB', @kill_ring.yank)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['abcde', 'AB'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
assert_equal(['AB', 'abcde'], @kill_ring.yank_pop)
|
||||
assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state))
|
||||
end
|
||||
end
|
|
@ -3,6 +3,7 @@
|
|||
# * https://github.com/rubygems/rubygems
|
||||
# * https://github.com/bundler/bundler
|
||||
# * https://github.com/ruby/rdoc
|
||||
# * https://github.com/ruby/reline
|
||||
# * https://github.com/flori/json
|
||||
# * https://github.com/ruby/psych
|
||||
# * https://github.com/ruby/fileutils
|
||||
|
@ -42,6 +43,7 @@ $repositories = {
|
|||
rubygems: 'rubygems/rubygems',
|
||||
bundler: 'bundler/bundler',
|
||||
rdoc: 'ruby/rdoc',
|
||||
reline: 'ruby/reline',
|
||||
json: 'flori/json',
|
||||
psych: 'ruby/psych',
|
||||
fileutils: 'ruby/fileutils',
|
||||
|
@ -102,6 +104,11 @@ def sync_default_gems(gem)
|
|||
`cp -rf ../rdoc/exe/ri ./libexec`
|
||||
`rm -f lib/rdoc/markdown.kpeg lib/rdoc/markdown/literals.kpeg lib/rdoc/rd/block_parser.ry lib/rdoc/rd/inline_parser.ry`
|
||||
`git checkout lib/rdoc/.document`
|
||||
when "reline"
|
||||
`rm -rf lib/reline* test/reline`
|
||||
`cp -rf ../reline/lib/reline* ./lib`
|
||||
`cp -rf ../reline/test test/reline`
|
||||
`cp ../reline/reline.gemspec ./lib/reline`
|
||||
when "json"
|
||||
`rm -rf ext/json test/json`
|
||||
`cp -rf ../../flori/json/ext/json/ext ext/json`
|
||||
|
|
Loading…
Reference in a new issue