diff --git a/COMPARED_WITH_PRY.md b/COMPARED_WITH_PRY.md index 94bf3020f..ef7ea1dec 100644 --- a/COMPARED_WITH_PRY.md +++ b/COMPARED_WITH_PRY.md @@ -9,7 +9,7 @@ Feel free to chip in and update this table - we appreciate your help! | Supported Rubies | `>= 2.0` | `>= 2.7` | | | Source code browsing | `show-source` | `show_source` | IRB's `show_source` can't display C source. See [#664](https://github.com/ruby/irb/issues/664) | | Document browsing | `ri` | `show_doc` | | -| Live help system | `help` or `command_name --help` | `show_cmds` | IRB doesn't support detailed descriptions for individual commands yet | +| Live help system | `help` or `command_name --help` | `help` | IRB doesn't support detailed descriptions for individual commands yet | | Open methods in editors | `edit` | `edit` | | | Syntax highlighting | Yes | Yes | | | Command shell integration | Yes | No | Currently, there's no plan to support such features in IRB | diff --git a/README.md b/README.md index 86cfbe876..ac1b164bc 100644 --- a/README.md +++ b/README.md @@ -107,9 +107,12 @@ Hello World ## Commands -The following commands are available on IRB. You can get the same output from the `show_cmds` command. +The following commands are available on IRB. You can get the same output from the `help` command. ```txt +Help + help List all available commands. Use `help ` to get information about a specific command. + IRB exit Exit the current irb session. exit! Exit the current process. @@ -117,7 +120,6 @@ IRB irb_require Require a Ruby file. source Loads a given file in the current session. irb_info Show information about IRB. - show_cmds List all available commands and their description. history Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output. Workspace @@ -146,13 +148,12 @@ Debugging info Start the debugger of debug.gem and run its `info` command. Misc - edit Open a file with the editor command defined with `ENV["VISUAL"]` or `ENV["EDITOR"]`. + edit Open a file or source location. measure `measure` enables the mode to measure processing time. `measure :off` disables it. Context - help [DEPRECATED] Enter the mode to look up RI documents. show_doc Enter the mode to look up RI documents. - ls Show methods, constants, and variables. `-g [query]` or `-G [query]` allows you to filter out the output. + ls Show methods, constants, and variables. show_source Show the source code of a given method or constant. whereami Show the source code around binding.irb again. @@ -228,7 +229,7 @@ end To learn about these features, please refer to `debug.gem`'s [commands list](https://github.com/ruby/debug#debug-command-on-the-debug-console). -In the `irb:rdbg` session, the `show_cmds` command will also display all commands from `debug.gem`. +In the `irb:rdbg` session, the `help` command will also display all commands from `debug.gem`. ### Advantages Over `debug.gem`'s Console diff --git a/lib/irb.rb b/lib/irb.rb index 73d96947e..09ea9256c 100644 --- a/lib/irb.rb +++ b/lib/irb.rb @@ -811,7 +811,7 @@ # # === 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 cab571cfe..c84474e63 100644 --- a/lib/irb/command.rb +++ b/lib/irb/command.rb @@ -162,6 +162,7 @@ def irb_context [ :irb_help, :Help, "command/help", [:help, NO_OVERRIDE], + [:show_cmds, NO_OVERRIDE], ], [ @@ -187,16 +188,10 @@ def irb_context :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], diff --git a/lib/irb/command/help.rb b/lib/irb/command/help.rb index 67cc31a0b..a111e4d11 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 ` 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.banner || 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/show_cmds.rb b/lib/irb/command/show_cmds.rb deleted file mode 100644 index 7f266d207..000000000 --- a/lib/irb/command/show_cmds.rb +++ /dev/null @@ -1,86 +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." - - 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.banner || 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") - # 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 - - output.string - end - end - end - - # :startdoc: -end diff --git a/lib/irb/statement.rb b/lib/irb/statement.rb index 009eb2d20..1e026d112 100644 --- a/lib/irb/statement.rb +++ b/lib/irb/statement.rb @@ -83,9 +83,8 @@ def suppresses_echo? 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 diff --git a/test/irb/command/test_help.rb b/test/irb/command/test_help.rb index f2b49e7f5..c82c43a4c 100644 --- a/test/irb/command/test_help.rb +++ b/test/irb/command/test_help.rb @@ -21,7 +21,7 @@ def test_help type "exit" end - assert_match(/List all available commands and their description/, out) + assert_match(/List all available commands/, out) assert_match(/Start the debugger of debug\.gem/, out) end @@ -31,7 +31,7 @@ def test_command_help type "exit" end - assert_match(/Show methods, constants, and variables\./, out) + assert_match(/Usage: ls \[obj\]/, out) end def test_command_help_not_found @@ -45,11 +45,11 @@ def test_command_help_not_found def test_show_cmds out = run_ruby_file do - type "show_cmds" + type "help" type "exit" end - assert_match(/List all available commands and their description/, out) + assert_match(/List all available commands/, out) assert_match(/Start the debugger of debug\.gem/, out) end diff --git a/test/irb/test_debugger_integration.rb b/test/irb/test_debugger_integration.rb index d95b01c3d..839a0d43f 100644 --- a/test/irb/test_debugger_integration.rb +++ b/test/irb/test_debugger_integration.rb @@ -345,19 +345,19 @@ def test_help_command_is_delegated_to_the_debugger assert_include(output, "### Frame control") end - def test_show_cmds_display_different_content_when_debugger_is_enabled + def test_help_display_different_content_when_debugger_is_enabled write_ruby <<~'ruby' binding.irb ruby output = run_ruby_file do type "debug" - type "show_cmds" + type "help" type "continue" end # IRB's commands should still be listed - assert_match(/show_cmds\s+List all available commands and their description\./, output) + assert_match(/help\s+List all available commands/, output) # debug gem's commands should be appended at the end assert_match(/Debugging \(from debug\.gem\)\s+### Control flow/, output) end diff --git a/test/irb/yamatanooroti/test_rendering.rb b/test/irb/yamatanooroti/test_rendering.rb index e121b302c..a0477ee48 100644 --- a/test/irb/yamatanooroti/test_rendering.rb +++ b/test/irb/yamatanooroti/test_rendering.rb @@ -356,7 +356,7 @@ def test_show_cmds_with_pager_can_quit_with_ctrl_c puts 'start IRB' LINES start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB') - write("show_cmds\n") + write("help\n") write("G") # move to the end of the screen write("\C-c") # quit pager write("'foo' + 'bar'\n") # eval something to make sure IRB resumes