irb 1.7.4 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea4ae752c3ffee02c55d78d1da5032244d6c9574fc8a7e64bcd4d0798e89b619
4
- data.tar.gz: 24eb6d55d8c1fdead9230a92d3f70016936ccbe99a69bdef60de9d68108e0336
3
+ metadata.gz: 0b6bfef2fbb8e5e7d7587a567055e2b7f019678d2355f6ae52f7a7d8161df0c0
4
+ data.tar.gz: 653be685d9f249341c3e165cb4303baa05563c5556cc2bf2584243c39ec0cb92
5
5
  SHA512:
6
- metadata.gz: 3aec5c7c99c1dc58ed3f427cd6ef397c1310b1b43f42923999d6dc7b12b6d9334af6660c7cc1cd2b0d1b8b3b5a6411d5e85bad84513a8230688924850f48819c
7
- data.tar.gz: e54020f1e5c7a777905d0218fcf1a1634acfe89fe9a64a27199154bbda4557b3af0b43444d2e36d5d124021783092ffe089df3ead84da45c053879cc7a5d5a1d
6
+ metadata.gz: 215ce7d8130e1a43382706858c487d7835971e326e93eb1c2ccb559b7dec5f1ecd216b451ad535beaba5e908419ec3e1c13bcc8dea8a0e6d2d7c45fed4639fdb
7
+ data.tar.gz: c950ff10929df5ac8365ec0b86fcafe1ac85685ef955b6d12ec7febaf2a9bc85be8b325a58b60583c2a7567889cc6fbe9c6c6eb9b16a10f35409b7da21c7cd32
data/Gemfile CHANGED
@@ -15,4 +15,5 @@ gem "stackprof" if is_unix && !is_truffleruby
15
15
  gem "reline", github: "ruby/reline" if ENV["WITH_LATEST_RELINE"] == "true"
16
16
  gem "rake"
17
17
  gem "test-unit"
18
+ gem "test-unit-ruby-core"
18
19
  gem "debug", github: "ruby/debug"
data/README.md CHANGED
@@ -1,12 +1,29 @@
1
1
  # IRB
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/irb.svg)](https://badge.fury.io/rb/irb)
3
+ [![Gem Version](https://badge.fury.io/rb/irb.svg)](https://badge.fury.io/rb/irb)
4
4
  [![build](https://github.com/ruby/irb/actions/workflows/test.yml/badge.svg)](https://github.com/ruby/irb/actions/workflows/test.yml)
5
5
 
6
6
  IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby expressions read from the standard input.
7
7
 
8
8
  The `irb` command from your shell will start the interpreter.
9
9
 
10
+ - [Installation](#installation)
11
+ - [Usage](#usage)
12
+ - [The `irb` Executable](#the-irb-executable)
13
+ - [The `binding.irb` Breakpoint](#the-bindingirb-breakpoint)
14
+ - [Commands](#commands)
15
+ - [Debugging with IRB](#debugging-with-irb)
16
+ - [More about `debug.gem`](#more-about-debuggem)
17
+ - [Advantages Over `debug.gem`'s Console](#advantages-over-debuggems-console)
18
+ - [Configuration](#configuration)
19
+ - [Environment Variables](#environment-variables)
20
+ - [Documentation](#documentation)
21
+ - [Extending IRB](#extending-irb)
22
+ - [Development](#development)
23
+ - [Contributing](#contributing)
24
+ - [Releasing](#releasing)
25
+ - [License](#license)
26
+
10
27
  ## Installation
11
28
 
12
29
  > **Note**
@@ -43,15 +60,15 @@ In the session, you can evaluate Ruby expressions or even prototype a small Ruby
43
60
 
44
61
  ```shell
45
62
  $ irb
46
- irb(main):001:0> 1 + 2
63
+ irb(main):001> 1 + 2
47
64
  => 3
48
- irb(main):002:1* class Foo
49
- irb(main):003:2* def foo
50
- irb(main):004:2* puts 1
51
- irb(main):005:1* end
52
- irb(main):006:0> end
65
+ irb(main):002* class Foo
66
+ irb(main):003* def foo
67
+ irb(main):004* puts 1
68
+ irb(main):005* end
69
+ irb(main):006> end
53
70
  => :foo
54
- irb(main):007:0> Foo.new.foo
71
+ irb(main):007> Foo.new.foo
55
72
  1
56
73
  => nil
57
74
  ```
@@ -84,23 +101,26 @@ Hello World
84
101
 
85
102
  The following commands are available on IRB. You can get the same output from the `show_cmds` command.
86
103
 
87
-
88
104
  ```
89
- IRB
105
+ Workspace
90
106
  cwws Show the current workspace.
91
107
  chws Change the current workspace to an object.
92
108
  workspaces Show workspaces.
93
109
  pushws Push an object to the workspace stack.
94
110
  popws Pop a workspace from the workspace stack.
111
+
112
+ IRB
95
113
  irb_load Load a Ruby file.
96
114
  irb_require Require a Ruby file.
97
115
  source Loads a given file in the current session.
116
+ irb_info Show information about IRB.
117
+ show_cmds List all available commands and their description.
118
+
119
+ Multi-irb (DEPRECATED)
98
120
  irb Start a child IRB.
99
121
  jobs List of current sessions.
100
122
  fg Switches to the session of the given number.
101
123
  kill Kills the session with the given number.
102
- irb_info Show information about IRB.
103
- show_cmds List all available commands and their description.
104
124
 
105
125
  Debugging
106
126
  debug Start the debugger of debug.gem.
@@ -115,29 +135,130 @@ Debugging
115
135
  info Start the debugger of debug.gem and run its `info` command.
116
136
 
117
137
  Misc
118
- edit Open a file with the editor command defined with `ENV["EDITOR"]`.
138
+ edit Open a file with the editor command defined with `ENV["VISUAL"]` or `ENV["EDITOR"]`.
119
139
  measure `measure` enables the mode to measure processing time. `measure :off` disables it.
120
140
 
121
141
  Context
142
+ help [DEPRECATED] Enter the mode to look up RI documents.
122
143
  show_doc Enter the mode to look up RI documents.
123
144
  ls Show methods, constants, and variables. `-g [query]` or `-G [query]` allows you to filter out the output.
124
145
  show_source Show the source code of a given method or constant.
125
146
  whereami Show the source code around binding.irb again.
126
147
  ```
127
148
 
149
+ ## Debugging with IRB
150
+
151
+ Starting from version 1.8.0, IRB boasts a powerful integration with `debug.gem`, providing a debugging experience akin to `pry-byebug`.
152
+
153
+ After hitting a `binding.irb` breakpoint, you can activate the debugger with the `debug` command.
154
+
155
+ ```shell
156
+ From: test.rb @ line 3 :
157
+
158
+ 1:
159
+ 2: def greet(word)
160
+ => 3: binding.irb
161
+ 4: puts "Hello #{word}"
162
+ 5: end
163
+ 6:
164
+ 7: greet("World")
165
+
166
+ irb(main):001> debug
167
+ irb:rdbg(main):002>
168
+ ```
169
+
170
+ Once activated, the prompt's header changes from `irb` to `irb:rdbg`, enabling you to use any of `debug.gem`'s [commands](https://github.com/ruby/debug#debug-command-on-the-debug-console):
171
+
172
+ ```shell
173
+ irb:rdbg(main):002> info # use info command to see available variables
174
+ %self = main
175
+ _ = nil
176
+ word = "World"
177
+ irb:rdbg(main):003> next # use next command to move to the next line
178
+ [1, 7] in test.rb
179
+ 1|
180
+ 2| def greet(word)
181
+ 3| binding.irb
182
+ => 4| puts "Hello #{word}"
183
+ 5| end
184
+ 6|
185
+ 7| greet("World")
186
+ =>#0 Object#greet(word="World") at test.rb:4
187
+ #1 <main> at test.rb:7
188
+ irb:rdbg(main):004>
189
+ ```
190
+
191
+ Simultaneously, you maintain access to IRB's commands, such as `show_source`:
192
+
193
+ ```shell
194
+ irb:rdbg(main):004> show_source greet
195
+
196
+ From: test.rb:2
197
+
198
+ def greet(word)
199
+ binding.irb
200
+ puts "Hello #{word}"
201
+ end
202
+ ```
203
+
204
+ ### More about `debug.gem`
205
+
206
+ `debug.gem` offers many advanced debugging features that simple REPLs can't provide, including:
207
+
208
+ - Step-debugging
209
+ - Frame navigation
210
+ - Setting breakpoints with commands
211
+ - Thread control
212
+ - ...and many more
213
+
214
+ To learn about these features, please refer to `debug.gem`'s [commands list](https://github.com/ruby/debug#debug-command-on-the-debug-console).
215
+
216
+ In the `irb:rdbg` session, the `show_cmds` command will also display all commands from `debug.gem`.
217
+
218
+ ### Advantages Over `debug.gem`'s Console
219
+
220
+ This integration offers several benefits over `debug.gem`'s native console:
221
+
222
+ 1. Access to handy IRB commands like `show_source` or `show_doc`.
223
+ 2. Support for multi-line input.
224
+ 3. Symbol shortcuts such as `@` (`whereami`) and `$` (`show_source`).
225
+ 4. Autocompletion.
226
+ 5. Customizable prompt.
227
+
228
+ However, there are also some limitations to be aware of:
229
+
230
+ 1. `binding.irb` doesn't support `pre` and `do` arguments like [`binding.break`](https://github.com/ruby/debug#bindingbreak-method).
231
+ 2. As IRB [doesn't currently support remote-connection](https://github.com/ruby/irb/issues/672), it can't be used with `debug.gem`'s remote debugging feature.
232
+ 3. Access to the previous return value via the underscore `_` is not supported.
233
+
128
234
  ## Configuration
129
235
 
130
236
  ### Environment Variables
131
237
 
132
238
  - `NO_COLOR`: Assigning a value to it disables IRB's colorization.
133
239
  - `IRB_USE_AUTOCOMPLETE`: Setting it to `false` disables IRB's autocompletion.
134
- - `EDITOR`: Its value would be used to open files by the `edit` command.
240
+ - `VISUAL`: Its value would be used to open files by the `edit` command.
241
+ - `EDITOR`: Its value would be used to open files by the `edit` command if `VISUAL` is unset.
135
242
  - `IRBRC`: The file specified would be evaluated as IRB's rc-file.
136
243
 
137
244
  ## Documentation
138
245
 
139
246
  https://docs.ruby-lang.org/en/master/IRB.html
140
247
 
248
+ ## Extending IRB
249
+
250
+ IRB is currently going through some refactoring to bring in some cool improvements and make things more flexible for developers.
251
+ We know that in the past, due to a lack of public APIs and documentation, many of you have had to use IRB's private APIs
252
+ and components to extend it. We also know that changes can be a bit annoying and might mess with your current setup.
253
+
254
+ We're sorry if this causes a bit of a scramble. We're working hard to make IRB better and your input is super important to us.
255
+ If you've been using private APIs or components in your projects, we'd love to hear about your use cases. Please feel free to file a new issue. Your feedback will be a massive help in guiding us on how to design and prioritize the development of official APIs in the future.
256
+
257
+ Right now, we've got command extension APIs on the drawing board, as you can see in [#513](https://github.com/ruby/irb/issues/513).
258
+ We've also got a prototype for helper method extension APIs in the works, as shown in [#588](https://github.com/ruby/irb/issues/588).
259
+
260
+ We really appreciate your understanding and patience during this transition. We're pretty excited about the improvements these changes will bring to the IRB ecosystem and we hope you are too!
261
+
141
262
  ## Development
142
263
 
143
264
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/Rakefile CHANGED
@@ -41,11 +41,4 @@ Rake::TestTask.new(:test_yamatanooroti) do |t|
41
41
  t.pattern = 'test/irb/yamatanooroti/test_*.rb'
42
42
  end
43
43
 
44
- task :sync_tool do
45
- require 'fileutils'
46
- FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib"
47
- FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib"
48
- FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib"
49
- end
50
-
51
44
  task :default => :test
data/doc/irb/irb.rd.ja CHANGED
@@ -125,7 +125,6 @@ irb起動時に``~/.irbrc''を読み込みます. もし存在しない場合は
125
125
 
126
126
  IRB.conf[:PROMPT][:MY_PROMPT] = { # プロンプトモードの名前
127
127
  :PROMPT_I => nil, # 通常のプロンプト
128
- :PROMPT_N => nil, # 継続行のプロンプト
129
128
  :PROMPT_S => nil, # 文字列などの継続行のプロンプト
130
129
  :PROMPT_C => nil, # 式が継続している時のプロンプト
131
130
  :RETURN => " ==>%s\n" # リターン時のプロンプト
@@ -140,7 +139,7 @@ OKです.
140
139
 
141
140
  IRB.conf[:PROMPT_MODE] = :MY_PROMPT
142
141
 
143
- PROMPT_I, PROMPT_N, PROMPT_S, PROMPT_Cは, フォーマットを指定します.
142
+ PROMPT_I, PROMPT_S, PROMPT_Cは, フォーマットを指定します.
144
143
 
145
144
  %N 起動しているコマンド名が出力される.
146
145
  %m mainオブジェクト(self)がto_sで出力される.
@@ -155,7 +154,6 @@ PROMPT_I, PROMPT_N, PROMPT_S, PROMPT_Cは, フォーマットを指定します.
155
154
 
156
155
  IRB.conf[:PROMPT][:DEFAULT] = {
157
156
  :PROMPT_I => "%N(%m):%03n:%i> ",
158
- :PROMPT_N => "%N(%m):%03n:%i> ",
159
157
  :PROMPT_S => "%N(%m):%03n:%i%l ",
160
158
  :PROMPT_C => "%N(%m):%03n:%i* ",
161
159
  :RETURN => "=> %s\n"
data/irb.gemspec CHANGED
@@ -41,5 +41,6 @@ Gem::Specification.new do |spec|
41
41
 
42
42
  spec.required_ruby_version = Gem::Requirement.new(">= 2.7")
43
43
 
44
- spec.add_dependency "reline", ">= 0.3.6"
44
+ spec.add_dependency "reline", ">= 0.3.8"
45
+ spec.add_dependency "rdoc"
45
46
  end
data/lib/irb/cmd/chws.rb CHANGED
@@ -13,7 +13,7 @@ module IRB
13
13
  module ExtendCommand
14
14
 
15
15
  class CurrentWorkingWorkspace < Nop
16
- category "IRB"
16
+ category "Workspace"
17
17
  description "Show the current workspace."
18
18
 
19
19
  def execute(*obj)
@@ -22,7 +22,7 @@ module IRB
22
22
  end
23
23
 
24
24
  class ChangeWorkspace < Nop
25
- category "IRB"
25
+ category "Workspace"
26
26
  description "Change the current workspace to an object."
27
27
 
28
28
  def execute(*obj)
data/lib/irb/cmd/debug.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require_relative "nop"
2
+ require_relative "../debug"
2
3
 
3
4
  module IRB
4
5
  # :stopdoc:
@@ -12,37 +13,46 @@ module IRB
12
13
  '<internal:prelude>',
13
14
  binding.method(:irb).source_location.first,
14
15
  ].map { |file| /\A#{Regexp.escape(file)}:\d+:in `irb'\z/ }
15
- IRB_DIR = File.expand_path('..', __dir__)
16
16
 
17
17
  def execute(pre_cmds: nil, do_cmds: nil)
18
- unless binding_irb?
19
- puts "`debug` command is only available when IRB is started with binding.irb"
20
- return
21
- end
18
+ if irb_context.with_debugger
19
+ # If IRB is already running with a debug session, throw the command and IRB.debug_readline will pass it to the debugger.
20
+ if cmd = pre_cmds || do_cmds
21
+ throw :IRB_EXIT, cmd
22
+ else
23
+ puts "IRB is already running with a debug session."
24
+ return
25
+ end
26
+ else
27
+ # If IRB is not running with a debug session yet, then:
28
+ # 1. Check if the debugging command is run from a `binding.irb` call.
29
+ # 2. If so, try setting up the debug gem.
30
+ # 3. Insert a debug breakpoint at `Irb#debug_break` with the intended command.
31
+ # 4. Exit the current Irb#run call via `throw :IRB_EXIT`.
32
+ # 5. `Irb#debug_break` will be called and trigger the breakpoint, which will run the intended command.
33
+ unless binding_irb?
34
+ puts "`debug` command is only available when IRB is started with binding.irb"
35
+ return
36
+ end
22
37
 
23
- unless setup_debugger
24
- puts <<~MSG
25
- You need to install the debug gem before using this command.
26
- If you use `bundle exec`, please add `gem "debug"` into your Gemfile.
27
- MSG
28
- return
29
- end
38
+ if IRB.respond_to?(:JobManager)
39
+ warn "Can't start the debugger when IRB is running in a multi-IRB session."
40
+ return
41
+ end
30
42
 
31
- options = { oneshot: true, hook_call: false }
32
- if pre_cmds || do_cmds
33
- options[:command] = ['irb', pre_cmds, do_cmds]
34
- end
35
- if DEBUGGER__::LineBreakpoint.instance_method(:initialize).parameters.include?([:key, :skip_src])
36
- options[:skip_src] = true
37
- end
43
+ unless IRB::Debug.setup(irb_context.irb)
44
+ puts <<~MSG
45
+ You need to install the debug gem before using this command.
46
+ If you use `bundle exec`, please add `gem "debug"` into your Gemfile.
47
+ MSG
48
+ return
49
+ end
38
50
 
39
- # To make debugger commands like `next` or `continue` work without asking
40
- # the user to quit IRB after that, we need to exit IRB first and then hit
41
- # a TracePoint on #debug_break.
42
- file, lineno = IRB::Irb.instance_method(:debug_break).source_location
43
- DEBUGGER__::SESSION.add_line_breakpoint(file, lineno + 1, **options)
44
- # exit current Irb#run call
45
- throw :IRB_EXIT
51
+ IRB::Debug.insert_debug_break(pre_cmds: pre_cmds, do_cmds: do_cmds)
52
+
53
+ # exit current Irb#run call
54
+ throw :IRB_EXIT
55
+ end
46
56
  end
47
57
 
48
58
  private
@@ -54,72 +64,6 @@ module IRB
54
64
  end
55
65
  end
56
66
  end
57
-
58
- module SkipPathHelperForIRB
59
- def skip_internal_path?(path)
60
- # The latter can be removed once https://github.com/ruby/debug/issues/866 is resolved
61
- super || path.match?(IRB_DIR) || path.match?('<internal:prelude>')
62
- end
63
- end
64
-
65
- def setup_debugger
66
- unless defined?(DEBUGGER__::SESSION)
67
- begin
68
- require "debug/session"
69
- rescue LoadError # debug.gem is not written in Gemfile
70
- return false unless load_bundled_debug_gem
71
- end
72
- DEBUGGER__.start(nonstop: true)
73
- end
74
-
75
- unless DEBUGGER__.respond_to?(:capture_frames_without_irb)
76
- DEBUGGER__.singleton_class.send(:alias_method, :capture_frames_without_irb, :capture_frames)
77
-
78
- def DEBUGGER__.capture_frames(*args)
79
- frames = capture_frames_without_irb(*args)
80
- frames.reject! do |frame|
81
- frame.realpath&.start_with?(IRB_DIR) || frame.path == "<internal:prelude>"
82
- end
83
- frames
84
- end
85
-
86
- DEBUGGER__::ThreadClient.prepend(SkipPathHelperForIRB)
87
- end
88
-
89
- true
90
- end
91
-
92
- # This is used when debug.gem is not written in Gemfile. Even if it's not
93
- # installed by `bundle install`, debug.gem is installed by default because
94
- # it's a bundled gem. This method tries to activate and load that.
95
- def load_bundled_debug_gem
96
- # Discover latest debug.gem under GEM_PATH
97
- debug_gem = Gem.paths.path.flat_map { |path| Dir.glob("#{path}/gems/debug-*") }.select do |path|
98
- File.basename(path).match?(/\Adebug-\d+\.\d+\.\d+(\w+)?\z/)
99
- end.sort_by do |path|
100
- Gem::Version.new(File.basename(path).delete_prefix('debug-'))
101
- end.last
102
- return false unless debug_gem
103
-
104
- # Discover debug/debug.so under extensions for Ruby 3.2+
105
- ext_name = "/debug/debug.#{RbConfig::CONFIG['DLEXT']}"
106
- ext_path = Gem.paths.path.flat_map do |path|
107
- Dir.glob("#{path}/extensions/**/#{File.basename(debug_gem)}#{ext_name}")
108
- end.first
109
-
110
- # Attempt to forcibly load the bundled gem
111
- if ext_path
112
- $LOAD_PATH << ext_path.delete_suffix(ext_name)
113
- end
114
- $LOAD_PATH << "#{debug_gem}/lib"
115
- begin
116
- require "debug/session"
117
- puts "Loaded #{File.basename(debug_gem)}"
118
- true
119
- rescue LoadError
120
- false
121
- end
122
- end
123
67
  end
124
68
 
125
69
  class DebugCommand < Debug
data/lib/irb/cmd/edit.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'shellwords'
2
2
  require_relative "nop"
3
+ require_relative "../source_finder"
3
4
 
4
5
  module IRB
5
6
  # :stopdoc:
@@ -7,7 +8,7 @@ module IRB
7
8
  module ExtendCommand
8
9
  class Edit < Nop
9
10
  category "Misc"
10
- description 'Open a file with the editor command defined with `ENV["EDITOR"]`.'
11
+ description 'Open a file with the editor command defined with `ENV["VISUAL"]` or `ENV["EDITOR"]`.'
11
12
 
12
13
  class << self
13
14
  def transform_args(args)
@@ -28,17 +29,15 @@ module IRB
28
29
  end
29
30
 
30
31
  if !File.exist?(path)
31
- require_relative "show_source"
32
-
33
32
  source =
34
33
  begin
35
- ShowSource.find_source(path, @irb_context)
34
+ SourceFinder.new(@irb_context).find_source(path)
36
35
  rescue NameError
37
36
  # if user enters a path that doesn't exist, it'll cause NameError when passed here because find_source would try to evaluate it as well
38
37
  # in this case, we should just ignore the error
39
38
  end
40
39
 
41
- if source && File.exist?(source.file)
40
+ if source
42
41
  path = source.file
43
42
  else
44
43
  puts "Can not find file: #{path}"
@@ -46,12 +45,12 @@ module IRB
46
45
  end
47
46
  end
48
47
 
49
- if editor = ENV['EDITOR']
48
+ if editor = (ENV['VISUAL'] || ENV['EDITOR'])
50
49
  puts "command: '#{editor}'"
51
50
  puts " path: #{path}"
52
51
  system(*Shellwords.split(editor), path)
53
52
  else
54
- puts "Can not find editor setting: ENV['EDITOR']"
53
+ puts "Can not find editor setting: ENV['VISUAL'] or ENV['EDITOR']"
55
54
  end
56
55
  end
57
56
  end
data/lib/irb/cmd/ls.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "reline"
4
+ require "stringio"
4
5
  require_relative "nop"
6
+ require_relative "../pager"
5
7
  require_relative "../color"
6
8
 
7
9
  module IRB
@@ -33,7 +35,7 @@ module IRB
33
35
  o.dump("instance variables", obj.instance_variables)
34
36
  o.dump("class variables", klass.class_variables)
35
37
  o.dump("locals", locals)
36
- nil
38
+ o.print_result
37
39
  end
38
40
 
39
41
  def dump_methods(o, klass, obj)
@@ -77,6 +79,11 @@ module IRB
77
79
  def initialize(grep: nil)
78
80
  @grep = grep
79
81
  @line_width = screen_width - MARGIN.length # right padding
82
+ @io = StringIO.new
83
+ end
84
+
85
+ def print_result
86
+ Pager.page_content(@io.string)
80
87
  end
81
88
 
82
89
  def dump(name, strs)
@@ -85,12 +92,12 @@ module IRB
85
92
  return if strs.empty?
86
93
 
87
94
  # Attempt a single line
88
- print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
95
+ @io.print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
89
96
  if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
90
- puts strs.join(MARGIN)
97
+ @io.puts strs.join(MARGIN)
91
98
  return
92
99
  end
93
- puts
100
+ @io.puts
94
101
 
95
102
  # Dump with the largest # of columns that fits on a line
96
103
  cols = strs.size
@@ -99,7 +106,7 @@ module IRB
99
106
  end
100
107
  widths = col_widths(strs, cols: cols)
101
108
  strs.each_slice(cols) do |ss|
102
- puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
109
+ @io.puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
103
110
  end
104
111
  end
105
112
 
@@ -12,7 +12,7 @@ module IRB
12
12
 
13
13
  module ExtendCommand
14
14
  class Workspaces < Nop
15
- category "IRB"
15
+ category "Workspace"
16
16
  description "Show workspaces."
17
17
 
18
18
  def execute(*obj)
@@ -21,7 +21,7 @@ module IRB
21
21
  end
22
22
 
23
23
  class PushWorkspace < Workspaces
24
- category "IRB"
24
+ category "Workspace"
25
25
  description "Push an object to the workspace stack."
26
26
 
27
27
  def execute(*obj)
@@ -31,7 +31,7 @@ module IRB
31
31
  end
32
32
 
33
33
  class PopWorkspace < Workspaces
34
- category "IRB"
34
+ category "Workspace"
35
35
  description "Pop a workspace from the workspace stack."
36
36
 
37
37
  def execute(*obj)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "stringio"
4
4
  require_relative "nop"
5
+ require_relative "../pager"
5
6
 
6
7
  module IRB
7
8
  # :stopdoc:
@@ -14,6 +15,16 @@ module IRB
14
15
  def execute(*args)
15
16
  commands_info = IRB::ExtendCommandBundle.all_commands_info
16
17
  commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] }
18
+
19
+ if irb_context.with_debugger
20
+ # Remove the original "Debugging" category
21
+ commands_grouped_by_categories.delete("Debugging")
22
+ # Remove the `help` command as it's delegated to the debugger
23
+ commands_grouped_by_categories["Context"].delete_if { |cmd| cmd[:display_name] == :help }
24
+ # Add an empty "Debugging (from debug.gem)" category at the end
25
+ commands_grouped_by_categories["Debugging (from debug.gem)"] = []
26
+ end
27
+
17
28
  longest_cmd_name_length = commands_info.map { |c| c[:display_name].length }.max
18
29
 
19
30
  output = StringIO.new
@@ -28,9 +39,12 @@ module IRB
28
39
  output.puts
29
40
  end
30
41
 
31
- puts output.string
42
+ # Append the debugger help at the end
43
+ if irb_context.with_debugger
44
+ output.puts DEBUGGER__.help
45
+ end
32
46
 
33
- nil
47
+ Pager.page_content(output.string)
34
48
  end
35
49
  end
36
50
  end