[ruby/irb] Add "show_cmds" command to list all commands'
descriptions (https://github.com/ruby/irb/pull/463) https://github.com/ruby/irb/commit/7e857655ac
This commit is contained in:
parent
2cea8e014d
commit
3956bb859c
@ -6,7 +6,7 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class Backtrace < Debug
|
||||
class Backtrace < DebugCommand
|
||||
def self.transform_args(args)
|
||||
args&.dump
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class Break < Debug
|
||||
class Break < DebugCommand
|
||||
def self.transform_args(args)
|
||||
args&.dump
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class Catch < Debug
|
||||
class Catch < DebugCommand
|
||||
def self.transform_args(args)
|
||||
args&.dump
|
||||
end
|
||||
|
@ -19,12 +19,18 @@ module IRB
|
||||
module ExtendCommand
|
||||
|
||||
class CurrentWorkingWorkspace < Nop
|
||||
category "IRB"
|
||||
description "Show the current workspace."
|
||||
|
||||
def execute(*obj)
|
||||
irb_context.main
|
||||
end
|
||||
end
|
||||
|
||||
class ChangeWorkspace < Nop
|
||||
category "IRB"
|
||||
description "Change the current workspace to an object."
|
||||
|
||||
def execute(*obj)
|
||||
irb_context.change_workspace(*obj)
|
||||
irb_context.main
|
||||
|
@ -6,7 +6,7 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class Continue < Debug
|
||||
class Continue < DebugCommand
|
||||
def execute(*args)
|
||||
super(do_cmds: ["continue", *args].join(" "))
|
||||
end
|
||||
|
@ -5,6 +5,9 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class Debug < Nop
|
||||
category "Debugging"
|
||||
description "Start the debugger of debug.gem."
|
||||
|
||||
BINDING_IRB_FRAME_REGEXPS = [
|
||||
'<internal:prelude>',
|
||||
binding.method(:irb).source_location.first,
|
||||
@ -108,5 +111,16 @@ module IRB
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class DebugCommand < Debug
|
||||
def self.category
|
||||
"Debugging"
|
||||
end
|
||||
|
||||
def self.description
|
||||
command_name = self.name.split("::").last.downcase
|
||||
"Start the debugger of debug.gem and run its `#{command_name}` command."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class Delete < Debug
|
||||
class Delete < DebugCommand
|
||||
def execute(*args)
|
||||
super(pre_cmds: ["delete", *args].join(" "))
|
||||
end
|
||||
|
@ -6,6 +6,9 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class Edit < Nop
|
||||
category "Misc"
|
||||
description 'Open a file with the editor command defined with `ENV["EDITOR"]`.'
|
||||
|
||||
class << self
|
||||
def transform_args(args)
|
||||
# Return a string literal as is for backward compatibility
|
||||
|
@ -6,7 +6,7 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class Finish < Debug
|
||||
class Finish < DebugCommand
|
||||
def execute(*args)
|
||||
super(do_cmds: ["finish", *args].join(" "))
|
||||
end
|
||||
|
@ -16,6 +16,9 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class Help < Nop
|
||||
category "Context"
|
||||
description "Enter the mode to look up RI documents."
|
||||
|
||||
def execute(*names)
|
||||
require 'rdoc/ri/driver'
|
||||
opts = RDoc::RI::Driver.process_args([])
|
||||
|
@ -6,7 +6,7 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class Info < Debug
|
||||
class Info < DebugCommand
|
||||
def self.transform_args(args)
|
||||
args&.dump
|
||||
end
|
||||
|
@ -7,6 +7,9 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class IrbInfo < Nop
|
||||
category "IRB"
|
||||
description "Show information about IRB."
|
||||
|
||||
def execute
|
||||
Class.new {
|
||||
def inspect
|
||||
|
@ -20,6 +20,9 @@ module IRB
|
||||
class Load < Nop
|
||||
include IrbLoader
|
||||
|
||||
category "IRB"
|
||||
description "Load a Ruby file."
|
||||
|
||||
def execute(file_name, priv = nil)
|
||||
return irb_load(file_name, priv)
|
||||
end
|
||||
@ -28,6 +31,9 @@ module IRB
|
||||
class Require < Nop
|
||||
include IrbLoader
|
||||
|
||||
category "IRB"
|
||||
description "Require a Ruby file."
|
||||
|
||||
def execute(file_name)
|
||||
|
||||
rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
|
||||
@ -58,6 +64,10 @@ module IRB
|
||||
|
||||
class Source < Nop
|
||||
include IrbLoader
|
||||
|
||||
category "IRB"
|
||||
description "Loads a given file in the current session."
|
||||
|
||||
def execute(file_name)
|
||||
source_file(file_name)
|
||||
end
|
||||
|
@ -9,6 +9,9 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class Ls < Nop
|
||||
category "Context"
|
||||
description "Show methods, constants, and variables. `-g [query]` or `-G [query]` allows you to filter out the output."
|
||||
|
||||
def self.transform_args(args)
|
||||
if match = args&.match(/\A(?<args>.+\s|)(-g|-G)\s+(?<grep>[^\s]+)\s*\n\z/)
|
||||
args = match[:args]
|
||||
|
@ -5,6 +5,9 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class Measure < Nop
|
||||
category "Misc"
|
||||
description "`measure` enables the mode to measure processing time. `measure :off` disables it."
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class Next < Debug
|
||||
class Next < DebugCommand
|
||||
def execute(*args)
|
||||
super(do_cmds: ["next", *args].join(" "))
|
||||
end
|
||||
|
@ -14,6 +14,17 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class Nop
|
||||
class << self
|
||||
def category(category = nil)
|
||||
@category = category if category
|
||||
@category
|
||||
end
|
||||
|
||||
def description(description = nil)
|
||||
@description = description if description
|
||||
@description
|
||||
end
|
||||
end
|
||||
|
||||
if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
|
||||
def self.execute(conf, *opts, **kwargs, &block)
|
||||
|
@ -18,12 +18,18 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class Workspaces < Nop
|
||||
category "IRB"
|
||||
description "Show workspaces."
|
||||
|
||||
def execute(*obj)
|
||||
irb_context.workspaces.collect{|ws| ws.main}
|
||||
end
|
||||
end
|
||||
|
||||
class PushWorkspace < Workspaces
|
||||
category "IRB"
|
||||
description "Push an object to the workspace stack."
|
||||
|
||||
def execute(*obj)
|
||||
irb_context.push_workspace(*obj)
|
||||
super
|
||||
@ -31,6 +37,9 @@ module IRB
|
||||
end
|
||||
|
||||
class PopWorkspace < Workspaces
|
||||
category "IRB"
|
||||
description "Pop a workspace from the workspace stack."
|
||||
|
||||
def execute(*obj)
|
||||
irb_context.pop_workspace(*obj)
|
||||
super
|
||||
|
39
lib/irb/cmd/show_cmds.rb
Normal file
39
lib/irb/cmd/show_cmds.rb
Normal file
@ -0,0 +1,39 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "stringio"
|
||||
require_relative "nop"
|
||||
|
||||
module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class ShowCmds < Nop
|
||||
category "IRB"
|
||||
description "List all available commands and their description."
|
||||
|
||||
def execute(*args)
|
||||
commands_info = IRB::ExtendCommandBundle.all_commands_info
|
||||
commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] }
|
||||
longest_cmd_name_length = commands_info.map { |c| c[:display_name] }.max { |a, b| a.length <=> b.length }.length
|
||||
|
||||
output = StringIO.new
|
||||
|
||||
commands_grouped_by_categories.each do |category, cmds|
|
||||
output.puts Color.colorize(category, [:BOLD])
|
||||
|
||||
cmds.each do |cmd|
|
||||
output.puts " #{cmd[:display_name].to_s.ljust(longest_cmd_name_length)} #{cmd[:description]}"
|
||||
end
|
||||
|
||||
output.puts
|
||||
end
|
||||
|
||||
puts output.string
|
||||
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# :startdoc:
|
||||
end
|
@ -9,6 +9,9 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class ShowSource < Nop
|
||||
category "Context"
|
||||
description "Show the source code of a given method or constant."
|
||||
|
||||
class << self
|
||||
def transform_args(args)
|
||||
# Return a string literal as is for backward compatibility
|
||||
|
@ -6,7 +6,7 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class Step < Debug
|
||||
class Step < DebugCommand
|
||||
def execute(*args)
|
||||
# Run `next` first to move out of binding.irb
|
||||
super(pre_cmds: "next", do_cmds: ["step", *args].join(" "))
|
||||
|
@ -30,24 +30,36 @@ module IRB
|
||||
end
|
||||
|
||||
class IrbCommand < MultiIRBCommand
|
||||
category "IRB"
|
||||
description "Start a child IRB."
|
||||
|
||||
def execute(*obj)
|
||||
IRB.irb(nil, *obj)
|
||||
end
|
||||
end
|
||||
|
||||
class Jobs < MultiIRBCommand
|
||||
category "IRB"
|
||||
description "List of current sessions."
|
||||
|
||||
def execute
|
||||
IRB.JobManager
|
||||
end
|
||||
end
|
||||
|
||||
class Foreground < MultiIRBCommand
|
||||
category "IRB"
|
||||
description "Switches to the session of the given number."
|
||||
|
||||
def execute(key)
|
||||
IRB.JobManager.switch(key)
|
||||
end
|
||||
end
|
||||
|
||||
class Kill < MultiIRBCommand
|
||||
category "IRB"
|
||||
description "Kills the session with the given number."
|
||||
|
||||
def execute(*keys)
|
||||
IRB.JobManager.kill(*keys)
|
||||
end
|
||||
|
@ -7,6 +7,9 @@ module IRB
|
||||
|
||||
module ExtendCommand
|
||||
class Whereami < Nop
|
||||
category "Context"
|
||||
description "Show the source code around binding.irb again."
|
||||
|
||||
def execute(*)
|
||||
code = irb_context.workspace.code_around_binding
|
||||
if code
|
||||
|
@ -45,14 +45,15 @@ module IRB # :nodoc:
|
||||
[:quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
|
||||
]
|
||||
|
||||
|
||||
@EXTEND_COMMANDS = [
|
||||
[
|
||||
:irb_current_working_workspace, :CurrentWorkingWorkspace, "cmd/chws",
|
||||
[:cwws, NO_OVERRIDE],
|
||||
[:pwws, NO_OVERRIDE],
|
||||
[:irb_print_working_workspace, OVERRIDE_ALL],
|
||||
[:irb_cwws, OVERRIDE_ALL],
|
||||
[:irb_pwws, OVERRIDE_ALL],
|
||||
[:cwws, NO_OVERRIDE],
|
||||
[:pwws, NO_OVERRIDE],
|
||||
[:irb_current_working_binding, OVERRIDE_ALL],
|
||||
[:irb_print_working_binding, OVERRIDE_ALL],
|
||||
[:irb_cwb, OVERRIDE_ALL],
|
||||
@ -60,10 +61,10 @@ module IRB # :nodoc:
|
||||
],
|
||||
[
|
||||
:irb_change_workspace, :ChangeWorkspace, "cmd/chws",
|
||||
[:irb_chws, OVERRIDE_ALL],
|
||||
[:irb_cws, OVERRIDE_ALL],
|
||||
[: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],
|
||||
@ -77,16 +78,16 @@ module IRB # :nodoc:
|
||||
],
|
||||
[
|
||||
:irb_push_workspace, :PushWorkspace, "cmd/pushws",
|
||||
[:irb_pushws, OVERRIDE_ALL],
|
||||
[:pushws, NO_OVERRIDE],
|
||||
[:irb_pushws, OVERRIDE_ALL],
|
||||
[:irb_push_binding, OVERRIDE_ALL],
|
||||
[:irb_pushb, OVERRIDE_ALL],
|
||||
[:pushb, NO_OVERRIDE],
|
||||
],
|
||||
[
|
||||
:irb_pop_workspace, :PopWorkspace, "cmd/pushws",
|
||||
[:irb_popws, OVERRIDE_ALL],
|
||||
[:popws, NO_OVERRIDE],
|
||||
[:irb_popws, OVERRIDE_ALL],
|
||||
[:irb_pop_binding, OVERRIDE_ALL],
|
||||
[:irb_popb, OVERRIDE_ALL],
|
||||
[:popb, NO_OVERRIDE],
|
||||
@ -131,7 +132,7 @@ module IRB # :nodoc:
|
||||
:irb_catch, :Catch, "cmd/catch",
|
||||
],
|
||||
[
|
||||
:irb_next, :Next, "cmd/next",
|
||||
:irb_next, :Next, "cmd/next"
|
||||
],
|
||||
[
|
||||
:irb_delete, :Delete, "cmd/delete",
|
||||
@ -187,9 +188,41 @@ module IRB # :nodoc:
|
||||
:irb_whereami, :Whereami, "cmd/whereami",
|
||||
[:whereami, NO_OVERRIDE],
|
||||
],
|
||||
|
||||
[
|
||||
:irb_show_cmds, :ShowCmds, "cmd/show_cmds",
|
||||
[:show_cmds, NO_OVERRIDE],
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
@@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?(ExtendCommand) || !ExtendCommand.const_defined?(cmd_class, false)
|
||||
require_relative load_file
|
||||
end
|
||||
|
||||
klass = ExtendCommand.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 }
|
||||
end
|
||||
|
||||
@@commands
|
||||
end
|
||||
|
||||
# Convert a command name to its implementation class if such command exists
|
||||
def self.load_command(command)
|
||||
command = command.to_sym
|
||||
|
@ -583,6 +583,16 @@ module TestIRB
|
||||
$bar = nil
|
||||
end
|
||||
|
||||
def test_show_cmds
|
||||
out, err = execute_lines(
|
||||
"show_cmds\n"
|
||||
)
|
||||
|
||||
assert_empty err
|
||||
assert_match(/List all available commands and their description/, out)
|
||||
assert_match(/Start the debugger of debug\.gem/, out)
|
||||
end
|
||||
|
||||
class EditTest < CommandTestCase
|
||||
def setup
|
||||
@original_editor = ENV["EDITOR"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user