irb 1.13.2 → 1.15.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 243737997cdd6abe7e129eb7e7945dca379f1af38ed4254dfe094f2a611918cc
4
- data.tar.gz: 5a1cbbdf5ab88a61278afe32a5497f38efa1342e123734ae3ede6135aae9b91f
3
+ metadata.gz: 0777b40af32d70077c30a5c818b82f9b7d6b1962a59648667016fe3b2a5bdc92
4
+ data.tar.gz: 3487682618e9aa452daaabd727117182dc95d85885a0b18b0b348f67e8a75f6e
5
5
  SHA512:
6
- metadata.gz: 0b4e5d658e1eba4a0503ffd3776c3baffabb0782eb43a993aac593b6dc4383e9e209ca3c1f077c78225f612a1ac7607f951bc11a2ff8fd78a93e12029fbf1954
7
- data.tar.gz: c9e978f318f22d322934b77b8c431830e67a9cb7cf365923041f77123ee5e7d39ffa814a4e7bdd9af759f4671d0b24bd2ae68a9d20beb54b4a0e4248e32ee85f
6
+ metadata.gz: 528a9784ba5b854519684bbe4cd03a7e6467b3619035d90ca7b7b864300b1dc22a4d755b1824ed5d653bd46e26631d88b577bfdecd6aeed24df16302471df47c
7
+ data.tar.gz: 9b401a6e0c08bdc361232be10797e307ac94567414300f7b385ae65392340aeb3ccd88ad53e447d8fb3543211ca55e2f61beb1d9543dd593a41fa736ed42c86f
data/Gemfile CHANGED
@@ -22,6 +22,8 @@ gem "rubocop"
22
22
  gem "tracer" if !is_truffleruby
23
23
  gem "debug", github: "ruby/debug", platforms: [:mri, :mswin]
24
24
 
25
+ gem "rdoc", ">= 6.11.0"
26
+
25
27
  if RUBY_VERSION >= "3.0.0" && !is_truffleruby
26
28
  gem "repl_type_completor"
27
29
  end
data/README.md CHANGED
@@ -1,33 +1,14 @@
1
1
  # IRB
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/irb.svg)](https://badge.fury.io/rb/irb)
4
+ [![Static Badge](https://img.shields.io/badge/RDoc-flat?style=flat&label=documentation&link=https%3A%2F%2Fruby.github.io%2Firb%2F)](https://ruby.github.io/irb/)
4
5
  [![build](https://github.com/ruby/irb/actions/workflows/test.yml/badge.svg)](https://github.com/ruby/irb/actions/workflows/test.yml)
5
6
 
7
+
6
8
  IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby expressions read from the standard input.
7
9
 
8
10
  The `irb` command from your shell will start the interpreter.
9
11
 
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
- - [Type Based Completion](#type-based-completion)
19
- - [How to Enable IRB::TypeCompletor](#how-to-enable-irbtypecompletor)
20
- - [Advantage over Default IRB::RegexpCompletor](#advantage-over-default-irbregexpcompletor)
21
- - [Difference between Steep's Completion](#difference-between-steeps-completion)
22
- - [Configuration](#configuration)
23
- - [Environment Variables](#environment-variables)
24
- - [Documentation](#documentation)
25
- - [Extending IRB](#extending-irb)
26
- - [Development](#development)
27
- - [Contributing](#contributing)
28
- - [Releasing](#releasing)
29
- - [License](#license)
30
-
31
12
  ## Installation
32
13
 
33
14
  > [!Note]
@@ -58,7 +39,7 @@ $ gem install irb
58
39
 
59
40
  > [!Note]
60
41
  >
61
- > We're working hard to match Pry's variety of powerful features in IRB, and you can track our progress or find contribution ideas in [this document](https://github.com/ruby/irb/blob/master/COMPARED_WITH_PRY.md).
42
+ > We're working hard to match Pry's variety of powerful features in IRB, and you can track our progress or find contribution ideas in [this document](https://ruby.github.io/irb/COMPARED_WITH_PRY_md.html).
62
43
 
63
44
  ### The `irb` Executable
64
45
 
@@ -105,293 +86,32 @@ irb(main):002:0> exit
105
86
  Hello World
106
87
  ```
107
88
 
108
- ## Commands
109
-
110
- The following commands are available on IRB. You can get the same output from the `help` command.
111
-
112
- ```txt
113
- Help
114
- help List all available commands. Use `help <command>` to get information about a specific command.
115
-
116
- IRB
117
- exit Exit the current irb session.
118
- exit! Exit the current process.
119
- irb_load Load a Ruby file.
120
- irb_require Require a Ruby file.
121
- source Loads a given file in the current session.
122
- irb_info Show information about IRB.
123
- history Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output.
124
-
125
- Workspace
126
- cwws Show the current workspace.
127
- chws Change the current workspace to an object.
128
- workspaces Show workspaces.
129
- pushws Push an object to the workspace stack.
130
- popws Pop a workspace from the workspace stack.
131
-
132
- Multi-irb (DEPRECATED)
133
- irb Start a child IRB.
134
- jobs List of current sessions.
135
- fg Switches to the session of the given number.
136
- kill Kills the session with the given number.
137
-
138
- Debugging
139
- debug Start the debugger of debug.gem.
140
- break Start the debugger of debug.gem and run its `break` command.
141
- catch Start the debugger of debug.gem and run its `catch` command.
142
- next Start the debugger of debug.gem and run its `next` command.
143
- delete Start the debugger of debug.gem and run its `delete` command.
144
- step Start the debugger of debug.gem and run its `step` command.
145
- continue Start the debugger of debug.gem and run its `continue` command.
146
- finish Start the debugger of debug.gem and run its `finish` command.
147
- backtrace Start the debugger of debug.gem and run its `backtrace` command.
148
- info Start the debugger of debug.gem and run its `info` command.
149
-
150
- Misc
151
- edit Open a file or source location.
152
- measure `measure` enables the mode to measure processing time. `measure :off` disables it.
153
-
154
- Context
155
- show_doc Enter the mode to look up RI documents.
156
- ls Show methods, constants, and variables.
157
- show_source Show the source code of a given method or constant.
158
- whereami Show the source code around binding.irb again.
159
-
160
- Aliases
161
- $ Alias for `show_source`
162
- @ Alias for `whereami`
163
- ```
164
-
165
- ## Debugging with IRB
166
-
167
- Starting from version 1.8.0, IRB boasts a powerful integration with `debug.gem`, providing a debugging experience akin to `pry-byebug`.
168
-
169
- After hitting a `binding.irb` breakpoint, you can activate the debugger with the `debug` command. Alternatively, if the `debug` method happens to already be defined in the current scope, you can call `irb_debug`.
170
-
171
- ```shell
172
- From: test.rb @ line 3 :
173
-
174
- 1:
175
- 2: def greet(word)
176
- => 3: binding.irb
177
- 4: puts "Hello #{word}"
178
- 5: end
179
- 6:
180
- 7: greet("World")
181
-
182
- irb(main):001> debug
183
- irb:rdbg(main):002>
184
- ```
185
-
186
- 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):
187
-
188
- ```shell
189
- irb:rdbg(main):002> info # use info command to see available variables
190
- %self = main
191
- _ = nil
192
- word = "World"
193
- irb:rdbg(main):003> next # use next command to move to the next line
194
- [1, 7] in test.rb
195
- 1|
196
- 2| def greet(word)
197
- 3| binding.irb
198
- => 4| puts "Hello #{word}"
199
- 5| end
200
- 6|
201
- 7| greet("World")
202
- =>#0 Object#greet(word="World") at test.rb:4
203
- #1 <main> at test.rb:7
204
- irb:rdbg(main):004>
205
- ```
206
-
207
- Simultaneously, you maintain access to IRB's commands, such as `show_source`:
208
-
209
- ```shell
210
- irb:rdbg(main):004> show_source greet
211
-
212
- From: test.rb:2
213
-
214
- def greet(word)
215
- binding.irb
216
- puts "Hello #{word}"
217
- end
218
- ```
219
-
220
- ### More about `debug.gem`
221
-
222
- `debug.gem` offers many advanced debugging features that simple REPLs can't provide, including:
223
-
224
- - Step-debugging
225
- - Frame navigation
226
- - Setting breakpoints with commands
227
- - Thread control
228
- - ...and many more
229
-
230
- To learn about these features, please refer to `debug.gem`'s [commands list](https://github.com/ruby/debug#debug-command-on-the-debug-console).
231
-
232
- In the `irb:rdbg` session, the `help` command will also display all commands from `debug.gem`.
233
-
234
- ### Advantages Over `debug.gem`'s Console
235
-
236
- This integration offers several benefits over `debug.gem`'s native console:
237
-
238
- 1. Access to handy IRB commands like `show_source` or `show_doc`.
239
- 2. Support for multi-line input.
240
- 3. Symbol shortcuts such as `@` (`whereami`) and `$` (`show_source`).
241
- 4. Autocompletion.
242
- 5. Customizable prompt.
243
-
244
- However, there are also some limitations to be aware of:
245
-
246
- 1. `binding.irb` doesn't support `pre` and `do` arguments like [`binding.break`](https://github.com/ruby/debug#bindingbreak-method).
247
- 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.
248
- 3. Access to the previous return value via the underscore `_` is not supported.
249
-
250
- ## Type Based Completion
251
-
252
- IRB's default completion `IRB::RegexpCompletor` uses Regexp. IRB has another experimental completion `IRB::TypeCompletor` that uses type analysis.
253
-
254
- ### How to Enable IRB::TypeCompletor
255
-
256
- Install [ruby/repl_type_completor](https://github.com/ruby/repl_type_completor/) with:
257
- ```
258
- $ gem install repl_type_completor
259
- ```
260
- Or add these lines to your project's Gemfile.
261
- ```ruby
262
- gem 'irb'
263
- gem 'repl_type_completor', group: [:development, :test]
264
- ```
265
-
266
- Now you can use type based completion by:
267
-
268
- Running IRB with the `--type-completor` option
269
- ```
270
- $ irb --type-completor
271
- ```
272
-
273
- Or writing this line to IRB's rc-file (e.g. `~/.irbrc`)
274
- ```ruby
275
- IRB.conf[:COMPLETOR] = :type # default is :regexp
276
- ```
277
-
278
- Or setting the environment variable `IRB_COMPLETOR`
279
- ```ruby
280
- ENV['IRB_COMPLETOR'] = 'type'
281
- IRB.start
282
- ```
283
-
284
- To check if it's enabled, type `irb_info` into IRB and see the `Completion` section.
285
- ```
286
- irb(main):001> irb_info
287
- ...
288
- # Enabled
289
- Completion: Autocomplete, ReplTypeCompletor: 0.1.0, Prism: 0.18.0, RBS: 3.3.0
290
- # Not enabled
291
- Completion: Autocomplete, RegexpCompletor
292
- ...
293
- ```
294
- If you have `sig/` directory or `rbs_collection.lock.yaml` in current directory, IRB will load it.
295
-
296
- ### Advantage over Default IRB::RegexpCompletor
297
-
298
- IRB::TypeCompletor can autocomplete chained methods, block parameters and more if type information is available.
299
- These are some examples IRB::RegexpCompletor cannot complete.
300
-
301
- ```ruby
302
- irb(main):001> 'Ruby'.upcase.chars.s # Array methods (sample, select, shift, size)
303
- ```
89
+ ### Debugging
304
90
 
305
- ```ruby
306
- irb(main):001> 10.times.map(&:to_s).each do |s|
307
- irb(main):002> s.up # String methods (upcase, upcase!, upto)
308
- ```
91
+ You can use IRB as a debugging console with `debug.gem` with these options:
309
92
 
310
- ```ruby
311
- irb(main):001> class User < ApplicationRecord
312
- irb(main):002> def foo
313
- irb(main):003> sa # save, save!
314
- ```
93
+ - In `binding.irb`, use the `debug` command to start an `irb:rdbg` session with access to all `debug.gem` commands.
94
+ - Use the `RUBY_DEBUG_IRB_CONSOLE=1` environment variable to make `debug.gem` use IRB as the debugging console.
315
95
 
316
- As a trade-off, completion calculation takes more time than IRB::RegexpCompletor.
96
+ To learn more about debugging with IRB, see [Debugging with IRB](https://ruby.github.io/irb/#label-Debugging+with+IRB).
317
97
 
318
- ### Difference between Steep's Completion
319
-
320
- Compared with Steep, IRB::TypeCompletor has some difference and limitations.
321
- ```ruby
322
- [0, 'a'].sample.
323
- # Steep completes intersection of Integer methods and String methods
324
- # IRB::TypeCompletor completes both Integer and String methods
325
- ```
326
-
327
- Some features like type narrowing is not implemented.
328
- ```ruby
329
- def f(arg = [0, 'a'].sample)
330
- if arg.is_a?(String)
331
- arg. # Completes both Integer and String methods
332
- ```
98
+ ## Documentation
333
99
 
334
- Unlike other static type checker, IRB::TypeCompletor uses runtime information to provide better completion.
335
- ```ruby
336
- irb(main):001> a = [1]
337
- => [1]
338
- irb(main):002> a.first. # Completes Integer methods
339
- ```
100
+ https://ruby.github.io/irb/ provides a comprehensive guide to IRB's features and usage.
340
101
 
341
102
  ## Configuration
342
103
 
343
- ### Environment Variables
344
-
345
- - `NO_COLOR`: Assigning a value to it disables IRB's colorization.
346
- - `IRB_USE_AUTOCOMPLETE`: Setting it to `false` disables IRB's autocompletion.
347
- - `IRB_COMPLETOR`: Configures IRB's auto-completion behavior, allowing settings for either `regexp` or `type`.
348
- - `VISUAL`: Its value would be used to open files by the `edit` command.
349
- - `EDITOR`: Its value would be used to open files by the `edit` command if `VISUAL` is unset.
350
- - `IRBRC`: The file specified would be evaluated as IRB's rc-file.
351
-
352
- ## Documentation
353
-
354
- https://ruby.github.io/irb/
104
+ See the [Configuration page](https://ruby.github.io/irb/Configurations_md.html) in the documentation.
355
105
 
356
106
  ## Extending IRB
357
107
 
358
108
  IRB `v1.13.0` and later versions allows users/libraries to extend its functionality through official APIs.
359
109
 
360
- For more information, please visit [EXTEND_IRB.md](./EXTEND_IRB.md).
361
-
362
- ## Development
363
-
364
- 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.
365
-
366
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
110
+ For more information, please visit the [IRB Extension Guide](https://ruby.github.io/irb/EXTEND_IRB_md.html).
367
111
 
368
112
  ## Contributing
369
113
 
370
- Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/irb.
371
-
372
- ### Set up the environment
373
-
374
- 1. Fork the project to your GithHub account
375
- 2. Clone the fork with `git clone git@github.com:[your_username]/irb.git`
376
- 3. Run `bundle install`
377
- 4. Run `bundle exec rake` to make sure tests pass locally
378
-
379
- ### Run integration tests
380
-
381
- If your changes affect component rendering, such as the autocompletion's dialog/dropdown, you may need to run IRB's integration tests, known as `yamatanooroti`.
382
-
383
- Before running these tests, ensure that you have `libvterm` installed. If you're using Homebrew, you can install it by running:
384
-
385
- ```bash
386
- brew install libvterm
387
- ```
388
-
389
- After installing `libvterm`, you can run the integration tests using the following commands:
390
-
391
- ```bash
392
- WITH_VTERM=1 bundle install
393
- WITH_VTERM=1 bundle exec rake test test_yamatanooroti
394
- ```
114
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for more information.
395
115
 
396
116
  ## Releasing
397
117
 
data/Rakefile CHANGED
@@ -45,10 +45,8 @@ end
45
45
  task :default => :test
46
46
 
47
47
  RDoc::Task.new do |rdoc|
48
- rdoc.title = "IRB"
49
- rdoc.rdoc_files.include("*.md", "lib/**/*.rb")
50
- rdoc.rdoc_files.exclude("lib/irb/xmp.rb")
51
- rdoc.rdoc_dir = "docs"
52
- rdoc.main = "README.md"
53
- rdoc.options.push("--copy-files", "LICENSE.txt")
48
+ rdoc.title = "IRB Documentation"
49
+ rdoc.main = "Index.md"
50
+ rdoc.rdoc_dir = "_site"
51
+ rdoc.options.push("lib")
54
52
  end
data/irb.gemspec CHANGED
@@ -18,11 +18,10 @@ Gem::Specification.new do |spec|
18
18
 
19
19
  spec.metadata["homepage_uri"] = spec.homepage
20
20
  spec.metadata["source_code_uri"] = spec.homepage
21
- spec.metadata["documentation_uri"] = spec.homepage
21
+ spec.metadata["documentation_uri"] = "https://ruby.github.io/irb/"
22
22
  spec.metadata["changelog_uri"] = "#{spec.homepage}/releases"
23
23
 
24
24
  spec.files = [
25
- ".document",
26
25
  "Gemfile",
27
26
  "LICENSE.txt",
28
27
  "README.md",
@@ -34,7 +33,9 @@ Gem::Specification.new do |spec|
34
33
  "exe/irb",
35
34
  "irb.gemspec",
36
35
  "man/irb.1",
37
- ] + Dir.glob("lib/**/*")
36
+ ] + Dir.chdir(File.expand_path('..', __FILE__)) do
37
+ Dir.glob("lib/**/*").map {|f| f unless File.directory?(f) }.compact
38
+ end
38
39
  spec.bindir = "exe"
39
40
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
40
41
  spec.require_paths = ["lib"]
@@ -43,4 +44,5 @@ Gem::Specification.new do |spec|
43
44
 
44
45
  spec.add_dependency "reline", ">= 0.4.2"
45
46
  spec.add_dependency "rdoc", ">= 4.0.0"
47
+ spec.add_dependency "pp", ">= 0.6.0"
46
48
  end
data/lib/irb/color.rb CHANGED
@@ -41,6 +41,7 @@ module IRB # :nodoc:
41
41
  on_embvar: [[RED], ALL],
42
42
  on_float: [[MAGENTA, BOLD], ALL],
43
43
  on_gvar: [[GREEN, BOLD], ALL],
44
+ on_backref: [[GREEN, BOLD], ALL],
44
45
  on_heredoc_beg: [[RED], ALL],
45
46
  on_heredoc_end: [[RED], ALL],
46
47
  on_ident: [[BLUE, BOLD], Ripper::EXPR_ENDFN],
@@ -4,12 +4,9 @@ require_relative 'color'
4
4
 
5
5
  module IRB
6
6
  class ColorPrinter < ::PP
7
- METHOD_RESPOND_TO = Object.instance_method(:respond_to?)
8
- METHOD_INSPECT = Object.instance_method(:inspect)
9
-
10
7
  class << self
11
- def pp(obj, out = $>, width = screen_width)
12
- q = ColorPrinter.new(out, width)
8
+ def pp(obj, out = $>, width = screen_width, colorize: true)
9
+ q = ColorPrinter.new(out, width, colorize: colorize)
13
10
  q.guard_inspect_key {q.pp obj}
14
11
  q.flush
15
12
  out << "\n"
@@ -24,12 +21,16 @@ module IRB
24
21
  end
25
22
  end
26
23
 
24
+ def initialize(out, width, colorize: true)
25
+ @colorize = colorize
26
+
27
+ super(out, width)
28
+ end
29
+
27
30
  def pp(obj)
28
31
  if String === obj
29
32
  # Avoid calling Ruby 2.4+ String#pretty_print that splits a string by "\n"
30
33
  text(obj.inspect)
31
- elsif !METHOD_RESPOND_TO.bind(obj).call(:inspect)
32
- text(METHOD_INSPECT.bind(obj).call)
33
34
  else
34
35
  super
35
36
  end
@@ -46,9 +47,9 @@ module IRB
46
47
  when ',', '=>', '[', ']', '{', '}', '..', '...', /\A@\w+\z/
47
48
  super(str, width)
48
49
  when /\A#</, '=', '>'
49
- super(Color.colorize(str, [:GREEN]), width)
50
+ super(@colorize ? Color.colorize(str, [:GREEN]) : str, width)
50
51
  else
51
- super(Color.colorize_code(str, ignore_error: true), width)
52
+ super(@colorize ? Color.colorize_code(str, ignore_error: true) : str, width)
52
53
  end
53
54
  end
54
55
  end
@@ -5,13 +5,13 @@
5
5
  #
6
6
 
7
7
  module IRB
8
- # :stopdoc:
9
-
10
8
  module Command
11
- class CommandArgumentError < StandardError; end
9
+ class CommandArgumentError < StandardError; end # :nodoc:
12
10
 
13
- def self.extract_ruby_args(*args, **kwargs)
14
- throw :EXTRACT_RUBY_ARGS, [args, kwargs]
11
+ class << self
12
+ def extract_ruby_args(*args, **kwargs) # :nodoc:
13
+ throw :EXTRACT_RUBY_ARGS, [args, kwargs]
14
+ end
15
15
  end
16
16
 
17
17
  class Base
@@ -31,6 +31,12 @@ module IRB
31
31
  @help_message
32
32
  end
33
33
 
34
+ def execute(irb_context, arg)
35
+ new(irb_context).execute(arg)
36
+ rescue CommandArgumentError => e
37
+ puts e.message
38
+ end
39
+
34
40
  private
35
41
 
36
42
  def highlight(text)
@@ -38,12 +44,6 @@ module IRB
38
44
  end
39
45
  end
40
46
 
41
- def self.execute(irb_context, arg)
42
- new(irb_context).execute(arg)
43
- rescue CommandArgumentError => e
44
- puts e.message
45
- end
46
-
47
47
  def initialize(irb_context)
48
48
  @irb_context = irb_context
49
49
  end
@@ -55,8 +55,6 @@ module IRB
55
55
  end
56
56
  end
57
57
 
58
- Nop = Base
58
+ Nop = Base # :nodoc:
59
59
  end
60
-
61
- # :startdoc:
62
60
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ module Command
5
+ class CD < Base
6
+ category "Workspace"
7
+ description "Move into the given object or leave the current context."
8
+
9
+ help_message(<<~HELP)
10
+ Usage: cd ([target]|..)
11
+
12
+ IRB uses a stack of workspaces to keep track of context(s), with `pushws` and `popws` commands to manipulate the stack.
13
+ The `cd` command is an attempt to simplify the operation and will be subject to change.
14
+
15
+ When given:
16
+ - an object, cd will use that object as the new context by pushing it onto the workspace stack.
17
+ - "..", cd will leave the current context by popping the top workspace off the stack.
18
+ - no arguments, cd will move to the top workspace on the stack by popping off all workspaces.
19
+
20
+ Examples:
21
+
22
+ cd Foo
23
+ cd Foo.new
24
+ cd @ivar
25
+ cd ..
26
+ cd
27
+ HELP
28
+
29
+ def execute(arg)
30
+ case arg
31
+ when ".."
32
+ irb_context.pop_workspace
33
+ when ""
34
+ # TODO: decide what workspace commands should be kept, and underlying APIs should look like,
35
+ # and perhaps add a new API to clear the workspace stack.
36
+ prev_workspace = irb_context.pop_workspace
37
+ while prev_workspace
38
+ prev_workspace = irb_context.pop_workspace
39
+ end
40
+ else
41
+ begin
42
+ obj = eval(arg, irb_context.workspace.binding)
43
+ irb_context.push_workspace(obj)
44
+ rescue StandardError => e
45
+ warn "Error: #{e}"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ module Command
5
+ class Copy < Base
6
+ category "Misc"
7
+ description "Copy expression output to clipboard"
8
+
9
+ help_message(<<~HELP)
10
+ Usage: copy ([expression])
11
+
12
+ When given:
13
+ - an expression, copy the inspect result of the expression to the clipboard.
14
+ - no arguments, copy the last evaluated result (`_`) to the clipboard.
15
+
16
+ Examples:
17
+
18
+ copy Foo.new
19
+ copy User.all.to_a
20
+ copy
21
+ HELP
22
+
23
+ def execute(arg)
24
+ # Copy last value if no expression was supplied
25
+ arg = '_' if arg.to_s.strip.empty?
26
+
27
+ value = irb_context.workspace.binding.eval(arg)
28
+ output = irb_context.inspect_method.inspect_value(value, +'', colorize: false).chomp
29
+
30
+ if clipboard_available?
31
+ copy_to_clipboard(output)
32
+ else
33
+ warn "System clipboard not found"
34
+ end
35
+ rescue StandardError => e
36
+ warn "Error: #{e}"
37
+ end
38
+
39
+ private
40
+
41
+ def copy_to_clipboard(text)
42
+ IO.popen(clipboard_program, 'w') do |io|
43
+ io.write(text)
44
+ end
45
+
46
+ raise IOError.new("Copying to clipboard failed") unless $? == 0
47
+
48
+ puts "Copied to system clipboard"
49
+ rescue Errno::ENOENT => e
50
+ warn e.message
51
+ warn "Is IRB.conf[:COPY_COMMAND] set to a bad value?"
52
+ end
53
+
54
+ def clipboard_program
55
+ @clipboard_program ||= if IRB.conf[:COPY_COMMAND]
56
+ IRB.conf[:COPY_COMMAND]
57
+ elsif executable?("pbcopy")
58
+ "pbcopy"
59
+ elsif executable?("xclip")
60
+ "xclip -selection clipboard"
61
+ end
62
+ end
63
+
64
+ def executable?(command)
65
+ system("which #{command} > /dev/null 2>&1")
66
+ end
67
+
68
+ def clipboard_available?
69
+ !!clipboard_program
70
+ end
71
+ end
72
+ end
73
+ end
@@ -58,13 +58,15 @@ module IRB
58
58
  end
59
59
 
60
60
  class DebugCommand < Debug
61
- def self.category
62
- "Debugging"
63
- end
61
+ class << self
62
+ def category
63
+ "Debugging"
64
+ end
64
65
 
65
- def self.description
66
- command_name = self.name.split("::").last.downcase
67
- "Start the debugger of debug.gem and run its `#{command_name}` command."
66
+ def description
67
+ command_name = self.name.split("::").last.downcase
68
+ "Start the debugger of debug.gem and run its `#{command_name}` command."
69
+ end
68
70
  end
69
71
  end
70
72
  end
@@ -39,7 +39,7 @@ module IRB
39
39
 
40
40
  help_cmds = commands_grouped_by_categories.delete("Help")
41
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|
42
+ aliases = irb_context.instance_variable_get(:@command_aliases).map do |alias_name, target|
43
43
  { display_name: alias_name, description: "Alias for `#{target}`" }
44
44
  end
45
45