diff options
| author | Stan Lo <stan001212@gmail.com> | 2024-02-18 18:21:00 +0000 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2024-02-18 18:21:08 +0000 |
| commit | 07c774e85cf0a3352c045ec3ae83db1215962997 (patch) | |
| tree | 9d478ba5140bcdce2a8086c93a75d112e6ea5ae5 /lib | |
| parent | 120c291fafd438e2bc58f098023c669dadc64b08 (diff) | |
[ruby/irb] Revamp `help` command
(https://github.com/ruby/irb/pull/877)
* Make help command display help for individual commands
Usage: `help [command]`
If the command is not specified, it will display a list of all available commands.
If the command is specified, it will display the banner OR description of the command.
If the command is not found, it will display a message saying that the command is not found.
* Rename test/irb/cmd to test/irb/command
* Add banner to edit and ls commands
* Promote help command in the help message
1. Make `show_cmds` an alias of `help` so it's not displayed in the help message
2. Update description of the help command to reflect `help <command>` syntax
* Rename banner to help_message
https://github.com/ruby/irb/commit/43a2c99f3f
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/irb.rb | 2 | ||||
| -rw-r--r-- | lib/irb/command.rb | 7 | ||||
| -rw-r--r-- | lib/irb/command/base.rb | 9 | ||||
| -rw-r--r-- | lib/irb/command/edit.rb | 18 | ||||
| -rw-r--r-- | lib/irb/command/help.rb | 82 | ||||
| -rw-r--r-- | lib/irb/command/ls.rb | 8 | ||||
| -rw-r--r-- | lib/irb/command/show_cmds.rb | 59 | ||||
| -rw-r--r-- | lib/irb/statement.rb | 3 |
8 files changed, 113 insertions, 75 deletions
diff --git a/lib/irb.rb b/lib/irb.rb index 73d96947ea..09ea9256cb 100644 --- a/lib/irb.rb +++ b/lib/irb.rb @@ -811,7 +811,7 @@ require_relative "irb/pager" # # === Commands # -# Please use the `show_cmds` command to see the list of available commands. +# Please use the `help` command to see the list of available commands. # # === IRB Sessions # diff --git a/lib/irb/command.rb b/lib/irb/command.rb index cab571cfe3..c84474e633 100644 --- a/lib/irb/command.rb +++ b/lib/irb/command.rb @@ -162,6 +162,7 @@ module IRB # :nodoc: [ :irb_help, :Help, "command/help", [:help, NO_OVERRIDE], + [:show_cmds, NO_OVERRIDE], ], [ @@ -187,17 +188,11 @@ module IRB # :nodoc: :irb_show_source, :ShowSource, "command/show_source", [:show_source, NO_OVERRIDE], ], - [ :irb_whereami, :Whereami, "command/whereami", [:whereami, NO_OVERRIDE], ], [ - :irb_show_cmds, :ShowCmds, "command/show_cmds", - [:show_cmds, NO_OVERRIDE], - ], - - [ :irb_history, :History, "command/history", [:history, NO_OVERRIDE], [:hist, NO_OVERRIDE], diff --git a/lib/irb/command/base.rb b/lib/irb/command/base.rb index 87d2fea356..880b781a46 100644 --- a/lib/irb/command/base.rb +++ b/lib/irb/command/base.rb @@ -22,12 +22,21 @@ module IRB @description end + def help_message(help_message = nil) + @help_message = help_message if help_message + @help_message + end + 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) diff --git a/lib/irb/command/edit.rb b/lib/irb/command/edit.rb index 1a8ded6bcf..ab8c62663e 100644 --- a/lib/irb/command/edit.rb +++ b/lib/irb/command/edit.rb @@ -8,7 +8,23 @@ module IRB module Command class Edit < Base category "Misc" - description 'Open a file with the editor command defined with `ENV["VISUAL"]` or `ENV["EDITOR"]`.' + description 'Open a file or source location.' + help_message <<~HELP_MESSAGE + Usage: edit [FILE or constant or method signature] + + Open a file in the editor specified in #{highlight('ENV["VISUAL"]')} or #{highlight('ENV["EDITOR"]')} + + - If no arguments are provided, IRB will attempt to open the file the current context was defined in. + - If FILE is provided, IRB will open the file. + - If a constant or method signature is provided, IRB will attempt to locate the source file and open it. + + Examples: + + edit + edit foo.rb + edit Foo + edit Foo#bar + HELP_MESSAGE class << self def transform_args(args) diff --git a/lib/irb/command/help.rb b/lib/irb/command/help.rb index 67cc31a0bf..19113dbbfe 100644 --- a/lib/irb/command/help.rb +++ b/lib/irb/command/help.rb @@ -1,12 +1,84 @@ # frozen_string_literal: true -require_relative "show_cmds" - module IRB module Command - class Help < ShowCmds - category "IRB" - description "List all available commands and their description." + class Help < Base + 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) + content = + if command_name + 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 + + private + + def help_message + commands_info = IRB::ExtendCommandBundle.all_commands_info + commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] } + + user_aliases = irb_context.instance_variable_get(:@user_aliases) + + commands_grouped_by_categories["Aliases"] = user_aliases.map do |alias_name, target| + { display_name: alias_name, description: "Alias for `#{target}`" } + end + + if irb_context.with_debugger + # Remove the original "Debugging" category + commands_grouped_by_categories.delete("Debugging") + # Add an empty "Debugging (from debug.gem)" category at the end + commands_grouped_by_categories["Debugging (from debug.gem)"] = [] + end + + longest_cmd_name_length = commands_info.map { |c| c[:display_name].length }.max + + output = StringIO.new + + help_cmds = commands_grouped_by_categories.delete("Help") + + add_category_to_output("Help", help_cmds, output, longest_cmd_name_length) + + commands_grouped_by_categories.each do |category, cmds| + add_category_to_output(category, cmds, output, longest_cmd_name_length) + end + + # Append the debugger help at the end + if irb_context.with_debugger + output.puts DEBUGGER__.help + end + + output.string + end + + def add_category_to_output(category, cmds, output, longest_cmd_name_length) + 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 end end end diff --git a/lib/irb/command/ls.rb b/lib/irb/command/ls.rb index bbe4a1ee98..6b6136c2fe 100644 --- a/lib/irb/command/ls.rb +++ b/lib/irb/command/ls.rb @@ -12,7 +12,13 @@ module IRB module Command class Ls < Base category "Context" - description "Show methods, constants, and variables. `-g [query]` or `-G [query]` allows you to filter out the output." + description "Show methods, constants, and variables." + + help_message <<~HELP_MESSAGE + Usage: ls [obj] [-g [query]] + + -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/) diff --git a/lib/irb/command/show_cmds.rb b/lib/irb/command/show_cmds.rb deleted file mode 100644 index 940ed490d3..0000000000 --- a/lib/irb/command/show_cmds.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -require "stringio" - -require_relative "../pager" - -module IRB - # :stopdoc: - - module Command - class ShowCmds < Base - 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] } - - user_aliases = irb_context.instance_variable_get(:@user_aliases) - - commands_grouped_by_categories["Aliases"] = user_aliases.map do |alias_name, target| - { display_name: alias_name, description: "Alias for `#{target}`" } - end - - if irb_context.with_debugger - # Remove the original "Debugging" category - commands_grouped_by_categories.delete("Debugging") - # Remove the `help` command as it's delegated to the debugger - commands_grouped_by_categories["Context"].delete_if { |cmd| cmd[:display_name] == :help } - # Add an empty "Debugging (from debug.gem)" category at the end - commands_grouped_by_categories["Debugging (from debug.gem)"] = [] - end - - longest_cmd_name_length = commands_info.map { |c| c[:display_name].length }.max - - 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 - - # Append the debugger help at the end - if irb_context.with_debugger - output.puts DEBUGGER__.help - end - - Pager.page_content(output.string) - end - end - end - - # :startdoc: -end diff --git a/lib/irb/statement.rb b/lib/irb/statement.rb index 009eb2d20b..1e026d112f 100644 --- a/lib/irb/statement.rb +++ b/lib/irb/statement.rb @@ -83,9 +83,8 @@ module IRB end def should_be_handled_by_debugger? - require_relative 'command/help' require_relative 'command/debug' - IRB::Command::DebugCommand > @command_class || IRB::Command::Help == @command_class + IRB::Command::DebugCommand > @command_class end def evaluable_code |
