irb 1.8.3 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.document +1 -1
  3. data/Gemfile +9 -1
  4. data/README.md +149 -25
  5. data/Rakefile +13 -3
  6. data/irb.gemspec +2 -2
  7. data/lib/irb/cmd/nop.rb +3 -52
  8. data/lib/irb/color.rb +2 -2
  9. data/lib/irb/command/backtrace.rb +17 -0
  10. data/lib/irb/command/base.rb +62 -0
  11. data/lib/irb/command/break.rb +17 -0
  12. data/lib/irb/command/catch.rb +17 -0
  13. data/lib/irb/command/chws.rb +40 -0
  14. data/lib/irb/command/context.rb +16 -0
  15. data/lib/irb/{cmd → command}/continue.rb +3 -3
  16. data/lib/irb/{cmd → command}/debug.rb +11 -20
  17. data/lib/irb/{cmd → command}/delete.rb +3 -3
  18. data/lib/irb/command/disable_irb.rb +19 -0
  19. data/lib/irb/command/edit.rb +63 -0
  20. data/lib/irb/command/exit.rb +18 -0
  21. data/lib/irb/{cmd → command}/finish.rb +3 -3
  22. data/lib/irb/command/force_exit.rb +18 -0
  23. data/lib/irb/command/help.rb +83 -0
  24. data/lib/irb/command/history.rb +45 -0
  25. data/lib/irb/command/info.rb +17 -0
  26. data/lib/irb/command/internal_helpers.rb +27 -0
  27. data/lib/irb/{cmd → command}/irb_info.rb +7 -7
  28. data/lib/irb/{cmd → command}/load.rb +23 -8
  29. data/lib/irb/{cmd → command}/ls.rb +30 -14
  30. data/lib/irb/{cmd → command}/measure.rb +18 -17
  31. data/lib/irb/{cmd → command}/next.rb +3 -3
  32. data/lib/irb/command/pushws.rb +65 -0
  33. data/lib/irb/command/show_doc.rb +51 -0
  34. data/lib/irb/command/show_source.rb +74 -0
  35. data/lib/irb/{cmd → command}/step.rb +3 -3
  36. data/lib/irb/{cmd → command}/subirb.rb +31 -17
  37. data/lib/irb/{cmd → command}/whereami.rb +3 -5
  38. data/lib/irb/command.rb +23 -0
  39. data/lib/irb/completion.rb +74 -31
  40. data/lib/irb/context.rb +144 -57
  41. data/lib/irb/debug.rb +18 -0
  42. data/lib/irb/default_commands.rb +260 -0
  43. data/lib/irb/easter-egg.rb +16 -6
  44. data/lib/irb/ext/change-ws.rb +6 -8
  45. data/lib/irb/ext/eval_history.rb +3 -3
  46. data/lib/irb/ext/loader.rb +4 -4
  47. data/lib/irb/ext/multi-irb.rb +5 -5
  48. data/lib/irb/ext/tracer.rb +12 -51
  49. data/lib/irb/ext/use-loader.rb +6 -8
  50. data/lib/irb/ext/workspaces.rb +10 -34
  51. data/lib/irb/frame.rb +1 -1
  52. data/lib/irb/help.rb +3 -3
  53. data/lib/irb/helper_method/base.rb +16 -0
  54. data/lib/irb/helper_method/conf.rb +11 -0
  55. data/lib/irb/helper_method.rb +29 -0
  56. data/lib/irb/history.rb +15 -4
  57. data/lib/irb/init.rb +119 -52
  58. data/lib/irb/input-method.rb +77 -27
  59. data/lib/irb/inspector.rb +3 -3
  60. data/lib/irb/lc/error.rb +1 -11
  61. data/lib/irb/lc/help-message +4 -0
  62. data/lib/irb/lc/ja/error.rb +1 -11
  63. data/lib/irb/lc/ja/help-message +13 -0
  64. data/lib/irb/locale.rb +2 -2
  65. data/lib/irb/nesting_parser.rb +13 -3
  66. data/lib/irb/notifier.rb +1 -1
  67. data/lib/irb/output-method.rb +2 -8
  68. data/lib/irb/pager.rb +16 -11
  69. data/lib/irb/ruby-lex.rb +2 -2
  70. data/lib/irb/ruby_logo.aa +43 -0
  71. data/lib/irb/source_finder.rb +112 -37
  72. data/lib/irb/statement.rb +24 -24
  73. data/lib/irb/version.rb +3 -3
  74. data/lib/irb/workspace.rb +22 -6
  75. data/lib/irb/ws-for-case-2.rb +1 -1
  76. data/lib/irb/xmp.rb +3 -3
  77. data/lib/irb.rb +1071 -556
  78. data/man/irb.1 +7 -0
  79. metadata +41 -31
  80. data/lib/irb/cmd/backtrace.rb +0 -21
  81. data/lib/irb/cmd/break.rb +0 -21
  82. data/lib/irb/cmd/catch.rb +0 -21
  83. data/lib/irb/cmd/chws.rb +0 -36
  84. data/lib/irb/cmd/edit.rb +0 -60
  85. data/lib/irb/cmd/help.rb +0 -23
  86. data/lib/irb/cmd/info.rb +0 -21
  87. data/lib/irb/cmd/pushws.rb +0 -45
  88. data/lib/irb/cmd/show_cmds.rb +0 -53
  89. data/lib/irb/cmd/show_doc.rb +0 -48
  90. data/lib/irb/cmd/show_source.rb +0 -61
  91. data/lib/irb/extend-command.rb +0 -354
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ # :stopdoc:
5
+
6
+ module Command
7
+ class DisableIrb < Base
8
+ category "IRB"
9
+ description "Disable binding.irb."
10
+
11
+ def execute(*)
12
+ ::Binding.define_method(:irb) {}
13
+ IRB.irb_exit
14
+ end
15
+ end
16
+ end
17
+
18
+ # :startdoc:
19
+ end
@@ -0,0 +1,63 @@
1
+ require 'shellwords'
2
+
3
+ require_relative "../color"
4
+ require_relative "../source_finder"
5
+
6
+ module IRB
7
+ # :stopdoc:
8
+
9
+ module Command
10
+ class Edit < Base
11
+ include RubyArgsExtractor
12
+
13
+ category "Misc"
14
+ description 'Open a file or source location.'
15
+ help_message <<~HELP_MESSAGE
16
+ Usage: edit [FILE or constant or method signature]
17
+
18
+ Open a file in the editor specified in #{highlight('ENV["VISUAL"]')} or #{highlight('ENV["EDITOR"]')}
19
+
20
+ - If no arguments are provided, IRB will attempt to open the file the current context was defined in.
21
+ - If FILE is provided, IRB will open the file.
22
+ - If a constant or method signature is provided, IRB will attempt to locate the source file and open it.
23
+
24
+ Examples:
25
+
26
+ edit
27
+ edit foo.rb
28
+ edit Foo
29
+ edit Foo#bar
30
+ HELP_MESSAGE
31
+
32
+ def execute(arg)
33
+ # Accept string literal for backward compatibility
34
+ path = unwrap_string_literal(arg)
35
+
36
+ if path.nil?
37
+ path = @irb_context.irb_path
38
+ elsif !File.exist?(path)
39
+ source = SourceFinder.new(@irb_context).find_source(path)
40
+
41
+ if source&.file_exist? && !source.binary_file?
42
+ path = source.file
43
+ end
44
+ end
45
+
46
+ unless File.exist?(path)
47
+ puts "Can not find file: #{path}"
48
+ return
49
+ end
50
+
51
+ if editor = (ENV['VISUAL'] || ENV['EDITOR'])
52
+ puts "command: '#{editor}'"
53
+ puts " path: #{path}"
54
+ system(*Shellwords.split(editor), path)
55
+ else
56
+ puts "Can not find editor setting: ENV['VISUAL'] or ENV['EDITOR']"
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ # :startdoc:
63
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ # :stopdoc:
5
+
6
+ module Command
7
+ class Exit < Base
8
+ category "IRB"
9
+ description "Exit the current irb session."
10
+
11
+ def execute(_arg)
12
+ IRB.irb_exit
13
+ end
14
+ end
15
+ end
16
+
17
+ # :startdoc:
18
+ end
@@ -5,10 +5,10 @@ require_relative "debug"
5
5
  module IRB
6
6
  # :stopdoc:
7
7
 
8
- module ExtendCommand
8
+ module Command
9
9
  class Finish < DebugCommand
10
- def execute(*args)
11
- super(do_cmds: ["finish", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(do_cmds: "finish #{arg}")
12
12
  end
13
13
  end
14
14
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ # :stopdoc:
5
+
6
+ module Command
7
+ class ForceExit < Base
8
+ category "IRB"
9
+ description "Exit the current process."
10
+
11
+ def execute(_arg)
12
+ throw :IRB_EXIT, true
13
+ end
14
+ end
15
+ end
16
+
17
+ # :startdoc:
18
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ module Command
5
+ class Help < Base
6
+ category "Help"
7
+ description "List all available commands. Use `help <command>` to get information about a specific command."
8
+
9
+ def execute(command_name)
10
+ content =
11
+ if command_name.empty?
12
+ help_message
13
+ else
14
+ if command_class = Command.load_command(command_name)
15
+ command_class.help_message || command_class.description
16
+ else
17
+ "Can't find command `#{command_name}`. Please check the command name and try again.\n\n"
18
+ end
19
+ end
20
+ Pager.page_content(content)
21
+ end
22
+
23
+ private
24
+
25
+ def help_message
26
+ commands_info = IRB::Command.all_commands_info
27
+ helper_methods_info = IRB::HelperMethod.all_helper_methods_info
28
+ commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] }
29
+ commands_grouped_by_categories["Helper methods"] = helper_methods_info
30
+
31
+ if irb_context.with_debugger
32
+ # Remove the original "Debugging" category
33
+ commands_grouped_by_categories.delete("Debugging")
34
+ end
35
+
36
+ longest_cmd_name_length = commands_info.map { |c| c[:display_name].length }.max
37
+
38
+ output = StringIO.new
39
+
40
+ help_cmds = commands_grouped_by_categories.delete("Help")
41
+ no_category_cmds = commands_grouped_by_categories.delete("No category")
42
+ aliases = irb_context.instance_variable_get(:@user_aliases).map do |alias_name, target|
43
+ { display_name: alias_name, description: "Alias for `#{target}`" }
44
+ end
45
+
46
+ # Display help commands first
47
+ add_category_to_output("Help", help_cmds, output, longest_cmd_name_length)
48
+
49
+ # Display the rest of the commands grouped by categories
50
+ commands_grouped_by_categories.each do |category, cmds|
51
+ add_category_to_output(category, cmds, output, longest_cmd_name_length)
52
+ end
53
+
54
+ # Display commands without a category
55
+ if no_category_cmds
56
+ add_category_to_output("No category", no_category_cmds, output, longest_cmd_name_length)
57
+ end
58
+
59
+ # Display aliases
60
+ add_category_to_output("Aliases", aliases, output, longest_cmd_name_length)
61
+
62
+ # Append the debugger help at the end
63
+ if irb_context.with_debugger
64
+ # Add "Debugging (from debug.gem)" category as title
65
+ add_category_to_output("Debugging (from debug.gem)", [], output, longest_cmd_name_length)
66
+ output.puts DEBUGGER__.help
67
+ end
68
+
69
+ output.string
70
+ end
71
+
72
+ def add_category_to_output(category, cmds, output, longest_cmd_name_length)
73
+ output.puts Color.colorize(category, [:BOLD])
74
+
75
+ cmds.each do |cmd|
76
+ output.puts " #{cmd[:display_name].to_s.ljust(longest_cmd_name_length)} #{cmd[:description]}"
77
+ end
78
+
79
+ output.puts
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+
5
+ require_relative "../pager"
6
+
7
+ module IRB
8
+ # :stopdoc:
9
+
10
+ module Command
11
+ class History < Base
12
+ category "IRB"
13
+ description "Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output."
14
+
15
+ def execute(arg)
16
+
17
+ if (match = arg&.match(/(-g|-G)\s+(?<grep>.+)\s*\n\z/))
18
+ grep = Regexp.new(match[:grep])
19
+ end
20
+
21
+ formatted_inputs = irb_context.io.class::HISTORY.each_with_index.reverse_each.filter_map do |input, index|
22
+ next if grep && !input.match?(grep)
23
+
24
+ header = "#{index}: "
25
+
26
+ first_line, *other_lines = input.split("\n")
27
+ first_line = "#{header}#{first_line}"
28
+
29
+ truncated_lines = other_lines.slice!(1..) # Show 1 additional line (2 total)
30
+ other_lines << "..." if truncated_lines&.any?
31
+
32
+ other_lines.map! do |line|
33
+ " " * header.length + line
34
+ end
35
+
36
+ [first_line, *other_lines].join("\n") + "\n"
37
+ end
38
+
39
+ Pager.page_content(formatted_inputs.join)
40
+ end
41
+ end
42
+ end
43
+
44
+ # :startdoc:
45
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "debug"
4
+
5
+ module IRB
6
+ # :stopdoc:
7
+
8
+ module Command
9
+ class Info < DebugCommand
10
+ def execute(arg)
11
+ execute_debug_command(pre_cmds: "info #{arg}")
12
+ end
13
+ end
14
+ end
15
+
16
+ # :startdoc:
17
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ module Command
5
+ # Internal use only, for default command's backward compatibility.
6
+ module RubyArgsExtractor # :nodoc:
7
+ def unwrap_string_literal(str)
8
+ return if str.empty?
9
+
10
+ sexp = Ripper.sexp(str)
11
+ if sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
12
+ @irb_context.workspace.binding.eval(str).to_s
13
+ else
14
+ str
15
+ end
16
+ end
17
+
18
+ def ruby_args(arg)
19
+ # Use throw and catch to handle arg that includes `;`
20
+ # For example: "1, kw: (2; 3); 4" will be parsed to [[1], { kw: 3 }]
21
+ catch(:EXTRACT_RUBY_ARGS) do
22
+ @irb_context.workspace.binding.eval "IRB::Command.extract_ruby_args #{arg}"
23
+ end || [[], {}]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,20 +1,20 @@
1
- # frozen_string_literal: false
2
-
3
- require_relative "nop"
1
+ # frozen_string_literal: true
4
2
 
5
3
  module IRB
6
4
  # :stopdoc:
7
5
 
8
- module ExtendCommand
9
- class IrbInfo < Nop
6
+ module Command
7
+ class IrbInfo < Base
10
8
  category "IRB"
11
9
  description "Show information about IRB."
12
10
 
13
- def execute
11
+ def execute(_arg)
14
12
  str = "Ruby version: #{RUBY_VERSION}\n"
15
13
  str += "IRB version: #{IRB.version}\n"
16
14
  str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
17
- str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
15
+ str += "Completion: #{IRB.CurrentContext.io.respond_to?(:completion_info) ? IRB.CurrentContext.io.completion_info : 'off'}\n"
16
+ rc_files = IRB.irbrc_files
17
+ str += ".irbrc paths: #{rc_files.join(", ")}\n" if rc_files.any?
18
18
  str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
19
19
  str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
20
20
  str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
@@ -1,17 +1,16 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # load.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
5
  #
6
-
7
- require_relative "nop"
8
6
  require_relative "../ext/loader"
9
7
 
10
8
  module IRB
11
9
  # :stopdoc:
12
10
 
13
- module ExtendCommand
14
- class LoaderCommand < Nop
11
+ module Command
12
+ class LoaderCommand < Base
13
+ include RubyArgsExtractor
15
14
  include IrbLoader
16
15
 
17
16
  def raise_cmd_argument_error
@@ -23,7 +22,12 @@ module IRB
23
22
  category "IRB"
24
23
  description "Load a Ruby file."
25
24
 
26
- def execute(file_name = nil, priv = nil)
25
+ def execute(arg)
26
+ args, kwargs = ruby_args(arg)
27
+ execute_internal(*args, **kwargs)
28
+ end
29
+
30
+ def execute_internal(file_name = nil, priv = nil)
27
31
  raise_cmd_argument_error unless file_name
28
32
  irb_load(file_name, priv)
29
33
  end
@@ -32,7 +36,13 @@ module IRB
32
36
  class Require < LoaderCommand
33
37
  category "IRB"
34
38
  description "Require a Ruby file."
35
- def execute(file_name = nil)
39
+
40
+ def execute(arg)
41
+ args, kwargs = ruby_args(arg)
42
+ execute_internal(*args, **kwargs)
43
+ end
44
+
45
+ def execute_internal(file_name = nil)
36
46
  raise_cmd_argument_error unless file_name
37
47
 
38
48
  rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
@@ -65,7 +75,12 @@ module IRB
65
75
  category "IRB"
66
76
  description "Loads a given file in the current session."
67
77
 
68
- def execute(file_name = nil)
78
+ def execute(arg)
79
+ args, kwargs = ruby_args(arg)
80
+ execute_internal(*args, **kwargs)
81
+ end
82
+
83
+ def execute_internal(file_name = nil)
69
84
  raise_cmd_argument_error unless file_name
70
85
 
71
86
  source_file(file_name)
@@ -2,39 +2,55 @@
2
2
 
3
3
  require "reline"
4
4
  require "stringio"
5
- require_relative "nop"
5
+
6
6
  require_relative "../pager"
7
7
  require_relative "../color"
8
8
 
9
9
  module IRB
10
10
  # :stopdoc:
11
11
 
12
- module ExtendCommand
13
- class Ls < Nop
12
+ module Command
13
+ class Ls < Base
14
+ include RubyArgsExtractor
15
+
14
16
  category "Context"
15
- description "Show methods, constants, and variables. `-g [query]` or `-G [query]` allows you to filter out the output."
17
+ description "Show methods, constants, and variables."
18
+
19
+ help_message <<~HELP_MESSAGE
20
+ Usage: ls [obj] [-g [query]]
21
+
22
+ -g [query] Filter the output with a query.
23
+ HELP_MESSAGE
16
24
 
17
- def self.transform_args(args)
18
- if match = args&.match(/\A(?<args>.+\s|)(-g|-G)\s+(?<grep>[^\s]+)\s*\n\z/)
19
- args = match[:args]
20
- "#{args}#{',' unless args.chomp.empty?} grep: /#{match[:grep]}/"
25
+ def execute(arg)
26
+ if match = arg.match(/\A(?<target>.+\s|)(-g|-G)\s+(?<grep>.+)$/)
27
+ if match[:target].empty?
28
+ use_main = true
29
+ else
30
+ obj = @irb_context.workspace.binding.eval(match[:target])
31
+ end
32
+ grep = Regexp.new(match[:grep])
21
33
  else
22
- args
34
+ args, kwargs = ruby_args(arg)
35
+ use_main = args.empty?
36
+ obj = args.first
37
+ grep = kwargs[:grep]
38
+ end
39
+
40
+ if use_main
41
+ obj = irb_context.workspace.main
42
+ locals = irb_context.workspace.binding.local_variables
23
43
  end
24
- end
25
44
 
26
- def execute(*arg, grep: nil)
27
45
  o = Output.new(grep: grep)
28
46
 
29
- obj = arg.empty? ? irb_context.workspace.main : arg.first
30
- locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
31
47
  klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
32
48
 
33
49
  o.dump("constants", obj.constants) if obj.respond_to?(:constants)
34
50
  dump_methods(o, klass, obj)
35
51
  o.dump("instance variables", obj.instance_variables)
36
52
  o.dump("class variables", klass.class_variables)
37
- o.dump("locals", locals)
53
+ o.dump("locals", locals) if locals
38
54
  o.print_result
39
55
  end
40
56
 
@@ -1,10 +1,10 @@
1
- require_relative "nop"
2
-
3
1
  module IRB
4
2
  # :stopdoc:
5
3
 
6
- module ExtendCommand
7
- class Measure < Nop
4
+ module Command
5
+ class Measure < Base
6
+ include RubyArgsExtractor
7
+
8
8
  category "Misc"
9
9
  description "`measure` enables the mode to measure processing time. `measure :off` disables it."
10
10
 
@@ -12,32 +12,33 @@ module IRB
12
12
  super(*args)
13
13
  end
14
14
 
15
- def execute(type = nil, arg = nil, &block)
15
+ def execute(arg)
16
+ if arg&.match?(/^do$|^do[^\w]|^\{/)
17
+ warn 'Configure IRB.conf[:MEASURE_PROC] to add custom measure methods.'
18
+ return
19
+ end
20
+ args, kwargs = ruby_args(arg)
21
+ execute_internal(*args, **kwargs)
22
+ end
23
+
24
+ def execute_internal(type = nil, arg = nil)
16
25
  # Please check IRB.init_config in lib/irb/init.rb that sets
17
26
  # IRB.conf[:MEASURE_PROC] to register default "measure" methods,
18
27
  # "measure :time" (abbreviated as "measure") and "measure :stackprof".
28
+
19
29
  case type
20
30
  when :off
21
- IRB.conf[:MEASURE] = nil
22
31
  IRB.unset_measure_callback(arg)
23
32
  when :list
24
33
  IRB.conf[:MEASURE_CALLBACKS].each do |type_name, _, arg_val|
25
34
  puts "- #{type_name}" + (arg_val ? "(#{arg_val.inspect})" : '')
26
35
  end
27
36
  when :on
28
- IRB.conf[:MEASURE] = true
29
- added = IRB.set_measure_callback(type, arg)
37
+ added = IRB.set_measure_callback(arg)
30
38
  puts "#{added[0]} is added." if added
31
39
  else
32
- if block_given?
33
- IRB.conf[:MEASURE] = true
34
- added = IRB.set_measure_callback(&block)
35
- puts "#{added[0]} is added." if added
36
- else
37
- IRB.conf[:MEASURE] = true
38
- added = IRB.set_measure_callback(type, arg)
39
- puts "#{added[0]} is added." if added
40
- end
40
+ added = IRB.set_measure_callback(type, arg)
41
+ puts "#{added[0]} is added." if added
41
42
  end
42
43
  nil
43
44
  end
@@ -5,10 +5,10 @@ require_relative "debug"
5
5
  module IRB
6
6
  # :stopdoc:
7
7
 
8
- module ExtendCommand
8
+ module Command
9
9
  class Next < DebugCommand
10
- def execute(*args)
11
- super(do_cmds: ["next", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(do_cmds: "next #{arg}")
12
12
  end
13
13
  end
14
14
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # change-ws.rb -
4
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
+ #
6
+
7
+ require_relative "../ext/workspaces"
8
+
9
+ module IRB
10
+ # :stopdoc:
11
+
12
+ module Command
13
+ class Workspaces < Base
14
+ category "Workspace"
15
+ description "Show workspaces."
16
+
17
+ def execute(_arg)
18
+ inspection_resuls = irb_context.instance_variable_get(:@workspace_stack).map do |ws|
19
+ truncated_inspect(ws.main)
20
+ end
21
+
22
+ puts "[" + inspection_resuls.join(", ") + "]"
23
+ end
24
+
25
+ private
26
+
27
+ def truncated_inspect(obj)
28
+ obj_inspection = obj.inspect
29
+
30
+ if obj_inspection.size > 20
31
+ obj_inspection = obj_inspection[0, 19] + "...>"
32
+ end
33
+
34
+ obj_inspection
35
+ end
36
+ end
37
+
38
+ class PushWorkspace < Workspaces
39
+ category "Workspace"
40
+ description "Push an object to the workspace stack."
41
+
42
+ def execute(arg)
43
+ if arg.empty?
44
+ irb_context.push_workspace
45
+ else
46
+ obj = eval(arg, irb_context.workspace.binding)
47
+ irb_context.push_workspace(obj)
48
+ end
49
+ super
50
+ end
51
+ end
52
+
53
+ class PopWorkspace < Workspaces
54
+ category "Workspace"
55
+ description "Pop a workspace from the workspace stack."
56
+
57
+ def execute(_arg)
58
+ irb_context.pop_workspace
59
+ super
60
+ end
61
+ end
62
+ end
63
+
64
+ # :startdoc:
65
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ module Command
5
+ class ShowDoc < Base
6
+ include RubyArgsExtractor
7
+
8
+ category "Context"
9
+ description "Look up documentation with RI."
10
+
11
+ help_message <<~HELP_MESSAGE
12
+ Usage: show_doc [name]
13
+
14
+ When name is provided, IRB will look up the documentation for the given name.
15
+ When no name is provided, a RI session will be started.
16
+
17
+ Examples:
18
+
19
+ show_doc
20
+ show_doc Array
21
+ show_doc Array#each
22
+
23
+ HELP_MESSAGE
24
+
25
+ def execute(arg)
26
+ # Accept string literal for backward compatibility
27
+ name = unwrap_string_literal(arg)
28
+ require 'rdoc/ri/driver'
29
+
30
+ unless ShowDoc.const_defined?(:Ri)
31
+ opts = RDoc::RI::Driver.process_args([])
32
+ ShowDoc.const_set(:Ri, RDoc::RI::Driver.new(opts))
33
+ end
34
+
35
+ if name.nil?
36
+ Ri.interactive
37
+ else
38
+ begin
39
+ Ri.display_name(name)
40
+ rescue RDoc::RI::Error
41
+ puts $!.message
42
+ end
43
+ end
44
+
45
+ nil
46
+ rescue LoadError, SystemExit
47
+ warn "Can't display document because `rdoc` is not installed."
48
+ end
49
+ end
50
+ end
51
+ end