summaryrefslogtreecommitdiff
path: root/lib/irb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/irb')
-rw-r--r--lib/irb/command.rb118
-rw-r--r--lib/irb/command/backtrace.rb8
-rw-r--r--lib/irb/command/base.rb35
-rw-r--r--lib/irb/command/break.rb8
-rw-r--r--lib/irb/command/catch.rb8
-rw-r--r--lib/irb/command/chws.rb11
-rw-r--r--lib/irb/command/context.rb16
-rw-r--r--lib/irb/command/continue.rb4
-rw-r--r--lib/irb/command/debug.rb6
-rw-r--r--lib/irb/command/delete.rb4
-rw-r--r--lib/irb/command/edit.rb16
-rw-r--r--lib/irb/command/finish.rb4
-rw-r--r--lib/irb/command/help.rb19
-rw-r--r--lib/irb/command/history.rb10
-rw-r--r--lib/irb/command/info.rb8
-rw-r--r--lib/irb/command/irb_info.rb2
-rw-r--r--lib/irb/command/load.rb22
-rw-r--r--lib/irb/command/ls.rb28
-rw-r--r--lib/irb/command/measure.rb16
-rw-r--r--lib/irb/command/next.rb4
-rw-r--r--lib/irb/command/pushws.rb15
-rw-r--r--lib/irb/command/show_doc.rb27
-rw-r--r--lib/irb/command/show_source.rb15
-rw-r--r--lib/irb/command/step.rb4
-rw-r--r--lib/irb/command/subirb.rb35
-rw-r--r--lib/irb/command/whereami.rb2
-rw-r--r--lib/irb/completion.rb17
-rw-r--r--lib/irb/context.rb12
-rw-r--r--lib/irb/ext/change-ws.rb8
-rw-r--r--lib/irb/ext/workspaces.rb7
-rw-r--r--lib/irb/statement.rb32
-rw-r--r--lib/irb/workspace.rb6
32 files changed, 237 insertions, 290 deletions
diff --git a/lib/irb/command.rb b/lib/irb/command.rb
index ef93049237..43cbda36b5 100644
--- a/lib/irb/command.rb
+++ b/lib/irb/command.rb
@@ -12,30 +12,18 @@ module IRB # :nodoc:
# Installs the default irb extensions command bundle.
module ExtendCommandBundle
- EXCB = ExtendCommandBundle # :nodoc:
-
- # See #install_alias_method.
+ # See ExtendCommandBundle.execute_as_command?.
NO_OVERRIDE = 0
- # See #install_alias_method.
OVERRIDE_PRIVATE_ONLY = 0x01
- # See #install_alias_method.
OVERRIDE_ALL = 0x02
- # Displays current configuration.
- #
- # Modifying the configuration is achieved by sending a message to IRB.conf.
- def irb_context
- IRB.CurrentContext
- end
-
- @ALIASES = [
- [:context, :irb_context, NO_OVERRIDE],
- [:conf, :irb_context, NO_OVERRIDE],
- ]
-
-
@EXTEND_COMMANDS = [
[
+ :irb_context, :Context, "command/context",
+ [:context, NO_OVERRIDE],
+ [:conf, NO_OVERRIDE],
+ ],
+ [
:irb_exit, :Exit, "command/exit",
[:exit, OVERRIDE_PRIVATE_ONLY],
[:quit, OVERRIDE_PRIVATE_ONLY],
@@ -204,6 +192,26 @@ module IRB # :nodoc:
],
]
+ def self.command_override_policies
+ @@command_override_policies ||= @EXTEND_COMMANDS.flat_map do |cmd_name, cmd_class, load_file, *aliases|
+ [[cmd_name, OVERRIDE_ALL]] + aliases
+ end.to_h
+ end
+
+ def self.execute_as_command?(name, public_method:, private_method:)
+ case command_override_policies[name]
+ when OVERRIDE_ALL
+ true
+ when OVERRIDE_PRIVATE_ONLY
+ !public_method
+ when NO_OVERRIDE
+ !public_method && !private_method
+ end
+ end
+
+ def self.command_names
+ command_override_policies.keys.map(&:to_s)
+ end
@@commands = []
@@ -247,77 +255,13 @@ module IRB # :nodoc:
nil
end
- # Installs the default irb commands.
- def self.install_extend_commands
- for args in @EXTEND_COMMANDS
- def_extend_command(*args)
- end
- end
-
- # Evaluate the given +cmd_name+ on the given +cmd_class+ Class.
- #
- # Will also define any given +aliases+ for the method.
- #
- # The optional +load_file+ parameter will be required within the method
- # definition.
def self.def_extend_command(cmd_name, cmd_class, load_file, *aliases)
- case cmd_class
- when Symbol
- cmd_class = cmd_class.id2name
- when String
- when Class
- cmd_class = cmd_class.name
- end
-
- line = __LINE__; eval %[
- def #{cmd_name}(*opts, **kwargs, &b)
- Kernel.require_relative "#{load_file}"
- ::IRB::Command::#{cmd_class}.execute(irb_context, *opts, **kwargs, &b)
- end
- ], nil, __FILE__, line
-
- for ali, flag in aliases
- @ALIASES.push [ali, cmd_name, flag]
- end
- end
-
- # Installs alias methods for the default irb commands, see
- # ::install_extend_commands.
- def install_alias_method(to, from, override = NO_OVERRIDE)
- to = to.id2name unless to.kind_of?(String)
- from = from.id2name unless from.kind_of?(String)
+ @EXTEND_COMMANDS.delete_if { |name,| name == cmd_name }
+ @EXTEND_COMMANDS << [cmd_name, cmd_class, load_file, *aliases]
- if override == OVERRIDE_ALL or
- (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or
- (override == NO_OVERRIDE) && !respond_to?(to, true)
- target = self
- (class << self; self; end).instance_eval{
- if target.respond_to?(to, true) &&
- !target.respond_to?(EXCB.irb_original_method_name(to), true)
- alias_method(EXCB.irb_original_method_name(to), to)
- end
- alias_method to, from
- }
- else
- Kernel.warn "irb: warn: can't alias #{to} from #{from}.\n"
- end
- end
-
- def self.irb_original_method_name(method_name) # :nodoc:
- "irb_" + method_name + "_org"
- end
-
- # Installs alias methods for the default irb commands on the given object
- # using #install_alias_method.
- def self.extend_object(obj)
- unless (class << obj; ancestors; end).include?(EXCB)
- super
- for ali, com, flg in @ALIASES
- obj.install_alias_method(ali, com, flg)
- end
- end
+ # Just clear memoized values
+ @@commands = []
+ @@command_override_policies = nil
end
-
- install_extend_commands
end
end
diff --git a/lib/irb/command/backtrace.rb b/lib/irb/command/backtrace.rb
index 47e5e60724..610f9ee22c 100644
--- a/lib/irb/command/backtrace.rb
+++ b/lib/irb/command/backtrace.rb
@@ -7,12 +7,8 @@ module IRB
module Command
class Backtrace < DebugCommand
- def self.transform_args(args)
- args&.dump
- end
-
- def execute(*args)
- super(pre_cmds: ["backtrace", *args].join(" "))
+ def execute(arg)
+ execute_debug_command(pre_cmds: "backtrace #{arg}".rstrip)
end
end
end
diff --git a/lib/irb/command/base.rb b/lib/irb/command/base.rb
index 3ce4f4d6c1..ff74b5fb35 100644
--- a/lib/irb/command/base.rb
+++ b/lib/irb/command/base.rb
@@ -10,6 +10,10 @@ module IRB
module Command
class CommandArgumentError < StandardError; end
+ def self.extract_ruby_args(*args, **kwargs)
+ throw :EXTRACT_RUBY_ARGS, [args, kwargs]
+ end
+
class Base
class << self
def category(category = nil)
@@ -29,19 +33,13 @@ module IRB
private
- def string_literal?(args)
- sexp = Ripper.sexp(args)
- sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
- end
-
def highlight(text)
Color.colorize(text, [:BOLD, :BLUE])
end
end
- def self.execute(irb_context, *opts, **kwargs, &block)
- command = new(irb_context)
- command.execute(*opts, **kwargs, &block)
+ def self.execute(irb_context, arg)
+ new(irb_context).execute(arg)
rescue CommandArgumentError => e
puts e.message
end
@@ -52,7 +50,26 @@ module IRB
attr_reader :irb_context
- def execute(*opts)
+ def unwrap_string_literal(str)
+ return if str.empty?
+
+ sexp = Ripper.sexp(str)
+ if sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
+ @irb_context.workspace.binding.eval(str).to_s
+ else
+ str
+ end
+ end
+
+ def ruby_args(arg)
+ # Use throw and catch to handle arg that includes `;`
+ # For example: "1, kw: (2; 3); 4" will be parsed to [[1], { kw: 3 }]
+ catch(:EXTRACT_RUBY_ARGS) do
+ @irb_context.workspace.binding.eval "IRB::Command.extract_ruby_args #{arg}"
+ end || [[], {}]
+ end
+
+ def execute(arg)
#nop
end
end
diff --git a/lib/irb/command/break.rb b/lib/irb/command/break.rb
index fa200f2d78..42ee002ce8 100644
--- a/lib/irb/command/break.rb
+++ b/lib/irb/command/break.rb
@@ -7,12 +7,8 @@ module IRB
module Command
class Break < DebugCommand
- def self.transform_args(args)
- args&.dump
- end
-
- def execute(args = nil)
- super(pre_cmds: "break #{args}")
+ def execute(arg)
+ execute_debug_command(pre_cmds: "break #{arg}".rstrip)
end
end
end
diff --git a/lib/irb/command/catch.rb b/lib/irb/command/catch.rb
index 6b2edff5e5..655c77d8af 100644
--- a/lib/irb/command/catch.rb
+++ b/lib/irb/command/catch.rb
@@ -7,12 +7,8 @@ module IRB
module Command
class Catch < DebugCommand
- def self.transform_args(args)
- args&.dump
- end
-
- def execute(*args)
- super(pre_cmds: ["catch", *args].join(" "))
+ def execute(arg)
+ execute_debug_command(pre_cmds: "catch #{arg}".rstrip)
end
end
end
diff --git a/lib/irb/command/chws.rb b/lib/irb/command/chws.rb
index e1047686c5..e0a406885f 100644
--- a/lib/irb/command/chws.rb
+++ b/lib/irb/command/chws.rb
@@ -14,7 +14,7 @@ module IRB
category "Workspace"
description "Show the current workspace."
- def execute(*obj)
+ def execute(_arg)
irb_context.main
end
end
@@ -23,8 +23,13 @@ module IRB
category "Workspace"
description "Change the current workspace to an object."
- def execute(*obj)
- irb_context.change_workspace(*obj)
+ def execute(arg)
+ if arg.empty?
+ irb_context.change_workspace
+ else
+ obj = eval(arg, irb_context.workspace.binding)
+ irb_context.change_workspace(obj)
+ end
irb_context.main
end
end
diff --git a/lib/irb/command/context.rb b/lib/irb/command/context.rb
new file mode 100644
index 0000000000..b4fc807343
--- /dev/null
+++ b/lib/irb/command/context.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module IRB
+ module Command
+ class Context < Base
+ category "IRB"
+ description "Displays current configuration."
+
+ def execute(_arg)
+ # This command just displays the configuration.
+ # Modifying the configuration is achieved by sending a message to IRB.conf.
+ Pager.page_content(IRB.CurrentContext.inspect)
+ end
+ end
+ end
+end
diff --git a/lib/irb/command/continue.rb b/lib/irb/command/continue.rb
index 8b6ffc860c..49e4384eb3 100644
--- a/lib/irb/command/continue.rb
+++ b/lib/irb/command/continue.rb
@@ -7,8 +7,8 @@ module IRB
module Command
class Continue < DebugCommand
- def execute(*args)
- super(do_cmds: ["continue", *args].join(" "))
+ def execute(arg)
+ execute_debug_command(do_cmds: "continue #{arg}".rstrip)
end
end
end
diff --git a/lib/irb/command/debug.rb b/lib/irb/command/debug.rb
index bdf91766bc..aeafe19b5f 100644
--- a/lib/irb/command/debug.rb
+++ b/lib/irb/command/debug.rb
@@ -13,7 +13,11 @@ module IRB
binding.method(:irb).source_location.first,
].map { |file| /\A#{Regexp.escape(file)}:\d+:in (`|'Binding#)irb'\z/ }
- def execute(pre_cmds: nil, do_cmds: nil)
+ def execute(_arg)
+ execute_debug_command
+ end
+
+ def execute_debug_command(pre_cmds: nil, do_cmds: nil)
if irb_context.with_debugger
# If IRB is already running with a debug session, throw the command and IRB.debug_readline will pass it to the debugger.
if cmd = pre_cmds || do_cmds
diff --git a/lib/irb/command/delete.rb b/lib/irb/command/delete.rb
index a36b4577b0..4b45a51e73 100644
--- a/lib/irb/command/delete.rb
+++ b/lib/irb/command/delete.rb
@@ -7,8 +7,8 @@ module IRB
module Command
class Delete < DebugCommand
- def execute(*args)
- super(pre_cmds: ["delete", *args].join(" "))
+ def execute(arg)
+ execute_debug_command(pre_cmds: "delete #{arg}".rstrip)
end
end
end
diff --git a/lib/irb/command/edit.rb b/lib/irb/command/edit.rb
index ab8c62663e..480100bfc7 100644
--- a/lib/irb/command/edit.rb
+++ b/lib/irb/command/edit.rb
@@ -26,19 +26,9 @@ module IRB
edit Foo#bar
HELP_MESSAGE
- class << self
- def transform_args(args)
- # Return a string literal as is for backward compatibility
- if args.nil? || args.empty? || string_literal?(args)
- args
- else # Otherwise, consider the input as a String for convenience
- args.strip.dump
- end
- end
- end
-
- def execute(*args)
- path = args.first
+ def execute(arg)
+ # Accept string literal for backward compatibility
+ path = unwrap_string_literal(arg)
if path.nil?
path = @irb_context.irb_path
diff --git a/lib/irb/command/finish.rb b/lib/irb/command/finish.rb
index 05501819e2..c1d62357f4 100644
--- a/lib/irb/command/finish.rb
+++ b/lib/irb/command/finish.rb
@@ -7,8 +7,8 @@ module IRB
module Command
class Finish < DebugCommand
- def execute(*args)
- super(do_cmds: ["finish", *args].join(" "))
+ def execute(arg)
+ execute_debug_command(do_cmds: "finish #{arg}".rstrip)
end
end
end
diff --git a/lib/irb/command/help.rb b/lib/irb/command/help.rb
index 19113dbbfe..c9f16e05bc 100644
--- a/lib/irb/command/help.rb
+++ b/lib/irb/command/help.rb
@@ -6,27 +6,16 @@ module IRB
category "Help"
description "List all available commands. Use `help <command>` to get information about a specific command."
- class << self
- def transform_args(args)
- # Return a string literal as is for backward compatibility
- if args.empty? || string_literal?(args)
- args
- else # Otherwise, consider the input as a String for convenience
- args.strip.dump
- end
- end
- end
-
- def execute(command_name = nil)
+ def execute(command_name)
content =
- if command_name
+ if command_name.empty?
+ help_message
+ else
if command_class = ExtendCommandBundle.load_command(command_name)
command_class.help_message || command_class.description
else
"Can't find command `#{command_name}`. Please check the command name and try again.\n\n"
end
- else
- help_message
end
Pager.page_content(content)
end
diff --git a/lib/irb/command/history.rb b/lib/irb/command/history.rb
index a47a8795dd..90f87f9102 100644
--- a/lib/irb/command/history.rb
+++ b/lib/irb/command/history.rb
@@ -12,14 +12,12 @@ module IRB
category "IRB"
description "Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output."
- def self.transform_args(args)
- match = args&.match(/(-g|-G)\s+(?<grep>.+)\s*\n\z/)
- return unless match
+ def execute(arg)
- "grep: #{Regexp.new(match[:grep]).inspect}"
- end
+ if (match = arg&.match(/(-g|-G)\s+(?<grep>.+)\s*\n\z/))
+ grep = Regexp.new(match[:grep])
+ end
- def execute(grep: nil)
formatted_inputs = irb_context.io.class::HISTORY.each_with_index.reverse_each.filter_map do |input, index|
next if grep && !input.match?(grep)
diff --git a/lib/irb/command/info.rb b/lib/irb/command/info.rb
index a67be3eb85..897ee2c430 100644
--- a/lib/irb/command/info.rb
+++ b/lib/irb/command/info.rb
@@ -7,12 +7,8 @@ module IRB
module Command
class Info < DebugCommand
- def self.transform_args(args)
- args&.dump
- end
-
- def execute(*args)
- super(pre_cmds: ["info", *args].join(" "))
+ def execute(arg)
+ execute_debug_command(pre_cmds: "info #{arg}".rstrip)
end
end
end
diff --git a/lib/irb/command/irb_info.rb b/lib/irb/command/irb_info.rb
index cc93fdcbd5..6d868de94c 100644
--- a/lib/irb/command/irb_info.rb
+++ b/lib/irb/command/irb_info.rb
@@ -8,7 +8,7 @@ module IRB
category "IRB"
description "Show information about IRB."
- def execute
+ def execute(_arg)
str = "Ruby version: #{RUBY_VERSION}\n"
str += "IRB version: #{IRB.version}\n"
str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
diff --git a/lib/irb/command/load.rb b/lib/irb/command/load.rb
index 9e89a7b7f3..33e327f4a9 100644
--- a/lib/irb/command/load.rb
+++ b/lib/irb/command/load.rb
@@ -21,7 +21,12 @@ module IRB
category "IRB"
description "Load a Ruby file."
- def execute(file_name = nil, priv = nil)
+ def execute(arg)
+ args, kwargs = ruby_args(arg)
+ execute_internal(*args, **kwargs)
+ end
+
+ def execute_internal(file_name = nil, priv = nil)
raise_cmd_argument_error unless file_name
irb_load(file_name, priv)
end
@@ -30,7 +35,13 @@ module IRB
class Require < LoaderCommand
category "IRB"
description "Require a Ruby file."
- def execute(file_name = nil)
+
+ def execute(arg)
+ args, kwargs = ruby_args(arg)
+ execute_internal(*args, **kwargs)
+ end
+
+ def execute_internal(file_name = nil)
raise_cmd_argument_error unless file_name
rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
@@ -63,7 +74,12 @@ module IRB
category "IRB"
description "Loads a given file in the current session."
- def execute(file_name = nil)
+ def execute(arg)
+ args, kwargs = ruby_args(arg)
+ execute_internal(*args, **kwargs)
+ end
+
+ def execute_internal(file_name = nil)
raise_cmd_argument_error unless file_name
source_file(file_name)
diff --git a/lib/irb/command/ls.rb b/lib/irb/command/ls.rb
index 6b6136c2fe..f6b1964864 100644
--- a/lib/irb/command/ls.rb
+++ b/lib/irb/command/ls.rb
@@ -20,27 +20,35 @@ module IRB
-g [query] Filter the output with a query.
HELP_MESSAGE
- def self.transform_args(args)
- if match = args&.match(/\A(?<args>.+\s|)(-g|-G)\s+(?<grep>[^\s]+)\s*\n\z/)
- args = match[:args]
- "#{args}#{',' unless args.chomp.empty?} grep: /#{match[:grep]}/"
+ def execute(arg)
+ if match = arg.match(/\A(?<target>.+\s|)(-g|-G)\s+(?<grep>.+)$/)
+ if match[:target].empty?
+ use_main = true
+ else
+ obj = @irb_context.workspace.binding.eval(match[:target])
+ end
+ grep = Regexp.new(match[:grep])
else
- args
+ args, kwargs = ruby_args(arg)
+ use_main = args.empty?
+ obj = args.first
+ grep = kwargs[:grep]
+ end
+
+ if use_main
+ obj = irb_context.workspace.main
+ locals = irb_context.workspace.binding.local_variables
end
- end
- def execute(*arg, grep: nil)
o = Output.new(grep: grep)
- obj = arg.empty? ? irb_context.workspace.main : arg.first
- locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
o.dump("constants", obj.constants) if obj.respond_to?(:constants)
dump_methods(o, klass, obj)
o.dump("instance variables", obj.instance_variables)
o.dump("class variables", klass.class_variables)
- o.dump("locals", locals)
+ o.dump("locals", locals) if locals
o.print_result
end
diff --git a/lib/irb/command/measure.rb b/lib/irb/command/measure.rb
index ee7927b010..70dc69cdec 100644
--- a/lib/irb/command/measure.rb
+++ b/lib/irb/command/measure.rb
@@ -10,15 +10,19 @@ module IRB
super(*args)
end
- def execute(type = nil, arg = nil)
- # Please check IRB.init_config in lib/irb/init.rb that sets
- # IRB.conf[:MEASURE_PROC] to register default "measure" methods,
- # "measure :time" (abbreviated as "measure") and "measure :stackprof".
-
- if block_given?
+ def execute(arg)
+ if arg&.match?(/^do$|^do[^\w]|^\{/)
warn 'Configure IRB.conf[:MEASURE_PROC] to add custom measure methods.'
return
end
+ args, kwargs = ruby_args(arg)
+ execute_internal(*args, **kwargs)
+ end
+
+ def execute_internal(type = nil, arg = nil)
+ # Please check IRB.init_config in lib/irb/init.rb that sets
+ # IRB.conf[:MEASURE_PROC] to register default "measure" methods,
+ # "measure :time" (abbreviated as "measure") and "measure :stackprof".
case type
when :off
diff --git a/lib/irb/command/next.rb b/lib/irb/command/next.rb
index 6487c9d24c..92d28e33ef 100644
--- a/lib/irb/command/next.rb
+++ b/lib/irb/command/next.rb
@@ -7,8 +7,8 @@ module IRB
module Command
class Next < DebugCommand
- def execute(*args)
- super(do_cmds: ["next", *args].join(" "))
+ def execute(arg)
+ execute_debug_command(do_cmds: "next #{arg}".rstrip)
end
end
end
diff --git a/lib/irb/command/pushws.rb b/lib/irb/command/pushws.rb
index 888fe466f1..b51928c650 100644
--- a/lib/irb/command/pushws.rb
+++ b/lib/irb/command/pushws.rb
@@ -14,7 +14,7 @@ module IRB
category "Workspace"
description "Show workspaces."
- def execute(*obj)
+ def execute(_arg)
inspection_resuls = irb_context.instance_variable_get(:@workspace_stack).map do |ws|
truncated_inspect(ws.main)
end
@@ -39,8 +39,13 @@ module IRB
category "Workspace"
description "Push an object to the workspace stack."
- def execute(*obj)
- irb_context.push_workspace(*obj)
+ def execute(arg)
+ if arg.empty?
+ irb_context.push_workspace
+ else
+ obj = eval(arg, irb_context.workspace.binding)
+ irb_context.push_workspace(obj)
+ end
super
end
end
@@ -49,8 +54,8 @@ module IRB
category "Workspace"
description "Pop a workspace from the workspace stack."
- def execute(*obj)
- irb_context.pop_workspace(*obj)
+ def execute(_arg)
+ irb_context.pop_workspace
super
end
end
diff --git a/lib/irb/command/show_doc.rb b/lib/irb/command/show_doc.rb
index 4dde28bee9..f9393cd3b5 100644
--- a/lib/irb/command/show_doc.rb
+++ b/lib/irb/command/show_doc.rb
@@ -3,17 +3,6 @@
module IRB
module Command
class ShowDoc < Base
- class << self
- def transform_args(args)
- # Return a string literal as is for backward compatibility
- if args.empty? || string_literal?(args)
- args
- else # Otherwise, consider the input as a String for convenience
- args.strip.dump
- end
- end
- end
-
category "Context"
description "Look up documentation with RI."
@@ -31,7 +20,9 @@ module IRB
HELP_MESSAGE
- def execute(*names)
+ def execute(arg)
+ # Accept string literal for backward compatibility
+ name = unwrap_string_literal(arg)
require 'rdoc/ri/driver'
unless ShowDoc.const_defined?(:Ri)
@@ -39,15 +30,13 @@ module IRB
ShowDoc.const_set(:Ri, RDoc::RI::Driver.new(opts))
end
- if names.empty?
+ if name.nil?
Ri.interactive
else
- names.each do |name|
- begin
- Ri.display_name(name.to_s)
- rescue RDoc::RI::Error
- puts $!.message
- end
+ begin
+ Ri.display_name(name)
+ rescue RDoc::RI::Error
+ puts $!.message
end
end
diff --git a/lib/irb/command/show_source.rb b/lib/irb/command/show_source.rb
index 32bdf74d31..c4c8fc0041 100644
--- a/lib/irb/command/show_source.rb
+++ b/lib/irb/command/show_source.rb
@@ -24,18 +24,9 @@ module IRB
show_source Foo::BAR
HELP_MESSAGE
- class << self
- def transform_args(args)
- # Return a string literal as is for backward compatibility
- if args.empty? || string_literal?(args)
- args
- else # Otherwise, consider the input as a String for convenience
- args.strip.dump
- end
- end
- end
-
- def execute(str = nil)
+ def execute(arg)
+ # Accept string literal for backward compatibility
+ str = unwrap_string_literal(arg)
unless str.is_a?(String)
puts "Error: Expected a string but got #{str.inspect}"
return
diff --git a/lib/irb/command/step.rb b/lib/irb/command/step.rb
index cce7d2b0f8..5149813029 100644
--- a/lib/irb/command/step.rb
+++ b/lib/irb/command/step.rb
@@ -7,8 +7,8 @@ module IRB
module Command
class Step < DebugCommand
- def execute(*args)
- super(do_cmds: ["step", *args].join(" "))
+ def execute(arg)
+ execute_debug_command(do_cmds: "step #{arg}".rstrip)
end
end
end
diff --git a/lib/irb/command/subirb.rb b/lib/irb/command/subirb.rb
index 5cc7b8c6f8..24428a5c13 100644
--- a/lib/irb/command/subirb.rb
+++ b/lib/irb/command/subirb.rb
@@ -9,10 +9,6 @@ module IRB
module Command
class MultiIRBCommand < Base
- def execute(*args)
- extend_irb_context
- end
-
private
def print_deprecated_warning
@@ -36,7 +32,12 @@ module IRB
category "Multi-irb (DEPRECATED)"
description "Start a child IRB."
- def execute(*obj)
+ def execute(arg)
+ args, kwargs = ruby_args(arg)
+ execute_internal(*args, **kwargs)
+ end
+
+ def execute_internal(*obj)
print_deprecated_warning
if irb_context.with_debugger
@@ -44,7 +45,7 @@ module IRB
return
end
- super
+ extend_irb_context
IRB.irb(nil, *obj)
end
end
@@ -53,7 +54,7 @@ module IRB
category "Multi-irb (DEPRECATED)"
description "List of current sessions."
- def execute
+ def execute(_arg)
print_deprecated_warning
if irb_context.with_debugger
@@ -61,7 +62,7 @@ module IRB
return
end
- super
+ extend_irb_context
IRB.JobManager
end
end
@@ -70,7 +71,12 @@ module IRB
category "Multi-irb (DEPRECATED)"
description "Switches to the session of the given number."
- def execute(key = nil)
+ def execute(arg)
+ args, kwargs = ruby_args(arg)
+ execute_internal(*args, **kwargs)
+ end
+
+ def execute_internal(key = nil)
print_deprecated_warning
if irb_context.with_debugger
@@ -78,7 +84,7 @@ module IRB
return
end
- super
+ extend_irb_context
raise CommandArgumentError.new("Please specify the id of target IRB job (listed in the `jobs` command).") unless key
IRB.JobManager.switch(key)
@@ -89,7 +95,12 @@ module IRB
category "Multi-irb (DEPRECATED)"
description "Kills the session with the given number."
- def execute(*keys)
+ def execute(arg)
+ args, kwargs = ruby_args(arg)
+ execute_internal(*args, **kwargs)
+ end
+
+ def execute_internal(*keys)
print_deprecated_warning
if irb_context.with_debugger
@@ -97,7 +108,7 @@ module IRB
return
end
- super
+ extend_irb_context
IRB.JobManager.kill(*keys)
end
end
diff --git a/lib/irb/command/whereami.rb b/lib/irb/command/whereami.rb
index d6658d7043..c8439f1212 100644
--- a/lib/irb/command/whereami.rb
+++ b/lib/irb/command/whereami.rb
@@ -8,7 +8,7 @@ module IRB
category "Context"
description "Show the source code around binding.irb again."
- def execute(*)
+ def execute(_arg)
code = irb_context.workspace.code_around_binding
if code
puts code
diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb
index b3813e8939..8a1df11561 100644
--- a/lib/irb/completion.rb
+++ b/lib/irb/completion.rb
@@ -86,6 +86,14 @@ module IRB
)
end
+ def command_completions(preposing, target)
+ if preposing.empty? && !target.empty?
+ IRB::ExtendCommandBundle.command_names.select { _1.start_with?(target) }
+ else
+ []
+ end
+ end
+
def retrieve_files_to_require_relative_from_current_dir
@files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
@@ -103,9 +111,11 @@ module IRB
end
def completion_candidates(preposing, target, _postposing, bind:)
+ commands = command_completions(preposing, target)
result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
- return [] unless result
- result.completion_candidates.map { target + _1 }
+ return commands unless result
+
+ commands | result.completion_candidates.map { target + _1 }
end
def doc_namespace(preposing, matched, _postposing, bind:)
@@ -181,7 +191,8 @@ module IRB
result = complete_require_path(target, preposing, postposing)
return result if result
end
- retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
+ commands = command_completions(preposing || '', target)
+ commands | retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
end
def doc_namespace(_preposing, matched, _postposing, bind:)
diff --git a/lib/irb/context.rb b/lib/irb/context.rb
index 60dfb9668d..e3c4192459 100644
--- a/lib/irb/context.rb
+++ b/lib/irb/context.rb
@@ -646,17 +646,5 @@ module IRB
def local_variables # :nodoc:
workspace.binding.local_variables
end
-
- # Return true if it's aliased from the argument and it's not an identifier.
- def symbol_alias?(command)
- return nil if command.match?(/\A\w+\z/)
- command_aliases.key?(command.to_sym)
- end
-
- # Return true if the command supports transforming args
- def transform_args?(command)
- command = command_aliases.fetch(command.to_sym, command)
- ExtendCommandBundle.load_command(command)&.respond_to?(:transform_args)
- end
end
end
diff --git a/lib/irb/ext/change-ws.rb b/lib/irb/ext/change-ws.rb
index 87fe03e23d..60e8afe31f 100644
--- a/lib/irb/ext/change-ws.rb
+++ b/lib/irb/ext/change-ws.rb
@@ -29,11 +29,9 @@ module IRB # :nodoc:
return main
end
- replace_workspace(WorkSpace.new(_main[0]))
-
- if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
- main.extend ExtendCommandBundle
- end
+ workspace = WorkSpace.new(_main[0])
+ replace_workspace(workspace)
+ workspace.load_helper_methods_to_main
end
end
end
diff --git a/lib/irb/ext/workspaces.rb b/lib/irb/ext/workspaces.rb
index 5a1edd89b7..da09faa83e 100644
--- a/lib/irb/ext/workspaces.rb
+++ b/lib/irb/ext/workspaces.rb
@@ -19,10 +19,9 @@ module IRB # :nodoc:
@workspace_stack.push current_workspace, previous_workspace
end
else
- @workspace_stack.push WorkSpace.new(workspace.binding, _main[0])
- if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
- main.extend ExtendCommandBundle
- end
+ new_workspace = WorkSpace.new(workspace.binding, _main[0])
+ @workspace_stack.push new_workspace
+ new_workspace.load_helper_methods_to_main
end
end
diff --git a/lib/irb/statement.rb b/lib/irb/statement.rb
index 1e026d112f..a3391c12a3 100644
--- a/lib/irb/statement.rb
+++ b/lib/irb/statement.rb
@@ -16,10 +16,6 @@ module IRB
raise NotImplementedError
end
- def evaluable_code
- raise NotImplementedError
- end
-
class EmptyInput < Statement
def is_assignment?
false
@@ -37,10 +33,6 @@ module IRB
def code
""
end
-
- def evaluable_code
- code
- end
end
class Expression < Statement
@@ -60,18 +52,15 @@ module IRB
def is_assignment?
@is_assignment
end
-
- def evaluable_code
- @code
- end
end
class Command < Statement
- def initialize(code, command, arg, command_class)
- @code = code
- @command = command
- @arg = arg
+ attr_reader :command_class, :arg
+
+ def initialize(original_code, command_class, arg)
+ @code = original_code
@command_class = command_class
+ @arg = arg
end
def is_assignment?
@@ -86,17 +75,6 @@ module IRB
require_relative 'command/debug'
IRB::Command::DebugCommand > @command_class
end
-
- def evaluable_code
- # Hook command-specific transformation to return valid Ruby code
- if @command_class.respond_to?(:transform_args)
- arg = @command_class.transform_args(@arg)
- else
- arg = @arg
- end
-
- [@command, arg].compact.join(' ')
- end
end
end
end
diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb
index 4c3b5e425e..1490f7b478 100644
--- a/lib/irb/workspace.rb
+++ b/lib/irb/workspace.rb
@@ -108,8 +108,10 @@ EOF
# <code>IRB.conf[:__MAIN__]</code>
attr_reader :main
- def load_commands_to_main
- main.extend ExtendCommandBundle
+ def load_helper_methods_to_main
+ if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
+ main.extend ExtendCommandBundle
+ end
end
# Evaluate the given +statements+ within the context of this workspace.