diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2019-04-23 21:55:29 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2019-04-23 21:55:29 +0900 |
commit | f4f66bd11c65882b86e0acf4d58f15fb596f25cf (patch) | |
tree | 34e6e50d15802ad6d8aab4f0d9d747efcd7c149d /lib | |
parent | 89271d4a3733bc5e70e9c56b4bd12f277e699c42 (diff) | |
download | ruby-f4f66bd11c65882b86e0acf4d58f15fb596f25cf.tar.gz |
Revert "IRB is improved with Reline and RDoc, take 2"
Accidentally merged when 89271d4a3733bc5e70e9c56b4bd12f277e699c42
"Adjusted indents".
Diffstat (limited to 'lib')
-rw-r--r-- | lib/irb.rb | 9 | ||||
-rw-r--r-- | lib/irb/completion.rb | 19 | ||||
-rw-r--r-- | lib/irb/context.rb | 81 | ||||
-rw-r--r-- | lib/irb/init.rb | 8 | ||||
-rw-r--r-- | lib/irb/input-method.rb | 85 | ||||
-rw-r--r-- | lib/irb/lc/help-message | 1 | ||||
-rw-r--r-- | lib/irb/lc/ja/help-message | 2 | ||||
-rw-r--r-- | lib/irb/ruby-lex.rb | 1259 | ||||
-rw-r--r-- | lib/rdoc/ri/paths.rb | 2 | ||||
-rw-r--r-- | lib/readline.rb | 6 | ||||
-rw-r--r-- | lib/reline.rb | 196 | ||||
-rw-r--r-- | lib/reline/ansi.rb | 87 | ||||
-rw-r--r-- | lib/reline/config.rb | 235 | ||||
-rw-r--r-- | lib/reline/key_actor.rb | 7 | ||||
-rw-r--r-- | lib/reline/key_actor/base.rb | 7 | ||||
-rw-r--r-- | lib/reline/key_actor/emacs.rb | 518 | ||||
-rw-r--r-- | lib/reline/key_actor/vi_command.rb | 519 | ||||
-rw-r--r-- | lib/reline/key_actor/vi_insert.rb | 518 | ||||
-rw-r--r-- | lib/reline/key_stroke.rb | 74 | ||||
-rw-r--r-- | lib/reline/kill_ring.rb | 113 | ||||
-rw-r--r-- | lib/reline/line_editor.rb | 1357 | ||||
-rw-r--r-- | lib/reline/reline.gemspec | 25 | ||||
-rw-r--r-- | lib/reline/unicode.rb | 415 | ||||
-rw-r--r-- | lib/reline/unicode/east_asian_width.rb | 1145 | ||||
-rw-r--r-- | lib/reline/version.rb | 3 | ||||
-rw-r--r-- | lib/reline/windows.rb | 132 | ||||
-rw-r--r-- | lib/rubygems.rb | 1 |
27 files changed, 1123 insertions, 5701 deletions
diff --git a/lib/irb.rb b/lib/irb.rb index 897cfae957..78d0b7c8cf 100644 --- a/lib/irb.rb +++ b/lib/irb.rb @@ -59,8 +59,6 @@ require "irb/version" # -W[level=2] Same as `ruby -W` # --inspect Use `inspect' for output (default except for bc mode) # --noinspect Don't use inspect for output -# --reidline Use Reidline extension module -# --noreidline Don't use Reidline extension module # --readline Use Readline extension module # --noreadline Don't use Readline extension module # --prompt prompt-mode @@ -68,13 +66,14 @@ require "irb/version" # Switch prompt mode. Pre-defined prompt modes are # `default', `simple', `xmp' and `inf-ruby' # --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs. -# Suppresses --reidline and --readline. +# Suppresses --readline. # --simple-prompt Simple prompt mode # --noprompt No prompt mode # --tracer Display trace for each execution of commands. # --back-trace-limit n # Display backtrace top n and tail n. The default # value is 16. +# --irb_debug n Set internal debug level to n (not for popular use) # -v, --version Print the version of irb # # == Configuration @@ -96,13 +95,13 @@ require "irb/version" # IRB.conf[:IRB_RC] = nil # IRB.conf[:BACK_TRACE_LIMIT]=16 # IRB.conf[:USE_LOADER] = false -# IRB.conf[:USE_REIDLINE] = nil # IRB.conf[:USE_READLINE] = nil # IRB.conf[:USE_TRACER] = false # IRB.conf[:IGNORE_SIGINT] = true # IRB.conf[:IGNORE_EOF] = false # IRB.conf[:PROMPT_MODE] = :DEFAULT # IRB.conf[:PROMPT] = {...} +# IRB.conf[:DEBUG_LEVEL]=0 # # === Auto indentation # @@ -411,7 +410,9 @@ module IRB @context = Context.new(self, workspace, input_method, output_method) @context.main.extend ExtendCommandBundle @signal_status = :IN_IRB + @scanner = RubyLex.new + @scanner.exception_on_syntax_error = false end def run(conf = IRB.conf) diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb index 4cd9427743..390e7254dd 100644 --- a/lib/irb/completion.rb +++ b/lib/irb/completion.rb @@ -8,10 +8,11 @@ # require "readline" -require "rdoc" module IRB module InputCompletor # :nodoc: + + # Set of reserved words used by Ruby, you should not use these for # constants or variables ReservedWords = %w[ @@ -34,8 +35,6 @@ module IRB yield ] - BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{(" - CompletionProc = proc { |input| bind = IRB.conf[:MAIN_CONTEXT].workspace.binding @@ -196,14 +195,6 @@ module IRB 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 Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~] @@ -245,3 +236,9 @@ module IRB end end end + +if Readline.respond_to?("basic_word_break_characters=") + Readline.basic_word_break_characters= " \t\n`><=;|&{(" +end +Readline.completion_append_character = nil +Readline.completion_proc = IRB::InputCompletor::CompletionProc diff --git a/lib/irb/context.rb b/lib/irb/context.rb index 866eb1de9d..e8e6a118e6 100644 --- a/lib/irb/context.rb +++ b/lib/irb/context.rb @@ -22,7 +22,7 @@ module IRB # # The optional +input_method+ argument: # - # +nil+:: uses stdin or Reidline or Readline + # +nil+:: uses stdin or Readline # +String+:: uses a File # +other+:: uses this as InputMethod def initialize(irb, workspace = nil, input_method = nil, output_method = nil) @@ -40,7 +40,6 @@ module IRB @load_modules = IRB.conf[:LOAD_MODULES] @use_readline = IRB.conf[:USE_READLINE] - @use_reidline = IRB.conf[:USE_REIDLINE] @verbose = IRB.conf[:VERBOSE] @io = nil @@ -65,41 +64,23 @@ module IRB case input_method when nil - @io = nil - case use_reidline? + case use_readline? when nil - if STDIN.tty? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_readline? - @io = ReidlineInputMethod.new + if (defined?(ReadlineInputMethod) && STDIN.tty? && + IRB.conf[:PROMPT_MODE] != :INF_RUBY) + @io = ReadlineInputMethod.new else - @io = nil + @io = StdioInputMethod.new end when false - @io = nil + @io = StdioInputMethod.new when true - @io = ReidlineInputMethod.new - end - unless @io - case use_readline? - when nil - if (defined?(ReadlineInputMethod) && STDIN.tty? && - IRB.conf[:PROMPT_MODE] != :INF_RUBY) - @io = ReadlineInputMethod.new - else - @io = nil - end - when false - @io = nil - when true - if defined?(ReadlineInputMethod) - @io = ReadlineInputMethod.new - else - @io = nil - end + if defined?(ReadlineInputMethod) + @io = ReadlineInputMethod.new else - @io = nil + @io = StdioInputMethod.new end end - @io = StdioInputMethod.new unless @io when String @io = FileInputMethod.new(input_method) @@ -120,6 +101,7 @@ module IRB if @echo.nil? @echo = true end + self.debug_level = IRB.conf[:DEBUG_LEVEL] end # The top-level workspace, see WorkSpace#main @@ -135,9 +117,9 @@ module IRB attr_reader :thread # The current input method # - # Can be either StdioInputMethod, ReadlineInputMethod, - # ReidlineInputMethod, FileInputMethod or other specified when the - # context is created. See ::new for more # information on +input_method+. + # Can be either StdioInputMethod, ReadlineInputMethod, FileInputMethod or + # other specified when the context is created. See ::new for more + # information on +input_method+. attr_accessor :io # Current irb session @@ -155,12 +137,6 @@ module IRB # +input_method+ passed to Context.new attr_accessor :irb_path - # Whether +Reidline+ is enabled or not. - # - # A copy of the default <code>IRB.conf[:USE_REIDLINE]</code> - # - # See #use_reidline= for more information. - attr_reader :use_reidline # Whether +Readline+ is enabled or not. # # A copy of the default <code>IRB.conf[:USE_READLINE]</code> @@ -235,6 +211,10 @@ module IRB # # A copy of the default <code>IRB.conf[:VERBOSE]</code> 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+. # @@ -245,8 +225,6 @@ module IRB # See IRB@Command+line+options for more command line options. attr_accessor :back_trace_limit - # Alias for #use_reidline - alias use_reidline? use_reidline # Alias for #use_readline alias use_readline? use_readline # Alias for #rc @@ -258,9 +236,7 @@ module IRB # Returns whether messages are displayed or not. def verbose? if @verbose.nil? - if @io.kind_of?(ReidlineInputMethod) - false - elsif defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod) + if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod) false elsif !STDIN.tty? or @io.kind_of?(FileInputMethod) true @@ -273,11 +249,9 @@ module IRB end # Whether #verbose? is +true+, and +input_method+ is either - # StdioInputMethod or ReidlineInputMethod or ReadlineInputMethod, see #io - # for more information. + # StdioInputMethod or ReadlineInputMethod, see #io for more information. def prompting? verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) || - @io.kind_of?(ReidlineInputMethod) || (defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod))) end @@ -387,6 +361,21 @@ module IRB print "Do nothing." 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: @line_no = line_no if exception diff --git a/lib/irb/init.rb b/lib/irb/init.rb index ec413679df..2066d8cb64 100644 --- a/lib/irb/init.rb +++ b/lib/irb/init.rb @@ -112,6 +112,8 @@ module IRB # :nodoc: @CONF[:LC_MESSAGES] = Locale.new @CONF[:AT_EXIT] = [] + + @CONF[:DEBUG_LEVEL] = 0 end def IRB.init_error @@ -163,10 +165,6 @@ module IRB # :nodoc: @CONF[:USE_READLINE] = true when "--noreadline" @CONF[:USE_READLINE] = false - when "--reidline" - @CONF[:USE_REIDLINE] = true - when "--noreidline" - @CONF[:USE_REIDLINE] = false when "--echo" @CONF[:ECHO] = true when "--noecho" @@ -193,6 +191,8 @@ module IRB # :nodoc: @CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i when "--single-irb" @CONF[:SINGLE_IRB] = true + when /^--irb_debug(?:=(.+))?/ + @CONF[:DEBUG_LEVEL] = ($1 || argv.shift).to_i when "-v", "--version" print IRB.version, "\n" exit 0 diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb index e29d282d2c..f491d5a760 100644 --- a/lib/irb/input-method.rb +++ b/lib/irb/input-method.rb @@ -11,8 +11,6 @@ # require_relative 'src_encoding' require_relative 'magic-file' -require_relative "completion" -require 'reline' module IRB STDIN_FILE_NAME = "(line)" # :nodoc: @@ -142,12 +140,6 @@ module IRB @stdin = IO.open(STDIN.to_i, :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 => "-") - - if Readline.respond_to?("basic_word_break_characters=") - Readline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS - end - Readline.completion_append_character = nil - Readline.completion_proc = IRB::InputCompletor::CompletionProc end # Reads the next line from this input method. @@ -194,84 +186,7 @@ module IRB def encoding @stdin.external_encoding end - - if Readline.respond_to?("basic_word_break_characters=") - Readline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS - end - Readline.completion_append_character = nil - Readline.completion_proc = IRB::InputCompletor::CompletionProc end rescue LoadError end - - class ReidlineInputMethod < InputMethod - include Reline - # Creates a new input method object using Readline - def initialize - super - - @line_no = 0 - @line = [] - @eof = false - - @stdin = IO.open(STDIN.to_i, :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 => "-") - - if Reline.respond_to?("basic_word_break_characters=") - Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS - end - Reline.completion_append_character = nil - Reline.completion_proc = IRB::InputCompletor::CompletionProc - Reline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc - end - - def check_termination(&block) - @check_termination_proc = block - end - - # Reads the next line from this input method. - # - # See IO#gets for more information. - def gets - Reline.input = @stdin - Reline.output = @stdout - if l = readmultiline(@prompt, false, &@check_termination_proc) - HISTORY.push(l) if !l.empty? - @line[@line_no += 1] = l + "\n" - else - @eof = true - l - end - end - - # Whether the end of this input method has been reached, returns +true+ - # if there is no more data to read. - # - # See IO#eof? for more information. - def eof? - @eof - end - - # Whether this input method is still readable when there is no more data to - # read. - # - # See IO#eof for more information. - def readable_after_eof? - true - end - - # Returns the current line number for #io. - # - # #line counts the number of times #gets is called. - # - # See IO#lineno for more information. - def line(line_no) - @line[line_no] - end - - # The external encoding for standard input. - def encoding - @stdin.external_encoding - end - end end diff --git a/lib/irb/lc/help-message b/lib/irb/lc/help-message index d1a66dddda..d43c6a1695 100644 --- a/lib/irb/lc/help-message +++ b/lib/irb/lc/help-message @@ -39,6 +39,7 @@ Usage: irb.rb [options] [programfile] [arguments] --back-trace-limit n Display backtrace top n and tail n. The default value is 16. + --irb_debug n Set internal debug level to n (not for popular use) --verbose Show details --noverbose Don't show details -v, --version Print the version of irb diff --git a/lib/irb/lc/ja/help-message b/lib/irb/lc/ja/help-message index 7a15f973c6..1b24d14d28 100644 --- a/lib/irb/lc/ja/help-message +++ b/lib/irb/lc/ja/help-message @@ -41,6 +41,8 @@ Usage: irb.rb [options] [programfile] [arguments] バックトレース表示をバックトレースの頭から n, 後ろ からnだけ行なう. デフォルトは16 + --irb_debug n irbのデバッグレベルをnに設定する(非推奨). + --verbose 詳細なメッセージを出力する. --noverbose 詳細なメッセージを出力しない(デフォルト). -v, --version irbのバージョンを表示する. diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb index c4bec4a854..555d1f024f 100644 --- a/lib/irb/ruby-lex.rb +++ b/lib/irb/ruby-lex.rb @@ -11,39 +11,73 @@ # require "e2mmap" -require "ripper" +require_relative "slex" +require_relative "ruby-token" # :stopdoc: class RubyLex extend Exception2MessageMapper + def_exception(:AlreadyDefinedToken, "Already defined token(%s)") + def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')") + def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')") + def_exception(:TkReading2TokenDuplicateError, + "key duplicate(token_n='%s', key='%s')") + def_exception(:SyntaxError, "%s") + def_exception(:TerminateLineInput, "Terminate Line Input") + include RubyToken + + class << self + attr_accessor :debug_level + def debug? + @debug_level > 0 + end + end + @debug_level = 0 + def initialize + lex_init + set_input(STDIN) + + @seek = 0 @exp_line_no = @line_no = 1 + @base_char_no = 0 + @char_no = 0 + @rests = [] + @readed = [] + @here_readed = [] + @indent = 0 + @indent_stack = [] + @lex_state = EXPR_BEG + @space_seen = false + @here_header = false + @post_symbeg = false + @continue = false @line = "" + + @skip_space = false + @readed_auto_clean_up = false + @exception_on_syntax_error = true + @prompt = nil end + attr_accessor :skip_space + attr_accessor :readed_auto_clean_up + attr_accessor :exception_on_syntax_error + + attr_reader :seek + attr_reader :char_no + attr_reader :line_no + attr_reader :indent + # io functions def set_input(io, p = nil, &block) @io = io - if @io.respond_to?(:check_termination) - @io.check_termination do |code| - @tokens = Ripper.lex(code) - continue = process_continue - code_block_open = check_code_block(code) - indent = process_nesting_level - ltype = process_literal_type - if code_block_open or ltype or continue or indent > 0 - false - else - true - end - end - end if p.respond_to?(:call) @input = p elsif block_given? @@ -53,6 +87,112 @@ class RubyLex end end + def get_readed + if idx = @readed.rindex("\n") + @base_char_no = @readed.size - (idx + 1) + else + @base_char_no += @readed.size + end + + readed = @readed.join("") + @readed = [] + readed + end + + def getc + while @rests.empty? + @rests.push nil unless buf_input + end + c = @rests.shift + if @here_header + @here_readed.push c + else + @readed.push c + end + @seek += 1 + if c == "\n" + @line_no += 1 + @char_no = 0 + else + @char_no += 1 + end + c + end + + def gets + l = "" + while c = getc + l.concat(c) + break if c == "\n" + end + return nil if l == "" and c.nil? + l + end + + def eof? + @io.eof? + end + + def getc_of_rests + if @rests.empty? + nil + else + getc + end + end + + def ungetc(c = nil) + if @here_readed.empty? + c2 = @readed.pop + else + c2 = @here_readed.pop + end + c = c2 unless c + @rests.unshift c #c = + @seek -= 1 + if c == "\n" + @line_no -= 1 + if idx = @readed.rindex("\n") + @char_no = idx + 1 + else + @char_no = @base_char_no + @readed.size + end + else + @char_no -= 1 + end + end + + def peek_equal?(str) + chrs = str.split(//) + until @rests.size >= chrs.size + return false unless buf_input + end + @rests[0, chrs.size] == chrs + end + + def peek_match?(regexp) + while @rests.empty? + return false unless buf_input + end + regexp =~ @rests.join("") + end + + def peek(i = 0) + while @rests.size <= i + return nil unless buf_input + end + @rests[i] + end + + def buf_input + prompt + line = @input.call + return nil unless line + @rests.concat line.chars.to_a + true + end + private :buf_input + def set_prompt(p = nil, &block) p = block if block_given? if p.respond_to?(:call) @@ -70,11 +210,20 @@ class RubyLex def initialize_input @ltype = nil + @quoted = nil @indent = 0 + @indent_stack = [] + @lex_state = EXPR_BEG + @space_seen = false + @here_header = false + @continue = false + @post_symbeg = false + + prompt + @line = "" @exp_line_no = @line_no - @code_block_open = false end def each_top_level_statement @@ -82,14 +231,13 @@ class RubyLex catch(:TERM_INPUT) do loop do begin + @continue = false prompt unless l = lex throw :TERM_INPUT if @line == '' else - @line_no += 1 - next if l == "\n" @line.concat l - if @code_block_open or @ltype or @continue or @indent > 0 + if @ltype or @continue or @indent > 0 next end end @@ -102,203 +250,930 @@ class RubyLex @exp_line_no = @line_no @indent = 0 + @indent_stack = [] + prompt rescue TerminateLineInput initialize_input prompt + get_readed end end end end def lex - line = @input.call - if @io.respond_to?(:check_termination) - return line # multiline - end - code = @line + (line.nil? ? '' : line) - code.gsub!(/\n*$/, '').concat("\n") - @tokens = Ripper.lex(code) - @continue = process_continue - @code_block_open = check_code_block(code) - @indent = process_nesting_level - @ltype = process_literal_type - line + continue = @continue + while tk = token + case tk + when TkNL, TkEND_OF_SCRIPT + @continue = continue unless continue.nil? + break unless @continue + when TkSPACE, TkCOMMENT + when TkSEMICOLON, TkBEGIN, TkELSE + @continue = continue = false + else + continue = nil + end + end + line = get_readed + if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil? + nil + else + line + end + end + + def token + @prev_seek = @seek + @prev_line_no = @line_no + @prev_char_no = @char_no + begin + begin + tk = @OP.match(self) + @space_seen = tk.kind_of?(TkSPACE) + @lex_state = EXPR_END if @post_symbeg && tk.kind_of?(TkOp) + @post_symbeg = tk.kind_of?(TkSYMBEG) + rescue SyntaxError + raise if @exception_on_syntax_error + tk = TkError.new(@seek, @line_no, @char_no) + end + end while @skip_space and tk.kind_of?(TkSPACE) + if @readed_auto_clean_up + get_readed + end + tk + end + + ENINDENT_CLAUSE = [ + "case", "class", "def", "do", "for", "if", + "module", "unless", "until", "while", "begin" + ] + DEINDENT_CLAUSE = ["end" + ] + + PERCENT_LTYPE = { + "q" => "\'", + "Q" => "\"", + "x" => "\`", + "r" => "/", + "w" => "]", + "W" => "]", + "i" => "]", + "I" => "]", + "s" => ":" + } + + PERCENT_PAREN = { + "{" => "}", + "[" => "]", + "<" => ">", + "(" => ")" + } + + Ltype2Token = { + "\'" => TkSTRING, + "\"" => TkSTRING, + "\`" => TkXSTRING, + "/" => TkREGEXP, + "]" => TkDSTRING, + ":" => TkSYMBOL + } + DLtype2Token = { + "\"" => TkDSTRING, + "\`" => TkDXSTRING, + "/" => TkDREGEXP, + } + + def lex_init() + @OP = IRB::SLex.new + @OP.def_rules("\0", "\004", "\032") do |op, io| + Token(TkEND_OF_SCRIPT) + end + + @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |op, io| + @space_seen = true + while getc =~ /[ \t\f\r\13]/; end + ungetc + Token(TkSPACE) + end + + @OP.def_rule("#") do |op, io| + identify_comment + end + + @OP.def_rule("=begin", + proc{|op, io| @prev_char_no == 0 && peek(0) =~ /\s/}) do + |op, io| + @ltype = "=" + until getc == "\n"; end + until peek_equal?("=end") && peek(4) =~ /\s/ + until getc == "\n"; end + end + gets + @ltype = nil + Token(TkRD_COMMENT) + end + + @OP.def_rule("\n") do |op, io| + print "\\n\n" if RubyLex.debug? + case @lex_state + when EXPR_BEG, EXPR_FNAME, EXPR_DOT + @continue = true + else + @continue = false + @lex_state = EXPR_BEG + until (@indent_stack.empty? || + [TkLPAREN, TkLBRACK, TkLBRACE, + TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last)) + @indent_stack.pop + end + end + @here_header = false + @here_readed = [] + Token(TkNL) + end + + @OP.def_rules("*", "**", + "=", "==", "===", + "=~", "<=>", + "<", "<=", + ">", ">=", ">>", + "!", "!=", "!~") do + |op, io| + case @lex_state + when EXPR_FNAME, EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_BEG + end + Token(op) + end + + @OP.def_rules("<<") do + |op, io| + tk = nil + if @lex_state != EXPR_END && @lex_state != EXPR_CLASS && + (@lex_state != EXPR_ARG || @space_seen) + c = peek(0) + if /[-~"'`\w]/ =~ c + tk = identify_here_document + end + end + unless tk + tk = Token(op) + case @lex_state + when EXPR_FNAME, EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_BEG + end + end + tk + end + + @OP.def_rules("'", '"') do + |op, io| + identify_string(op) + end + + @OP.def_rules("`") do + |op, io| + if @lex_state == EXPR_FNAME + @lex_state = EXPR_END + Token(op) + else + identify_string(op) + end + end + + @OP.def_rules('?') do + |op, io| + if @lex_state == EXPR_END + @lex_state = EXPR_BEG + Token(TkQUESTION) + else + ch = getc + if @lex_state == EXPR_ARG && ch =~ /\s/ + ungetc + @lex_state = EXPR_BEG; + Token(TkQUESTION) + else + if (ch == '\\') + read_escape + end + @lex_state = EXPR_END + Token(TkINTEGER) + end + end + end + + @OP.def_rules("&", "&&", "|", "||") do + |op, io| + @lex_state = EXPR_BEG + Token(op) + end + + @OP.def_rules("+=", "-=", "*=", "**=", + "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do + |op, io| + @lex_state = EXPR_BEG + op =~ /^(.*)=$/ + Token(TkOPASGN, $1) + end + + @OP.def_rule("+@", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_ARG + Token(op) + end + + @OP.def_rule("-@", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_ARG + Token(op) + end + + @OP.def_rules("+", "-") do + |op, io| + catch(:RET) do + if @lex_state == EXPR_ARG + if @space_seen and peek(0) =~ /[0-9]/ + throw :RET, identify_number + else + @lex_state = EXPR_BEG + end + elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/ + throw :RET, identify_number + else + @lex_state = EXPR_BEG + end + Token(op) + end + end + + @OP.def_rule(".") do + |op, io| + @lex_state = EXPR_BEG + if peek(0) =~ /[0-9]/ + ungetc + identify_number + else + # for "obj.if" etc. + @lex_state = EXPR_DOT + Token(TkDOT) + end + end + + @OP.def_rules("..", "...") do + |op, io| + @lex_state = EXPR_BEG + Token(op) + end + + lex_int2 + end + + def lex_int2 + @OP.def_rules("]", "}", ")") do + |op, io| + @lex_state = EXPR_END + @indent -= 1 + @indent_stack.pop + Token(op) + end + + @OP.def_rule(":") do + |op, io| + if @lex_state == EXPR_END || peek(0) =~ /\s/ + @lex_state = EXPR_BEG + Token(TkCOLON) + else + @lex_state = EXPR_FNAME + Token(TkSYMBEG) + end + end + + @OP.def_rule("::") do + |op, io| + if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen + @lex_state = EXPR_BEG + Token(TkCOLON3) + else + @lex_state = EXPR_DOT + Token(TkCOLON2) + end + end + + @OP.def_rule("/") do + |op, io| + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + identify_string(op) + elsif peek(0) == '=' + getc + @lex_state = EXPR_BEG + Token(TkOPASGN, "/") #/) + elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ + identify_string(op) + else + @lex_state = EXPR_BEG + Token("/") #/) + end + end + + @OP.def_rules("^") do + |op, io| + @lex_state = EXPR_BEG + Token("^") + end + + @OP.def_rules(",") do + |op, io| + @lex_state = EXPR_BEG + Token(op) + end + + @OP.def_rules(";") do + |op, io| + @lex_state = EXPR_BEG + until (@indent_stack.empty? || + [TkLPAREN, TkLBRACK, TkLBRACE, + TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last)) + @indent_stack.pop + end + Token(op) + end + + @OP.def_rule("~") do + |op, io| + @lex_state = EXPR_BEG + Token("~") + end + + @OP.def_rule("~@", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_BEG + Token("~") + end + + @OP.def_rule("(") do + |op, io| + @indent += 1 + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + @lex_state = EXPR_BEG + tk_c = TkfLPAREN + else + @lex_state = EXPR_BEG + tk_c = TkLPAREN + end + @indent_stack.push tk_c + Token(tk_c) + end + + @OP.def_rule("[]", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_ARG + Token("[]") + end + + @OP.def_rule("[]=", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_ARG + Token("[]=") + end + + @OP.def_rule("[") do + |op, io| + @indent += 1 + if @lex_state == EXPR_FNAME + tk_c = TkfLBRACK + else + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + tk_c = TkLBRACK + elsif @lex_state == EXPR_ARG && @space_seen + tk_c = TkLBRACK + else + tk_c = TkfLBRACK + end + @lex_state = EXPR_BEG + end + @indent_stack.push tk_c + Token(tk_c) + end + + @OP.def_rule("{") do + |op, io| + @indent += 1 + if @lex_state != EXPR_END && @lex_state != EXPR_ARG + tk_c = TkLBRACE + else + tk_c = TkfLBRACE + end + @lex_state = EXPR_BEG + @indent_stack.push tk_c + Token(tk_c) + end + + @OP.def_rule('\\') do + |op, io| + if getc == "\n" + @space_seen = true + @continue = true + Token(TkSPACE) + else + read_escape + Token("\\") + end + end + + @OP.def_rule('%') do + |op, io| + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + identify_quotation + elsif peek(0) == '=' + getc + Token(TkOPASGN, :%) + elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ + identify_quotation + else + @lex_state = EXPR_BEG + Token("%") #)) + end + end + + @OP.def_rule('$') do + |op, io| + identify_gvar + end + + @OP.def_rule('@') do + |op, io| + if peek(0) =~ /[\w@]/ + ungetc + identify_identifier + else + Token("@") + end + end + + @OP.def_rule("") do + |op, io| + printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug? + if peek(0) =~ /[0-9]/ + t = identify_number + elsif peek(0) =~ /[^\x00-\/:-@\[-^`{-\x7F]/ + t = identify_identifier + end + printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug? + t + end + + p @OP if RubyLex.debug? end - def process_continue - continued_bits = Ripper::EXPR_BEG | Ripper::EXPR_FNAME | Ripper::EXPR_DOT - # last token is always newline - if @tokens.size >= 2 and @tokens[-2][1] == :on_regexp_end - # end of regexp literal - return false - elsif @tokens.size >= 2 and @tokens[-2][1] == :on_semicolon - return false - elsif @tokens.size >= 2 and @tokens[-2][1] == :on_kw and (@tokens[-2][2] == 'begin' or @tokens[-2][2] == 'else') - return false - elsif !@tokens.empty? and @tokens.last[2] == "\\\n" - return true - elsif @tokens.size >= 2 and @tokens[-2][3].anybits?(continued_bits) - # end of literal except for regexp - return true - end - false + def identify_gvar + @lex_state = EXPR_END + + case ch = getc + when /[~_*$?!@\/\\;,=:<>".]/ #" + Token(TkGVAR, "$" + ch) + when "-" + Token(TkGVAR, "$-" + getc) + when "&", "`", "'", "+" + Token(TkBACK_REF, "$"+ch) + when /[1-9]/ + while getc =~ /[0-9]/; end + ungetc + Token(TkNTH_REF) + when /\w/ + ungetc + ungetc + identify_identifier + else + ungetc + Token("$") + end end - def check_code_block(code) - return true if @tokens.empty? - if @tokens.last[1] == :on_heredoc_beg - return true - end - - begin # check if parser error are available - RubyVM::InstructionSequence.compile(code) - rescue SyntaxError => e - case e.message - when /unterminated (?:string|regexp) meets end of file/ - # "unterminated regexp meets end of file" - # - # example: - # / - # - # "unterminated string meets end of file" - # - # example: - # ' - return true - when /syntax error, unexpected end-of-input/ - # "syntax error, unexpected end-of-input, expecting keyword_end" - # - # example: - # if ture - # hoge - # if false - # fuga - # end - return true - when /syntax error, unexpected keyword_end/ - # "syntax error, unexpected keyword_end" - # - # example: - # if ( - # end - # - # example: - # end - return false - when /unexpected tREGEXP_BEG/ - # "syntax error, unexpected tREGEXP_BEG, expecting keyword_do or '{' or '('" - # - # example: - # method / f / - return false - end - end - - last_lex_state = @tokens.last[3] - if last_lex_state.allbits?(Ripper::EXPR_BEG) - return false - elsif last_lex_state.allbits?(Ripper::EXPR_DOT) - return true - elsif last_lex_state.allbits?(Ripper::EXPR_CLASS) - return true - elsif last_lex_state.allbits?(Ripper::EXPR_FNAME) - return true - elsif last_lex_state.allbits?(Ripper::EXPR_VALUE) - return true - elsif last_lex_state.allbits?(Ripper::EXPR_ARG) - return false - end - - false + def identify_identifier + token = "" + if peek(0) =~ /[$@]/ + token.concat(c = getc) + if c == "@" and peek(0) == "@" + token.concat getc + end + end + + while (ch = getc) =~ /[^\x00-\/:-@\[-^`{-\x7F]/ + print ":", ch, ":" if RubyLex.debug? + token.concat ch + end + ungetc + + if (ch == "!" || ch == "?") && token[0,1] =~ /\w/ && peek(0) != "=" + token.concat getc + end + + # almost fix token + + case token + when /^\$/ + return Token(TkGVAR, token) + when /^\@\@/ + @lex_state = EXPR_END + # p Token(TkCVAR, token) + return Token(TkCVAR, token) + when /^\@/ + @lex_state = EXPR_END + return Token(TkIVAR, token) + end + + if @lex_state != EXPR_DOT + print token, "\n" if RubyLex.debug? + + token_c, *trans = TkReading2Token[token] + if token_c + # reserved word? + + if (@lex_state != EXPR_BEG && + @lex_state != EXPR_FNAME && + trans[1]) + # modifiers + token_c = TkSymbol2Token[trans[1]] + @lex_state = trans[0] + else + if @lex_state != EXPR_FNAME and peek(0) != ':' + if ENINDENT_CLAUSE.include?(token) + # check for ``class = val'' etc. + valid = true + case token + when "class" + valid = false unless peek_match?(/^\s*(<<|\w|::)/) + when "def" + valid = false if peek_match?(/^\s*(([+\-\/*&\|^]|<<|>>|\|\||\&\&)=|\&\&|\|\|)/) + when "do" + valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&)/) + when *ENINDENT_CLAUSE + valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&|\|)/) + else + # no nothing + end + if valid + if token == "do" + if ![TkFOR, TkWHILE, TkUNTIL].include?(@indent_stack.last) + @indent += 1 + @indent_stack.push token_c + end + else + @indent += 1 + @indent_stack.push token_c + end + end + + elsif DEINDENT_CLAUSE.include?(token) + @indent -= 1 + @indent_stack.pop + end + @lex_state = trans[0] + else + @lex_state = EXPR_END + end + end + return Token(token_c, token) + end + end + + if @lex_state == EXPR_FNAME + @lex_state = EXPR_END + if peek(0) == '=' + token.concat getc + end + elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_END + end + + if token[0, 1] =~ /[A-Z]/ + return Token(TkCONSTANT, token) + elsif token[token.size - 1, 1] =~ /[!?]/ + return Token(TkFID, token) + else + return Token(TkIDENTIFIER, token) + end end - def process_nesting_level - @tokens.inject(0) { |indent, t| - case t[1] - when :on_lbracket, :on_lbrace, :on_lparen - indent += 1 - when :on_rbracket, :on_rbrace, :on_rparen - indent -= 1 - when :on_kw - case t[2] - when 'def', 'do', 'case', 'for', 'begin', 'class', 'module' - indent += 1 - when 'if', 'unless', 'while', 'until', 'rescue' - # postfix if/unless/while/until/rescue must be Ripper::EXPR_LABEL - indent += 1 unless t[3].allbits?(Ripper::EXPR_LABEL) - when 'end' - indent -= 1 + def identify_here_document + ch = getc + if ch == "-" || ch == "~" + ch = getc + indent = true + end + if /['"`]/ =~ ch + lt = ch + quoted = "" + while (c = getc) && c != lt + quoted.concat c + end + else + lt = '"' + quoted = ch.dup + while (c = getc) && c =~ /\w/ + quoted.concat c + end + ungetc + end + + ltback, @ltype = @ltype, lt + reserve = [] + while ch = getc + reserve.push ch + if ch == "\\" + reserve.push ch = getc + elsif ch == "\n" + break + end + end + + @here_header = false + + line = "" + while ch = getc + if ch == "\n" + if line == quoted + break + end + line = "" + else + line.concat ch unless indent && line == "" && /\s/ =~ ch + if @ltype != "'" && ch == "#" && peek(0) == "{" + identify_string_dvar + end + end + end + + @here_header = true + @here_readed.concat reserve + while ch = reserve.pop + ungetc ch + end + + @ltype = ltback + @lex_state = EXPR_END + Token(Ltype2Token[lt]) + end + + def identify_quotation + ch = getc + if lt = PERCENT_LTYPE[ch] + ch = getc + elsif ch =~ /\W/ + lt = "\"" + else + RubyLex.fail SyntaxError, "unknown type of %string" + end + @quoted = ch unless @quoted = PERCENT_PAREN[ch] + identify_string(lt, @quoted) + end + + def identify_number + @lex_state = EXPR_END + + if peek(0) == "0" && peek(1) !~ /[.eE]/ + getc + case peek(0) + when /[xX]/ + ch = getc + match = /[0-9a-fA-F_]/ + when /[bB]/ + ch = getc + match = /[01_]/ + when /[oO]/ + ch = getc + match = /[0-7_]/ + when /[dD]/ + ch = getc + match = /[0-9_]/ + when /[0-7]/ + match = /[0-7_]/ + when /[89]/ + RubyLex.fail SyntaxError, "Invalid octal digit" + else + return Token(TkINTEGER) + end + + len0 = true + non_digit = false + while ch = getc + if match =~ ch + if ch == "_" + if non_digit + RubyLex.fail SyntaxError, "trailing `#{ch}' in number" + else + non_digit = ch + end + else + non_digit = false + len0 = false + end + else + ungetc + if len0 + RubyLex.fail SyntaxError, "numeric literal without digits" + end + if non_digit + RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" + end + break + end + end + return Token(TkINTEGER) + end + + type = TkINTEGER + allow_point = true + allow_e = true + non_digit = false + while ch = getc + case ch + when /[0-9]/ + non_digit = false + when "_" + non_digit = ch + when allow_point && "." + if non_digit + RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" + end + type = TkFLOAT + if peek(0) !~ /[0-9]/ + type = TkINTEGER + ungetc + break + end + allow_point = false + when allow_e && "e", allow_e && "E" + if non_digit + RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" + end + type = TkFLOAT + if peek(0) =~ /[+-]/ + getc + end + allow_e = false + allow_point = false + non_digit = ch + else + if non_digit + RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" end + ungetc + break end - # percent literals are not indented - indent - } + end + Token(type) + end + + def identify_string(ltype, quoted = ltype) + @ltype = ltype + @quoted = quoted + subtype = nil + begin + nest = 0 + while ch = getc + if @quoted == ch and nest == 0 + break + elsif @ltype != "'" && ch == "#" && peek(0) == "{" + identify_string_dvar + elsif @ltype != "'" && @ltype != "]" && @ltype != ":" and ch == "#" + subtype = true + elsif ch == '\\' and @ltype == "'" #' + case ch = getc + when "\\", "\n", "'" + else + ungetc + end + elsif ch == '\\' #' + read_escape + end + if PERCENT_PAREN.values.include?(@quoted) + if PERCENT_PAREN[ch] == @quoted + nest += 1 + elsif ch == @quoted + nest -= 1 + end + end + end + if @ltype == "/" + while /[imxoesun]/ =~ peek(0) + getc + end + end + if subtype + Token(DLtype2Token[ltype]) + else + Token(Ltype2Token[ltype]) + end + ensure + @ltype = nil + @quoted = nil + @lex_state = EXPR_END + end end - def check_string_literal - i = 0 - start_token = [] - end_type = [] - while i < @tokens.size - t = @tokens[i] - case t[1] - when :on_tstring_beg - start_token << t - end_type << :on_tstring_end - when :on_regexp_beg - start_token << t - end_type << :on_regexp_end - when :on_symbeg - if (i + 1) < @tokens.size and @tokens[i + 1][1] != :on_ident - start_token << t - end_type << :on_tstring_end + def identify_string_dvar + begin + getc + + reserve_continue = @continue + reserve_ltype = @ltype + reserve_indent = @indent + reserve_indent_stack = @indent_stack + reserve_state = @lex_state + reserve_quoted = @quoted + + @ltype = nil + @quoted = nil + @indent = 0 + @indent_stack = [] + @lex_state = EXPR_BEG + + loop do + @continue = false + prompt + tk = token + if @ltype or @continue or @indent >= 0 + next end - when :on_backtick - start_token << t - end_type << :on_tstring_end - when :on_qwords_beg, :on_words_beg, :on_qsymbols_beg, :on_symbols_beg - start_token << t - end_type << :on_tstring_end - when :on_heredoc_beg - start_token << t - end_type << :on_heredoc_end - when end_type.last - start_token.pop - end_type.pop - end - i += 1 - end - start_token.last.nil? ? '' : start_token.last + break if tk.kind_of?(TkRBRACE) + end + ensure + @continue = reserve_continue + @ltype = reserve_ltype + @indent = reserve_indent + @indent_stack = reserve_indent_stack + @lex_state = reserve_state + @quoted = reserve_quoted + end end - def process_literal_type - start_token = check_string_literal - case start_token[1] - when :on_tstring_beg - case start_token[2] - when ?" then ?" - when /^%.$/ then ?" - when /^%Q.$/ then ?" - when ?' then ?' - when /^%q.$/ then ?' - end - when :on_regexp_beg then ?/ - when :on_symbeg then ?: - when :on_backtick then ?` - when :on_qwords_beg then ?] - when :on_words_beg then ?] - when :on_qsymbols_beg then ?] - when :on_symbols_beg then ?] - when :on_heredoc_beg - start_token[2] =~ /<<[-~]?(['"`])[_a-zA-Z0-9]+\1/ - case $1 - when ?" then ?" - when ?' then ?' - when ?` then ?` - else ?" + def identify_comment + @ltype = "#" + + while ch = getc + if ch == "\n" + @ltype = nil + ungetc + break + end + end + return Token(TkCOMMENT) + end + + def read_escape + case ch = getc + when "\n", "\r", "\f" + when "\\", "n", "t", "r", "f", "v", "a", "e", "b", "s" #" + when /[0-7]/ + ungetc ch + 3.times do + case ch = getc + when /[0-7]/ + when nil + break + else + ungetc + break + end + end + + when "x" + 2.times do + case ch = getc + when /[0-9a-fA-F]/ + when nil + break + else + ungetc + break + end + end + + when "M" + if (ch = getc) != '-' + ungetc + else + if (ch = getc) == "\\" #" + read_escape + end + end + + when "C", "c" #, "^" + if ch == "C" and (ch = getc) != "-" + ungetc + elsif (ch = getc) == "\\" #" + read_escape end else - nil + # other characters end end end diff --git a/lib/rdoc/ri/paths.rb b/lib/rdoc/ri/paths.rb index f76721d318..d41e610591 100644 --- a/lib/rdoc/ri/paths.rb +++ b/lib/rdoc/ri/paths.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'rdoc/rdoc' +require 'rdoc/ri' ## # The directories where ri data lives. Paths can be enumerated via ::each, or diff --git a/lib/readline.rb b/lib/readline.rb deleted file mode 100644 index 690441e05c..0000000000 --- a/lib/readline.rb +++ /dev/null @@ -1,6 +0,0 @@ -begin - require 'readline.so' -rescue LoadError - require 'reline' - Readline = Reline -end diff --git a/lib/reline.rb b/lib/reline.rb deleted file mode 100644 index b1d7718b7e..0000000000 --- a/lib/reline.rb +++ /dev/null @@ -1,196 +0,0 @@ -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 diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb deleted file mode 100644 index f34c4207e5..0000000000 --- a/lib/reline/ansi.rb +++ /dev/null @@ -1,87 +0,0 @@ -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 diff --git a/lib/reline/config.rb b/lib/reline/config.rb deleted file mode 100644 index 0800dfd30f..0000000000 --- a/lib/reline/config.rb +++ /dev/null @@ -1,235 +0,0 @@ -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 diff --git a/lib/reline/key_actor.rb b/lib/reline/key_actor.rb deleted file mode 100644 index ebe09d2009..0000000000 --- a/lib/reline/key_actor.rb +++ /dev/null @@ -1,7 +0,0 @@ -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' diff --git a/lib/reline/key_actor/base.rb b/lib/reline/key_actor/base.rb deleted file mode 100644 index f4abac55d4..0000000000 --- a/lib/reline/key_actor/base.rb +++ /dev/null @@ -1,7 +0,0 @@ -class Reline::KeyActor::Base - MAPPING = Array.new(256) - - def get_method(key) - self.class::MAPPING[key] - end -end diff --git a/lib/reline/key_actor/emacs.rb b/lib/reline/key_actor/emacs.rb deleted file mode 100644 index 0836cd340c..0000000000 --- a/lib/reline/key_actor/emacs.rb +++ /dev/null @@ -1,518 +0,0 @@ -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 diff --git a/lib/reline/key_actor/vi_command.rb b/lib/reline/key_actor/vi_command.rb deleted file mode 100644 index 724f459011..0000000000 --- a/lib/reline/key_actor/vi_command.rb +++ /dev/null @@ -1,519 +0,0 @@ -class Reline::KeyActor::ViCommand < Reline::KeyActor::Base - MAPPING = [ - # 0 ^@ - :ed_unassigned, - # 1 ^A - :ed_move_to_beg, - # 2 ^B - :ed_unassigned, - # 3 ^C - :ed_ignore, - # 4 ^D - :vi_end_of_transmission, - # 5 ^E - :ed_move_to_end, - # 6 ^F - :ed_unassigned, - # 7 ^G - :ed_unassigned, - # 8 ^H - :ed_delete_prev_char, - # 9 ^I - :ed_unassigned, - # 10 ^J - :ed_newline, - # 11 ^K - :ed_kill_line, - # 12 ^L - :ed_clear_screen, - # 13 ^M - :ed_newline, - # 14 ^N - :ed_next_history, - # 15 ^O - :ed_ignore, - # 16 ^P - :ed_prev_history, - # 17 ^Q - :ed_ignore, - # 18 ^R - :ed_redisplay, - # 19 ^S - :ed_ignore, - # 20 ^T - :ed_unassigned, - # 21 ^U - :vi_kill_line_prev, - # 22 ^V - :ed_quoted_insert, - # 23 ^W - :ed_delete_prev_word, - # 24 ^X - :ed_unassigned, - # 25 ^Y - :ed_unassigned, - # 26 ^Z - :ed_unassigned, - # 27 ^[ - :em_meta_next, - # 28 ^\ - :ed_ignore, - # 29 ^] - :ed_unassigned, - # 30 ^^ - :ed_unassigned, - # 31 ^_ - :ed_unassigned, - # 32 SPACE - :ed_next_char, - # 33 ! - :ed_unassigned, - # 34 " - :ed_unassigned, - # 35 # - :vi_comment_out, - # 36 $ - :ed_move_to_end, - # 37 % - :vi_match, - # 38 & - :ed_unassigned, - # 39 ' - :ed_unassigned, - # 40 ( - :ed_unassigned, - # 41 ) - :ed_unassigned, - # 42 * - :ed_unassigned, - # 43 + - :ed_next_history, - # 44 , - :vi_repeat_prev_char, - # 45 - - :ed_prev_history, - # 46 . - :vi_redo, - # 47 / - :vi_search_prev, - # 48 0 - :vi_zero, - # 49 1 - :ed_argument_digit, - # 50 2 - :ed_argument_digit, - # 51 3 - :ed_argument_digit, - # 52 4 - :ed_argument_digit, - # 53 5 - :ed_argument_digit, - # 54 6 - :ed_argument_digit, - # 55 7 - :ed_argument_digit, - # 56 8 - :ed_argument_digit, - # 57 9 - :ed_argument_digit, - # 58 : - :ed_command, - # 59 ; - :vi_repeat_next_char, - # 60 < - :ed_unassigned, - # 61 = - :ed_unassigned, - # 62 > - :ed_unassigned, - # 63 ? - :vi_search_next, - # 64 @ - :vi_alias, - # 65 A - :vi_add_at_eol, - # 66 B - :vi_prev_big_word, - # 67 C - :vi_change_to_eol, - # 68 D - :ed_kill_line, - # 69 E - :vi_end_big_word, - # 70 F - :vi_prev_char, - # 71 G - :vi_to_history_line, - # 72 H - :ed_unassigned, - # 73 I - :vi_insert_at_bol, - # 74 J - :ed_search_next_history, - # 75 K - :ed_search_prev_history, - # 76 L - :ed_unassigned, - # 77 M - :ed_unassigned, - # 78 N - :vi_repeat_search_prev, - # 79 O - :ed_sequence_lead_in, - # 80 P - :vi_paste_prev, - # 81 Q - :ed_unassigned, - # 82 R - :vi_replace_mode, - # 83 S - :vi_substitute_line, - # 84 T - :vi_to_prev_char, - # 85 U - :vi_undo_line, - # 86 V - :ed_unassigned, - # 87 W - :vi_next_big_word, - # 88 X - :ed_delete_prev_char, - # 89 Y - :vi_yank_end, - # 90 Z - :ed_unassigned, - # 91 [ - :ed_sequence_lead_in, - # 92 \ - :ed_unassigned, - # 93 ] - :ed_unassigned, - # 94 ^ - :ed_move_to_beg, - # 95 _ - :vi_history_word, - # 96 ` - :ed_unassigned, - # 97 a - :vi_add, - # 98 b - :vi_prev_word, - # 99 c - :vi_change_meta, - # 100 d - :vi_delete_meta, - # 101 e - :vi_end_word, - # 102 f - :vi_next_char, - # 103 g - :ed_unassigned, - # 104 h - :ed_prev_char, - # 105 i - :vi_insert, - # 106 j - :ed_next_history, - # 107 k - :ed_prev_history, - # 108 l - :ed_next_char, - # 109 m - :ed_unassigned, - # 110 n - :vi_repeat_search_next, - # 111 o - :ed_unassigned, - # 112 p - :vi_paste_next, - # 113 q - :ed_unassigned, - # 114 r - :vi_replace_char, - # 115 s - :vi_substitute_char, - # 116 t - :vi_to_next_char, - # 117 u - :vi_undo, - # 118 v - :vi_histedit, - # 119 w - :vi_next_word, - # 120 x - :ed_delete_next_char, - # 121 y - :vi_yank, - # 122 z - :ed_unassigned, - # 123 { - :ed_unassigned, - # 124 | - :vi_to_column, - # 125 } - :ed_unassigned, - # 126 ~ - :vi_change_case, - # 127 ^? - :ed_delete_prev_char, - # 128 M-^@ - :ed_unassigned, - # 129 M-^A - :ed_unassigned, - # 130 M-^B - :ed_unassigned, - # 131 M-^C - :ed_unassigned, - # 132 M-^D - :ed_unassigned, - # 133 M-^E - :ed_unassigned, - # 134 M-^F - :ed_unassigned, - # 135 M-^G - :ed_unassigned, - # 136 M-^H - :ed_unassigned, - # 137 M-^I - :ed_unassigned, - # 138 M-^J - :ed_unassigned, - # 139 M-^K - :ed_unassigned, - # 140 M-^L - :ed_unassigned, - # 141 M-^M - :ed_unassigned, - # 142 M-^N - :ed_unassigned, - # 143 M-^O - :ed_unassigned, - # 144 M-^P - :ed_unassigned, - # 145 M-^Q - :ed_unassigned, - # 146 M-^R - :ed_unassigned, - # 147 M-^S - :ed_unassigned, - # 148 M-^T - :ed_unassigned, - # 149 M-^U - :ed_unassigned, - # 150 M-^V - :ed_unassigned, - # 151 M-^W - :ed_unassigned, - # 152 M-^X - :ed_unassigned, - # 153 M-^Y - :ed_unassigned, - # 154 M-^Z - :ed_unassigned, - # 155 M-^[ - :ed_unassigned, - # 156 M-^\ - :ed_unassigned, - # 157 M-^] - :ed_unassigned, - # 158 M-^^ - :ed_unassigned, - # 159 M-^_ - :ed_unassigned, - # 160 M-SPACE - :ed_unassigned, - # 161 M-! - :ed_unassigned, - # 162 M-" - :ed_unassigned, - # 163 M-# - :ed_unassigned, - # 164 M-$ - :ed_unassigned, - # 165 M-% - :ed_unassigned, - # 166 M-& - :ed_unassigned, - # 167 M-' - :ed_unassigned, - # 168 M-( - :ed_unassigned, - # 169 M-) - :ed_unassigned, - # 170 M-* - :ed_unassigned, - # 171 M-+ - :ed_unassigned, - # 172 M-, - :ed_unassigned, - # 173 M-- - :ed_unassigned, - # 174 M-. - :ed_unassigned, - # 175 M-/ - :ed_unassigned, - # 176 M-0 - :ed_unassigned, - # 177 M-1 - :ed_unassigned, - # 178 M-2 - :ed_unassigned, - # 179 M-3 - :ed_unassigned, - # 180 M-4 - :ed_unassigned, - # 181 M-5 - :ed_unassigned, - # 182 M-6 - :ed_unassigned, - # 183 M-7 - :ed_unassigned, - # 184 M-8 - :ed_unassigned, - # 185 M-9 - :ed_unassigned, - # 186 M-: - :ed_unassigned, - # 187 M-; - :ed_unassigned, - # 188 M-< - :ed_unassigned, - # 189 M-= - :ed_unassigned, - # 190 M-> - :ed_unassigned, - # 191 M-? - :ed_unassigned, - # 192 M-@ - :ed_unassigned, - # 193 M-A - :ed_unassigned, - # 194 M-B - :ed_unassigned, - # 195 M-C - :ed_unassigned, - # 196 M-D - :ed_unassigned, - # 197 M-E - :ed_unassigned, - # 198 M-F - :ed_unassigned, - # 199 M-G - :ed_unassigned, - # 200 M-H - :ed_unassigned, - # 201 M-I - :ed_unassigned, - # 202 M-J - :ed_unassigned, - # 203 M-K - :ed_unassigned, - # 204 M-L - :ed_unassigned, - # 205 M-M - :ed_unassigned, - # 206 M-N - :ed_unassigned, - # 207 M-O - :ed_sequence_lead_in, - # 208 M-P - :ed_unassigned, - # 209 M-Q - :ed_unassigned, - # 210 M-R - :ed_unassigned, - # 211 M-S - :ed_unassigned, - # 212 M-T - :ed_unassigned, - # 213 M-U - :ed_unassigned, - # 214 M-V - :ed_unassigned, - # 215 M-W - :ed_unassigned, - # 216 M-X - :ed_unassigned, - # 217 M-Y - :ed_unassigned, - # 218 M-Z - :ed_unassigned, - # 219 M-[ - :ed_sequence_lead_in, - # 220 M-\ - :ed_unassigned, - # 221 M-] - :ed_unassigned, - # 222 M-^ - :ed_unassigned, - # 223 M-_ - :ed_unassigned, - # 223 M-` - :ed_unassigned, - # 224 M-a - :ed_unassigned, - # 225 M-b - :ed_unassigned, - # 226 M-c - :ed_unassigned, - # 227 M-d - :ed_unassigned, - # 228 M-e - :ed_unassigned, - # 229 M-f - :ed_unassigned, - # 230 M-g - :ed_unassigned, - # 231 M-h - :ed_unassigned, - # 232 M-i - :ed_unassigned, - # 233 M-j - :ed_unassigned, - # 234 M-k - :ed_unassigned, - # 235 M-l - :ed_unassigned, - # 236 M-m - :ed_unassigned, - # 237 M-n - :ed_unassigned, - # 238 M-o - :ed_unassigned, - # 239 M-p - :ed_unassigned, - # 240 M-q - :ed_unassigned, - # 241 M-r - :ed_unassigned, - # 242 M-s - :ed_unassigned, - # 243 M-t - :ed_unassigned, - # 244 M-u - :ed_unassigned, - # 245 M-v - :ed_unassigned, - # 246 M-w - :ed_unassigned, - # 247 M-x - :ed_unassigned, - # 248 M-y - :ed_unassigned, - # 249 M-z - :ed_unassigned, - # 250 M-{ - :ed_unassigned, - # 251 M-| - :ed_unassigned, - # 252 M-} - :ed_unassigned, - # 253 M-~ - :ed_unassigned, - # 254 M-^? - :ed_unassigned - # 255 - # EOF - ] -end - diff --git a/lib/reline/key_actor/vi_insert.rb b/lib/reline/key_actor/vi_insert.rb deleted file mode 100644 index 8585a642ab..0000000000 --- a/lib/reline/key_actor/vi_insert.rb +++ /dev/null @@ -1,518 +0,0 @@ -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 diff --git a/lib/reline/key_stroke.rb b/lib/reline/key_stroke.rb deleted file mode 100644 index ac0a820759..0000000000 --- a/lib/reline/key_stroke.rb +++ /dev/null @@ -1,74 +0,0 @@ -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 diff --git a/lib/reline/kill_ring.rb b/lib/reline/kill_ring.rb deleted file mode 100644 index 842fd04697..0000000000 --- a/lib/reline/kill_ring.rb +++ /dev/null @@ -1,113 +0,0 @@ -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 diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb deleted file mode 100644 index 7d1030ea0e..0000000000 --- a/lib/reline/line_editor.rb +++ /dev/null @@ -1,1357 +0,0 @@ -require 'reline/kill_ring' -require 'reline/unicode' - -require 'tempfile' -require 'pathname' - -class Reline::LineEditor - # TODO: undo - attr_reader :line - attr_accessor :confirm_multiline_termination_proc - attr_accessor :completion_proc - attr_accessor :dig_perfect_match_proc - attr_writer :retrieve_completion_block - - ARGUMENTABLE = %i{ - ed_delete_next_char - ed_delete_prev_char - ed_delete_prev_word - ed_next_char - ed_next_history - ed_next_line# - ed_prev_char - ed_prev_history - ed_prev_line# - ed_prev_word - ed_quoted_insert - vi_to_column - vi_next_word - vi_prev_word - vi_end_word - vi_next_big_word - vi_prev_big_word - vi_end_big_word - vi_next_char - vi_delete_meta - vi_paste_prev - vi_paste_next - vi_replace_char - } - - VI_OPERATORS = %i{ - vi_change_meta - vi_delete_meta - vi_yank - } - - VI_MOTIONS = %i{ - ed_prev_char - ed_next_char - vi_zero - ed_move_to_beg - ed_move_to_end - vi_to_column - vi_next_char - vi_prev_char - vi_next_word - vi_prev_word - vi_to_next_char - vi_to_prev_char - vi_end_word - vi_next_big_word - vi_prev_big_word - vi_end_big_word - vi_repeat_next_char - vi_repeat_prev_char - } - - module CompletionState - NORMAL = :normal - COMPLETION = :completion - MENU = :menu - JOURNEY = :journey - PERFECT_MATCH = :perfect_match - end - - CompletionJourneyData = Struct.new('CompletionJourneyData', :preposing, :postposing, :list, :pointer) - MenuInfo = Struct.new('MenuInfo', :target, :list) - - def initialize(config, prompt, encoding = Encoding.default_external) - @config = config - @prompt = prompt - @prompt_width = calculate_width(@prompt) - @cursor = 0 - @cursor_max = 0 - @byte_pointer = 0 - @encoding = encoding - @buffer_of_lines = [String.new(encoding: @encoding)] - @line_index = 0 - @previous_line_index = nil - @line = @buffer_of_lines[0] - @is_multiline = false - @finished = false - @cleared = false - @rerender_all = false - @is_confirm_multiline_termination = false - @history_pointer = nil - @line_backup_in_history = nil - @kill_ring = Reline::KillRing.new - @vi_clipboard = '' - @vi_arg = nil - @multibyte_buffer = String.new(encoding: 'ASCII-8BIT') - @meta_prefix = false - @waiting_proc = nil - @waiting_operator_proc = nil - @completion_journey_data = nil - @completion_state = CompletionState::NORMAL - @perfect_matched = nil - @screen_size = Reline.get_screen_size - @first_line_started_from = 0 - @move_up = 0 - @started_from = 0 - @highest_in_this = 1 - @highest_in_all = 1 - @menu_info = nil - end - - def multiline_on - @is_multiline = true - end - - def multiline_off - @is_multiline = false - end - - private def insert_new_line(cursor_line, next_line) - @line = cursor_line - @buffer_of_lines.insert(@line_index + 1, String.new(next_line, encoding: @encoding)) - @previous_line_index = @line_index - @line_index += 1 - end - - private def calculate_height_by_width(width) - return 1 if width.zero? - height = 1 - max_width = @screen_size.last - while width > max_width * height - height += 1 - end - height += 1 if (width % max_width).zero? - height - end - - private def split_by_width(str, max_width) - lines = [String.new(encoding: @encoding)] - width = 0 - str.encode(Encoding::UTF_8).grapheme_clusters.each do |gc| - mbchar_width = Reline::Unicode.get_mbchar_width(gc) - width += mbchar_width - if width > max_width - width = mbchar_width - lines << String.new(encoding: @encoding) - end - lines.last << gc - end - # The cursor moves to next line in first - lines << String.new(encoding: @encoding) if width == max_width - lines - end - - private def scroll_down(val) - if val <= @rest_height - Reline.move_cursor_down(val) - @rest_height -= val - else - Reline.move_cursor_down(@rest_height) - Reline.scroll_down(val - @rest_height) - @rest_height = 0 - end - end - - private def move_cursor_up(val) - if val > 0 - Reline.move_cursor_up(val) - @rest_height += val - elsif val < 0 - move_cursor_down(-val) - end - end - - private def move_cursor_down(val) - if val > 0 - Reline.move_cursor_down(val) - @rest_height -= val - @rest_height = 0 if @rest_height < 0 - elsif val < 0 - move_cursor_up(-val) - end - end - - private def calculate_nearest_cursor - @cursor_max = calculate_width(line) - new_cursor = 0 - new_byte_pointer = 0 - height = 1 - max_width = @screen_size.last - @line.encode(Encoding::UTF_8).grapheme_clusters.each do |gc| - mbchar_width = Reline::Unicode.get_mbchar_width(gc) - now = new_cursor + mbchar_width - if now > @cursor_max or now > @cursor - break - end - new_cursor += mbchar_width - if new_cursor > max_width * height - height += 1 - end - new_byte_pointer += gc.bytesize - end - @started_from = height - 1 - @cursor = new_cursor - @byte_pointer = new_byte_pointer - end - - def rerender # TODO: support physical and logical lines - @rest_height ||= (Reline.get_screen_size.first - 1) - Reline.cursor_pos.y - if @menu_info - puts - @menu_info.list.each do |item| - puts item - end - @menu_info = nil - end - return if @line.nil? - if @vi_arg - prompt = "(arg: #{@vi_arg}) " - prompt_width = calculate_width(prompt) - else - prompt = @prompt - prompt_width = @prompt_width - end - if @cleared - Reline.clear_screen - @cleared = false - back = 0 - @buffer_of_lines.each_with_index do |line, index| - line = @line if index == @line_index - height = render_partial(prompt, prompt_width, line, false) - if index < (@buffer_of_lines.size - 1) - move_cursor_down(height) - back += height - end - end - move_cursor_up(back) - move_cursor_down(@first_line_started_from + @started_from) - Reline.move_cursor_column((prompt_width + @cursor) % @screen_size.last) - return - end - # FIXME: end of logical line sometimes breaks - if @previous_line_index - previous_line = @line - all_height = @buffer_of_lines.inject(0) { |result, line| - result + calculate_height_by_width(@prompt_width + calculate_width(line)) - } - diff = all_height - @highest_in_all - if diff > 0 - @highest_in_all = all_height - scroll_down(diff) - move_cursor_up(@first_line_started_from + @started_from + diff) - back = 0 - @buffer_of_lines.each_with_index do |line, index| - line = @line if index == @previous_line_index - height = render_partial(prompt, prompt_width, line, false) - if index < (@buffer_of_lines.size - 1) - move_cursor_down(height) - back += height - end - end - move_cursor_up(back) - else - render_partial(prompt, prompt_width, previous_line) - move_cursor_up(@first_line_started_from + @started_from) - end - @buffer_of_lines[@previous_line_index] = @line - @line = @buffer_of_lines[@line_index] - @first_line_started_from = - if @line_index.zero? - 0 - else - @buffer_of_lines[0..(@line_index - 1)].inject(0) { |result, line| - result + calculate_height_by_width(@prompt_width + calculate_width(line)) - } - end - move_cursor_down(@first_line_started_from) - calculate_nearest_cursor - @highest_in_this = calculate_height_by_width(@prompt_width + @cursor_max) - @previous_line_index = nil - elsif @rerender_all - move_cursor_up(@first_line_started_from + @started_from) - Reline.move_cursor_column(0) - back = 0 - @buffer_of_lines.each do |line| - width = prompt_width + calculate_width(line) - height = calculate_height_by_width(width) - back += height - end - if back > @highest_in_all - scroll_down(back) - move_cursor_up(back) - elsif back < @highest_in_all - scroll_down(back) - Reline.erase_after_cursor - (@highest_in_all - back).times do - scroll_down(1) - Reline.erase_after_cursor - end - move_cursor_up(@highest_in_all) - end - @buffer_of_lines.each_with_index do |line, index| - height = render_partial(prompt, prompt_width, line, false) - if index < (@buffer_of_lines.size - 1) - move_cursor_down(1) - end - end - move_cursor_up(back - 1) - @highest_in_all = back - @highest_in_this = calculate_height_by_width(@prompt_width + @cursor_max) - @first_line_started_from = - if @line_index.zero? - 0 - else - @buffer_of_lines[0..(@line_index - 1)].inject(0) { |result, line| - result + calculate_height_by_width(@prompt_width + calculate_width(line)) - } - end - move_cursor_down(@first_line_started_from) - @rerender_all = false - end - render_partial(prompt, prompt_width, @line) if !@is_multiline or !finished? - if @is_multiline and finished? - scroll_down(1) unless @buffer_of_lines.last.empty? - Reline.move_cursor_column(0) - Reline.erase_after_cursor - end - end - - private def render_partial(prompt, prompt_width, line_to_render, with_control = true) - whole_line = prompt + (line_to_render.nil? ? '' : line_to_render) - visual_lines = split_by_width(whole_line, @screen_size.last) - if with_control - if visual_lines.size > @highest_in_this - diff = visual_lines.size - @highest_in_this - scroll_down(diff) - @highest_in_all += diff - @highest_in_this = visual_lines.size - move_cursor_up(1) - end - move_cursor_up(@started_from) - @started_from = calculate_height_by_width(prompt_width + @cursor) - 1 - end - visual_lines.each_with_index do |line, index| - Reline.move_cursor_column(0) - escaped_print line - Reline.erase_after_cursor - move_cursor_down(1) if index < (visual_lines.size - 1) - end - if with_control - if finished? - puts - else - move_cursor_up((visual_lines.size - 1) - @started_from) - Reline.move_cursor_column((prompt_width + @cursor) % @screen_size.last) - end - end - visual_lines.size - end - - def editing_mode - @config.editing_mode - end - - private def escaped_print(str) - print str.chars.map { |gr| - escaped = Reline::Unicode::EscapedPairs[gr.ord] - if escaped - escaped - else - gr - end - }.join - end - - private def menu(target, list) - @menu_info = MenuInfo.new(target, list) - end - - private def complete_internal_proc(list, is_menu) - preposing, target, postposing = @retrieve_completion_block.(@line, @byte_pointer) - list = list.select { |i| i&.start_with?(target) } - if is_menu - menu(target, list) - return nil - end - completed = list.inject { |memo, item| - memo_mbchars = memo.unicode_normalize.grapheme_clusters - item_mbchars = item.unicode_normalize.grapheme_clusters - size = [memo_mbchars.size, item_mbchars.size].min - result = '' - size.times do |i| - if memo_mbchars[i] == item_mbchars[i] - result << memo_mbchars[i] - else - break - end - end - result - } - [target, preposing, completed, postposing] - end - - private def complete(list) - case @completion_state - when CompletionState::NORMAL, CompletionState::JOURNEY - @completion_state = CompletionState::COMPLETION - when CompletionState::PERFECT_MATCH - @dig_perfect_match_proc&.(@perfect_matched) - end - is_menu = (@completion_state == CompletionState::MENU) - result = complete_internal_proc(list, is_menu) - return if result.nil? - target, preposing, completed, postposing = result - return if completed.nil? - if target <= completed and (@completion_state == CompletionState::COMPLETION or @completion_state == CompletionState::PERFECT_MATCH) - @completion_state = CompletionState::MENU - if list.include?(completed) - @completion_state = CompletionState::PERFECT_MATCH - @perfect_matched = completed - end - if target < completed - @line = preposing + completed + postposing - line_to_pointer = preposing + completed - @cursor_max = calculate_width(@line) - @cursor = calculate_width(line_to_pointer) - @byte_pointer = line_to_pointer.bytesize - end - end - end - - private def move_completed_list(list, direction) - case @completion_state - when CompletionState::NORMAL, CompletionState::COMPLETION, CompletionState::MENU - @completion_state = CompletionState::JOURNEY - result = @retrieve_completion_block.(@line, @byte_pointer) - return if result.nil? - preposing, target, postposing = result - @completion_journey_data = CompletionJourneyData.new( - preposing, postposing, - [target] + list.select{ |item| item.start_with?(target) }, 0) - @completion_state = CompletionState::JOURNEY - else - case direction - when :up - @completion_journey_data.pointer -= 1 - if @completion_journey_data.pointer < 0 - @completion_journey_data.pointer = @completion_journey_data.list.size - 1 - end - when :down - @completion_journey_data.pointer += 1 - if @completion_journey_data.pointer >= @completion_journey_data.list.size - @completion_journey_data.pointer = 0 - end - end - completed = @completion_journey_data.list[@completion_journey_data.pointer] - @line = @completion_journey_data.preposing + completed + @completion_journey_data.postposing - line_to_pointer = @completion_journey_data.preposing + completed - @cursor_max = calculate_width(@line) - @cursor = calculate_width(line_to_pointer) - @byte_pointer = line_to_pointer.bytesize - end - end - - private def run_for_operators(key, method_symbol, &block) - if @waiting_operator_proc - if VI_MOTIONS.include?(method_symbol) - old_cursor, old_byte_pointer = @cursor, @byte_pointer - block.() - unless @waiting_proc - cursor_diff, byte_pointer_diff = @cursor - old_cursor, @byte_pointer - old_byte_pointer - @cursor, @byte_pointer = old_cursor, old_byte_pointer - @waiting_operator_proc.(cursor_diff, byte_pointer_diff) - else - old_waiting_proc = @waiting_proc - old_waiting_operator_proc = @waiting_operator_proc - @waiting_proc = proc { |key| - old_cursor, old_byte_pointer = @cursor, @byte_pointer - old_waiting_proc.(key) - cursor_diff, byte_pointer_diff = @cursor - old_cursor, @byte_pointer - old_byte_pointer - @cursor, @byte_pointer = old_cursor, old_byte_pointer - @waiting_operator_proc.(cursor_diff, byte_pointer_diff) - } - end - else - # Ignores operator when not motion is given. - block.() - end - @waiting_operator_proc = nil - else - block.() - end - end - - private def process_key(key, method_symbol, method_obj) - if @vi_arg - if key.chr =~ /[0-9]/ - ed_argument_digit(key) - else - if ARGUMENTABLE.include?(method_symbol) and method_obj - run_for_operators(key, method_symbol) do - method_obj.(key, arg: @vi_arg) - end - elsif @waiting_proc - @waiting_proc.(key) - elsif method_obj - method_obj.(key) - else - ed_insert(key) - end - @kill_ring.process - @vi_arg = nil - end - elsif @waiting_proc - @waiting_proc.(key) - @kill_ring.process - elsif method_obj - if method_symbol == :ed_argument_digit - method_obj.(key) - else - run_for_operators(key, method_symbol) do - method_obj.(key) - end - end - @kill_ring.process - else - ed_insert(key) - end - end - - private def normal_char(key) - method_symbol = method_obj = nil - @multibyte_buffer << key - if @multibyte_buffer.size > 1 - if @multibyte_buffer.dup.force_encoding(@encoding).valid_encoding? - key = @multibyte_buffer.dup.force_encoding(@encoding) - @multibyte_buffer.clear - else - # invalid - return - end - else # single byte - return if key >= 128 # maybe, first byte of multi byte - if @meta_prefix - key |= 0b10000000 if key.nobits?(0b10000000) - @meta_prefix = false - end - method_symbol = @config.editing_mode.get_method(key) - if key.allbits?(0b10000000) and method_symbol == :ed_unassigned - return # This is unknown input - end - if method_symbol and respond_to?(method_symbol, true) - method_obj = method(method_symbol) - end - @multibyte_buffer.clear - end - process_key(key, method_symbol, method_obj) - if @config.editing_mode_is?(:vi_command) and @cursor > 0 and @cursor == @cursor_max - byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer) - @byte_pointer -= byte_size - mbchar = @line.byteslice(@byte_pointer, byte_size) - width = Reline::Unicode.get_mbchar_width(mbchar) - @cursor -= width - end - end - - def input_key(key) - completion_occurs = false - if @config.editing_mode_is?(:emacs, :vi_insert) and key == "\C-i".ord - result = @completion_proc&.(@line) - if result.is_a?(Array) - completion_occurs = true - complete(result) - end - elsif @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key) - result = @completion_proc&.(@line) - if result.is_a?(Array) - completion_occurs = true - move_completed_list(result, "\C-p".ord == key ? :up : :down) - end - elsif @config.editing_mode_is?(:emacs) and key == "\e".ord # meta key - if @meta_prefix - # escape twice - @meta_prefix = false - @kill_ring.process - else - @meta_prefix = true - end - elsif @config.editing_mode_is?(:vi_command) and key == "\e".ord - # suppress ^[ when command_mode - elsif Symbol === key and respond_to?(key, true) - process_key(key, key, method(key)) - else - normal_char(key) - end - unless completion_occurs - @completion_state = CompletionState::NORMAL - end - if @is_confirm_multiline_termination and @confirm_multiline_termination_proc - @is_confirm_multiline_termination = false - temp_buffer = @buffer_of_lines.dup - if @previous_line_index and @line_index == (@buffer_of_lines.size - 1) - temp_buffer[@previous_line_index] = @line - end - finish if @confirm_multiline_termination_proc.(temp_buffer.join("\n")) - end - end - - def whole_buffer - temp_lines = @buffer_of_lines.dup - temp_lines[@line_index] = @line - if @buffer_of_lines.size == 1 and @line.nil? - nil - else - temp_lines.join("\n") - end - end - - def finished? - @finished - end - - def finish - @finished = true - @config.reset - end - - private def byteslice!(str, byte_pointer, size) - new_str = str.byteslice(0, byte_pointer) - new_str << str.byteslice(byte_pointer + size, str.bytesize) - [new_str, str.byteslice(byte_pointer, size)] - end - - private def byteinsert(str, byte_pointer, other) - new_str = str.byteslice(0, byte_pointer) - new_str << other - new_str << str.byteslice(byte_pointer, str.bytesize) - new_str - end - - private def calculate_width(str) - str.encode(Encoding::UTF_8).grapheme_clusters.inject(0) { |width, gc| - width + Reline::Unicode.get_mbchar_width(gc) - } - end - - private def ed_insert(key) - if key.instance_of?(String) - width = Reline::Unicode.get_mbchar_width(key) - if @cursor == @cursor_max - @line += key - else - @line = byteinsert(@line, @byte_pointer, key) - end - @byte_pointer += key.bytesize - @cursor += width - @cursor_max += width - else - if @cursor == @cursor_max - @line += key.chr - else - @line = byteinsert(@line, @byte_pointer, key.chr) - end - width = Reline::Unicode.get_mbchar_width(key.chr) - @byte_pointer += 1 - @cursor += width - @cursor_max += width - end - end - alias_method :ed_digit, :ed_insert - - private def ed_quoted_insert(str, arg: 1) - @waiting_proc = proc { |key| - arg.times do - ed_insert(key) - end - @waiting_proc = nil - } - end - - private def ed_next_char(key, arg: 1) - byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer) - if (@byte_pointer < @line.bytesize) - mbchar = @line.byteslice(@byte_pointer, byte_size) - width = Reline::Unicode.get_mbchar_width(mbchar) - @cursor += width if width - @byte_pointer += byte_size - end - arg -= 1 - ed_next_char(key, arg: arg) if arg > 0 - end - - private def ed_prev_char(key, arg: 1) - if @cursor > 0 - byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer) - @byte_pointer -= byte_size - mbchar = @line.byteslice(@byte_pointer, byte_size) - width = Reline::Unicode.get_mbchar_width(mbchar) - @cursor -= width - end - arg -= 1 - ed_prev_char(key, arg: arg) if arg > 0 - end - - private def ed_move_to_beg(key) - @byte_pointer, @cursor = Reline::Unicode.ed_move_to_begin(@line) - end - - private def ed_move_to_end(key) - @byte_pointer = 0 - @cursor = 0 - byte_size = 0 - while @byte_pointer < @line.bytesize - byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer) - if byte_size > 0 - mbchar = @line.byteslice(@byte_pointer, byte_size) - @cursor += Reline::Unicode.get_mbchar_width(mbchar) - end - @byte_pointer += byte_size - end - end - - private def ed_prev_history(key, arg: 1) - if @is_multiline and @line_index > 0 - @previous_line_index = @line_index - @line_index -= 1 - return - end - if Reline::HISTORY.empty? - return - end - if @history_pointer.nil? - @history_pointer = Reline::HISTORY.size - 1 - if @is_multiline - @line_backup_in_history = whole_buffer - @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n") - @line_index = @buffer_of_lines.size - 1 - @line = @buffer_of_lines.last - @rerender_all = true - else - @line_backup_in_history = @line - @line = Reline::HISTORY[@history_pointer] - end - elsif @history_pointer.zero? - return - else - if @is_multiline - Reline::HISTORY[@history_pointer] = whole_buffer - @history_pointer -= 1 - @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n") - @line_index = @buffer_of_lines.size - 1 - @line = @buffer_of_lines.last - @rerender_all = true - else - Reline::HISTORY[@history_pointer] = @line - @history_pointer -= 1 - @line = Reline::HISTORY[@history_pointer] - end - end - if @config.editing_mode_is?(:emacs) - @cursor_max = @cursor = calculate_width(@line) - @byte_pointer = @line.bytesize - elsif @config.editing_mode_is?(:vi_command) - @byte_pointer = @cursor = 0 - @cursor_max = calculate_width(@line) - end - arg -= 1 - ed_prev_history(key, arg: arg) if arg > 0 - end - - private def ed_next_history(key, arg: 1) - if @is_multiline and @line_index < (@buffer_of_lines.size - 1) - @previous_line_index = @line_index - @line_index += 1 - return - end - if @history_pointer.nil? - return - elsif @history_pointer == (Reline::HISTORY.size - 1) - if @is_multiline - @history_pointer = nil - @buffer_of_lines = @line_backup_in_history.split("\n") - @buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty? - @line_index = 0 - @line = @buffer_of_lines.first - @rerender_all = true - else - @history_pointer = nil - @line = @line_backup_in_history - end - else - if @is_multiline - Reline::HISTORY[@history_pointer] = whole_buffer - @history_pointer += 1 - @buffer_of_lines = Reline::HISTORY[@history_pointer].split("\n") - @line_index = 0 - @line = @buffer_of_lines.first - @rerender_all = true - else - Reline::HISTORY[@history_pointer] = @line - @history_pointer += 1 - @line = Reline::HISTORY[@history_pointer] - end - end - @line = '' unless @line - if @config.editing_mode_is?(:emacs) - @cursor_max = @cursor = calculate_width(@line) - @byte_pointer = @line.bytesize - elsif @config.editing_mode_is?(:vi_command) - @byte_pointer = @cursor = 0 - @cursor_max = calculate_width(@line) - end - arg -= 1 - ed_next_history(key, arg: arg) if arg > 0 - end - - private def ed_newline(key) - if @is_multiline - if @config.editing_mode_is?(:vi_command) - if @line_index < (@buffer_of_lines.size - 1) - ed_next_history(key) - else - @is_confirm_multiline_termination = true - end - else - next_line = @line.byteslice(@byte_pointer, @line.bytesize - @byte_pointer) - cursor_line = @line.byteslice(0, @byte_pointer) - insert_new_line(cursor_line, next_line) - if @line_index == (@buffer_of_lines.size - 1) - @is_confirm_multiline_termination = true - end - end - return - end - if @history_pointer - Reline::HISTORY[@history_pointer] = @line - @history_pointer = nil - end - finish - end - - private def em_delete_prev_char(key) - if @is_multiline and @cursor == 0 and @line_index > 0 - @buffer_of_lines[@line_index] = @line - @cursor = calculate_width(@buffer_of_lines[@line_index - 1]) - @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize - @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index) - @line_index -= 1 - @line = @buffer_of_lines[@line_index] - @cursor_max = calculate_width(@line) - @rerender_all = true - elsif @cursor > 0 - byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer) - @byte_pointer -= byte_size - @line, mbchar = byteslice!(@line, @byte_pointer, byte_size) - width = Reline::Unicode.get_mbchar_width(mbchar) - @cursor -= width - @cursor_max -= width - end - end - - private def ed_kill_line(key) - if @line.bytesize > @byte_pointer - @line, deleted = byteslice!(@line, @byte_pointer, @line.bytesize - @byte_pointer) - @byte_pointer = @line.bytesize - @cursor = @cursor_max = calculate_width(@line) - @kill_ring.append(deleted) - end - end - - private def em_kill_line(key) - if @byte_pointer > 0 - @line, deleted = byteslice!(@line, 0, @byte_pointer) - @byte_pointer = 0 - @kill_ring.append(deleted, true) - @cursor_max = calculate_width(@line) - @cursor = 0 - end - end - - private def em_delete_or_list(key) - if @line.empty? - @line = nil - finish - elsif @byte_pointer < @line.bytesize - splitted_last = @line.byteslice(@byte_pointer, @line.bytesize) - mbchar = splitted_last.grapheme_clusters.first - width = Reline::Unicode.get_mbchar_width(mbchar) - @cursor_max -= width - @line, = byteslice!(@line, @byte_pointer, mbchar.bytesize) - end - end - - private def em_yank(key) - yanked = @kill_ring.yank - if yanked - @line = byteinsert(@line, @byte_pointer, yanked) - yanked_width = calculate_width(yanked) - @cursor += yanked_width - @cursor_max += yanked_width - @byte_pointer += yanked.bytesize - end - end - - private def em_yank_pop(key) - yanked, prev_yank = @kill_ring.yank_pop - if yanked - prev_yank_width = calculate_width(prev_yank) - @cursor -= prev_yank_width - @cursor_max -= prev_yank_width - @byte_pointer -= prev_yank.bytesize - @line, = byteslice!(@line, @byte_pointer, prev_yank.bytesize) - @line = byteinsert(@line, @byte_pointer, yanked) - yanked_width = calculate_width(yanked) - @cursor += yanked_width - @cursor_max += yanked_width - @byte_pointer += yanked.bytesize - end - end - - private def ed_clear_screen(key) - @cleared = true - end - - private def em_next_word(key) - if @line.bytesize > @byte_pointer - byte_size, width = Reline::Unicode.em_forward_word(@line, @byte_pointer) - @byte_pointer += byte_size - @cursor += width - end - end - - private def ed_prev_word(key) - if @byte_pointer > 0 - byte_size, width = Reline::Unicode.em_backward_word(@line, @byte_pointer) - @byte_pointer -= byte_size - @cursor -= width - end - end - - private def em_delete_next_word(key) - if @line.bytesize > @byte_pointer - byte_size, width = Reline::Unicode.em_forward_word(@line, @byte_pointer) - @line, word = byteslice!(@line, @byte_pointer, byte_size) - @kill_ring.append(word) - @cursor_max -= width - end - end - - private def ed_delete_prev_word(key) - if @byte_pointer > 0 - byte_size, width = Reline::Unicode.em_backward_word(@line, @byte_pointer) - @line, word = byteslice!(@line, @byte_pointer - byte_size, byte_size) - @kill_ring.append(word, true) - @byte_pointer -= byte_size - @cursor -= width - @cursor_max -= width - end - end - - private def ed_transpose_chars(key) - if @byte_pointer > 0 - if @cursor_max > @cursor - byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer) - mbchar = @line.byteslice(@byte_pointer, byte_size) - width = Reline::Unicode.get_mbchar_width(mbchar) - @cursor += width - @byte_pointer += byte_size - end - back1_byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer) - if (@byte_pointer - back1_byte_size) > 0 - back2_byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer - back1_byte_size) - back2_pointer = @byte_pointer - back1_byte_size - back2_byte_size - @line, back2_mbchar = byteslice!(@line, back2_pointer, back2_byte_size) - @line = byteinsert(@line, @byte_pointer - back2_byte_size, back2_mbchar) - end - end - end - - private def em_capitol_case(key) - if @line.bytesize > @byte_pointer - byte_size, _, new_str = Reline::Unicode.em_forward_word_with_capitalization(@line, @byte_pointer) - before = @line.byteslice(0, @byte_pointer) - after = @line.byteslice((@byte_pointer + byte_size)..-1) - @line = before + new_str + after - @byte_pointer += new_str.bytesize - @cursor += calculate_width(new_str) - end - end - - private def em_lower_case(key) - if @line.bytesize > @byte_pointer - byte_size, = Reline::Unicode.em_forward_word(@line, @byte_pointer) - part = @line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar| - mbchar =~ /[A-Z]/ ? mbchar.downcase : mbchar - }.join - rest = @line.byteslice((@byte_pointer + byte_size)..-1) - @line = @line.byteslice(0, @byte_pointer) + part - @byte_pointer = @line.bytesize - @cursor = calculate_width(@line) - @cursor_max = @cursor + calculate_width(rest) - @line += rest - end - end - - private def em_upper_case(key) - if @line.bytesize > @byte_pointer - byte_size, = Reline::Unicode.em_forward_word(@line, @byte_pointer) - part = @line.byteslice(@byte_pointer, byte_size).grapheme_clusters.map { |mbchar| - mbchar =~ /[a-z]/ ? mbchar.upcase : mbchar - }.join - rest = @line.byteslice((@byte_pointer + byte_size)..-1) - @line = @line.byteslice(0, @byte_pointer) + part - @byte_pointer = @line.bytesize - @cursor = calculate_width(@line) - @cursor_max = @cursor + calculate_width(rest) - @line += rest - end - end - - private def em_kill_region(key) - if @byte_pointer > 0 - byte_size, width = Reline::Unicode.em_big_backward_word(@line, @byte_pointer) - @line, deleted = byteslice!(@line, @byte_pointer - byte_size, byte_size) - @byte_pointer -= byte_size - @cursor -= width - @cursor_max -= width - @kill_ring.append(deleted) - end - end - - private def copy_for_vi(text) - if @config.editing_mode_is?(:vi_insert) or @config.editing_mode_is?(:vi_command) - @vi_clipboard = text - end - end - - private def vi_insert(key) - @config.editing_mode = :vi_insert - end - - private def vi_add(key) - @config.editing_mode = :vi_insert - ed_next_char(key) - end - - private def vi_command_mode(key) - ed_prev_char(key) - @config.editing_mode = :vi_command - end - - private def vi_next_word(key, arg: 1) - if @line.bytesize > @byte_pointer - byte_size, width = Reline::Unicode.vi_forward_word(@line, @byte_pointer) - @byte_pointer += byte_size - @cursor += width - end - arg -= 1 - vi_next_word(key, arg: arg) if arg > 0 - end - - private def vi_prev_word(key, arg: 1) - if @byte_pointer > 0 - byte_size, width = Reline::Unicode.vi_backward_word(@line, @byte_pointer) - @byte_pointer -= byte_size - @cursor -= width - end - arg -= 1 - vi_prev_word(key, arg: arg) if arg > 0 - end - - private def vi_end_word(key, arg: 1) - if @line.bytesize > @byte_pointer - byte_size, width = Reline::Unicode.vi_forward_end_word(@line, @byte_pointer) - @byte_pointer += byte_size - @cursor += width - end - arg -= 1 - vi_end_word(key, arg: arg) if arg > 0 - end - - private def vi_next_big_word(key, arg: 1) - if @line.bytesize > @byte_pointer - byte_size, width = Reline::Unicode.vi_big_forward_word(@line, @byte_pointer) - @byte_pointer += byte_size - @cursor += width - end - arg -= 1 - vi_next_big_word(key, arg: arg) if arg > 0 - end - - private def vi_prev_big_word(key, arg: 1) - if @byte_pointer > 0 - byte_size, width = Reline::Unicode.vi_big_backward_word(@line, @byte_pointer) - @byte_pointer -= byte_size - @cursor -= width - end - arg -= 1 - vi_prev_big_word(key, arg: arg) if arg > 0 - end - - private def vi_end_big_word(key, arg: 1) - if @line.bytesize > @byte_pointer - byte_size, width = Reline::Unicode.vi_big_forward_end_word(@line, @byte_pointer) - @byte_pointer += byte_size - @cursor += width - end - arg -= 1 - vi_end_big_word(key, arg: arg) if arg > 0 - end - - private def vi_delete_prev_char(key) - if @is_multiline and @cursor == 0 and @line_index > 0 - @buffer_of_lines[@line_index] = @line - @cursor = calculate_width(@buffer_of_lines[@line_index - 1]) - @byte_pointer = @buffer_of_lines[@line_index - 1].bytesize - @buffer_of_lines[@line_index - 1] += @buffer_of_lines.delete_at(@line_index) - @line_index -= 1 - @line = @buffer_of_lines[@line_index] - @cursor_max = calculate_width(@line) - @rerender_all = true - elsif @cursor > 0 - byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer) - @byte_pointer -= byte_size - @line, mbchar = byteslice!(@line, @byte_pointer, byte_size) - width = Reline::Unicode.get_mbchar_width(mbchar) - @cursor -= width - @cursor_max -= width - end - end - - private def ed_delete_prev_char(key, arg: 1) - deleted = '' - arg.times do - if @cursor > 0 - byte_size = Reline::Unicode.get_prev_mbchar_size(@line, @byte_pointer) - @byte_pointer -= byte_size - @line, mbchar = byteslice!(@line, @byte_pointer, byte_size) - deleted.prepend(mbchar) - width = Reline::Unicode.get_mbchar_width(mbchar) - @cursor -= width - @cursor_max -= width - end - end - copy_for_vi(deleted) - end - - private def vi_zero(key) - @byte_pointer = 0 - @cursor = 0 - end - - private def vi_change_meta(key) - end - - private def vi_delete_meta(key) - @waiting_operator_proc = proc { |cursor_diff, byte_pointer_diff| - if byte_pointer_diff > 0 - @line, cut = byteslice!(@line, @byte_pointer, byte_pointer_diff) - elsif byte_pointer_diff < 0 - @line, cut = byteslice!(@line, @byte_pointer + byte_pointer_diff, -byte_pointer_diff) - end - copy_for_vi(cut) - @cursor += cursor_diff if cursor_diff < 0 - @cursor_max -= cursor_diff.abs - @byte_pointer += byte_pointer_diff if byte_pointer_diff < 0 - } - end - - private def vi_yank(key) - end - - private def vi_end_of_transmission(key) - if @line.empty? - @line = nil - finish - end - end - - private def vi_list_or_eof(key) - if @line.empty? - @line = nil - finish - else - # TODO: list - end - end - - private def ed_delete_next_char(key, arg: 1) - unless @line.empty? - byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer) - @line, mbchar = byteslice!(@line, @byte_pointer, byte_size) - copy_for_vi(mbchar) - width = Reline::Unicode.get_mbchar_width(mbchar) - @cursor_max -= width # FIXME - if @cursor > 0 and @cursor >= @cursor_max - @byte_pointer -= byte_size - @cursor -= width - end - end - arg -= 1 - ed_delete_next_char(key, arg: arg) if arg > 0 - end - - private def vi_to_history_line(key) - if Reline::HISTORY.empty? - return - end - if @history_pointer.nil? - @history_pointer = 0 - @line_backup_in_history = @line - @line = Reline::HISTORY[@history_pointer] - @cursor_max = calculate_width(@line) - @cursor = 0 - @byte_pointer = 0 - elsif @history_pointer.zero? - return - else - Reline::HISTORY[@history_pointer] = @line - @history_pointer = 0 - @line = Reline::HISTORY[@history_pointer] - @cursor_max = calculate_width(@line) - @cursor = 0 - @byte_pointer = 0 - end - end - - private def vi_histedit(key) - path = Tempfile.open { |fp| - fp.write @line - fp.path - } - system("#{ENV['EDITOR']} #{path}") - @line = Pathname.new(path).read - finish - end - - private def vi_paste_prev(key, arg: 1) - if @vi_clipboard.size > 0 - @line = byteinsert(@line, @byte_pointer, @vi_clipboard) - @cursor_max += calculate_width(@vi_clipboard) - cursor_point = @vi_clipboard.grapheme_clusters[0..-2].join - @cursor += calculate_width(cursor_point) - @byte_pointer += cursor_point.bytesize - end - arg -= 1 - vi_paste_prev(key, arg: arg) if arg > 0 - end - - private def vi_paste_next(key, arg: 1) - if @vi_clipboard.size > 0 - byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer) - @line = byteinsert(@line, @byte_pointer + byte_size, @vi_clipboard) - @cursor_max += calculate_width(@vi_clipboard) - @cursor += calculate_width(@vi_clipboard) - @byte_pointer += @vi_clipboard.bytesize - end - arg -= 1 - vi_paste_next(key, arg: arg) if arg > 0 - end - - private def ed_argument_digit(key) - if @vi_arg.nil? - unless key.chr.to_i.zero? - @vi_arg = key.chr.to_i - end - else - @vi_arg = @vi_arg * 10 + key.chr.to_i - end - end - - private def vi_to_column(key, arg: 0) - @byte_pointer, @cursor = @line.grapheme_clusters.inject([0, 0]) { |total, gc| - # total has [byte_size, cursor] - mbchar_width = Reline::Unicode.get_mbchar_width(gc) - if (total.last + mbchar_width) >= arg - break total - elsif (total.last + mbchar_width) >= @cursor_max - break total - else - total = [total.first + gc.bytesize, total.last + mbchar_width] - total - end - } - end - - private def vi_replace_char(key, arg: 1) - @waiting_proc = ->(key) { - if arg == 1 - byte_size = Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer) - before = @line.byteslice(0, @byte_pointer) - remaining_point = @byte_pointer + byte_size - after = @line.byteslice(remaining_point, @line.size - remaining_point) - @line = before + key.chr + after - @cursor_max = calculate_width(@line) - @waiting_proc = nil - elsif arg > 1 - byte_size = 0 - arg.times do - byte_size += Reline::Unicode.get_next_mbchar_size(@line, @byte_pointer + byte_size) - end - before = @line.byteslice(0, @byte_pointer) - remaining_point = @byte_pointer + byte_size - after = @line.byteslice(remaining_point, @line.size - remaining_point) - replaced = key.chr * arg - @line = before + replaced + after - @byte_pointer += replaced.bytesize - @cursor += calculate_width(replaced) - @cursor_max = calculate_width(@line) - @waiting_proc = nil - end - } - end - - private def vi_next_char(key, arg: 1) - @waiting_proc = ->(key_for_proc) { search_next_char(key_for_proc, arg) } - end - - private def search_next_char(key, arg) - if key.instance_of?(String) - inputed_char = key - else - inputed_char = key.chr - end - total = nil - found = false - @line.byteslice(@byte_pointer..-1).grapheme_clusters.each do |mbchar| - # total has [byte_size, cursor] - unless total - # skip cursor point - width = Reline::Unicode.get_mbchar_width(mbchar) - total = [mbchar.bytesize, width] - else - if inputed_char == mbchar - arg -= 1 - if arg.zero? - found = true - break - end - end - width = Reline::Unicode.get_mbchar_width(mbchar) - total = [total.first + mbchar.bytesize, total.last + width] - end - end - if found and total - byte_size, width = total - @byte_pointer += byte_size - @cursor += width - end - @waiting_proc = nil - end -end diff --git a/lib/reline/reline.gemspec b/lib/reline/reline.gemspec deleted file mode 100644 index 9ff9ca2128..0000000000 --- a/lib/reline/reline.gemspec +++ /dev/null @@ -1,25 +0,0 @@ - -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 diff --git a/lib/reline/unicode.rb b/lib/reline/unicode.rb deleted file mode 100644 index bdb182f59c..0000000000 --- a/lib/reline/unicode.rb +++ /dev/null @@ -1,415 +0,0 @@ -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' diff --git a/lib/reline/unicode/east_asian_width.rb b/lib/reline/unicode/east_asian_width.rb deleted file mode 100644 index 4eea3a7cdf..0000000000 --- a/lib/reline/unicode/east_asian_width.rb +++ /dev/null @@ -1,1145 +0,0 @@ -class Reline::Unicode::EastAsianWidth - # This is based on EastAsianWidth.txt - # http://www.unicode.org/Public/10.0.0/ucd/EastAsianWidth.txt - - # Fullwidth - TYPE_F = /^( - \u{3000} | - [\u{FF01}-\u{FF60}] | - [\u{FFE0}-\u{FFE6}] - )/x - - # Halfwidth - TYPE_H = /^( - \u{20A9} | - [\u{FF61}-\u{FFBE}] | - [\u{FFC2}-\u{FFC7}] | - [\u{FFCA}-\u{FFCF}] | - [\u{FFD2}-\u{FFD7}] | - [\u{FFDA}-\u{FFDC}] | - [\u{FFE8}-\u{FFEE}] - )/x - - # Wide - TYPE_W = /^( - [\u{1100}-\u{115F}] | - [\u{231A}-\u{231B}] | - [\u{2329}-\u{232A}] | - [\u{23E9}-\u{23EC}] | - \u{23F0} | - \u{23F3} | - [\u{25FD}-\u{25FE}] | - [\u{2614}-\u{2615}] | - [\u{2648}-\u{2653}] | - \u{267F} | - \u{2693} | - \u{26A1} | - [\u{26AA}-\u{26AB}] | - [\u{26BD}-\u{26BE}] | - [\u{26C4}-\u{26C5}] | - \u{26CE} | - \u{26D4} | - \u{26EA} | - [\u{26F2}-\u{26F3}] | - \u{26F5} | - \u{26FA} | - \u{26FD} | - \u{2705} | - [\u{270A}-\u{270B}] | - \u{2728} | - \u{274C} | - \u{274E} | - [\u{2753}-\u{2755}] | - \u{2757} | - [\u{2795}-\u{2797}] | - \u{27B0} | - \u{27BF} | - [\u{2B1B}-\u{2B1C}] | - \u{2B50} | - \u{2B55} | - [\u{2E80}-\u{2E99}] | - [\u{2E9B}-\u{2EF3}] | - [\u{2F00}-\u{2FD5}] | - [\u{2FF0}-\u{2FFB}] | - [\u{3001}-\u{303E}] | - [\u{3041}-\u{3096}] | - [\u{3099}-\u{30FF}] | - [\u{3105}-\u{312F}] | - [\u{3131}-\u{318E}] | - [\u{3190}-\u{31BA}] | - [\u{31C0}-\u{31E3}] | - [\u{31F0}-\u{321E}] | - [\u{3220}-\u{3247}] | - [\u{3250}-\u{4DBF}] | - [\u{4E00}-\u{A48C}] | - [\u{A490}-\u{A4C6}] | - [\u{A960}-\u{A97C}] | - [\u{AC00}-\u{D7A3}] | - [\u{F900}-\u{FAFF}] | - [\u{FE10}-\u{FE19}] | - [\u{FE30}-\u{FE52}] | - [\u{FE54}-\u{FE66}] | - [\u{FE68}-\u{FE6B}] | - [\u{16FE0}-\u{16FE3}] | - [\u{17000}-\u{187F7}] | - [\u{18800}-\u{18AF2}] | - [\u{1B000}-\u{1B11E}] | - [\u{1B150}-\u{1B152}] | - [\u{1B164}-\u{1B167}] | - [\u{1B170}-\u{1B2FB}] | - \u{1F004} | - \u{1F0CF} | - \u{1F18E} | - [\u{1F191}-\u{1F19A}] | - [\u{1F200}-\u{1F202}] | - [\u{1F210}-\u{1F23B}] | - [\u{1F240}-\u{1F248}] | - [\u{1F250}-\u{1F251}] | - [\u{1F260}-\u{1F265}] | - [\u{1F300}-\u{1F320}] | - [\u{1F32D}-\u{1F335}] | - [\u{1F337}-\u{1F37C}] | - [\u{1F37E}-\u{1F393}] | - [\u{1F3A0}-\u{1F3CA}] | - [\u{1F3CF}-\u{1F3D3}] | - [\u{1F3E0}-\u{1F3F0}] | - \u{1F3F4} | - [\u{1F3F8}-\u{1F43E}] | - \u{1F440} | - [\u{1F442}-\u{1F4FC}] | - [\u{1F4FF}-\u{1F53D}] | - [\u{1F54B}-\u{1F54E}] | - [\u{1F550}-\u{1F567}] | - \u{1F57A} | - [\u{1F595}-\u{1F596}] | - \u{1F5A4} | - [\u{1F5FB}-\u{1F64F}] | - [\u{1F680}-\u{1F6C5}] | - \u{1F6CC} | - [\u{1F6D0}-\u{1F6D2}] | - \u{1F6D5} | - [\u{1F6EB}-\u{1F6EC}] | - [\u{1F6F4}-\u{1F6FA}] | - [\u{1F7E0}-\u{1F7EB}] | - [\u{1F90D}-\u{1F971}] | - [\u{1F973}-\u{1F976}] | - [\u{1F97A}-\u{1F9A2}] | - [\u{1F9A5}-\u{1F9AA}] | - [\u{1F9AE}-\u{1F9CA}] | - [\u{1F9CD}-\u{1F9FF}] | - [\u{1FA70}-\u{1FA73}] | - [\u{1FA78}-\u{1FA7A}] | - [\u{1FA80}-\u{1FA82}] | - [\u{1FA90}-\u{1FA95}] | - [\u{20000}-\u{2FFFD}] | - [\u{30000}-\u{3FFFD}] - )/x - - # Narrow - TYPE_NA = /^( - [\u{0020}-\u{007E}] | - [\u{00A2}-\u{00A3}] | - [\u{00A5}-\u{00A6}] | - \u{00AC} | - \u{00AF} | - [\u{27E6}-\u{27ED}] | - [\u{2985}-\u{2986}] - )/x - - # Ambiguous - TYPE_A = /^( - \u{00A1} | - \u{00A4} | - [\u{00A7}-\u{00A8}] | - \u{00AA} | - [\u{00AD}-\u{00AE}] | - [\u{00B0}-\u{00B4}] | - [\u{00B6}-\u{00BA}] | - [\u{00BC}-\u{00BF}] | - \u{00C6} | - \u{00D0} | - [\u{00D7}-\u{00D8}] | - [\u{00DE}-\u{00E1}] | - \u{00E6} | - [\u{00E8}-\u{00EA}] | - [\u{00EC}-\u{00ED}] | - \u{00F0} | - [\u{00F2}-\u{00F3}] | - [\u{00F7}-\u{00FA}] | - \u{00FC} | - \u{00FE} | - \u{0101} | - \u{0111} | - \u{0113} | - \u{011B} | - [\u{0126}-\u{0127}] | - \u{012B} | - [\u{0131}-\u{0133}] | - \u{0138} | - [\u{013F}-\u{0142}] | - \u{0144} | - [\u{0148}-\u{014B}] | - \u{014D} | - [\u{0152}-\u{0153}] | - [\u{0166}-\u{0167}] | - \u{016B} | - \u{01CE} | - \u{01D0} | - \u{01D2} | - \u{01D4} | - \u{01D6} | - \u{01D8} | - \u{01DA} | - \u{01DC} | - \u{0251} | - \u{0261} | - \u{02C4} | - \u{02C7} | - [\u{02C9}-\u{02CB}] | - \u{02CD} | - \u{02D0} | - [\u{02D8}-\u{02DB}] | - \u{02DD} | - \u{02DF} | - [\u{0300}-\u{036F}] | - [\u{0391}-\u{03A1}] | - [\u{03A3}-\u{03A9}] | - [\u{03B1}-\u{03C1}] | - [\u{03C3}-\u{03C9}] | - \u{0401} | - [\u{0410}-\u{044F}] | - \u{0451} | - \u{2010} | - [\u{2013}-\u{2016}] | - [\u{2018}-\u{2019}] | - [\u{201C}-\u{201D}] | - [\u{2020}-\u{2022}] | - [\u{2024}-\u{2027}] | - \u{2030} | - [\u{2032}-\u{2033}] | - \u{2035} | - \u{203B} | - \u{203E} | - \u{2074} | - \u{207F} | - [\u{2081}-\u{2084}] | - \u{20AC} | - \u{2103} | - \u{2105} | - \u{2109} | - \u{2113} | - \u{2116} | - [\u{2121}-\u{2122}] | - \u{2126} | - \u{212B} | - [\u{2153}-\u{2154}] | - [\u{215B}-\u{215E}] | - [\u{2160}-\u{216B}] | - [\u{2170}-\u{2179}] | - \u{2189} | - [\u{2190}-\u{2199}] | - [\u{21B8}-\u{21B9}] | - \u{21D2} | - \u{21D4} | - \u{21E7} | - \u{2200} | - [\u{2202}-\u{2203}] | - [\u{2207}-\u{2208}] | - \u{220B} | - \u{220F} | - \u{2211} | - \u{2215} | - \u{221A} | - [\u{221D}-\u{2220}] | - \u{2223} | - \u{2225} | - [\u{2227}-\u{222C}] | - \u{222E} | - [\u{2234}-\u{2237}] | - [\u{223C}-\u{223D}] | - \u{2248} | - \u{224C} | - \u{2252} | - [\u{2260}-\u{2261}] | - [\u{2264}-\u{2267}] | - [\u{226A}-\u{226B}] | - [\u{226E}-\u{226F}] | - [\u{2282}-\u{2283}] | - [\u{2286}-\u{2287}] | - \u{2295} | - \u{2299} | - \u{22A5} | - \u{22BF} | - \u{2312} | - [\u{2460}-\u{24E9}] | - [\u{24EB}-\u{254B}] | - [\u{2550}-\u{2573}] | - [\u{2580}-\u{258F}] | - [\u{2592}-\u{2595}] | - [\u{25A0}-\u{25A1}] | - [\u{25A3}-\u{25A9}] | - [\u{25B2}-\u{25B3}] | - [\u{25B6}-\u{25B7}] | - [\u{25BC}-\u{25BD}] | - [\u{25C0}-\u{25C1}] | - [\u{25C6}-\u{25C8}] | - \u{25CB} | - [\u{25CE}-\u{25D1}] | - [\u{25E2}-\u{25E5}] | - \u{25EF} | - [\u{2605}-\u{2606}] | - \u{2609} | - [\u{260E}-\u{260F}] | - \u{261C} | - \u{261E} | - \u{2640} | - \u{2642} | - [\u{2660}-\u{2661}] | - [\u{2663}-\u{2665}] | - [\u{2667}-\u{266A}] | - [\u{266C}-\u{266D}] | - \u{266F} | - [\u{269E}-\u{269F}] | - \u{26BF} | - [\u{26C6}-\u{26CD}] | - [\u{26CF}-\u{26D3}] | - [\u{26D5}-\u{26E1}] | - \u{26E3} | - [\u{26E8}-\u{26E9}] | - [\u{26EB}-\u{26F1}] | - \u{26F4} | - [\u{26F6}-\u{26F9}] | - [\u{26FB}-\u{26FC}] | - [\u{26FE}-\u{26FF}] | - \u{273D} | - [\u{2776}-\u{277F}] | - [\u{2B56}-\u{2B59}] | - [\u{3248}-\u{324F}] | - [\u{E000}-\u{F8FF}] | - [\u{FE00}-\u{FE0F}] | - \u{FFFD} | - [\u{1F100}-\u{1F10A}] | - [\u{1F110}-\u{1F12D}] | - [\u{1F130}-\u{1F169}] | - [\u{1F170}-\u{1F18D}] | - [\u{1F18F}-\u{1F190}] | - [\u{1F19B}-\u{1F1AC}] | - [\u{E0100}-\u{E01EF}] | - [\u{F0000}-\u{FFFFD}] | - [\u{100000}-\u{10FFFD}] - )/x - - # Neutral - TYPE_N = /^( - [\u{0000}-\u{001F}] | - [\u{007F}-\u{00A0}] | - \u{00A9} | - \u{00AB} | - \u{00B5} | - \u{00BB} | - [\u{00C0}-\u{00C5}] | - [\u{00C7}-\u{00CF}] | - [\u{00D1}-\u{00D6}] | - [\u{00D9}-\u{00DD}] | - [\u{00E2}-\u{00E5}] | - \u{00E7} | - \u{00EB} | - [\u{00EE}-\u{00EF}] | - \u{00F1} | - [\u{00F4}-\u{00F6}] | - \u{00FB} | - \u{00FD} | - [\u{00FF}-\u{0100}] | - [\u{0102}-\u{0110}] | - \u{0112} | - [\u{0114}-\u{011A}] | - [\u{011C}-\u{0125}] | - [\u{0128}-\u{012A}] | - [\u{012C}-\u{0130}] | - [\u{0134}-\u{0137}] | - [\u{0139}-\u{013E}] | - \u{0143} | - [\u{0145}-\u{0147}] | - \u{014C} | - [\u{014E}-\u{0151}] | - [\u{0154}-\u{0165}] | - [\u{0168}-\u{016A}] | - [\u{016C}-\u{01CD}] | - \u{01CF} | - \u{01D1} | - \u{01D3} | - \u{01D5} | - \u{01D7} | - \u{01D9} | - \u{01DB} | - [\u{01DD}-\u{0250}] | - [\u{0252}-\u{0260}] | - [\u{0262}-\u{02C3}] | - [\u{02C5}-\u{02C6}] | - \u{02C8} | - \u{02CC} | - [\u{02CE}-\u{02CF}] | - [\u{02D1}-\u{02D7}] | - \u{02DC} | - \u{02DE} | - [\u{02E0}-\u{02FF}] | - [\u{0370}-\u{0377}] | - [\u{037A}-\u{037F}] | - [\u{0384}-\u{038A}] | - \u{038C} | - [\u{038E}-\u{0390}] | - [\u{03AA}-\u{03B0}] | - \u{03C2} | - [\u{03CA}-\u{0400}] | - [\u{0402}-\u{040F}] | - \u{0450} | - [\u{0452}-\u{052F}] | - [\u{0531}-\u{0556}] | - [\u{0559}-\u{058A}] | - [\u{058D}-\u{058F}] | - [\u{0591}-\u{05C7}] | - [\u{05D0}-\u{05EA}] | - [\u{05EF}-\u{05F4}] | - [\u{0600}-\u{061C}] | - [\u{061E}-\u{070D}] | - [\u{070F}-\u{074A}] | - [\u{074D}-\u{07B1}] | - [\u{07C0}-\u{07FA}] | - [\u{07FD}-\u{082D}] | - [\u{0830}-\u{083E}] | - [\u{0840}-\u{085B}] | - \u{085E} | - [\u{0860}-\u{086A}] | - [\u{08A0}-\u{08B4}] | - [\u{08B6}-\u{08BD}] | - [\u{08D3}-\u{0983}] | - [\u{0985}-\u{098C}] | - [\u{098F}-\u{0990}] | - [\u{0993}-\u{09A8}] | - [\u{09AA}-\u{09B0}] | - \u{09B2} | - [\u{09B6}-\u{09B9}] | - [\u{09BC}-\u{09C4}] | - [\u{09C7}-\u{09C8}] | - [\u{09CB}-\u{09CE}] | - \u{09D7} | - [\u{09DC}-\u{09DD}] | - [\u{09DF}-\u{09E3}] | - [\u{09E6}-\u{09FE}] | - [\u{0A01}-\u{0A03}] | - [\u{0A05}-\u{0A0A}] | - [\u{0A0F}-\u{0A10}] | - [\u{0A13}-\u{0A28}] | - [\u{0A2A}-\u{0A30}] | - [\u{0A32}-\u{0A33}] | - [\u{0A35}-\u{0A36}] | - [\u{0A38}-\u{0A39}] | - \u{0A3C} | - [\u{0A3E}-\u{0A42}] | - [\u{0A47}-\u{0A48}] | - [\u{0A4B}-\u{0A4D}] | - \u{0A51} | - [\u{0A59}-\u{0A5C}] | - \u{0A5E} | - [\u{0A66}-\u{0A76}] | - [\u{0A81}-\u{0A83}] | - [\u{0A85}-\u{0A8D}] | - [\u{0A8F}-\u{0A91}] | - [\u{0A93}-\u{0AA8}] | - [\u{0AAA}-\u{0AB0}] | - [\u{0AB2}-\u{0AB3}] | - [\u{0AB5}-\u{0AB9}] | - [\u{0ABC}-\u{0AC5}] | - [\u{0AC7}-\u{0AC9}] | - [\u{0ACB}-\u{0ACD}] | - \u{0AD0} | - [\u{0AE0}-\u{0AE3}] | - [\u{0AE6}-\u{0AF1}] | - [\u{0AF9}-\u{0AFF}] | - [\u{0B01}-\u{0B03}] | - [\u{0B05}-\u{0B0C}] | - [\u{0B0F}-\u{0B10}] | - [\u{0B13}-\u{0B28}] | - [\u{0B2A}-\u{0B30}] | - [\u{0B32}-\u{0B33}] | - [\u{0B35}-\u{0B39}] | - [\u{0B3C}-\u{0B44}] | - [\u{0B47}-\u{0B48}] | - [\u{0B4B}-\u{0B4D}] | - [\u{0B56}-\u{0B57}] | - [\u{0B5C}-\u{0B5D}] | - [\u{0B5F}-\u{0B63}] | - [\u{0B66}-\u{0B77}] | - [\u{0B82}-\u{0B83}] | - [\u{0B85}-\u{0B8A}] | - [\u{0B8E}-\u{0B90}] | - [\u{0B92}-\u{0B95}] | - [\u{0B99}-\u{0B9A}] | - \u{0B9C} | - [\u{0B9E}-\u{0B9F}] | - [\u{0BA3}-\u{0BA4}] | - [\u{0BA8}-\u{0BAA}] | - [\u{0BAE}-\u{0BB9}] | - [\u{0BBE}-\u{0BC2}] | - [\u{0BC6}-\u{0BC8}] | - [\u{0BCA}-\u{0BCD}] | - \u{0BD0} | - \u{0BD7} | - [\u{0BE6}-\u{0BFA}] | - [\u{0C00}-\u{0C0C}] | - [\u{0C0E}-\u{0C10}] | - [\u{0C12}-\u{0C28}] | - [\u{0C2A}-\u{0C39}] | - [\u{0C3D}-\u{0C44}] | - [\u{0C46}-\u{0C48}] | - [\u{0C4A}-\u{0C4D}] | - [\u{0C55}-\u{0C56}] | - [\u{0C58}-\u{0C5A}] | - [\u{0C60}-\u{0C63}] | - [\u{0C66}-\u{0C6F}] | - [\u{0C77}-\u{0C8C}] | - [\u{0C8E}-\u{0C90}] | - [\u{0C92}-\u{0CA8}] | - [\u{0CAA}-\u{0CB3}] | - [\u{0CB5}-\u{0CB9}] | - [\u{0CBC}-\u{0CC4}] | - [\u{0CC6}-\u{0CC8}] | - [\u{0CCA}-\u{0CCD}] | - [\u{0CD5}-\u{0CD6}] | - \u{0CDE} | - [\u{0CE0}-\u{0CE3}] | - [\u{0CE6}-\u{0CEF}] | - [\u{0CF1}-\u{0CF2}] | - [\u{0D00}-\u{0D03}] | - [\u{0D05}-\u{0D0C}] | - [\u{0D0E}-\u{0D10}] | - [\u{0D12}-\u{0D44}] | - [\u{0D46}-\u{0D48}] | - [\u{0D4A}-\u{0D4F}] | - [\u{0D54}-\u{0D63}] | - [\u{0D66}-\u{0D7F}] | - [\u{0D82}-\u{0D83}] | - [\u{0D85}-\u{0D96}] | - [\u{0D9A}-\u{0DB1}] | - [\u{0DB3}-\u{0DBB}] | - \u{0DBD} | - [\u{0DC0}-\u{0DC6}] | - \u{0DCA} | - [\u{0DCF}-\u{0DD4}] | - \u{0DD6} | - [\u{0DD8}-\u{0DDF}] | - [\u{0DE6}-\u{0DEF}] | - [\u{0DF2}-\u{0DF4}] | - [\u{0E01}-\u{0E3A}] | - [\u{0E3F}-\u{0E5B}] | - [\u{0E81}-\u{0E82}] | - \u{0E84} | - [\u{0E86}-\u{0E8A}] | - [\u{0E8C}-\u{0EA3}] | - \u{0EA5} | - [\u{0EA7}-\u{0EBD}] | - [\u{0EC0}-\u{0EC4}] | - \u{0EC6} | - [\u{0EC8}-\u{0ECD}] | - [\u{0ED0}-\u{0ED9}] | - [\u{0EDC}-\u{0EDF}] | - [\u{0F00}-\u{0F47}] | - [\u{0F49}-\u{0F6C}] | - [\u{0F71}-\u{0F97}] | - [\u{0F99}-\u{0FBC}] | - [\u{0FBE}-\u{0FCC}] | - [\u{0FCE}-\u{0FDA}] | - [\u{1000}-\u{10C5}] | - \u{10C7} | - \u{10CD} | - [\u{10D0}-\u{10FF}] | - [\u{1160}-\u{1248}] | - [\u{124A}-\u{124D}] | - [\u{1250}-\u{1256}] | - \u{1258} | - [\u{125A}-\u{125D}] | - [\u{1260}-\u{1288}] | - [\u{128A}-\u{128D}] | - [\u{1290}-\u{12B0}] | - [\u{12B2}-\u{12B5}] | - [\u{12B8}-\u{12BE}] | - \u{12C0} | - [\u{12C2}-\u{12C5}] | - [\u{12C8}-\u{12D6}] | - [\u{12D8}-\u{1310}] | - [\u{1312}-\u{1315}] | - [\u{1318}-\u{135A}] | - [\u{135D}-\u{137C}] | - [\u{1380}-\u{1399}] | - [\u{13A0}-\u{13F5}] | - [\u{13F8}-\u{13FD}] | - [\u{1400}-\u{169C}] | - [\u{16A0}-\u{16F8}] | - [\u{1700}-\u{170C}] | - [\u{170E}-\u{1714}] | - [\u{1720}-\u{1736}] | - [\u{1740}-\u{1753}] | - [\u{1760}-\u{176C}] | - [\u{176E}-\u{1770}] | - [\u{1772}-\u{1773}] | - [\u{1780}-\u{17DD}] | - [\u{17E0}-\u{17E9}] | - [\u{17F0}-\u{17F9}] | - [\u{1800}-\u{180E}] | - [\u{1810}-\u{1819}] | - [\u{1820}-\u{1878}] | - [\u{1880}-\u{18AA}] | - [\u{18B0}-\u{18F5}] | - [\u{1900}-\u{191E}] | - [\u{1920}-\u{192B}] | - [\u{1930}-\u{193B}] | - \u{1940} | - [\u{1944}-\u{196D}] | - [\u{1970}-\u{1974}] | - [\u{1980}-\u{19AB}] | - [\u{19B0}-\u{19C9}] | - [\u{19D0}-\u{19DA}] | - [\u{19DE}-\u{1A1B}] | - [\u{1A1E}-\u{1A5E}] | - [\u{1A60}-\u{1A7C}] | - [\u{1A7F}-\u{1A89}] | - [\u{1A90}-\u{1A99}] | - [\u{1AA0}-\u{1AAD}] | - [\u{1AB0}-\u{1ABE}] | - [\u{1B00}-\u{1B4B}] | - [\u{1B50}-\u{1B7C}] | - [\u{1B80}-\u{1BF3}] | - [\u{1BFC}-\u{1C37}] | - [\u{1C3B}-\u{1C49}] | - [\u{1C4D}-\u{1C88}] | - [\u{1C90}-\u{1CBA}] | - [\u{1CBD}-\u{1CC7}] | - [\u{1CD0}-\u{1CFA}] | - [\u{1D00}-\u{1DF9}] | - [\u{1DFB}-\u{1F15}] | - [\u{1F18}-\u{1F1D}] | - [\u{1F20}-\u{1F45}] | - [\u{1F48}-\u{1F4D}] | - [\u{1F50}-\u{1F57}] | - \u{1F59} | - \u{1F5B} | - \u{1F5D} | - [\u{1F5F}-\u{1F7D}] | - [\u{1F80}-\u{1FB4}] | - [\u{1FB6}-\u{1FC4}] | - [\u{1FC6}-\u{1FD3}] | - [\u{1FD6}-\u{1FDB}] | - [\u{1FDD}-\u{1FEF}] | - [\u{1FF2}-\u{1FF4}] | - [\u{1FF6}-\u{1FFE}] | - [\u{2000}-\u{200F}] | - [\u{2011}-\u{2012}] | - \u{2017} | - [\u{201A}-\u{201B}] | - [\u{201E}-\u{201F}] | - \u{2023} | - [\u{2028}-\u{202F}] | - \u{2031} | - \u{2034} | - [\u{2036}-\u{203A}] | - [\u{203C}-\u{203D}] | - [\u{203F}-\u{2064}] | - [\u{2066}-\u{2071}] | - [\u{2075}-\u{207E}] | - \u{2080} | - [\u{2085}-\u{208E}] | - [\u{2090}-\u{209C}] | - [\u{20A0}-\u{20A8}] | - [\u{20AA}-\u{20AB}] | - [\u{20AD}-\u{20BF}] | - [\u{20D0}-\u{20F0}] | - [\u{2100}-\u{2102}] | - \u{2104} | - [\u{2106}-\u{2108}] | - [\u{210A}-\u{2112}] | - [\u{2114}-\u{2115}] | - [\u{2117}-\u{2120}] | - [\u{2123}-\u{2125}] | - [\u{2127}-\u{212A}] | - [\u{212C}-\u{2152}] | - [\u{2155}-\u{215A}] | - \u{215F} | - [\u{216C}-\u{216F}] | - [\u{217A}-\u{2188}] | - [\u{218A}-\u{218B}] | - [\u{219A}-\u{21B7}] | - [\u{21BA}-\u{21D1}] | - \u{21D3} | - [\u{21D5}-\u{21E6}] | - [\u{21E8}-\u{21FF}] | - \u{2201} | - [\u{2204}-\u{2206}] | - [\u{2209}-\u{220A}] | - [\u{220C}-\u{220E}] | - \u{2210} | - [\u{2212}-\u{2214}] | - [\u{2216}-\u{2219}] | - [\u{221B}-\u{221C}] | - [\u{2221}-\u{2222}] | - \u{2224} | - \u{2226} | - \u{222D} | - [\u{222F}-\u{2233}] | - [\u{2238}-\u{223B}] | - [\u{223E}-\u{2247}] | - [\u{2249}-\u{224B}] | - [\u{224D}-\u{2251}] | - [\u{2253}-\u{225F}] | - [\u{2262}-\u{2263}] | - [\u{2268}-\u{2269}] | - [\u{226C}-\u{226D}] | - [\u{2270}-\u{2281}] | - [\u{2284}-\u{2285}] | - [\u{2288}-\u{2294}] | - [\u{2296}-\u{2298}] | - [\u{229A}-\u{22A4}] | - [\u{22A6}-\u{22BE}] | - [\u{22C0}-\u{2311}] | - [\u{2313}-\u{2319}] | - [\u{231C}-\u{2328}] | - [\u{232B}-\u{23E8}] | - [\u{23ED}-\u{23EF}] | - [\u{23F1}-\u{23F2}] | - [\u{23F4}-\u{2426}] | - [\u{2440}-\u{244A}] | - \u{24EA} | - [\u{254C}-\u{254F}] | - [\u{2574}-\u{257F}] | - [\u{2590}-\u{2591}] | - [\u{2596}-\u{259F}] | - \u{25A2} | - [\u{25AA}-\u{25B1}] | - [\u{25B4}-\u{25B5}] | - [\u{25B8}-\u{25BB}] | - [\u{25BE}-\u{25BF}] | - [\u{25C2}-\u{25C5}] | - [\u{25C9}-\u{25CA}] | - [\u{25CC}-\u{25CD}] | - [\u{25D2}-\u{25E1}] | - [\u{25E6}-\u{25EE}] | - [\u{25F0}-\u{25FC}] | - [\u{25FF}-\u{2604}] | - [\u{2607}-\u{2608}] | - [\u{260A}-\u{260D}] | - [\u{2610}-\u{2613}] | - [\u{2616}-\u{261B}] | - \u{261D} | - [\u{261F}-\u{263F}] | - \u{2641} | - [\u{2643}-\u{2647}] | - [\u{2654}-\u{265F}] | - \u{2662} | - \u{2666} | - \u{266B} | - \u{266E} | - [\u{2670}-\u{267E}] | - [\u{2680}-\u{2692}] | - [\u{2694}-\u{269D}] | - \u{26A0} | - [\u{26A2}-\u{26A9}] | - [\u{26AC}-\u{26BC}] | - [\u{26C0}-\u{26C3}] | - \u{26E2} | - [\u{26E4}-\u{26E7}] | - [\u{2700}-\u{2704}] | - [\u{2706}-\u{2709}] | - [\u{270C}-\u{2727}] | - [\u{2729}-\u{273C}] | - [\u{273E}-\u{274B}] | - \u{274D} | - [\u{274F}-\u{2752}] | - \u{2756} | - [\u{2758}-\u{2775}] | - [\u{2780}-\u{2794}] | - [\u{2798}-\u{27AF}] | - [\u{27B1}-\u{27BE}] | - [\u{27C0}-\u{27E5}] | - [\u{27EE}-\u{2984}] | - [\u{2987}-\u{2B1A}] | - [\u{2B1D}-\u{2B4F}] | - [\u{2B51}-\u{2B54}] | - [\u{2B5A}-\u{2B73}] | - [\u{2B76}-\u{2B95}] | - [\u{2B98}-\u{2C2E}] | - [\u{2C30}-\u{2C5E}] | - [\u{2C60}-\u{2CF3}] | - [\u{2CF9}-\u{2D25}] | - \u{2D27} | - \u{2D2D} | - [\u{2D30}-\u{2D67}] | - [\u{2D6F}-\u{2D70}] | - [\u{2D7F}-\u{2D96}] | - [\u{2DA0}-\u{2DA6}] | - [\u{2DA8}-\u{2DAE}] | - [\u{2DB0}-\u{2DB6}] | - [\u{2DB8}-\u{2DBE}] | - [\u{2DC0}-\u{2DC6}] | - [\u{2DC8}-\u{2DCE}] | - [\u{2DD0}-\u{2DD6}] | - [\u{2DD8}-\u{2DDE}] | - [\u{2DE0}-\u{2E4F}] | - \u{303F} | - [\u{4DC0}-\u{4DFF}] | - [\u{A4D0}-\u{A62B}] | - [\u{A640}-\u{A6F7}] | - [\u{A700}-\u{A7BF}] | - [\u{A7C2}-\u{A7C6}] | - [\u{A7F7}-\u{A82B}] | - [\u{A830}-\u{A839}] | - [\u{A840}-\u{A877}] | - [\u{A880}-\u{A8C5}] | - [\u{A8CE}-\u{A8D9}] | - [\u{A8E0}-\u{A953}] | - \u{A95F} | - [\u{A980}-\u{A9CD}] | - [\u{A9CF}-\u{A9D9}] | - [\u{A9DE}-\u{A9FE}] | - [\u{AA00}-\u{AA36}] | - [\u{AA40}-\u{AA4D}] | - [\u{AA50}-\u{AA59}] | - [\u{AA5C}-\u{AAC2}] | - [\u{AADB}-\u{AAF6}] | - [\u{AB01}-\u{AB06}] | - [\u{AB09}-\u{AB0E}] | - [\u{AB11}-\u{AB16}] | - [\u{AB20}-\u{AB26}] | - [\u{AB28}-\u{AB2E}] | - [\u{AB30}-\u{AB67}] | - [\u{AB70}-\u{ABED}] | - [\u{ABF0}-\u{ABF9}] | - [\u{D7B0}-\u{D7C6}] | - [\u{D7CB}-\u{D7FB}] | - [\u{FB00}-\u{FB06}] | - [\u{FB13}-\u{FB17}] | - [\u{FB1D}-\u{FB36}] | - [\u{FB38}-\u{FB3C}] | - \u{FB3E} | - [\u{FB40}-\u{FB41}] | - [\u{FB43}-\u{FB44}] | - [\u{FB46}-\u{FBC1}] | - [\u{FBD3}-\u{FD3F}] | - [\u{FD50}-\u{FD8F}] | - [\u{FD92}-\u{FDC7}] | - [\u{FDF0}-\u{FDFD}] | - [\u{FE20}-\u{FE2F}] | - [\u{FE70}-\u{FE74}] | - [\u{FE76}-\u{FEFC}] | - \u{FEFF} | - [\u{FFF9}-\u{FFFC}] | - [\u{10000}-\u{1000B}] | - [\u{1000D}-\u{10026}] | - [\u{10028}-\u{1003A}] | - [\u{1003C}-\u{1003D}] | - [\u{1003F}-\u{1004D}] | - [\u{10050}-\u{1005D}] | - [\u{10080}-\u{100FA}] | - [\u{10100}-\u{10102}] | - [\u{10107}-\u{10133}] | - [\u{10137}-\u{1018E}] | - [\u{10190}-\u{1019B}] | - \u{101A0} | - [\u{101D0}-\u{101FD}] | - [\u{10280}-\u{1029C}] | - [\u{102A0}-\u{102D0}] | - [\u{102E0}-\u{102FB}] | - [\u{10300}-\u{10323}] | - [\u{1032D}-\u{1034A}] | - [\u{10350}-\u{1037A}] | - [\u{10380}-\u{1039D}] | - [\u{1039F}-\u{103C3}] | - [\u{103C8}-\u{103D5}] | - [\u{10400}-\u{1049D}] | - [\u{104A0}-\u{104A9}] | - [\u{104B0}-\u{104D3}] | - [\u{104D8}-\u{104FB}] | - [\u{10500}-\u{10527}] | - [\u{10530}-\u{10563}] | - \u{1056F} | - [\u{10600}-\u{10736}] | - [\u{10740}-\u{10755}] | - [\u{10760}-\u{10767}] | - [\u{10800}-\u{10805}] | - \u{10808} | - [\u{1080A}-\u{10835}] | - [\u{10837}-\u{10838}] | - \u{1083C} | - [\u{1083F}-\u{10855}] | - [\u{10857}-\u{1089E}] | - [\u{108A7}-\u{108AF}] | - [\u{108E0}-\u{108F2}] | - [\u{108F4}-\u{108F5}] | - [\u{108FB}-\u{1091B}] | - [\u{1091F}-\u{10939}] | - \u{1093F} | - [\u{10980}-\u{109B7}] | - [\u{109BC}-\u{109CF}] | - [\u{109D2}-\u{10A03}] | - [\u{10A05}-\u{10A06}] | - [\u{10A0C}-\u{10A13}] | - [\u{10A15}-\u{10A17}] | - [\u{10A19}-\u{10A35}] | - [\u{10A38}-\u{10A3A}] | - [\u{10A3F}-\u{10A48}] | - [\u{10A50}-\u{10A58}] | - [\u{10A60}-\u{10A9F}] | - [\u{10AC0}-\u{10AE6}] | - [\u{10AEB}-\u{10AF6}] | - [\u{10B00}-\u{10B35}] | - [\u{10B39}-\u{10B55}] | - [\u{10B58}-\u{10B72}] | - [\u{10B78}-\u{10B91}] | - [\u{10B99}-\u{10B9C}] | - [\u{10BA9}-\u{10BAF}] | - [\u{10C00}-\u{10C48}] | - [\u{10C80}-\u{10CB2}] | - [\u{10CC0}-\u{10CF2}] | - [\u{10CFA}-\u{10D27}] | - [\u{10D30}-\u{10D39}] | - [\u{10E60}-\u{10E7E}] | - [\u{10F00}-\u{10F27}] | - [\u{10F30}-\u{10F59}] | - [\u{10FE0}-\u{10FF6}] | - [\u{11000}-\u{1104D}] | - [\u{11052}-\u{1106F}] | - [\u{1107F}-\u{110C1}] | - \u{110CD} | - [\u{110D0}-\u{110E8}] | - [\u{110F0}-\u{110F9}] | - [\u{11100}-\u{11134}] | - [\u{11136}-\u{11146}] | - [\u{11150}-\u{11176}] | - [\u{11180}-\u{111CD}] | - [\u{111D0}-\u{111DF}] | - [\u{111E1}-\u{111F4}] | - [\u{11200}-\u{11211}] | - [\u{11213}-\u{1123E}] | - [\u{11280}-\u{11286}] | - \u{11288} | - [\u{1128A}-\u{1128D}] | - [\u{1128F}-\u{1129D}] | - [\u{1129F}-\u{112A9}] | - [\u{112B0}-\u{112EA}] | - [\u{112F0}-\u{112F9}] | - [\u{11300}-\u{11303}] | - [\u{11305}-\u{1130C}] | - [\u{1130F}-\u{11310}] | - [\u{11313}-\u{11328}] | - [\u{1132A}-\u{11330}] | - [\u{11332}-\u{11333}] | - [\u{11335}-\u{11339}] | - [\u{1133B}-\u{11344}] | - [\u{11347}-\u{11348}] | - [\u{1134B}-\u{1134D}] | - \u{11350} | - \u{11357} | - [\u{1135D}-\u{11363}] | - [\u{11366}-\u{1136C}] | - [\u{11370}-\u{11374}] | - [\u{11400}-\u{11459}] | - \u{1145B} | - [\u{1145D}-\u{1145F}] | - [\u{11480}-\u{114C7}] | - [\u{114D0}-\u{114D9}] | - [\u{11580}-\u{115B5}] | - [\u{115B8}-\u{115DD}] | - [\u{11600}-\u{11644}] | - [\u{11650}-\u{11659}] | - [\u{11660}-\u{1166C}] | - [\u{11680}-\u{116B8}] | - [\u{116C0}-\u{116C9}] | - [\u{11700}-\u{1171A}] | - [\u{1171D}-\u{1172B}] | - [\u{11730}-\u{1173F}] | - [\u{11800}-\u{1183B}] | - [\u{118A0}-\u{118F2}] | - \u{118FF} | - [\u{119A0}-\u{119A7}] | - [\u{119AA}-\u{119D7}] | - [\u{119DA}-\u{119E4}] | - [\u{11A00}-\u{11A47}] | - [\u{11A50}-\u{11AA2}] | - [\u{11AC0}-\u{11AF8}] | - [\u{11C00}-\u{11C08}] | - [\u{11C0A}-\u{11C36}] | - [\u{11C38}-\u{11C45}] | - [\u{11C50}-\u{11C6C}] | - [\u{11C70}-\u{11C8F}] | - [\u{11C92}-\u{11CA7}] | - [\u{11CA9}-\u{11CB6}] | - [\u{11D00}-\u{11D06}] | - [\u{11D08}-\u{11D09}] | - [\u{11D0B}-\u{11D36}] | - \u{11D3A} | - [\u{11D3C}-\u{11D3D}] | - [\u{11D3F}-\u{11D47}] | - [\u{11D50}-\u{11D59}] | - [\u{11D60}-\u{11D65}] | - [\u{11D67}-\u{11D68}] | - [\u{11D6A}-\u{11D8E}] | - [\u{11D90}-\u{11D91}] | - [\u{11D93}-\u{11D98}] | - [\u{11DA0}-\u{11DA9}] | - [\u{11EE0}-\u{11EF8}] | - [\u{11FC0}-\u{11FF1}] | - [\u{11FFF}-\u{12399}] | - [\u{12400}-\u{1246E}] | - [\u{12470}-\u{12474}] | - [\u{12480}-\u{12543}] | - [\u{13000}-\u{1342E}] | - [\u{13430}-\u{13438}] | - [\u{14400}-\u{14646}] | - [\u{16800}-\u{16A38}] | - [\u{16A40}-\u{16A5E}] | - [\u{16A60}-\u{16A69}] | - [\u{16A6E}-\u{16A6F}] | - [\u{16AD0}-\u{16AED}] | - [\u{16AF0}-\u{16AF5}] | - [\u{16B00}-\u{16B45}] | - [\u{16B50}-\u{16B59}] | - [\u{16B5B}-\u{16B61}] | - [\u{16B63}-\u{16B77}] | - [\u{16B7D}-\u{16B8F}] | - [\u{16E40}-\u{16E9A}] | - [\u{16F00}-\u{16F4A}] | - [\u{16F4F}-\u{16F87}] | - [\u{16F8F}-\u{16F9F}] | - [\u{1BC00}-\u{1BC6A}] | - [\u{1BC70}-\u{1BC7C}] | - [\u{1BC80}-\u{1BC88}] | - [\u{1BC90}-\u{1BC99}] | - [\u{1BC9C}-\u{1BCA3}] | - [\u{1D000}-\u{1D0F5}] | - [\u{1D100}-\u{1D126}] | - [\u{1D129}-\u{1D1E8}] | - [\u{1D200}-\u{1D245}] | - [\u{1D2E0}-\u{1D2F3}] | - [\u{1D300}-\u{1D356}] | - [\u{1D360}-\u{1D378}] | - [\u{1D400}-\u{1D454}] | - [\u{1D456}-\u{1D49C}] | - [\u{1D49E}-\u{1D49F}] | - \u{1D4A2} | - [\u{1D4A5}-\u{1D4A6}] | - [\u{1D4A9}-\u{1D4AC}] | - [\u{1D4AE}-\u{1D4B9}] | - \u{1D4BB} | - [\u{1D4BD}-\u{1D4C3}] | - [\u{1D4C5}-\u{1D505}] | - [\u{1D507}-\u{1D50A}] | - [\u{1D50D}-\u{1D514}] | - [\u{1D516}-\u{1D51C}] | - [\u{1D51E}-\u{1D539}] | - [\u{1D53B}-\u{1D53E}] | - [\u{1D540}-\u{1D544}] | - \u{1D546} | - [\u{1D54A}-\u{1D550}] | - [\u{1D552}-\u{1D6A5}] | - [\u{1D6A8}-\u{1D7CB}] | - [\u{1D7CE}-\u{1DA8B}] | - [\u{1DA9B}-\u{1DA9F}] | - [\u{1DAA1}-\u{1DAAF}] | - [\u{1E000}-\u{1E006}] | - [\u{1E008}-\u{1E018}] | - [\u{1E01B}-\u{1E021}] | - [\u{1E023}-\u{1E024}] | - [\u{1E026}-\u{1E02A}] | - [\u{1E100}-\u{1E12C}] | - [\u{1E130}-\u{1E13D}] | - [\u{1E140}-\u{1E149}] | - [\u{1E14E}-\u{1E14F}] | - [\u{1E2C0}-\u{1E2F9}] | - \u{1E2FF} | - [\u{1E800}-\u{1E8C4}] | - [\u{1E8C7}-\u{1E8D6}] | - [\u{1E900}-\u{1E94B}] | - [\u{1E950}-\u{1E959}] | - [\u{1E95E}-\u{1E95F}] | - [\u{1EC71}-\u{1ECB4}] | - [\u{1ED01}-\u{1ED3D}] | - [\u{1EE00}-\u{1EE03}] | - [\u{1EE05}-\u{1EE1F}] | - [\u{1EE21}-\u{1EE22}] | - \u{1EE24} | - \u{1EE27} | - [\u{1EE29}-\u{1EE32}] | - [\u{1EE34}-\u{1EE37}] | - \u{1EE39} | - \u{1EE3B} | - \u{1EE42} | - \u{1EE47} | - \u{1EE49} | - \u{1EE4B} | - [\u{1EE4D}-\u{1EE4F}] | - [\u{1EE51}-\u{1EE52}] | - \u{1EE54} | - \u{1EE57} | - \u{1EE59} | - \u{1EE5B} | - \u{1EE5D} | - \u{1EE5F} | - [\u{1EE61}-\u{1EE62}] | - \u{1EE64} | - [\u{1EE67}-\u{1EE6A}] | - [\u{1EE6C}-\u{1EE72}] | - [\u{1EE74}-\u{1EE77}] | - [\u{1EE79}-\u{1EE7C}] | - \u{1EE7E} | - [\u{1EE80}-\u{1EE89}] | - [\u{1EE8B}-\u{1EE9B}] | - [\u{1EEA1}-\u{1EEA3}] | - [\u{1EEA5}-\u{1EEA9}] | - [\u{1EEAB}-\u{1EEBB}] | - [\u{1EEF0}-\u{1EEF1}] | - [\u{1F000}-\u{1F003}] | - [\u{1F005}-\u{1F02B}] | - [\u{1F030}-\u{1F093}] | - [\u{1F0A0}-\u{1F0AE}] | - [\u{1F0B1}-\u{1F0BF}] | - [\u{1F0C1}-\u{1F0CE}] | - [\u{1F0D1}-\u{1F0F5}] | - [\u{1F10B}-\u{1F10C}] | - [\u{1F12E}-\u{1F12F}] | - [\u{1F16A}-\u{1F16C}] | - [\u{1F1E6}-\u{1F1FF}] | - [\u{1F321}-\u{1F32C}] | - \u{1F336} | - \u{1F37D} | - [\u{1F394}-\u{1F39F}] | - [\u{1F3CB}-\u{1F3CE}] | - [\u{1F3D4}-\u{1F3DF}] | - [\u{1F3F1}-\u{1F3F3}] | - [\u{1F3F5}-\u{1F3F7}] | - \u{1F43F} | - \u{1F441} | - [\u{1F4FD}-\u{1F4FE}] | - [\u{1F53E}-\u{1F54A}] | - \u{1F54F} | - [\u{1F568}-\u{1F579}] | - [\u{1F57B}-\u{1F594}] | - [\u{1F597}-\u{1F5A3}] | - [\u{1F5A5}-\u{1F5FA}] | - [\u{1F650}-\u{1F67F}] | - [\u{1F6C6}-\u{1F6CB}] | - [\u{1F6CD}-\u{1F6CF}] | - [\u{1F6D3}-\u{1F6D4}] | - [\u{1F6E0}-\u{1F6EA}] | - [\u{1F6F0}-\u{1F6F3}] | - [\u{1F700}-\u{1F773}] | - [\u{1F780}-\u{1F7D8}] | - [\u{1F800}-\u{1F80B}] | - [\u{1F810}-\u{1F847}] | - [\u{1F850}-\u{1F859}] | - [\u{1F860}-\u{1F887}] | - [\u{1F890}-\u{1F8AD}] | - [\u{1F900}-\u{1F90B}] | - [\u{1FA00}-\u{1FA53}] | - [\u{1FA60}-\u{1FA6D}] | - \u{E0001} | - [\u{E0020}-\u{E007F}] - )/x -end diff --git a/lib/reline/version.rb b/lib/reline/version.rb deleted file mode 100644 index 58a69a09a0..0000000000 --- a/lib/reline/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Reline - VERSION = '0.0.0' -end diff --git a/lib/reline/windows.rb b/lib/reline/windows.rb deleted file mode 100644 index f41ec17489..0000000000 --- a/lib/reline/windows.rb +++ /dev/null @@ -1,132 +0,0 @@ -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 diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 16cdb7cb04..54bd995b83 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -18,7 +18,6 @@ require 'rubygems/compatibility' require 'rubygems/defaults' require 'rubygems/deprecate' require 'rubygems/errors' -require 'rubygems/path_support' ## # RubyGems is the Ruby standard for publishing and managing third party |