summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2019-04-28 06:37:39 +0900
committeraycabta <aycabta@gmail.com>2019-05-25 02:16:19 +0900
commit260235ce871c3e7718af8d612f1a8ed400b56070 (patch)
tree4852bd597db06acd5c95f76d4e315f66f007884d /lib
parentff43b2262702e828e2008ba65e68b331d263e3d0 (diff)
Use Reline as Reidline multiline editor in IRB
Diffstat (limited to 'lib')
-rw-r--r--lib/irb.rb6
-rw-r--r--lib/irb/completion.rb8
-rw-r--r--lib/irb/context.rb61
-rw-r--r--lib/irb/init.rb4
-rw-r--r--lib/irb/input-method.rb84
-rw-r--r--lib/irb/ruby-lex.rb3
6 files changed, 142 insertions, 24 deletions
diff --git a/lib/irb.rb b/lib/irb.rb
index 773d0d07a4..1badb9b394 100644
--- a/lib/irb.rb
+++ b/lib/irb.rb
@@ -60,6 +60,8 @@ 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
# --colorize Use colorization
@@ -69,7 +71,7 @@ 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 --readline.
+# Suppresses --reidline and --readline.
# --simple-prompt Simple prompt mode
# --noprompt No prompt mode
# --tracer Display trace for each execution of commands.
@@ -97,6 +99,7 @@ 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_COLORIZE] = true
# IRB.conf[:USE_TRACER] = false
@@ -412,7 +415,6 @@ module IRB
@context = Context.new(self, workspace, input_method, output_method)
@context.main.extend ExtendCommandBundle
@signal_status = :IN_IRB
-
@scanner = RubyLex.new
end
diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb
index 390e7254dd..289180a3b2 100644
--- a/lib/irb/completion.rb
+++ b/lib/irb/completion.rb
@@ -35,6 +35,8 @@ module IRB
yield
]
+ BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
+
CompletionProc = proc { |input|
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
@@ -236,9 +238,3 @@ 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 7037b2bd66..571df2c21a 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 Readline
+ # +nil+:: uses stdin or Reidline or Readline
# +String+:: uses a File
# +other+:: uses this as InputMethod
def initialize(irb, workspace = nil, input_method = nil, output_method = nil)
@@ -40,6 +40,7 @@ module IRB
@load_modules = IRB.conf[:LOAD_MODULES]
@use_readline = IRB.conf[:USE_READLINE]
+ @use_reidline = IRB.conf[:USE_REIDLINE]
@use_colorize = IRB.conf[:USE_COLORIZE]
@verbose = IRB.conf[:VERBOSE]
@io = nil
@@ -65,23 +66,41 @@ module IRB
case input_method
when nil
- case use_readline?
+ @io = nil
+ case use_reidline?
when nil
- if (defined?(ReadlineInputMethod) && STDIN.tty? &&
- IRB.conf[:PROMPT_MODE] != :INF_RUBY)
- @io = ReadlineInputMethod.new
+ if STDIN.tty? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_readline?
+ @io = ReidlineInputMethod.new
else
- @io = StdioInputMethod.new
+ @io = nil
end
when false
- @io = StdioInputMethod.new
+ @io = nil
when true
- if defined?(ReadlineInputMethod)
- @io = ReadlineInputMethod.new
+ @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
else
- @io = StdioInputMethod.new
+ @io = nil
end
end
+ @io = StdioInputMethod.new unless @io
when String
@io = FileInputMethod.new(input_method)
@@ -117,9 +136,9 @@ module IRB
attr_reader :thread
# The current input method
#
- # Can be either StdioInputMethod, ReadlineInputMethod, FileInputMethod or
- # other specified when the context is created. See ::new for more
- # information on +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+.
attr_accessor :io
# Current irb session
@@ -137,6 +156,12 @@ 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>
@@ -225,6 +250,8 @@ 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 #use_colorize
@@ -238,7 +265,9 @@ module IRB
# Returns whether messages are displayed or not.
def verbose?
if @verbose.nil?
- if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
+ if @io.kind_of?(ReidlineInputMethod)
+ false
+ elsif defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
false
elsif !STDIN.tty? or @io.kind_of?(FileInputMethod)
true
@@ -251,9 +280,11 @@ module IRB
end
# Whether #verbose? is +true+, and +input_method+ is either
- # StdioInputMethod or ReadlineInputMethod, see #io for more information.
+ # StdioInputMethod or ReidlineInputMethod 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
diff --git a/lib/irb/init.rb b/lib/irb/init.rb
index d2e325b86e..50a4d7b3bb 100644
--- a/lib/irb/init.rb
+++ b/lib/irb/init.rb
@@ -164,6 +164,10 @@ 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"
diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb
index f491d5a760..bb0930495f 100644
--- a/lib/irb/input-method.rb
+++ b/lib/irb/input-method.rb
@@ -11,6 +11,8 @@
#
require_relative 'src_encoding'
require_relative 'magic-file'
+require_relative 'completion'
+require 'reline'
module IRB
STDIN_FILE_NAME = "(line)" # :nodoc:
@@ -140,6 +142,12 @@ 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.
@@ -186,7 +194,83 @@ 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
+ 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/ruby-lex.rb b/lib/irb/ruby-lex.rb
index 7b933662f9..71d69348fb 100644
--- a/lib/irb/ruby-lex.rb
+++ b/lib/irb/ruby-lex.rb
@@ -32,6 +32,7 @@ class RubyLex
@io = io
if @io.respond_to?(:check_termination)
@io.check_termination do |code|
+ code.gsub!(/\s*\z/, '').concat("\n")
@tokens = Ripper.lex(code)
continue = process_continue
code_block_open = check_code_block(code)
@@ -116,7 +117,7 @@ class RubyLex
return line # multiline
end
code = @line + (line.nil? ? '' : line)
- code.gsub!(/\n*$/, '').concat("\n")
+ code.gsub!(/\s*\z/, '').concat("\n")
@tokens = Ripper.lex(code)
@continue = process_continue
@code_block_open = check_code_block(code)