mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
IRB is improved with Reline and RDoc
Reline is a readline stdlib compatible library. It also supports multiline input. IRB is improved with Reline and supports multiline. Besides, supports showing documents when completed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67645 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
91faab7f14
commit
7f273ac6d0
34 changed files with 8183 additions and 1119 deletions
|
@ -70,8 +70,6 @@ irbの使い方は, Rubyさえ知っていればいたって簡単です. 基本
|
||||||
--back-trace-limit n
|
--back-trace-limit n
|
||||||
バックトレース表示をバックトレースの頭から n, 後ろ
|
バックトレース表示をバックトレースの頭から n, 後ろ
|
||||||
からnだけ行なう. デフォルトは16
|
からnだけ行なう. デフォルトは16
|
||||||
--irb_debug n irbのデバッグデバッグレベルをnに設定する(利用しな
|
|
||||||
い方が無難でしょう).
|
|
||||||
-v, --version irbのバージョンを表示する
|
-v, --version irbのバージョンを表示する
|
||||||
|
|
||||||
= コンフィギュレーション
|
= コンフィギュレーション
|
||||||
|
@ -97,7 +95,6 @@ irb起動時に``~/.irbrc''を読み込みます. もし存在しない場合は
|
||||||
IRB.conf[:IGNORE_EOF] = false
|
IRB.conf[:IGNORE_EOF] = false
|
||||||
IRB.conf[:PROMPT_MODE] = :DEFAULT
|
IRB.conf[:PROMPT_MODE] = :DEFAULT
|
||||||
IRB.conf[:PROMPT] = {...}
|
IRB.conf[:PROMPT] = {...}
|
||||||
IRB.conf[:DEBUG_LEVEL]=0
|
|
||||||
IRB.conf[:VERBOSE]=true
|
IRB.conf[:VERBOSE]=true
|
||||||
|
|
||||||
== プロンプトの設定
|
== プロンプトの設定
|
||||||
|
@ -183,9 +180,6 @@ irb拡張コマンドは, 簡単な名前と頭に`irb_'をつけた名前と両
|
||||||
バックトレース表示をバックトレースの頭からn, 後ろからnだけ行なう.
|
バックトレース表示をバックトレースの頭からn, 後ろからnだけ行なう.
|
||||||
デフォルトは16
|
デフォルトは16
|
||||||
|
|
||||||
--- conf.debug_level = N
|
|
||||||
irb用のデバッグレベルの設定
|
|
||||||
|
|
||||||
--- conf.ignore_eof = true/false
|
--- conf.ignore_eof = true/false
|
||||||
^Dが入力された時の動作を設定する. trueの時は^Dを無視する, falseの
|
^Dが入力された時の動作を設定する. trueの時は^Dを無視する, falseの
|
||||||
時はirbを終了する.
|
時はirbを終了する.
|
||||||
|
|
|
@ -73,7 +73,6 @@ require "irb/version"
|
||||||
# --back-trace-limit n
|
# --back-trace-limit n
|
||||||
# Display backtrace top n and tail n. The default
|
# Display backtrace top n and tail n. The default
|
||||||
# value is 16.
|
# value is 16.
|
||||||
# --irb_debug n Set internal debug level to n (not for popular use)
|
|
||||||
# -v, --version Print the version of irb
|
# -v, --version Print the version of irb
|
||||||
#
|
#
|
||||||
# == Configuration
|
# == Configuration
|
||||||
|
@ -101,7 +100,6 @@ require "irb/version"
|
||||||
# IRB.conf[:IGNORE_EOF] = false
|
# IRB.conf[:IGNORE_EOF] = false
|
||||||
# IRB.conf[:PROMPT_MODE] = :DEFAULT
|
# IRB.conf[:PROMPT_MODE] = :DEFAULT
|
||||||
# IRB.conf[:PROMPT] = {...}
|
# IRB.conf[:PROMPT] = {...}
|
||||||
# IRB.conf[:DEBUG_LEVEL]=0
|
|
||||||
#
|
#
|
||||||
# === Auto indentation
|
# === Auto indentation
|
||||||
#
|
#
|
||||||
|
@ -410,9 +408,7 @@ module IRB
|
||||||
@context = Context.new(self, workspace, input_method, output_method)
|
@context = Context.new(self, workspace, input_method, output_method)
|
||||||
@context.main.extend ExtendCommandBundle
|
@context.main.extend ExtendCommandBundle
|
||||||
@signal_status = :IN_IRB
|
@signal_status = :IN_IRB
|
||||||
|
|
||||||
@scanner = RubyLex.new
|
@scanner = RubyLex.new
|
||||||
@scanner.exception_on_syntax_error = false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(conf = IRB.conf)
|
def run(conf = IRB.conf)
|
||||||
|
|
|
@ -8,11 +8,10 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
require "readline"
|
require "readline"
|
||||||
|
require "rdoc"
|
||||||
|
|
||||||
module IRB
|
module IRB
|
||||||
module InputCompletor # :nodoc:
|
module InputCompletor # :nodoc:
|
||||||
|
|
||||||
|
|
||||||
# Set of reserved words used by Ruby, you should not use these for
|
# Set of reserved words used by Ruby, you should not use these for
|
||||||
# constants or variables
|
# constants or variables
|
||||||
ReservedWords = %w[
|
ReservedWords = %w[
|
||||||
|
@ -195,6 +194,14 @@ module IRB
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RDocRIDriver = RDoc::RI::Driver.new
|
||||||
|
PerfectMatchedProc = proc { |matched|
|
||||||
|
begin
|
||||||
|
RDocRIDriver.display_name(matched)
|
||||||
|
rescue RDoc::RI::Driver::NotFoundError
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
# Set of available operators in Ruby
|
# Set of available operators in Ruby
|
||||||
Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~]
|
Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~]
|
||||||
|
|
||||||
|
@ -242,3 +249,4 @@ if Readline.respond_to?("basic_word_break_characters=")
|
||||||
end
|
end
|
||||||
Readline.completion_append_character = nil
|
Readline.completion_append_character = nil
|
||||||
Readline.completion_proc = IRB::InputCompletor::CompletionProc
|
Readline.completion_proc = IRB::InputCompletor::CompletionProc
|
||||||
|
Readline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc
|
||||||
|
|
|
@ -101,7 +101,6 @@ module IRB
|
||||||
if @echo.nil?
|
if @echo.nil?
|
||||||
@echo = true
|
@echo = true
|
||||||
end
|
end
|
||||||
self.debug_level = IRB.conf[:DEBUG_LEVEL]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# The top-level workspace, see WorkSpace#main
|
# The top-level workspace, see WorkSpace#main
|
||||||
|
@ -211,10 +210,6 @@ module IRB
|
||||||
#
|
#
|
||||||
# A copy of the default <code>IRB.conf[:VERBOSE]</code>
|
# A copy of the default <code>IRB.conf[:VERBOSE]</code>
|
||||||
attr_accessor :verbose
|
attr_accessor :verbose
|
||||||
# The debug level of irb
|
|
||||||
#
|
|
||||||
# See #debug_level= for more information.
|
|
||||||
attr_reader :debug_level
|
|
||||||
|
|
||||||
# The limit of backtrace lines displayed as top +n+ and tail +n+.
|
# The limit of backtrace lines displayed as top +n+ and tail +n+.
|
||||||
#
|
#
|
||||||
|
@ -361,21 +356,6 @@ module IRB
|
||||||
print "Do nothing."
|
print "Do nothing."
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets the debug level of irb
|
|
||||||
#
|
|
||||||
# Can also be set using the +--irb_debug+ command line option.
|
|
||||||
#
|
|
||||||
# See IRB@Command+line+options for more command line options.
|
|
||||||
def debug_level=(value)
|
|
||||||
@debug_level = value
|
|
||||||
RubyLex.debug_level = value
|
|
||||||
end
|
|
||||||
|
|
||||||
# Whether or not debug mode is enabled, see #debug_level=.
|
|
||||||
def debug?
|
|
||||||
@debug_level > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
def evaluate(line, line_no, exception: nil) # :nodoc:
|
def evaluate(line, line_no, exception: nil) # :nodoc:
|
||||||
@line_no = line_no
|
@line_no = line_no
|
||||||
if exception
|
if exception
|
||||||
|
|
|
@ -112,8 +112,6 @@ module IRB # :nodoc:
|
||||||
@CONF[:LC_MESSAGES] = Locale.new
|
@CONF[:LC_MESSAGES] = Locale.new
|
||||||
|
|
||||||
@CONF[:AT_EXIT] = []
|
@CONF[:AT_EXIT] = []
|
||||||
|
|
||||||
@CONF[:DEBUG_LEVEL] = 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def IRB.init_error
|
def IRB.init_error
|
||||||
|
@ -191,8 +189,6 @@ module IRB # :nodoc:
|
||||||
@CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i
|
@CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i
|
||||||
when "--single-irb"
|
when "--single-irb"
|
||||||
@CONF[:SINGLE_IRB] = true
|
@CONF[:SINGLE_IRB] = true
|
||||||
when /^--irb_debug(?:=(.+))?/
|
|
||||||
@CONF[:DEBUG_LEVEL] = ($1 || argv.shift).to_i
|
|
||||||
when "-v", "--version"
|
when "-v", "--version"
|
||||||
print IRB.version, "\n"
|
print IRB.version, "\n"
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -142,13 +142,17 @@ module IRB
|
||||||
@stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
@stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_termination(&block)
|
||||||
|
@check_termination_proc = block
|
||||||
|
end
|
||||||
|
|
||||||
# Reads the next line from this input method.
|
# Reads the next line from this input method.
|
||||||
#
|
#
|
||||||
# See IO#gets for more information.
|
# See IO#gets for more information.
|
||||||
def gets
|
def gets
|
||||||
Readline.input = @stdin
|
Readline.input = @stdin
|
||||||
Readline.output = @stdout
|
Readline.output = @stdout
|
||||||
if l = readline(@prompt, false)
|
if l = readmultiline(@prompt, false, &@check_termination_proc)
|
||||||
HISTORY.push(l) if !l.empty?
|
HISTORY.push(l) if !l.empty?
|
||||||
@line[@line_no += 1] = l + "\n"
|
@line[@line_no += 1] = l + "\n"
|
||||||
else
|
else
|
||||||
|
|
|
@ -39,7 +39,6 @@ Usage: irb.rb [options] [programfile] [arguments]
|
||||||
--back-trace-limit n
|
--back-trace-limit n
|
||||||
Display backtrace top n and tail n. The default
|
Display backtrace top n and tail n. The default
|
||||||
value is 16.
|
value is 16.
|
||||||
--irb_debug n Set internal debug level to n (not for popular use)
|
|
||||||
--verbose Show details
|
--verbose Show details
|
||||||
--noverbose Don't show details
|
--noverbose Don't show details
|
||||||
-v, --version Print the version of irb
|
-v, --version Print the version of irb
|
||||||
|
|
|
@ -41,8 +41,6 @@ Usage: irb.rb [options] [programfile] [arguments]
|
||||||
バックトレース表示をバックトレースの頭から n, 後ろ
|
バックトレース表示をバックトレースの頭から n, 後ろ
|
||||||
からnだけ行なう. デフォルトは16
|
からnだけ行なう. デフォルトは16
|
||||||
|
|
||||||
--irb_debug n irbのデバッグレベルをnに設定する(非推奨).
|
|
||||||
|
|
||||||
--verbose 詳細なメッセージを出力する.
|
--verbose 詳細なメッセージを出力する.
|
||||||
--noverbose 詳細なメッセージを出力しない(デフォルト).
|
--noverbose 詳細なメッセージを出力しない(デフォルト).
|
||||||
-v, --version irbのバージョンを表示する.
|
-v, --version irbのバージョンを表示する.
|
||||||
|
|
1259
lib/irb/ruby-lex.rb
1259
lib/irb/ruby-lex.rb
File diff suppressed because it is too large
Load diff
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
|
196
lib/reline.rb
Normal file
196
lib/reline.rb
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
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/
|
||||||
|
require 'Win32API'
|
||||||
|
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 = '"\''
|
||||||
|
@completer_quote_characters
|
||||||
|
@completer_word_break_characters = @basic_word_break_characters.dup
|
||||||
|
@completion_append_character
|
||||||
|
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
|
||||||
|
@completion_case_fold
|
||||||
|
@filename_quote_characters
|
||||||
|
|
||||||
|
@@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
|
||||||
|
|
||||||
|
@@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
|
||||||
|
:ed_unassigned,
|
||||||
|
# 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
|
1309
lib/reline/line_editor.rb
Normal file
1309
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/aycabta/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
|
132
lib/reline/windows.rb
Normal file
132
lib/reline/windows.rb
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
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
|
|
@ -18,6 +18,7 @@ require 'rubygems/compatibility'
|
||||||
require 'rubygems/defaults'
|
require 'rubygems/defaults'
|
||||||
require 'rubygems/deprecate'
|
require 'rubygems/deprecate'
|
||||||
require 'rubygems/errors'
|
require 'rubygems/errors'
|
||||||
|
require 'rubygems/path_support'
|
||||||
|
|
||||||
##
|
##
|
||||||
# RubyGems is the Ruby standard for publishing and managing third party
|
# RubyGems is the Ruby standard for publishing and managing third party
|
||||||
|
|
111
test/reline/config_test.rb
Normal file
111
test/reline/config_test.rb
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
require 'helper'
|
||||||
|
|
||||||
|
class Reline::Config::Test < Reline::TestCase
|
||||||
|
def setup
|
||||||
|
@tmpdir = File.join(Dir.tmpdir, "test_reline_config_#{$$}")
|
||||||
|
Dir.mkdir(@tmpdir)
|
||||||
|
Dir.chdir(@tmpdir)
|
||||||
|
@config = Reline::Config.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
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
|
66
test/reline/helper.rb
Normal file
66
test/reline/helper.rb
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
||||||
|
require 'reline'
|
||||||
|
require 'test-unit'
|
||||||
|
|
||||||
|
RELINE_TEST_ENCODING = Encoding.find(ENV['RELINE_TEST_ENCODING']) if ENV['RELINE_TEST_ENCODING']
|
||||||
|
|
||||||
|
class Reline::TestCase < Test::Unit::TestCase
|
||||||
|
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
|
1173
test/reline/key_actor_emacs_test.rb
Normal file
1173
test/reline/key_actor_emacs_test.rb
Normal file
File diff suppressed because it is too large
Load diff
990
test/reline/key_actor_vi_test.rb
Normal file
990
test/reline/key_actor_vi_test.rb
Normal file
|
@ -0,0 +1,990 @@
|
||||||
|
require 'helper'
|
||||||
|
|
||||||
|
class Reline::KeyActor::ViInsert::Test < Reline::TestCase
|
||||||
|
def setup
|
||||||
|
@prompt = '> '
|
||||||
|
@config = Reline::Config.new
|
||||||
|
@config.read_lines(<<~LINES.split(/(?<=\n)/))
|
||||||
|
set editing-mode vi
|
||||||
|
LINES
|
||||||
|
@line_editor = Reline::LineEditor.new(
|
||||||
|
@config, @prompt,
|
||||||
|
(RELINE_TEST_ENCODING rescue Encoding.default_external))
|
||||||
|
@line_editor.retrieve_completion_block = Reline.method(:retrieve_completion_block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_command_mode
|
||||||
|
input_keys("\C-[")
|
||||||
|
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_command_mode_with_input
|
||||||
|
input_keys("abc\C-[")
|
||||||
|
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
|
||||||
|
assert_line('abc')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_insert_one
|
||||||
|
input_keys('a')
|
||||||
|
assert_line('a')
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_insert_two
|
||||||
|
input_keys('ab')
|
||||||
|
assert_line('ab')
|
||||||
|
assert_byte_pointer_size('ab')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_insert_mbchar_one
|
||||||
|
input_keys('か')
|
||||||
|
assert_line('か')
|
||||||
|
assert_byte_pointer_size('か')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_insert_mbchar_two
|
||||||
|
input_keys('かき')
|
||||||
|
assert_line('かき')
|
||||||
|
assert_byte_pointer_size('かき')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(4)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_insert_for_mbchar_by_plural_code_points
|
||||||
|
input_keys("か\u3099")
|
||||||
|
assert_line("か\u3099")
|
||||||
|
assert_byte_pointer_size("か\u3099")
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_insert_for_plural_mbchar_by_plural_code_points
|
||||||
|
input_keys("か\u3099き\u3099")
|
||||||
|
assert_line("か\u3099き\u3099")
|
||||||
|
assert_byte_pointer_size("か\u3099き\u3099")
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(4)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_next_char
|
||||||
|
input_keys("abcdef\C-[0")
|
||||||
|
assert_line('abcdef')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
input_keys('l')
|
||||||
|
assert_line('abcdef')
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
input_keys('2l')
|
||||||
|
assert_line('abcdef')
|
||||||
|
assert_byte_pointer_size('abc')
|
||||||
|
assert_cursor(3)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_prev_char
|
||||||
|
input_keys("abcdef\C-[")
|
||||||
|
assert_line('abcdef')
|
||||||
|
assert_byte_pointer_size('abcde')
|
||||||
|
assert_cursor(5)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
input_keys('h')
|
||||||
|
assert_line('abcdef')
|
||||||
|
assert_byte_pointer_size('abcd')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
input_keys('2h')
|
||||||
|
assert_line('abcdef')
|
||||||
|
assert_byte_pointer_size('ab')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_history
|
||||||
|
Reline::HISTORY.concat(%w{abc 123 AAA})
|
||||||
|
input_keys("\C-[")
|
||||||
|
assert_line('')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
input_keys('k')
|
||||||
|
assert_line('AAA')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
input_keys('2k')
|
||||||
|
assert_line('abc')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
input_keys('j')
|
||||||
|
assert_line('123')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
input_keys('2j')
|
||||||
|
assert_line('')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_paste_prev
|
||||||
|
input_keys("abcde\C-[3h")
|
||||||
|
assert_line('abcde')
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(5)
|
||||||
|
input_keys('P')
|
||||||
|
assert_line('abcde')
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(5)
|
||||||
|
input_keys('d$')
|
||||||
|
assert_line('a')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(1)
|
||||||
|
input_keys('P')
|
||||||
|
assert_line('bcdea')
|
||||||
|
assert_byte_pointer_size('bcd')
|
||||||
|
assert_cursor(3)
|
||||||
|
assert_cursor_max(5)
|
||||||
|
input_keys('2P')
|
||||||
|
assert_line('bcdbcdbcdeeea')
|
||||||
|
assert_byte_pointer_size('bcdbcdbcd')
|
||||||
|
assert_cursor(9)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_paste_next
|
||||||
|
input_keys("abcde\C-[3h")
|
||||||
|
assert_line('abcde')
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(5)
|
||||||
|
input_keys('p')
|
||||||
|
assert_line('abcde')
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(5)
|
||||||
|
input_keys('d$')
|
||||||
|
assert_line('a')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(1)
|
||||||
|
input_keys('p')
|
||||||
|
assert_line('abcde')
|
||||||
|
assert_byte_pointer_size('abcd')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(5)
|
||||||
|
input_keys('2p')
|
||||||
|
assert_line('abcdebcdebcde')
|
||||||
|
assert_byte_pointer_size('abcdebcdebcd')
|
||||||
|
assert_cursor(12)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_paste_prev_for_mbchar
|
||||||
|
input_keys("あいうえお\C-[3h")
|
||||||
|
assert_line('あいうえお')
|
||||||
|
assert_byte_pointer_size('あ')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('P')
|
||||||
|
assert_line('あいうえお')
|
||||||
|
assert_byte_pointer_size('あ')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('d$')
|
||||||
|
assert_line('あ')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
input_keys('P')
|
||||||
|
assert_line('いうえおあ')
|
||||||
|
assert_byte_pointer_size('いうえ')
|
||||||
|
assert_cursor(6)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('2P')
|
||||||
|
assert_line('いうえいうえいうえおおおあ')
|
||||||
|
assert_byte_pointer_size('いうえいうえいうえ')
|
||||||
|
assert_cursor(18)
|
||||||
|
assert_cursor_max(26)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_paste_next_for_mbchar
|
||||||
|
input_keys("あいうえお\C-[3h")
|
||||||
|
assert_line('あいうえお')
|
||||||
|
assert_byte_pointer_size('あ')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('p')
|
||||||
|
assert_line('あいうえお')
|
||||||
|
assert_byte_pointer_size('あ')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('d$')
|
||||||
|
assert_line('あ')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
input_keys('p')
|
||||||
|
assert_line('あいうえお')
|
||||||
|
assert_byte_pointer_size('あいうえ')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('2p')
|
||||||
|
assert_line('あいうえおいうえおいうえお')
|
||||||
|
assert_byte_pointer_size('あいうえおいうえおいうえ')
|
||||||
|
assert_cursor(24)
|
||||||
|
assert_cursor_max(26)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_paste_prev_for_mbchar_by_plural_code_points
|
||||||
|
input_keys("か\u3099き\u3099く\u3099け\u3099こ\u3099\C-[3h")
|
||||||
|
assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
|
||||||
|
assert_byte_pointer_size("か\u3099")
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('P')
|
||||||
|
assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
|
||||||
|
assert_byte_pointer_size("か\u3099")
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('d$')
|
||||||
|
assert_line("か\u3099")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
input_keys('P')
|
||||||
|
assert_line("き\u3099く\u3099け\u3099こ\u3099か\u3099")
|
||||||
|
assert_byte_pointer_size("き\u3099く\u3099け\u3099")
|
||||||
|
assert_cursor(6)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('2P')
|
||||||
|
assert_line("き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099こ\u3099こ\u3099こ\u3099か\u3099")
|
||||||
|
assert_byte_pointer_size("き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099")
|
||||||
|
assert_cursor(18)
|
||||||
|
assert_cursor_max(26)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_paste_next_for_mbchar_by_plural_code_points
|
||||||
|
input_keys("か\u3099き\u3099く\u3099け\u3099こ\u3099\C-[3h")
|
||||||
|
assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
|
||||||
|
assert_byte_pointer_size("か\u3099")
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('p')
|
||||||
|
assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
|
||||||
|
assert_byte_pointer_size("か\u3099")
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('d$')
|
||||||
|
assert_line("か\u3099")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
input_keys('p')
|
||||||
|
assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
|
||||||
|
assert_byte_pointer_size("か\u3099き\u3099く\u3099け\u3099")
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
input_keys('2p')
|
||||||
|
assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099")
|
||||||
|
assert_byte_pointer_size("か\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099")
|
||||||
|
assert_cursor(24)
|
||||||
|
assert_cursor_max(26)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_prev_next_word
|
||||||
|
input_keys("aaa b{b}b ccc\C-[0")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('w')
|
||||||
|
assert_byte_pointer_size('aaa ')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('w')
|
||||||
|
assert_byte_pointer_size('aaa b')
|
||||||
|
assert_cursor(5)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('w')
|
||||||
|
assert_byte_pointer_size('aaa b{')
|
||||||
|
assert_cursor(6)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('w')
|
||||||
|
assert_byte_pointer_size('aaa b{b')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('w')
|
||||||
|
assert_byte_pointer_size('aaa b{b}')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('w')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b ')
|
||||||
|
assert_cursor(10)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('w')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b cc')
|
||||||
|
assert_cursor(12)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('b')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b ')
|
||||||
|
assert_cursor(10)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('b')
|
||||||
|
assert_byte_pointer_size('aaa b{b}')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('b')
|
||||||
|
assert_byte_pointer_size('aaa b{b')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('b')
|
||||||
|
assert_byte_pointer_size('aaa b{')
|
||||||
|
assert_cursor(6)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('b')
|
||||||
|
assert_byte_pointer_size('aaa b')
|
||||||
|
assert_cursor(5)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('b')
|
||||||
|
assert_byte_pointer_size('aaa ')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('b')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('3w')
|
||||||
|
assert_byte_pointer_size('aaa b{')
|
||||||
|
assert_cursor(6)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('3w')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b ')
|
||||||
|
assert_cursor(10)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('3w')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b cc')
|
||||||
|
assert_cursor(12)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('3b')
|
||||||
|
assert_byte_pointer_size('aaa b{b')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('3b')
|
||||||
|
assert_byte_pointer_size('aaa ')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('3b')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_end_word
|
||||||
|
input_keys("aaa b{b}}}b ccc\C-[0")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('e')
|
||||||
|
assert_byte_pointer_size('aa')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('e')
|
||||||
|
assert_byte_pointer_size('aaa ')
|
||||||
|
assert_cursor(6)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('e')
|
||||||
|
assert_byte_pointer_size('aaa b')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('e')
|
||||||
|
assert_byte_pointer_size('aaa b{')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('e')
|
||||||
|
assert_byte_pointer_size('aaa b{b}}')
|
||||||
|
assert_cursor(11)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('e')
|
||||||
|
assert_byte_pointer_size('aaa b{b}}}')
|
||||||
|
assert_cursor(12)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('e')
|
||||||
|
assert_byte_pointer_size('aaa b{b}}}b cc')
|
||||||
|
assert_cursor(18)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('e')
|
||||||
|
assert_byte_pointer_size('aaa b{b}}}b cc')
|
||||||
|
assert_cursor(18)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('03e')
|
||||||
|
assert_byte_pointer_size('aaa b')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('3e')
|
||||||
|
assert_byte_pointer_size('aaa b{b}}}')
|
||||||
|
assert_cursor(12)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('3e')
|
||||||
|
assert_byte_pointer_size('aaa b{b}}}b cc')
|
||||||
|
assert_cursor(18)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_prev_next_big_word
|
||||||
|
input_keys("aaa b{b}b ccc\C-[0")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('W')
|
||||||
|
assert_byte_pointer_size('aaa ')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('W')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b ')
|
||||||
|
assert_cursor(10)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('W')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b cc')
|
||||||
|
assert_cursor(12)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('B')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b ')
|
||||||
|
assert_cursor(10)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('B')
|
||||||
|
assert_byte_pointer_size('aaa ')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('B')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('2W')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b ')
|
||||||
|
assert_cursor(10)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('2W')
|
||||||
|
assert_byte_pointer_size('aaa b{b}b cc')
|
||||||
|
assert_cursor(12)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('2B')
|
||||||
|
assert_byte_pointer_size('aaa ')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
input_keys('2B')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(13)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_end_big_word
|
||||||
|
input_keys("aaa b{b}}}b ccc\C-[0")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('E')
|
||||||
|
assert_byte_pointer_size('aa')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('E')
|
||||||
|
assert_byte_pointer_size('aaa b{b}}}')
|
||||||
|
assert_cursor(12)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('E')
|
||||||
|
assert_byte_pointer_size('aaa b{b}}}b cc')
|
||||||
|
assert_cursor(18)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
input_keys('E')
|
||||||
|
assert_byte_pointer_size('aaa b{b}}}b cc')
|
||||||
|
assert_cursor(18)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_quoted_insert
|
||||||
|
input_keys("ab\C-v\C-acd")
|
||||||
|
assert_line("ab\C-acd")
|
||||||
|
assert_byte_pointer_size("ab\C-acd")
|
||||||
|
assert_cursor(6)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_quoted_insert_with_vi_arg
|
||||||
|
input_keys("ab\C-[3\C-v\C-aacd")
|
||||||
|
assert_line("a\C-a\C-a\C-abcd")
|
||||||
|
assert_byte_pointer_size("a\C-a\C-a\C-abcd")
|
||||||
|
assert_cursor(10)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_delete_next_char
|
||||||
|
input_keys("abc\C-[h")
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
assert_line('abc')
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
assert_line('ac')
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(1)
|
||||||
|
assert_line('a')
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
assert_line('')
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
assert_line('')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_delete_next_char_for_mbchar
|
||||||
|
input_keys("あいう\C-[h")
|
||||||
|
assert_byte_pointer_size('あ')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
assert_line('あいう')
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('あ')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(4)
|
||||||
|
assert_line('あう')
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
assert_line('あ')
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
assert_line('')
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
assert_line('')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_delete_next_char_for_mbchar_by_plural_code_points
|
||||||
|
input_keys("か\u3099き\u3099く\u3099\C-[h")
|
||||||
|
assert_byte_pointer_size("か\u3099")
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
assert_line("か\u3099き\u3099く\u3099")
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size("か\u3099")
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(4)
|
||||||
|
assert_line("か\u3099く\u3099")
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
assert_line("か\u3099")
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
assert_line('')
|
||||||
|
input_keys('x')
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
assert_line('')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_delete_prev_char
|
||||||
|
input_keys('ab')
|
||||||
|
assert_byte_pointer_size('ab')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
input_keys("\C-h")
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(1)
|
||||||
|
assert_line('a')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_delete_prev_char_for_mbchar
|
||||||
|
input_keys('かき')
|
||||||
|
assert_byte_pointer_size('かき')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(4)
|
||||||
|
input_keys("\C-h")
|
||||||
|
assert_byte_pointer_size('か')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
assert_line('か')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_delete_prev_char_for_mbchar_by_plural_code_points
|
||||||
|
input_keys("か\u3099き\u3099")
|
||||||
|
assert_byte_pointer_size("か\u3099き\u3099")
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(4)
|
||||||
|
input_keys("\C-h")
|
||||||
|
assert_byte_pointer_size("か\u3099")
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
assert_line("か\u3099")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_delete_prev_char
|
||||||
|
input_keys("abcdefg\C-[h")
|
||||||
|
assert_byte_pointer_size('abcde')
|
||||||
|
assert_cursor(5)
|
||||||
|
assert_cursor_max(7)
|
||||||
|
assert_line('abcdefg')
|
||||||
|
input_keys('X')
|
||||||
|
assert_byte_pointer_size('abcd')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
assert_line('abcdfg')
|
||||||
|
input_keys('3X')
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
assert_line('afg')
|
||||||
|
input_keys('p')
|
||||||
|
assert_byte_pointer_size('abcd')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
assert_line('afbcdg')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_delete_prev_word
|
||||||
|
input_keys('abc def{bbb}ccc')
|
||||||
|
assert_byte_pointer_size('abc def{bbb}ccc')
|
||||||
|
assert_cursor(15)
|
||||||
|
assert_cursor_max(15)
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('abc def{bbb}')
|
||||||
|
assert_cursor(12)
|
||||||
|
assert_cursor_max(12)
|
||||||
|
assert_line('abc def{bbb}')
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('abc def{')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(8)
|
||||||
|
assert_line('abc def{')
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('abc ')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(4)
|
||||||
|
assert_line('abc ')
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
assert_line('')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_delete_prev_word_for_mbchar
|
||||||
|
input_keys('あいう かきく{さしす}たちつ')
|
||||||
|
assert_byte_pointer_size('あいう かきく{さしす}たちつ')
|
||||||
|
assert_cursor(27)
|
||||||
|
assert_cursor_max(27)
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('あいう かきく{さしす}')
|
||||||
|
assert_cursor(21)
|
||||||
|
assert_cursor_max(21)
|
||||||
|
assert_line('あいう かきく{さしす}')
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('あいう かきく{')
|
||||||
|
assert_cursor(14)
|
||||||
|
assert_cursor_max(14)
|
||||||
|
assert_line('あいう かきく{')
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('あいう ')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(7)
|
||||||
|
assert_line('あいう ')
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
assert_line('')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_delete_prev_word_for_mbchar_by_plural_code_points
|
||||||
|
input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
|
||||||
|
assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
|
||||||
|
assert_cursor(27)
|
||||||
|
assert_cursor_max(27)
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}")
|
||||||
|
assert_cursor(21)
|
||||||
|
assert_cursor_max(21)
|
||||||
|
assert_line("あいう か\u3099き\u3099く\u3099{さしす}")
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{")
|
||||||
|
assert_cursor(14)
|
||||||
|
assert_cursor_max(14)
|
||||||
|
assert_line("あいう か\u3099き\u3099く\u3099{")
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('あいう ')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(7)
|
||||||
|
assert_line('あいう ')
|
||||||
|
input_keys("\C-w")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(0)
|
||||||
|
assert_line('')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_newline_with_cr
|
||||||
|
input_keys('ab')
|
||||||
|
assert_byte_pointer_size('ab')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
refute(@line_editor.finished?)
|
||||||
|
input_keys("\C-m")
|
||||||
|
assert_line('ab')
|
||||||
|
assert(@line_editor.finished?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_newline_with_lf
|
||||||
|
input_keys('ab')
|
||||||
|
assert_byte_pointer_size('ab')
|
||||||
|
assert_cursor(2)
|
||||||
|
assert_cursor_max(2)
|
||||||
|
refute(@line_editor.finished?)
|
||||||
|
input_keys("\C-j")
|
||||||
|
assert_line('ab')
|
||||||
|
assert(@line_editor.finished?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_list_or_eof
|
||||||
|
input_keys('a')
|
||||||
|
assert_byte_pointer_size('a')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(1)
|
||||||
|
refute(@line_editor.finished?)
|
||||||
|
input_keys("\C-d")
|
||||||
|
assert_line('a')
|
||||||
|
refute(@line_editor.finished?)
|
||||||
|
input_keys("\C-h\C-d")
|
||||||
|
assert_line(nil)
|
||||||
|
assert(@line_editor.finished?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_completion_journey
|
||||||
|
@line_editor.completion_proc = proc { |word|
|
||||||
|
%w{
|
||||||
|
foo_bar
|
||||||
|
foo_bar_baz
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input_keys('foo')
|
||||||
|
assert_byte_pointer_size('foo')
|
||||||
|
assert_cursor(3)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
assert_line('foo')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('foo')
|
||||||
|
assert_cursor(3)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
assert_line('foo')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('foo_bar')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(7)
|
||||||
|
assert_line('foo_bar')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('foo_bar_baz')
|
||||||
|
assert_cursor(11)
|
||||||
|
assert_cursor_max(11)
|
||||||
|
assert_line('foo_bar_baz')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('foo')
|
||||||
|
assert_cursor(3)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
assert_line('foo')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('foo_bar')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(7)
|
||||||
|
assert_line('foo_bar')
|
||||||
|
input_keys("_\C-n")
|
||||||
|
assert_byte_pointer_size('foo_bar_')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(8)
|
||||||
|
assert_line('foo_bar_')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('foo_bar_baz')
|
||||||
|
assert_cursor(11)
|
||||||
|
assert_cursor_max(11)
|
||||||
|
assert_line('foo_bar_baz')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('foo_bar_')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(8)
|
||||||
|
assert_line('foo_bar_')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_completion_journey_reverse
|
||||||
|
@line_editor.completion_proc = proc { |word|
|
||||||
|
%w{
|
||||||
|
foo_bar
|
||||||
|
foo_bar_baz
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input_keys('foo')
|
||||||
|
assert_byte_pointer_size('foo')
|
||||||
|
assert_cursor(3)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
assert_line('foo')
|
||||||
|
input_keys("\C-p")
|
||||||
|
assert_byte_pointer_size('foo')
|
||||||
|
assert_cursor(3)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
assert_line('foo')
|
||||||
|
input_keys("\C-p")
|
||||||
|
assert_byte_pointer_size('foo_bar_baz')
|
||||||
|
assert_cursor(11)
|
||||||
|
assert_cursor_max(11)
|
||||||
|
assert_line('foo_bar_baz')
|
||||||
|
input_keys("\C-p")
|
||||||
|
assert_byte_pointer_size('foo_bar')
|
||||||
|
assert_cursor(7)
|
||||||
|
assert_cursor_max(7)
|
||||||
|
assert_line('foo_bar')
|
||||||
|
input_keys("\C-p")
|
||||||
|
assert_byte_pointer_size('foo')
|
||||||
|
assert_cursor(3)
|
||||||
|
assert_cursor_max(3)
|
||||||
|
assert_line('foo')
|
||||||
|
input_keys("\C-p")
|
||||||
|
assert_byte_pointer_size('foo_bar_baz')
|
||||||
|
assert_cursor(11)
|
||||||
|
assert_cursor_max(11)
|
||||||
|
assert_line('foo_bar_baz')
|
||||||
|
input_keys("\C-h\C-p")
|
||||||
|
assert_byte_pointer_size('foo_bar_ba')
|
||||||
|
assert_cursor(10)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
assert_line('foo_bar_ba')
|
||||||
|
input_keys("\C-p")
|
||||||
|
assert_byte_pointer_size('foo_bar_baz')
|
||||||
|
assert_cursor(11)
|
||||||
|
assert_cursor_max(11)
|
||||||
|
assert_line('foo_bar_baz')
|
||||||
|
input_keys("\C-p")
|
||||||
|
assert_byte_pointer_size('foo_bar_ba')
|
||||||
|
assert_cursor(10)
|
||||||
|
assert_cursor_max(10)
|
||||||
|
assert_line('foo_bar_ba')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_completion_journey_in_middle_of_line
|
||||||
|
@line_editor.completion_proc = proc { |word|
|
||||||
|
%w{
|
||||||
|
foo_bar
|
||||||
|
foo_bar_baz
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input_keys('abcde fo ABCDE')
|
||||||
|
assert_line('abcde fo ABCDE')
|
||||||
|
input_keys("\C-[" + 'h' * 5 + "i\C-n")
|
||||||
|
assert_byte_pointer_size('abcde fo')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(14)
|
||||||
|
assert_line('abcde fo ABCDE')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('abcde foo_bar')
|
||||||
|
assert_cursor(13)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
assert_line('abcde foo_bar ABCDE')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('abcde foo_bar_baz')
|
||||||
|
assert_cursor(17)
|
||||||
|
assert_cursor_max(23)
|
||||||
|
assert_line('abcde foo_bar_baz ABCDE')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('abcde fo')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(14)
|
||||||
|
assert_line('abcde fo ABCDE')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('abcde foo_bar')
|
||||||
|
assert_cursor(13)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
assert_line('abcde foo_bar ABCDE')
|
||||||
|
input_keys("_\C-n")
|
||||||
|
assert_byte_pointer_size('abcde foo_bar_')
|
||||||
|
assert_cursor(14)
|
||||||
|
assert_cursor_max(20)
|
||||||
|
assert_line('abcde foo_bar_ ABCDE')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('abcde foo_bar_baz')
|
||||||
|
assert_cursor(17)
|
||||||
|
assert_cursor_max(23)
|
||||||
|
assert_line('abcde foo_bar_baz ABCDE')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('abcde foo_bar_')
|
||||||
|
assert_cursor(14)
|
||||||
|
assert_cursor_max(20)
|
||||||
|
assert_line('abcde foo_bar_ ABCDE')
|
||||||
|
input_keys("\C-n")
|
||||||
|
assert_byte_pointer_size('abcde foo_bar_baz')
|
||||||
|
assert_cursor(17)
|
||||||
|
assert_cursor_max(23)
|
||||||
|
assert_line('abcde foo_bar_baz ABCDE')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ed_move_to_beg
|
||||||
|
input_keys("abcde\C-[^")
|
||||||
|
assert_byte_pointer_size('')
|
||||||
|
assert_cursor(0)
|
||||||
|
assert_cursor_max(5)
|
||||||
|
input_keys("0\C-ki")
|
||||||
|
input_keys(" abcde\C-[^")
|
||||||
|
assert_byte_pointer_size(' ')
|
||||||
|
assert_cursor(1)
|
||||||
|
assert_cursor_max(6)
|
||||||
|
input_keys("0\C-ki")
|
||||||
|
input_keys(" abcde ABCDE \C-[^")
|
||||||
|
assert_byte_pointer_size(' ')
|
||||||
|
assert_cursor(3)
|
||||||
|
assert_cursor_max(17)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_vi_delete_meta
|
||||||
|
input_keys("aaa bbb ccc ddd eee\C-[02w")
|
||||||
|
assert_byte_pointer_size('aaa bbb ')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(19)
|
||||||
|
assert_line('aaa bbb ccc ddd eee')
|
||||||
|
input_keys('dw')
|
||||||
|
assert_byte_pointer_size('aaa bbb ')
|
||||||
|
assert_cursor(8)
|
||||||
|
assert_cursor_max(15)
|
||||||
|
assert_line('aaa bbb ddd eee')
|
||||||
|
input_keys('db')
|
||||||
|
assert_byte_pointer_size('aaa ')
|
||||||
|
assert_cursor(4)
|
||||||
|
assert_cursor_max(11)
|
||||||
|
assert_line('aaa ddd eee')
|
||||||
|
end
|
||||||
|
end
|
51
test/reline/key_stroke_test.rb
Normal file
51
test/reline/key_stroke_test.rb
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
require '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
|
256
test/reline/kill_ring_test.rb
Normal file
256
test/reline/kill_ring_test.rb
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
require '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/rubygems/rubygems
|
||||||
# * https://github.com/bundler/bundler
|
# * https://github.com/bundler/bundler
|
||||||
# * https://github.com/ruby/rdoc
|
# * https://github.com/ruby/rdoc
|
||||||
|
# * https://github.com/aycabta/reline
|
||||||
# * https://github.com/flori/json
|
# * https://github.com/flori/json
|
||||||
# * https://github.com/ruby/psych
|
# * https://github.com/ruby/psych
|
||||||
# * https://github.com/ruby/fileutils
|
# * https://github.com/ruby/fileutils
|
||||||
|
@ -42,6 +43,7 @@ $repositories = {
|
||||||
rubygems: 'rubygems/rubygems',
|
rubygems: 'rubygems/rubygems',
|
||||||
bundler: 'bundler/bundler',
|
bundler: 'bundler/bundler',
|
||||||
rdoc: 'ruby/rdoc',
|
rdoc: 'ruby/rdoc',
|
||||||
|
reline: 'aycabta/reline',
|
||||||
json: 'flori/json',
|
json: 'flori/json',
|
||||||
psych: 'ruby/psych',
|
psych: 'ruby/psych',
|
||||||
fileutils: 'ruby/fileutils',
|
fileutils: 'ruby/fileutils',
|
||||||
|
@ -102,6 +104,11 @@ def sync_default_gems(gem)
|
||||||
`cp -rf ../rdoc/exe/ri ./libexec`
|
`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`
|
`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`
|
`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"
|
when "json"
|
||||||
`rm -rf ext/json test/json`
|
`rm -rf ext/json test/json`
|
||||||
`cp -rf ../../flori/json/ext/json/ext ext/json`
|
`cp -rf ../../flori/json/ext/json/ext ext/json`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue