mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Use Reline as Reidline multiline editor in IRB
This commit is contained in:
parent
ff43b22627
commit
260235ce87
6 changed files with 142 additions and 24 deletions
|
|
@ -60,6 +60,8 @@ require "irb/version"
|
||||||
# -W[level=2] Same as `ruby -W`
|
# -W[level=2] Same as `ruby -W`
|
||||||
# --inspect Use `inspect' for output (default except for bc mode)
|
# --inspect Use `inspect' for output (default except for bc mode)
|
||||||
# --noinspect Don't use inspect for output
|
# --noinspect Don't use inspect for output
|
||||||
|
# --reidline Use Reidline extension module
|
||||||
|
# --noreidline Don't use Reidline extension module
|
||||||
# --readline Use Readline extension module
|
# --readline Use Readline extension module
|
||||||
# --noreadline Don't use Readline extension module
|
# --noreadline Don't use Readline extension module
|
||||||
# --colorize Use colorization
|
# --colorize Use colorization
|
||||||
|
|
@ -69,7 +71,7 @@ require "irb/version"
|
||||||
# Switch prompt mode. Pre-defined prompt modes are
|
# Switch prompt mode. Pre-defined prompt modes are
|
||||||
# `default', `simple', `xmp' and `inf-ruby'
|
# `default', `simple', `xmp' and `inf-ruby'
|
||||||
# --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
|
# --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
|
||||||
# Suppresses --readline.
|
# Suppresses --reidline and --readline.
|
||||||
# --simple-prompt Simple prompt mode
|
# --simple-prompt Simple prompt mode
|
||||||
# --noprompt No prompt mode
|
# --noprompt No prompt mode
|
||||||
# --tracer Display trace for each execution of commands.
|
# --tracer Display trace for each execution of commands.
|
||||||
|
|
@ -97,6 +99,7 @@ require "irb/version"
|
||||||
# IRB.conf[:IRB_RC] = nil
|
# IRB.conf[:IRB_RC] = nil
|
||||||
# IRB.conf[:BACK_TRACE_LIMIT]=16
|
# IRB.conf[:BACK_TRACE_LIMIT]=16
|
||||||
# IRB.conf[:USE_LOADER] = false
|
# IRB.conf[:USE_LOADER] = false
|
||||||
|
# IRB.conf[:USE_REIDLINE] = nil
|
||||||
# IRB.conf[:USE_READLINE] = nil
|
# IRB.conf[:USE_READLINE] = nil
|
||||||
# IRB.conf[:USE_COLORIZE] = true
|
# IRB.conf[:USE_COLORIZE] = true
|
||||||
# IRB.conf[:USE_TRACER] = false
|
# IRB.conf[:USE_TRACER] = false
|
||||||
|
|
@ -412,7 +415,6 @@ module IRB
|
||||||
@context = Context.new(self, workspace, input_method, output_method)
|
@context = Context.new(self, workspace, input_method, output_method)
|
||||||
@context.main.extend ExtendCommandBundle
|
@context.main.extend ExtendCommandBundle
|
||||||
@signal_status = :IN_IRB
|
@signal_status = :IN_IRB
|
||||||
|
|
||||||
@scanner = RubyLex.new
|
@scanner = RubyLex.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ module IRB
|
||||||
yield
|
yield
|
||||||
]
|
]
|
||||||
|
|
||||||
|
BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
|
||||||
|
|
||||||
CompletionProc = proc { |input|
|
CompletionProc = proc { |input|
|
||||||
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
|
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
|
||||||
|
|
||||||
|
|
@ -236,9 +238,3 @@ module IRB
|
||||||
end
|
end
|
||||||
end
|
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
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ module IRB
|
||||||
#
|
#
|
||||||
# The optional +input_method+ argument:
|
# The optional +input_method+ argument:
|
||||||
#
|
#
|
||||||
# +nil+:: uses stdin or Readline
|
# +nil+:: uses stdin or Reidline or Readline
|
||||||
# +String+:: uses a File
|
# +String+:: uses a File
|
||||||
# +other+:: uses this as InputMethod
|
# +other+:: uses this as InputMethod
|
||||||
def initialize(irb, workspace = nil, input_method = nil, output_method = nil)
|
def initialize(irb, workspace = nil, input_method = nil, output_method = nil)
|
||||||
|
|
@ -40,6 +40,7 @@ module IRB
|
||||||
@load_modules = IRB.conf[:LOAD_MODULES]
|
@load_modules = IRB.conf[:LOAD_MODULES]
|
||||||
|
|
||||||
@use_readline = IRB.conf[:USE_READLINE]
|
@use_readline = IRB.conf[:USE_READLINE]
|
||||||
|
@use_reidline = IRB.conf[:USE_REIDLINE]
|
||||||
@use_colorize = IRB.conf[:USE_COLORIZE]
|
@use_colorize = IRB.conf[:USE_COLORIZE]
|
||||||
@verbose = IRB.conf[:VERBOSE]
|
@verbose = IRB.conf[:VERBOSE]
|
||||||
@io = nil
|
@io = nil
|
||||||
|
|
@ -65,23 +66,41 @@ module IRB
|
||||||
|
|
||||||
case input_method
|
case input_method
|
||||||
when nil
|
when nil
|
||||||
|
@io = nil
|
||||||
|
case use_reidline?
|
||||||
|
when nil
|
||||||
|
if STDIN.tty? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_readline?
|
||||||
|
@io = ReidlineInputMethod.new
|
||||||
|
else
|
||||||
|
@io = nil
|
||||||
|
end
|
||||||
|
when false
|
||||||
|
@io = nil
|
||||||
|
when true
|
||||||
|
@io = ReidlineInputMethod.new
|
||||||
|
end
|
||||||
|
unless @io
|
||||||
case use_readline?
|
case use_readline?
|
||||||
when nil
|
when nil
|
||||||
if (defined?(ReadlineInputMethod) && STDIN.tty? &&
|
if (defined?(ReadlineInputMethod) && STDIN.tty? &&
|
||||||
IRB.conf[:PROMPT_MODE] != :INF_RUBY)
|
IRB.conf[:PROMPT_MODE] != :INF_RUBY)
|
||||||
@io = ReadlineInputMethod.new
|
@io = ReadlineInputMethod.new
|
||||||
else
|
else
|
||||||
@io = StdioInputMethod.new
|
@io = nil
|
||||||
end
|
end
|
||||||
when false
|
when false
|
||||||
@io = StdioInputMethod.new
|
@io = nil
|
||||||
when true
|
when true
|
||||||
if defined?(ReadlineInputMethod)
|
if defined?(ReadlineInputMethod)
|
||||||
@io = ReadlineInputMethod.new
|
@io = ReadlineInputMethod.new
|
||||||
else
|
else
|
||||||
@io = StdioInputMethod.new
|
@io = nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
@io = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@io = StdioInputMethod.new unless @io
|
||||||
|
|
||||||
when String
|
when String
|
||||||
@io = FileInputMethod.new(input_method)
|
@io = FileInputMethod.new(input_method)
|
||||||
|
|
@ -117,9 +136,9 @@ module IRB
|
||||||
attr_reader :thread
|
attr_reader :thread
|
||||||
# The current input method
|
# The current input method
|
||||||
#
|
#
|
||||||
# Can be either StdioInputMethod, ReadlineInputMethod, FileInputMethod or
|
# Can be either StdioInputMethod, ReadlineInputMethod,
|
||||||
# other specified when the context is created. See ::new for more
|
# ReidlineInputMethod, FileInputMethod or other specified when the
|
||||||
# information on +input_method+.
|
# context is created. See ::new for more # information on +input_method+.
|
||||||
attr_accessor :io
|
attr_accessor :io
|
||||||
|
|
||||||
# Current irb session
|
# Current irb session
|
||||||
|
|
@ -137,6 +156,12 @@ module IRB
|
||||||
# +input_method+ passed to Context.new
|
# +input_method+ passed to Context.new
|
||||||
attr_accessor :irb_path
|
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.
|
# Whether +Readline+ is enabled or not.
|
||||||
#
|
#
|
||||||
# A copy of the default <code>IRB.conf[:USE_READLINE]</code>
|
# 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.
|
# See IRB@Command+line+options for more command line options.
|
||||||
attr_accessor :back_trace_limit
|
attr_accessor :back_trace_limit
|
||||||
|
|
||||||
|
# Alias for #use_reidline
|
||||||
|
alias use_reidline? use_reidline
|
||||||
# Alias for #use_readline
|
# Alias for #use_readline
|
||||||
alias use_readline? use_readline
|
alias use_readline? use_readline
|
||||||
# Alias for #use_colorize
|
# Alias for #use_colorize
|
||||||
|
|
@ -238,7 +265,9 @@ module IRB
|
||||||
# Returns whether messages are displayed or not.
|
# Returns whether messages are displayed or not.
|
||||||
def verbose?
|
def verbose?
|
||||||
if @verbose.nil?
|
if @verbose.nil?
|
||||||
if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
|
if @io.kind_of?(ReidlineInputMethod)
|
||||||
|
false
|
||||||
|
elsif defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
|
||||||
false
|
false
|
||||||
elsif !STDIN.tty? or @io.kind_of?(FileInputMethod)
|
elsif !STDIN.tty? or @io.kind_of?(FileInputMethod)
|
||||||
true
|
true
|
||||||
|
|
@ -251,9 +280,11 @@ module IRB
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether #verbose? is +true+, and +input_method+ is either
|
# 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?
|
def prompting?
|
||||||
verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
|
verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
|
||||||
|
@io.kind_of?(ReidlineInputMethod) ||
|
||||||
(defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
|
(defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,10 @@ module IRB # :nodoc:
|
||||||
@CONF[:USE_READLINE] = true
|
@CONF[:USE_READLINE] = true
|
||||||
when "--noreadline"
|
when "--noreadline"
|
||||||
@CONF[:USE_READLINE] = false
|
@CONF[:USE_READLINE] = false
|
||||||
|
when "--reidline"
|
||||||
|
@CONF[:USE_REIDLINE] = true
|
||||||
|
when "--noreidline"
|
||||||
|
@CONF[:USE_REIDLINE] = false
|
||||||
when "--echo"
|
when "--echo"
|
||||||
@CONF[:ECHO] = true
|
@CONF[:ECHO] = true
|
||||||
when "--noecho"
|
when "--noecho"
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
#
|
#
|
||||||
require_relative 'src_encoding'
|
require_relative 'src_encoding'
|
||||||
require_relative 'magic-file'
|
require_relative 'magic-file'
|
||||||
|
require_relative 'completion'
|
||||||
|
require 'reline'
|
||||||
|
|
||||||
module IRB
|
module IRB
|
||||||
STDIN_FILE_NAME = "(line)" # :nodoc:
|
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 => "-")
|
@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 => "-")
|
@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
|
end
|
||||||
|
|
||||||
# Reads the next line from this input method.
|
# Reads the next line from this input method.
|
||||||
|
|
@ -186,7 +194,83 @@ module IRB
|
||||||
def encoding
|
def encoding
|
||||||
@stdin.external_encoding
|
@stdin.external_encoding
|
||||||
end
|
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
|
end
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
end
|
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
|
end
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ class RubyLex
|
||||||
@io = io
|
@io = io
|
||||||
if @io.respond_to?(:check_termination)
|
if @io.respond_to?(:check_termination)
|
||||||
@io.check_termination do |code|
|
@io.check_termination do |code|
|
||||||
|
code.gsub!(/\s*\z/, '').concat("\n")
|
||||||
@tokens = Ripper.lex(code)
|
@tokens = Ripper.lex(code)
|
||||||
continue = process_continue
|
continue = process_continue
|
||||||
code_block_open = check_code_block(code)
|
code_block_open = check_code_block(code)
|
||||||
|
|
@ -116,7 +117,7 @@ class RubyLex
|
||||||
return line # multiline
|
return line # multiline
|
||||||
end
|
end
|
||||||
code = @line + (line.nil? ? '' : line)
|
code = @line + (line.nil? ? '' : line)
|
||||||
code.gsub!(/\n*$/, '').concat("\n")
|
code.gsub!(/\s*\z/, '').concat("\n")
|
||||||
@tokens = Ripper.lex(code)
|
@tokens = Ripper.lex(code)
|
||||||
@continue = process_continue
|
@continue = process_continue
|
||||||
@code_block_open = check_code_block(code)
|
@code_block_open = check_code_block(code)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue