summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/irb.rb2
-rw-r--r--lib/irb/command.rb262
-rw-r--r--lib/irb/command/edit.rb1
-rw-r--r--lib/irb/default_commands.rb248
-rw-r--r--test/irb/test_command.rb34
5 files changed, 268 insertions, 279 deletions
diff --git a/lib/irb.rb b/lib/irb.rb
index 723035f15a..ab50c797c7 100644
--- a/lib/irb.rb
+++ b/lib/irb.rb
@@ -10,7 +10,7 @@ require "reline"
require_relative "irb/init"
require_relative "irb/context"
-require_relative "irb/command"
+require_relative "irb/default_commands"
require_relative "irb/ruby-lex"
require_relative "irb/statement"
diff --git a/lib/irb/command.rb b/lib/irb/command.rb
index 43cbda36b5..19fde56356 100644
--- a/lib/irb/command.rb
+++ b/lib/irb/command.rb
@@ -7,261 +7,23 @@
require_relative "command/base"
module IRB # :nodoc:
- module Command; end
- ExtendCommand = Command
+ module Command
+ @commands = {}
- # Installs the default irb extensions command bundle.
- module ExtendCommandBundle
- # See ExtendCommandBundle.execute_as_command?.
- NO_OVERRIDE = 0
- OVERRIDE_PRIVATE_ONLY = 0x01
- OVERRIDE_ALL = 0x02
+ class << self
+ attr_reader :commands
- @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],
- [:irb_quit, OVERRIDE_PRIVATE_ONLY],
- ],
- [
- :irb_exit!, :ForceExit, "command/force_exit",
- [:exit!, OVERRIDE_PRIVATE_ONLY],
- ],
-
- [
- :irb_current_working_workspace, :CurrentWorkingWorkspace, "command/chws",
- [:cwws, NO_OVERRIDE],
- [:pwws, NO_OVERRIDE],
- [:irb_print_working_workspace, OVERRIDE_ALL],
- [:irb_cwws, OVERRIDE_ALL],
- [:irb_pwws, OVERRIDE_ALL],
- [:irb_current_working_binding, OVERRIDE_ALL],
- [:irb_print_working_binding, OVERRIDE_ALL],
- [:irb_cwb, OVERRIDE_ALL],
- [:irb_pwb, OVERRIDE_ALL],
- ],
- [
- :irb_change_workspace, :ChangeWorkspace, "command/chws",
- [:chws, NO_OVERRIDE],
- [:cws, NO_OVERRIDE],
- [:irb_chws, OVERRIDE_ALL],
- [:irb_cws, OVERRIDE_ALL],
- [:irb_change_binding, OVERRIDE_ALL],
- [:irb_cb, OVERRIDE_ALL],
- [:cb, NO_OVERRIDE],
- ],
-
- [
- :irb_workspaces, :Workspaces, "command/pushws",
- [:workspaces, NO_OVERRIDE],
- [:irb_bindings, OVERRIDE_ALL],
- [:bindings, NO_OVERRIDE],
- ],
- [
- :irb_push_workspace, :PushWorkspace, "command/pushws",
- [:pushws, NO_OVERRIDE],
- [:irb_pushws, OVERRIDE_ALL],
- [:irb_push_binding, OVERRIDE_ALL],
- [:irb_pushb, OVERRIDE_ALL],
- [:pushb, NO_OVERRIDE],
- ],
- [
- :irb_pop_workspace, :PopWorkspace, "command/pushws",
- [:popws, NO_OVERRIDE],
- [:irb_popws, OVERRIDE_ALL],
- [:irb_pop_binding, OVERRIDE_ALL],
- [:irb_popb, OVERRIDE_ALL],
- [:popb, NO_OVERRIDE],
- ],
-
- [
- :irb_load, :Load, "command/load"],
- [
- :irb_require, :Require, "command/load"],
- [
- :irb_source, :Source, "command/load",
- [:source, NO_OVERRIDE],
- ],
-
- [
- :irb, :IrbCommand, "command/subirb"],
- [
- :irb_jobs, :Jobs, "command/subirb",
- [:jobs, NO_OVERRIDE],
- ],
- [
- :irb_fg, :Foreground, "command/subirb",
- [:fg, NO_OVERRIDE],
- ],
- [
- :irb_kill, :Kill, "command/subirb",
- [:kill, OVERRIDE_PRIVATE_ONLY],
- ],
-
- [
- :irb_debug, :Debug, "command/debug",
- [:debug, NO_OVERRIDE],
- ],
- [
- :irb_edit, :Edit, "command/edit",
- [:edit, NO_OVERRIDE],
- ],
- [
- :irb_break, :Break, "command/break",
- ],
- [
- :irb_catch, :Catch, "command/catch",
- ],
- [
- :irb_next, :Next, "command/next"
- ],
- [
- :irb_delete, :Delete, "command/delete",
- [:delete, NO_OVERRIDE],
- ],
- [
- :irb_step, :Step, "command/step",
- [:step, NO_OVERRIDE],
- ],
- [
- :irb_continue, :Continue, "command/continue",
- [:continue, NO_OVERRIDE],
- ],
- [
- :irb_finish, :Finish, "command/finish",
- [:finish, NO_OVERRIDE],
- ],
- [
- :irb_backtrace, :Backtrace, "command/backtrace",
- [:backtrace, NO_OVERRIDE],
- [:bt, NO_OVERRIDE],
- ],
- [
- :irb_debug_info, :Info, "command/info",
- [:info, NO_OVERRIDE],
- ],
-
- [
- :irb_help, :Help, "command/help",
- [:help, NO_OVERRIDE],
- [:show_cmds, NO_OVERRIDE],
- ],
-
- [
- :irb_show_doc, :ShowDoc, "command/show_doc",
- [:show_doc, NO_OVERRIDE],
- ],
-
- [
- :irb_info, :IrbInfo, "command/irb_info"
- ],
-
- [
- :irb_ls, :Ls, "command/ls",
- [:ls, NO_OVERRIDE],
- ],
-
- [
- :irb_measure, :Measure, "command/measure",
- [:measure, NO_OVERRIDE],
- ],
-
- [
- :irb_show_source, :ShowSource, "command/show_source",
- [:show_source, NO_OVERRIDE],
- ],
- [
- :irb_whereami, :Whereami, "command/whereami",
- [:whereami, NO_OVERRIDE],
- ],
- [
- :irb_history, :History, "command/history",
- [:history, NO_OVERRIDE],
- [:hist, NO_OVERRIDE],
- ],
-
- [
- :irb_disable_irb, :DisableIrb, "command/disable_irb",
- [:disable_irb, NO_OVERRIDE],
- ],
- ]
-
- 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 = []
-
- def self.all_commands_info
- return @@commands unless @@commands.empty?
- user_aliases = IRB.CurrentContext.command_aliases.each_with_object({}) do |(alias_name, target), result|
- result[target] ||= []
- result[target] << alias_name
- end
-
- @EXTEND_COMMANDS.each do |cmd_name, cmd_class, load_file, *aliases|
- if !defined?(Command) || !Command.const_defined?(cmd_class, false)
- require_relative load_file
- end
-
- klass = Command.const_get(cmd_class, false)
- aliases = aliases.map { |a| a.first }
-
- if additional_aliases = user_aliases[cmd_name]
- aliases += additional_aliases
- end
-
- display_name = aliases.shift || cmd_name
- @@commands << { display_name: display_name, description: klass.description, category: klass.category }
+ # Registers a command with the given name.
+ # Aliasing is intentionally not supported at the moment.
+ def register(name, command_class)
+ @commands[name] = [command_class, []]
end
- @@commands
- end
-
- # Convert a command name to its implementation class if such command exists
- def self.load_command(command)
- command = command.to_sym
- @EXTEND_COMMANDS.each do |cmd_name, cmd_class, load_file, *aliases|
- next if cmd_name != command && aliases.all? { |alias_name, _| alias_name != command }
-
- if !defined?(Command) || !Command.const_defined?(cmd_class, false)
- require_relative load_file
- end
- return Command.const_get(cmd_class, false)
+ # This API is for IRB's internal use only and may change at any time.
+ # Please do NOT use it.
+ def _register_with_aliases(name, command_class, *aliases)
+ @commands[name] = [command_class, aliases]
end
- nil
- end
-
- def self.def_extend_command(cmd_name, cmd_class, load_file, *aliases)
- @EXTEND_COMMANDS.delete_if { |name,| name == cmd_name }
- @EXTEND_COMMANDS << [cmd_name, cmd_class, load_file, *aliases]
-
- # Just clear memoized values
- @@commands = []
- @@command_override_policies = nil
end
end
end
diff --git a/lib/irb/command/edit.rb b/lib/irb/command/edit.rb
index 480100bfc7..3c4a54e5e2 100644
--- a/lib/irb/command/edit.rb
+++ b/lib/irb/command/edit.rb
@@ -1,5 +1,6 @@
require 'shellwords'
+require_relative "../color"
require_relative "../source_finder"
module IRB
diff --git a/lib/irb/default_commands.rb b/lib/irb/default_commands.rb
new file mode 100644
index 0000000000..6025b0547d
--- /dev/null
+++ b/lib/irb/default_commands.rb
@@ -0,0 +1,248 @@
+# frozen_string_literal: true
+
+require_relative "command"
+require_relative "command/context"
+require_relative "command/exit"
+require_relative "command/force_exit"
+require_relative "command/chws"
+require_relative "command/pushws"
+require_relative "command/subirb"
+require_relative "command/load"
+require_relative "command/debug"
+require_relative "command/edit"
+require_relative "command/break"
+require_relative "command/catch"
+require_relative "command/next"
+require_relative "command/delete"
+require_relative "command/step"
+require_relative "command/continue"
+require_relative "command/finish"
+require_relative "command/backtrace"
+require_relative "command/info"
+require_relative "command/help"
+require_relative "command/show_doc"
+require_relative "command/irb_info"
+require_relative "command/ls"
+require_relative "command/measure"
+require_relative "command/show_source"
+require_relative "command/whereami"
+require_relative "command/history"
+
+module IRB
+ ExtendCommand = Command
+
+ # Installs the default irb extensions command bundle.
+ module ExtendCommandBundle
+ # See #install_alias_method.
+ NO_OVERRIDE = 0
+ # See #install_alias_method.
+ OVERRIDE_PRIVATE_ONLY = 0x01
+ # See #install_alias_method.
+ OVERRIDE_ALL = 0x02
+
+ Command._register_with_aliases(:irb_context, Command::Context,
+ [
+ [:context, NO_OVERRIDE],
+ [:conf, NO_OVERRIDE],
+ ],
+ )
+
+ Command._register_with_aliases(:irb_exit, Command::Exit,
+ [:exit, OVERRIDE_PRIVATE_ONLY],
+ [:quit, OVERRIDE_PRIVATE_ONLY],
+ [:irb_quit, OVERRIDE_PRIVATE_ONLY]
+ )
+
+ Command._register_with_aliases(:irb_exit!, Command::ForceExit,
+ [:exit!, OVERRIDE_PRIVATE_ONLY]
+ )
+
+ Command._register_with_aliases(:irb_current_working_workspace, Command::CurrentWorkingWorkspace,
+ [:cwws, NO_OVERRIDE],
+ [:pwws, NO_OVERRIDE],
+ [:irb_print_working_workspace, OVERRIDE_ALL],
+ [:irb_cwws, OVERRIDE_ALL],
+ [:irb_pwws, OVERRIDE_ALL],
+ [:irb_current_working_binding, OVERRIDE_ALL],
+ [:irb_print_working_binding, OVERRIDE_ALL],
+ [:irb_cwb, OVERRIDE_ALL],
+ [:irb_pwb, OVERRIDE_ALL],
+ )
+
+ Command._register_with_aliases(:irb_change_workspace, Command::ChangeWorkspace,
+ [:chws, NO_OVERRIDE],
+ [:cws, NO_OVERRIDE],
+ [:irb_chws, OVERRIDE_ALL],
+ [:irb_cws, OVERRIDE_ALL],
+ [:irb_change_binding, OVERRIDE_ALL],
+ [:irb_cb, OVERRIDE_ALL],
+ [:cb, NO_OVERRIDE],
+ )
+
+ Command._register_with_aliases(:irb_workspaces, Command::Workspaces,
+ [:workspaces, NO_OVERRIDE],
+ [:irb_bindings, OVERRIDE_ALL],
+ [:bindings, NO_OVERRIDE],
+ )
+
+ Command._register_with_aliases(:irb_push_workspace, Command::PushWorkspace,
+ [:pushws, NO_OVERRIDE],
+ [:irb_pushws, OVERRIDE_ALL],
+ [:irb_push_binding, OVERRIDE_ALL],
+ [:irb_pushb, OVERRIDE_ALL],
+ [:pushb, NO_OVERRIDE],
+ )
+
+ Command._register_with_aliases(:irb_pop_workspace, Command::PopWorkspace,
+ [:popws, NO_OVERRIDE],
+ [:irb_popws, OVERRIDE_ALL],
+ [:irb_pop_binding, OVERRIDE_ALL],
+ [:irb_popb, OVERRIDE_ALL],
+ [:popb, NO_OVERRIDE],
+ )
+
+ Command._register_with_aliases(:irb_load, Command::Load)
+ Command._register_with_aliases(:irb_require, Command::Require)
+ Command._register_with_aliases(:irb_source, Command::Source,
+ [:source, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb, Command::IrbCommand)
+ Command._register_with_aliases(:irb_jobs, Command::Jobs,
+ [:jobs, NO_OVERRIDE]
+ )
+ Command._register_with_aliases(:irb_fg, Command::Foreground,
+ [:fg, NO_OVERRIDE]
+ )
+ Command._register_with_aliases(:irb_kill, Command::Kill,
+ [:kill, OVERRIDE_PRIVATE_ONLY]
+ )
+
+ Command._register_with_aliases(:irb_debug, Command::Debug,
+ [:debug, NO_OVERRIDE]
+ )
+ Command._register_with_aliases(:irb_edit, Command::Edit,
+ [:edit, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_break, Command::Break)
+ Command._register_with_aliases(:irb_catch, Command::Catch)
+ Command._register_with_aliases(:irb_next, Command::Next)
+ Command._register_with_aliases(:irb_delete, Command::Delete,
+ [:delete, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_step, Command::Step,
+ [:step, NO_OVERRIDE]
+ )
+ Command._register_with_aliases(:irb_continue, Command::Continue,
+ [:continue, NO_OVERRIDE]
+ )
+ Command._register_with_aliases(:irb_finish, Command::Finish,
+ [:finish, NO_OVERRIDE]
+ )
+ Command._register_with_aliases(:irb_backtrace, Command::Backtrace,
+ [:backtrace, NO_OVERRIDE],
+ [:bt, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_debug_info, Command::Info,
+ [:info, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_help, Command::Help,
+ [:help, NO_OVERRIDE],
+ [:show_cmds, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_show_doc, Command::ShowDoc,
+ [:show_doc, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_info, Command::IrbInfo)
+
+ Command._register_with_aliases(:irb_ls, Command::Ls,
+ [:ls, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_measure, Command::Measure,
+ [:measure, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_show_source, Command::ShowSource,
+ [:show_source, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_whereami, Command::Whereami,
+ [:whereami, NO_OVERRIDE]
+ )
+
+ Command._register_with_aliases(:irb_history, Command::History,
+ [:history, NO_OVERRIDE],
+ [:hist, NO_OVERRIDE]
+ )
+
+ def self.all_commands_info
+ user_aliases = IRB.CurrentContext.command_aliases.each_with_object({}) do |(alias_name, target), result|
+ result[target] ||= []
+ result[target] << alias_name
+ end
+
+ Command.commands.map do |command_name, (command_class, aliases)|
+ aliases = aliases.map { |a| a.first }
+
+ if additional_aliases = user_aliases[command_name]
+ aliases += additional_aliases
+ end
+
+ display_name = aliases.shift || command_name
+ {
+ display_name: display_name,
+ description: command_class.description,
+ category: command_class.category
+ }
+ end
+ end
+
+ def self.command_override_policies
+ @@command_override_policies ||= Command.commands.flat_map do |cmd_name, (cmd_class, 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
+
+ # Convert a command name to its implementation class if such command exists
+ def self.load_command(command)
+ command = command.to_sym
+ Command.commands.each do |command_name, (command_class, aliases)|
+ if command_name == command || aliases.any? { |alias_name, _| alias_name == command }
+ return command_class
+ end
+ end
+ nil
+ end
+
+ # Deprecated. Doesn't have any effect.
+ @EXTEND_COMMANDS = []
+
+ # Drepcated. Use Command.regiser instead.
+ def self.def_extend_command(cmd_name, cmd_class, _, *aliases)
+ Command._register_with_aliases(cmd_name, cmd_class, *aliases)
+ @@command_override_policies = nil
+ end
+ end
+end
diff --git a/test/irb/test_command.rb b/test/irb/test_command.rb
index ca90ec92f8..03fdd37855 100644
--- a/test/irb/test_command.rb
+++ b/test/irb/test_command.rb
@@ -212,20 +212,13 @@ module TestIRB
class CustomCommandTestCase < CommandTestCase
def setup
- super
- execute_lines("help\n") # To ensure command initialization is done
- @EXTEND_COMMANDS_backup = IRB::ExtendCommandBundle.instance_variable_get(:@EXTEND_COMMANDS).dup
- @cvars_backup = IRB::ExtendCommandBundle.class_variables.to_h do |cvar|
- [cvar, IRB::ExtendCommandBundle.class_variable_get(cvar)]
- end
+ @commands_backup = IRB::Command.commands
+ IRB::ExtendCommandBundle.class_variable_set(:@@command_override_policies, nil)
end
def teardown
- super
- IRB::ExtendCommandBundle.instance_variable_set(:@EXTEND_COMMANDS, @EXTEND_COMMANDS_backup)
- @cvars_backup.each do |cvar, value|
- IRB::ExtendCommandBundle.class_variable_set(cvar, value)
- end
+ IRB::ExtendCommandBundle.class_variable_set(:@@command_override_policies, nil)
+ IRB::Command.instance_variable_set(:@commands, @commands_backup)
end
end
@@ -239,8 +232,7 @@ module TestIRB
end
def test_arg
- IRB::Command.const_set :PrintArgCommand, PrintArgCommand
- IRB::ExtendCommandBundle.def_extend_command(:print_arg, :PrintArgCommand, nil, [:pa, IRB::ExtendCommandBundle::OVERRIDE_ALL])
+ IRB::Command._register_with_aliases(:print_arg, PrintArgCommand, [:pa, IRB::ExtendCommandBundle::OVERRIDE_ALL])
out, err = execute_lines("print_arg\n")
assert_empty err
assert_include(out, 'arg=""')
@@ -260,8 +252,6 @@ module TestIRB
out, err = execute_lines("pa a r g \n")
assert_empty err
assert_include(out, 'arg="a r g"')
- ensure
- IRB::Command.send(:remove_const, :PrintArgCommand)
end
end
@@ -274,20 +264,8 @@ module TestIRB
end
end
- def setup
- super
- IRB::Command.const_set :FooBarCommand, FooBarCommand
- end
-
- def teardown
- super
- IRB::Command.send(:remove_const, :FooBarCommand)
- end
-
def test_def_extend_command
- command = [:foobar, :FooBarCommand, nil, [:fbalias, IRB::ExtendCommandBundle::OVERRIDE_ALL]]
- IRB::ExtendCommandBundle.instance_variable_get(:@EXTEND_COMMANDS).push(command)
- IRB::ExtendCommandBundle.def_extend_command(*command)
+ IRB::Command._register_with_aliases(:foobar, FooBarCommand, [:fbalias, IRB::ExtendCommandBundle::OVERRIDE_ALL])
out, err = execute_lines("foobar\n")
assert_empty err
assert_include(out, "FooBar executed")