irb 1.14.0 → 1.18.0

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rdoc_options +5 -0
  3. data/CONTRIBUTING.md +52 -0
  4. data/EXTEND_IRB.md +3 -0
  5. data/Gemfile +11 -1
  6. data/README.md +13 -293
  7. data/doc/COMMAND_LINE_OPTIONS.md +69 -0
  8. data/doc/COMPARED_WITH_PRY.md +22 -0
  9. data/doc/Configurations.md +274 -0
  10. data/doc/EXTEND_IRB.md +122 -0
  11. data/doc/Index.md +705 -0
  12. data/doc/irb/irb.rd.ja +1 -1
  13. data/lib/irb/color.rb +251 -162
  14. data/lib/irb/color_printer.rb +10 -9
  15. data/lib/irb/command/base.rb +46 -13
  16. data/lib/irb/command/copy.rb +83 -0
  17. data/lib/irb/command/debug.rb +8 -6
  18. data/lib/irb/command/help.rb +1 -1
  19. data/lib/irb/command/history.rb +1 -1
  20. data/lib/irb/command/internal_helpers.rb +7 -4
  21. data/lib/irb/command/ls.rb +29 -15
  22. data/lib/irb/completion.rb +81 -57
  23. data/lib/irb/context.rb +132 -53
  24. data/lib/irb/debug/ui.rb +2 -4
  25. data/lib/irb/debug.rb +9 -12
  26. data/lib/irb/default_commands.rb +19 -8
  27. data/lib/irb/easter-egg.rb +13 -7
  28. data/lib/irb/ext/multi-irb.rb +2 -0
  29. data/lib/irb/history.rb +84 -55
  30. data/lib/irb/init.rb +7 -2
  31. data/lib/irb/input-method.rb +167 -130
  32. data/lib/irb/inspector.rb +42 -36
  33. data/lib/irb/lc/help-message +2 -2
  34. data/lib/irb/lc/ja/help-message +4 -4
  35. data/lib/irb/nesting_parser.rb +364 -213
  36. data/lib/irb/pager.rb +137 -7
  37. data/lib/irb/ruby-lex.rb +230 -302
  38. data/lib/irb/ruby_logo.aa +79 -37
  39. data/lib/irb/source_finder.rb +15 -22
  40. data/lib/irb/startup_message.rb +83 -0
  41. data/lib/irb/statement.rb +21 -0
  42. data/lib/irb/version.rb +2 -2
  43. data/lib/irb/workspace.rb +22 -31
  44. data/lib/irb.rb +148 -986
  45. data/man/irb.1 +37 -2
  46. metadata +42 -12
  47. data/.document +0 -4
  48. data/Rakefile +0 -54
  49. data/bin/console +0 -6
  50. data/bin/setup +0 -6
  51. data/irb.gemspec +0 -46
data/lib/irb.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
6
6
  #
7
7
 
8
- require "ripper"
8
+ require "prism"
9
9
  require "reline"
10
10
 
11
11
  require_relative "irb/init"
@@ -14,906 +14,64 @@ require_relative "irb/default_commands"
14
14
 
15
15
  require_relative "irb/ruby-lex"
16
16
  require_relative "irb/statement"
17
+ require_relative "irb/history"
17
18
  require_relative "irb/input-method"
18
19
  require_relative "irb/locale"
19
20
  require_relative "irb/color"
20
21
 
21
22
  require_relative "irb/version"
22
23
  require_relative "irb/easter-egg"
24
+ require_relative "irb/startup_message"
23
25
  require_relative "irb/debug"
24
26
  require_relative "irb/pager"
25
27
 
26
- # ## IRB
27
- #
28
- # Module IRB ("Interactive Ruby") provides a shell-like interface that supports
29
- # user interaction with the Ruby interpreter.
30
- #
31
- # It operates as a *read-eval-print loop*
32
- # ([REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop))
33
- # that:
34
- #
35
- # * ***Reads*** each character as you type. You can modify the IRB context to
36
- # change the way input works. See [Input](rdoc-ref:IRB@Input).
37
- # * ***Evaluates*** the code each time it has read a syntactically complete
38
- # passage.
39
- # * ***Prints*** after evaluating. You can modify the IRB context to change
40
- # the way output works. See [Output](rdoc-ref:IRB@Output).
41
- #
42
- #
43
- # Example:
44
- #
45
- # $ irb
46
- # irb(main):001> File.basename(Dir.pwd)
47
- # => "irb"
48
- # irb(main):002> Dir.entries('.').size
49
- # => 25
50
- # irb(main):003* Dir.entries('.').select do |entry|
51
- # irb(main):004* entry.start_with?('R')
52
- # irb(main):005> end
53
- # => ["README.md", "Rakefile"]
54
- #
55
- # The typed input may also include [\IRB-specific
56
- # commands](rdoc-ref:IRB@IRB-Specific+Commands).
57
- #
58
- # As seen above, you can start IRB by using the shell command `irb`.
59
- #
60
- # You can stop an IRB session by typing command `exit`:
61
- #
62
- # irb(main):006> exit
63
- # $
64
- #
65
- # At that point, IRB calls any hooks found in array `IRB.conf[:AT_EXIT]`, then
66
- # exits.
67
- #
68
- # ## Startup
69
- #
70
- # At startup, IRB:
71
- #
72
- # 1. Interprets (as Ruby code) the content of the [configuration
73
- # file](rdoc-ref:IRB@Configuration+File) (if given).
74
- # 2. Constructs the initial session context from [hash
75
- # IRB.conf](rdoc-ref:IRB@Hash+IRB.conf) and from default values; the hash
76
- # content may have been affected by [command-line
77
- # options](rdoc-ref:IB@Command-Line+Options), and by direct assignments in
78
- # the configuration file.
79
- # 3. Assigns the context to variable `conf`.
80
- # 4. Assigns command-line arguments to variable `ARGV`.
81
- # 5. Prints the [prompt](rdoc-ref:IRB@Prompt+and+Return+Formats).
82
- # 6. Puts the content of the [initialization
83
- # script](rdoc-ref:IRB@Initialization+Script) onto the IRB shell, just as if
84
- # it were user-typed commands.
85
- #
86
- #
87
- # ### The Command Line
88
- #
89
- # On the command line, all options precede all arguments; the first item that is
90
- # not recognized as an option is treated as an argument, as are all items that
91
- # follow.
92
- #
93
- # #### Command-Line Options
94
- #
95
- # Many command-line options affect entries in hash `IRB.conf`, which in turn
96
- # affect the initial configuration of the IRB session.
97
- #
98
- # Details of the options are described in the relevant subsections below.
99
- #
100
- # A cursory list of the IRB command-line options may be seen in the [help
101
- # message](https://raw.githubusercontent.com/ruby/irb/master/lib/irb/lc/help-message),
102
- # which is also displayed if you use command-line option `--help`.
103
- #
104
- # If you are interested in a specific option, consult the
105
- # [index](rdoc-ref:doc/irb/indexes.md@Index+of+Command-Line+Options).
106
- #
107
- # #### Command-Line Arguments
108
- #
109
- # Command-line arguments are passed to IRB in array `ARGV`:
110
- #
111
- # $ irb --noscript Foo Bar Baz
112
- # irb(main):001> ARGV
113
- # => ["Foo", "Bar", "Baz"]
114
- # irb(main):002> exit
115
- # $
116
- #
117
- # Command-line option `--` causes everything that follows to be treated as
118
- # arguments, even those that look like options:
119
- #
120
- # $ irb --noscript -- --noscript -- Foo Bar Baz
121
- # irb(main):001> ARGV
122
- # => ["--noscript", "--", "Foo", "Bar", "Baz"]
123
- # irb(main):002> exit
124
- # $
125
- #
126
- # ### Configuration File
127
- #
128
- # You can initialize IRB via a *configuration file*.
129
- #
130
- # If command-line option `-f` is given, no configuration file is looked for.
131
- #
132
- # Otherwise, IRB reads and interprets a configuration file if one is available.
133
- #
134
- # The configuration file can contain any Ruby code, and can usefully include
135
- # user code that:
136
- #
137
- # * Can then be debugged in IRB.
138
- # * Configures IRB itself.
139
- # * Requires or loads files.
140
- #
141
- #
142
- # The path to the configuration file is the first found among:
143
- #
144
- # * The value of variable `$IRBRC`, if defined.
145
- # * The value of variable `$XDG_CONFIG_HOME/irb/irbrc`, if defined.
146
- # * File `$HOME/.irbrc`, if it exists.
147
- # * File `$HOME/.config/irb/irbrc`, if it exists.
148
- # * File `.irbrc` in the current directory, if it exists.
149
- # * File `irb.rc` in the current directory, if it exists.
150
- # * File `_irbrc` in the current directory, if it exists.
151
- # * File `$irbrc` in the current directory, if it exists.
152
- #
153
- #
154
- # If the search fails, there is no configuration file.
155
- #
156
- # If the search succeeds, the configuration file is read as Ruby code, and so
157
- # can contain any Ruby programming you like.
158
- #
159
- # Method `conf.rc?` returns `true` if a configuration file was read, `false`
160
- # otherwise. Hash entry `IRB.conf[:RC]` also contains that value.
161
- #
162
- # ### Hash `IRB.conf`
163
- #
164
- # The initial entries in hash `IRB.conf` are determined by:
165
- #
166
- # * Default values.
167
- # * Command-line options, which may override defaults.
168
- # * Direct assignments in the configuration file.
169
- #
170
- #
171
- # You can see the hash by typing `IRB.conf`.
172
- #
173
- # Details of the entries' meanings are described in the relevant subsections
174
- # below.
175
- #
176
- # If you are interested in a specific entry, consult the
177
- # [index](rdoc-ref:doc/irb/indexes.md@Index+of+IRB.conf+Entries).
178
- #
179
- # ### Notes on Initialization Precedence
180
- #
181
- # * Any conflict between an entry in hash `IRB.conf` and a command-line option
182
- # is resolved in favor of the hash entry.
183
- # * Hash `IRB.conf` affects the context only once, when the configuration file
184
- # is interpreted; any subsequent changes to it do not affect the context and
185
- # are therefore essentially meaningless.
186
- #
187
- #
188
- # ### Initialization Script
189
- #
190
- # By default, the first command-line argument (after any options) is the path to
191
- # a Ruby initialization script.
192
- #
193
- # IRB reads the initialization script and puts its content onto the IRB shell,
194
- # just as if it were user-typed commands.
195
- #
196
- # Command-line option `--noscript` causes the first command-line argument to be
197
- # treated as an ordinary argument (instead of an initialization script);
198
- # `--script` is the default.
199
- #
200
- # ## Input
201
- #
202
- # This section describes the features that allow you to change the way IRB input
203
- # works; see also [Input and Output](rdoc-ref:IRB@Input+and+Output).
204
- #
205
- # ### Input Command History
206
- #
207
- # By default, IRB stores a history of up to 1000 input commands in a file named
208
- # `.irb_history`. The history file will be in the same directory as the
209
- # [configuration file](rdoc-ref:IRB@Configuration+File) if one is found, or in
210
- # `~/` otherwise.
211
- #
212
- # A new IRB session creates the history file if it does not exist, and appends
213
- # to the file if it does exist.
214
- #
215
- # You can change the filepath by adding to your configuration file:
216
- # `IRB.conf[:HISTORY_FILE] = *filepath*`, where *filepath* is a string filepath.
217
- #
218
- # During the session, method `conf.history_file` returns the filepath, and
219
- # method `conf.history_file = *new_filepath*` copies the history to the file at
220
- # *new_filepath*, which becomes the history file for the session.
221
- #
222
- # You can change the number of commands saved by adding to your configuration
223
- # file: `IRB.conf[:SAVE_HISTORY] = *n*`, wheHISTORY_FILEre *n* is one of:
224
- #
225
- # * Positive integer: the number of commands to be saved,
226
- # * Zero: all commands are to be saved.
227
- # * `nil`: no commands are to be saved,.
228
- #
229
- #
230
- # During the session, you can use methods `conf.save_history` or
231
- # `conf.save_history=` to retrieve or change the count.
232
- #
233
- # ### Command Aliases
234
- #
235
- # By default, IRB defines several command aliases:
236
- #
237
- # irb(main):001> conf.command_aliases
238
- # => {:"$"=>:show_source, :"@"=>:whereami}
239
- #
240
- # You can change the initial aliases in the configuration file with:
241
- #
242
- # IRB.conf[:COMMAND_ALIASES] = {foo: :show_source, bar: :whereami}
243
- #
244
- # You can replace the current aliases at any time with configuration method
245
- # `conf.command_aliases=`; Because `conf.command_aliases` is a hash, you can
246
- # modify it.
247
- #
248
- # ### End-of-File
249
- #
250
- # By default, `IRB.conf[:IGNORE_EOF]` is `false`, which means that typing the
251
- # end-of-file character `Ctrl-D` causes the session to exit.
252
- #
253
- # You can reverse that behavior by adding `IRB.conf[:IGNORE_EOF] = true` to the
254
- # configuration file.
255
- #
256
- # During the session, method `conf.ignore_eof?` returns the setting, and method
257
- # `conf.ignore_eof = *boolean*` sets it.
258
- #
259
- # ### SIGINT
260
- #
261
- # By default, `IRB.conf[:IGNORE_SIGINT]` is `true`, which means that typing the
262
- # interrupt character `Ctrl-C` causes the session to exit.
263
- #
264
- # You can reverse that behavior by adding `IRB.conf[:IGNORE_SIGING] = false` to
265
- # the configuration file.
266
- #
267
- # During the session, method `conf.ignore_siging?` returns the setting, and
268
- # method `conf.ignore_sigint = *boolean*` sets it.
269
- #
270
- # ### Automatic Completion
271
- #
272
- # By default, IRB enables [automatic
273
- # completion](https://en.wikipedia.org/wiki/Autocomplete#In_command-line_interpr
274
- # eters):
275
- #
276
- # You can disable it by either of these:
277
- #
278
- # * Adding `IRB.conf[:USE_AUTOCOMPLETE] = false` to the configuration file.
279
- # * Giving command-line option `--noautocomplete` (`--autocomplete` is the
280
- # default).
281
- #
282
- #
283
- # Method `conf.use_autocomplete?` returns `true` if automatic completion is
284
- # enabled, `false` otherwise.
285
- #
286
- # The setting may not be changed during the session.
287
- #
288
- # ### Automatic Indentation
289
- #
290
- # By default, IRB automatically indents lines of code to show structure (e.g.,
291
- # it indent the contents of a block).
292
- #
293
- # The current setting is returned by the configuration method
294
- # `conf.auto_indent_mode`.
295
- #
296
- # The default initial setting is `true`:
297
- #
298
- # irb(main):001> conf.auto_indent_mode
299
- # => true
300
- # irb(main):002* Dir.entries('.').select do |entry|
301
- # irb(main):003* entry.start_with?('R')
302
- # irb(main):004> end
303
- # => ["README.md", "Rakefile"]
304
- #
305
- # You can change the initial setting in the configuration file with:
306
- #
307
- # IRB.conf[:AUTO_INDENT] = false
308
- #
309
- # Note that the *current* setting *may not* be changed in the IRB session.
310
- #
311
- # ### Input Method
312
- #
313
- # The IRB input method determines how command input is to be read; by default,
314
- # the input method for a session is IRB::RelineInputMethod. Unless the
315
- # value of the TERM environment variable is 'dumb', in which case the
316
- # most simplistic input method is used.
317
- #
318
- # You can set the input method by:
319
- #
320
- # * Adding to the configuration file:
321
- #
322
- # * `IRB.conf[:USE_SINGLELINE] = true` or `IRB.conf[:USE_MULTILINE]=
323
- # false` sets the input method to IRB::ReadlineInputMethod.
324
- # * `IRB.conf[:USE_SINGLELINE] = false` or `IRB.conf[:USE_MULTILINE] =
325
- # true` sets the input method to IRB::RelineInputMethod.
326
- #
327
- #
328
- # * Giving command-line options:
329
- #
330
- # * `--singleline` or `--nomultiline` sets the input method to
331
- # IRB::ReadlineInputMethod.
332
- # * `--nosingleline` or `--multiline` sets the input method to
333
- # IRB::RelineInputMethod.
334
- # * `--nosingleline` together with `--nomultiline` sets the
335
- # input to IRB::StdioInputMethod.
336
- #
337
- #
338
- # Method `conf.use_multiline?` and its synonym `conf.use_reline` return:
339
- #
340
- # * `true` if option `--multiline` was given.
341
- # * `false` if option `--nomultiline` was given.
342
- # * `nil` if neither was given.
343
- #
344
- #
345
- # Method `conf.use_singleline?` and its synonym `conf.use_readline` return:
346
- #
347
- # * `true` if option `--singleline` was given.
348
- # * `false` if option `--nosingleline` was given.
349
- # * `nil` if neither was given.
350
- #
351
- #
352
- # ## Output
353
- #
354
- # This section describes the features that allow you to change the way IRB
355
- # output works; see also [Input and Output](rdoc-ref:IRB@Input+and+Output).
356
- #
357
- # ### Return-Value Printing (Echoing)
358
- #
359
- # By default, IRB prints (echoes) the values returned by all input commands.
360
- #
361
- # You can change the initial behavior and suppress all echoing by:
362
- #
363
- # * Adding to the configuration file: `IRB.conf[:ECHO] = false`. (The default
364
- # value for this entry is `nil`, which means the same as `true`.)
365
- # * Giving command-line option `--noecho`. (The default is `--echo`.)
366
- #
367
- #
368
- # During the session, you can change the current setting with configuration
369
- # method `conf.echo=` (set to `true` or `false`).
370
- #
371
- # As stated above, by default IRB prints the values returned by all input
372
- # commands; but IRB offers special treatment for values returned by assignment
373
- # statements, which may be:
374
- #
375
- # * Printed with truncation (to fit on a single line of output), which is the
376
- # default; an ellipsis (`...` is suffixed, to indicate the truncation):
377
- #
378
- # irb(main):001> x = 'abc' * 100
379
- #
380
- #
381
- # > "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc...
382
- #
383
- # * Printed in full (regardless of the length).
384
- # * Suppressed (not printed at all)
385
- #
386
- #
387
- # You can change the initial behavior by:
388
- #
389
- # * Adding to the configuration file: `IRB.conf[:ECHO_ON_ASSIGNMENT] = false`.
390
- # (The default value for this entry is `niL`, which means the same as
391
- # `:truncate`.)
392
- # * Giving command-line option `--noecho-on-assignment` or
393
- # `--echo-on-assignment`. (The default is `--truncate-echo-on-assignment`.)
394
- #
395
- #
396
- # During the session, you can change the current setting with configuration
397
- # method `conf.echo_on_assignment=` (set to `true`, `false`, or `:truncate`).
398
- #
399
- # By default, IRB formats returned values by calling method `inspect`.
400
- #
401
- # You can change the initial behavior by:
402
- #
403
- # * Adding to the configuration file: `IRB.conf[:INSPECT_MODE] = false`. (The
404
- # default value for this entry is `true`.)
405
- # * Giving command-line option `--noinspect`. (The default is `--inspect`.)
406
- #
407
- #
408
- # During the session, you can change the setting using method
409
- # `conf.inspect_mode=`.
410
- #
411
- # ### Multiline Output
412
- #
413
- # By default, IRB prefixes a newline to a multiline response.
414
- #
415
- # You can change the initial default value by adding to the configuration file:
416
- #
417
- # IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT] = false
418
- #
419
- # During a session, you can retrieve or set the value using methods
420
- # `conf.newline_before_multiline_output?` and
421
- # `conf.newline_before_multiline_output=`.
422
- #
423
- # Examples:
424
- #
425
- # irb(main):001> conf.inspect_mode = false
426
- # => false
427
- # irb(main):002> "foo\nbar"
428
- # =>
429
- # foo
430
- # bar
431
- # irb(main):003> conf.newline_before_multiline_output = false
432
- # => false
433
- # irb(main):004> "foo\nbar"
434
- # => foo
435
- # bar
436
- #
437
- # ### Evaluation History
438
- #
439
- # By default, IRB saves no history of evaluations (returned values), and the
440
- # related methods `conf.eval_history`, `_`, and `__` are undefined.
441
- #
442
- # You can turn on that history, and set the maximum number of evaluations to be
443
- # stored:
444
- #
445
- # * In the configuration file: add `IRB.conf[:EVAL_HISTORY] = *n*`. (Examples
446
- # below assume that we've added `IRB.conf[:EVAL_HISTORY] = 5`.)
447
- # * In the session (at any time): `conf.eval_history = *n*`.
448
- #
449
- #
450
- # If `n` is zero, all evaluation history is stored.
451
- #
452
- # Doing either of the above:
453
- #
454
- # * Sets the maximum size of the evaluation history; defines method
455
- # `conf.eval_history`, which returns the maximum size `n` of the evaluation
456
- # history:
457
- #
458
- # irb(main):001> conf.eval_history = 5
459
- # => 5
460
- # irb(main):002> conf.eval_history
461
- # => 5
462
- #
463
- # * Defines variable `_`, which contains the most recent evaluation, or `nil`
464
- # if none; same as method `conf.last_value`:
465
- #
466
- # irb(main):003> _
467
- # => 5
468
- # irb(main):004> :foo
469
- # => :foo
470
- # irb(main):005> :bar
471
- # => :bar
472
- # irb(main):006> _
473
- # => :bar
474
- # irb(main):007> _
475
- # => :bar
476
- #
477
- # * Defines variable `__`:
478
- #
479
- # * `__` unadorned: contains all evaluation history:
480
- #
481
- # irb(main):008> :foo
482
- # => :foo
483
- # irb(main):009> :bar
484
- # => :bar
485
- # irb(main):010> :baz
486
- # => :baz
487
- # irb(main):011> :bat
488
- # => :bat
489
- # irb(main):012> :bam
490
- # => :bam
491
- # irb(main):013> __
492
- # =>
493
- # 9 :bar
494
- # 10 :baz
495
- # 11 :bat
496
- # 12 :bam
497
- # irb(main):014> __
498
- # =>
499
- # 10 :baz
500
- # 11 :bat
501
- # 12 :bam
502
- # 13 ...self-history...
503
- #
504
- # Note that when the evaluation is multiline, it is displayed
505
- # differently.
506
- #
507
- # * `__[`*m*`]`:
508
- #
509
- # * Positive *m*: contains the evaluation for the given line number,
510
- # or `nil` if that line number is not in the evaluation history:
511
- #
512
- # irb(main):015> __[12]
513
- # => :bam
514
- # irb(main):016> __[1]
515
- # => nil
516
- #
517
- # * Negative *m*: contains the `mth`-from-end evaluation, or `nil` if
518
- # that evaluation is not in the evaluation history:
519
- #
520
- # irb(main):017> __[-3]
521
- # => :bam
522
- # irb(main):018> __[-13]
523
- # => nil
524
- #
525
- # * Zero *m*: contains `nil`:
526
- #
527
- # irb(main):019> __[0]
528
- # => nil
529
- #
530
- #
531
- #
532
- #
533
- # ### Prompt and Return Formats
534
- #
535
- # By default, IRB uses the prompt and return value formats defined in its
536
- # `:DEFAULT` prompt mode.
537
- #
538
- # #### The Default Prompt and Return Format
539
- #
540
- # The default prompt and return values look like this:
541
- #
542
- # irb(main):001> 1 + 1
543
- # => 2
544
- # irb(main):002> 2 + 2
545
- # => 4
546
- #
547
- # The prompt includes:
548
- #
549
- # * The name of the running program (`irb`); see [IRB
550
- # Name](rdoc-ref:IRB@IRB+Name).
551
- # * The name of the current session (`main`); See [IRB
552
- # Sessions](rdoc-ref:IRB@IRB+Sessions).
553
- # * A 3-digit line number (1-based).
554
- #
555
- #
556
- # The default prompt actually defines three formats:
557
- #
558
- # * One for most situations (as above):
559
- #
560
- # irb(main):003> Dir
561
- # => Dir
562
- #
563
- # * One for when the typed command is a statement continuation (adds trailing
564
- # asterisk):
565
- #
566
- # irb(main):004* Dir.
567
- #
568
- # * One for when the typed command is a string continuation (adds trailing
569
- # single-quote):
570
- #
571
- # irb(main):005' Dir.entries('.
572
- #
573
- #
574
- # You can see the prompt change as you type the characters in the following:
575
- #
576
- # irb(main):001* Dir.entries('.').select do |entry|
577
- # irb(main):002* entry.start_with?('R')
578
- # irb(main):003> end
579
- # => ["README.md", "Rakefile"]
580
- #
581
- # #### Pre-Defined Prompts
582
- #
583
- # IRB has several pre-defined prompts, stored in hash `IRB.conf[:PROMPT]`:
584
- #
585
- # irb(main):001> IRB.conf[:PROMPT].keys
586
- # => [:NULL, :DEFAULT, :CLASSIC, :SIMPLE, :INF_RUBY, :XMP]
587
- #
588
- # To see the full data for these, type `IRB.conf[:PROMPT]`.
589
- #
590
- # Most of these prompt definitions include specifiers that represent values like
591
- # the IRB name, session name, and line number; see [Prompt
592
- # Specifiers](rdoc-ref:IRB@Prompt+Specifiers).
593
- #
594
- # You can change the initial prompt and return format by:
595
- #
596
- # * Adding to the configuration file: `IRB.conf[:PROMPT] = *mode*` where
597
- # *mode* is the symbol name of a prompt mode.
598
- # * Giving a command-line option:
599
- #
600
- # * `--prompt *mode*`: sets the prompt mode to *mode*. where *mode* is the
601
- # symbol name of a prompt mode.
602
- # * `--simple-prompt` or `--sample-book-mode`: sets the prompt mode to
603
- # `:SIMPLE`.
604
- # * `--inf-ruby-mode`: sets the prompt mode to `:INF_RUBY` and suppresses
605
- # both `--multiline` and `--singleline`.
606
- # * `--noprompt`: suppresses prompting; does not affect echoing.
607
- #
608
- #
609
- #
610
- # You can retrieve or set the current prompt mode with methods
611
- #
612
- # `conf.prompt_mode` and `conf.prompt_mode=`.
613
- #
614
- # If you're interested in prompts and return formats other than the defaults,
615
- # you might experiment by trying some of the others.
616
- #
617
- # #### Custom Prompts
618
- #
619
- # You can also define custom prompts and return formats, which may be done
620
- # either in an IRB session or in the configuration file.
621
- #
622
- # A prompt in IRB actually defines three prompts, as seen above. For simple
623
- # custom data, we'll make all three the same:
624
- #
625
- # irb(main):001* IRB.conf[:PROMPT][:MY_PROMPT] = {
626
- # irb(main):002* PROMPT_I: ': ',
627
- # irb(main):003* PROMPT_C: ': ',
628
- # irb(main):004* PROMPT_S: ': ',
629
- # irb(main):005* RETURN: '=> '
630
- # irb(main):006> }
631
- # => {:PROMPT_I=>": ", :PROMPT_C=>": ", :PROMPT_S=>": ", :RETURN=>"=> "}
632
- #
633
- # If you define the custom prompt in the configuration file, you can also make
634
- # it the current prompt by adding:
635
- #
636
- # IRB.conf[:PROMPT_MODE] = :MY_PROMPT
637
- #
638
- # Regardless of where it's defined, you can make it the current prompt in a
639
- # session:
640
- #
641
- # conf.prompt_mode = :MY_PROMPT
642
- #
643
- # You can view or modify the current prompt data with various configuration
644
- # methods:
645
- #
646
- # * `conf.prompt_mode`, `conf.prompt_mode=`.
647
- # * `conf.prompt_c`, `conf.c=`.
648
- # * `conf.prompt_i`, `conf.i=`.
649
- # * `conf.prompt_s`, `conf.s=`.
650
- # * `conf.return_format`, `return_format=`.
651
- #
652
- #
653
- # #### Prompt Specifiers
654
- #
655
- # A prompt's definition can include specifiers for which certain values are
656
- # substituted:
657
- #
658
- # * `%N`: the name of the running program.
659
- # * `%m`: the value of `self.to_s`.
660
- # * `%M`: the value of `self.inspect`.
661
- # * `%l`: an indication of the type of string; one of `"`, `'`, `/`, `]`.
662
- # * `%NNi`: Indentation level. NN is a 2-digit number that specifies the number
663
- # of digits of the indentation level (03 will result in 001).
664
- # * `%NNn`: Line number. NN is a 2-digit number that specifies the number
665
- # of digits of the line number (03 will result in 001).
666
- # * `%%`: Literal `%`.
667
- #
668
- #
669
- # ### Verbosity
670
- #
671
- # By default, IRB verbosity is disabled, which means that output is smaller
672
- # rather than larger.
673
- #
674
- # You can enable verbosity by:
675
- #
676
- # * Adding to the configuration file: `IRB.conf[:VERBOSE] = true` (the default
677
- # is `nil`).
678
- # * Giving command-line options `--verbose` (the default is `--noverbose`).
679
- #
680
- #
681
- # During a session, you can retrieve or set verbosity with methods
682
- # `conf.verbose` and `conf.verbose=`.
683
- #
684
- # ### Help
685
- #
686
- # Command-line option `--version` causes IRB to print its help text and exit.
687
- #
688
- # ### Version
689
- #
690
- # Command-line option `--version` causes IRB to print its version text and exit.
691
- #
692
- # ## Input and Output
693
- #
694
- # ### Color Highlighting
695
- #
696
- # By default, IRB color highlighting is enabled, and is used for both:
697
- #
698
- # * Input: As you type, IRB reads the typed characters and highlights elements
699
- # that it recognizes; it also highlights errors such as mismatched
700
- # parentheses.
701
- # * Output: IRB highlights syntactical elements.
702
- #
703
- #
704
- # You can disable color highlighting by:
705
- #
706
- # * Adding to the configuration file: `IRB.conf[:USE_COLORIZE] = false` (the
707
- # default value is `true`).
708
- # * Giving command-line option `--nocolorize`
709
- #
710
- #
711
- # ## Debugging
712
- #
713
- # Command-line option `-d` sets variables `$VERBOSE` and `$DEBUG` to `true`;
714
- # these have no effect on IRB output.
715
- #
716
- # ### Warnings
717
- #
718
- # Command-line option `-w` suppresses warnings.
719
- #
720
- # Command-line option `-W[*level*]` sets warning level;
721
- #
722
- # * 0=silence
723
- # * 1=medium
724
- # * 2=verbose
725
- #
726
- # ## Other Features
727
- #
728
- # ### Load Modules
729
- #
730
- # You can specify the names of modules that are to be required at startup.
731
- #
732
- # Array `conf.load_modules` determines the modules (if any) that are to be
733
- # required during session startup. The array is used only during session
734
- # startup, so the initial value is the only one that counts.
735
- #
736
- # The default initial value is `[]` (load no modules):
737
- #
738
- # irb(main):001> conf.load_modules
739
- # => []
740
- #
741
- # You can set the default initial value via:
742
- #
743
- # * Command-line option `-r`
744
- #
745
- # $ irb -r csv -r json
746
- # irb(main):001> conf.load_modules
747
- # => ["csv", "json"]
748
- #
749
- # * Hash entry `IRB.conf[:LOAD_MODULES] = *array*`:
750
- #
751
- # IRB.conf[:LOAD_MODULES] = %w[csv, json]
752
- #
753
- #
754
- # Note that the configuration file entry overrides the command-line options.
755
- #
756
- # ### RI Documentation Directories
757
- #
758
- # You can specify the paths to RI documentation directories that are to be
759
- # loaded (in addition to the default directories) at startup; see details about
760
- # RI by typing `ri --help`.
761
- #
762
- # Array `conf.extra_doc_dirs` determines the directories (if any) that are to be
763
- # loaded during session startup. The array is used only during session startup,
764
- # so the initial value is the only one that counts.
765
- #
766
- # The default initial value is `[]` (load no extra documentation):
767
- #
768
- # irb(main):001> conf.extra_doc_dirs
769
- # => []
770
- #
771
- # You can set the default initial value via:
772
- #
773
- # * Command-line option `--extra_doc_dir`
774
- #
775
- # $ irb --extra-doc-dir your_doc_dir --extra-doc-dir my_doc_dir
776
- # irb(main):001> conf.extra_doc_dirs
777
- # => ["your_doc_dir", "my_doc_dir"]
778
- #
779
- # * Hash entry `IRB.conf[:EXTRA_DOC_DIRS] = *array*`:
780
- #
781
- # IRB.conf[:EXTRA_DOC_DIRS] = %w[your_doc_dir my_doc_dir]
782
- #
783
- #
784
- # Note that the configuration file entry overrides the command-line options.
785
- #
786
- # ### IRB Name
787
- #
788
- # You can specify a name for IRB.
789
- #
790
- # The default initial value is `'irb'`:
791
- #
792
- # irb(main):001> conf.irb_name
793
- # => "irb"
794
- #
795
- # You can set the default initial value via hash entry `IRB.conf[:IRB_NAME] =
796
- # *string*`:
797
- #
798
- # IRB.conf[:IRB_NAME] = 'foo'
799
- #
800
- # ### Application Name
801
- #
802
- # You can specify an application name for the IRB session.
803
- #
804
- # The default initial value is `'irb'`:
805
- #
806
- # irb(main):001> conf.ap_name
807
- # => "irb"
808
- #
809
- # You can set the default initial value via hash entry `IRB.conf[:AP_NAME] =
810
- # *string*`:
811
- #
812
- # IRB.conf[:AP_NAME] = 'my_ap_name'
813
- #
814
- # ### Configuration Monitor
815
- #
816
- # You can monitor changes to the configuration by assigning a proc to
817
- # `IRB.conf[:IRB_RC]` in the configuration file:
818
- #
819
- # IRB.conf[:IRB_RC] = proc {|conf| puts conf.class }
820
- #
821
- # Each time the configuration is changed, that proc is called with argument
822
- # `conf`:
823
- #
824
- # ### Encodings
825
- #
826
- # Command-line option `-E *ex*[:*in*]` sets initial external (ex) and internal
827
- # (in) encodings.
828
- #
829
- # Command-line option `-U` sets both to UTF-8.
830
- #
831
- # ### Commands
832
- #
833
- # Please use the `help` command to see the list of available commands.
834
- #
835
- # ### IRB Sessions
836
- #
837
- # IRB has a special feature, that allows you to manage many sessions at once.
838
- #
839
- # You can create new sessions with Irb.irb, and get a list of current sessions
840
- # with the `jobs` command in the prompt.
841
- #
842
- # #### Configuration
843
- #
844
- # The command line options, or IRB.conf, specify the default behavior of
845
- # Irb.irb.
846
- #
847
- # On the other hand, each conf in IRB@Command-Line+Options is used to
848
- # individually configure IRB.irb.
849
- #
850
- # If a proc is set for `IRB.conf[:IRB_RC]`, its will be invoked after execution
851
- # of that proc with the context of the current session as its argument. Each
852
- # session can be configured using this mechanism.
853
- #
854
- # #### Session variables
855
- #
856
- # There are a few variables in every Irb session that can come in handy:
857
- #
858
- # `_`
859
- # : The value command executed, as a local variable
860
- # `__`
861
- # : The history of evaluated commands. Available only if
862
- # `IRB.conf[:EVAL_HISTORY]` is not `nil` (which is the default). See also
863
- # IRB::Context#eval_history= and IRB::History.
864
- # `__[line_no]`
865
- # : Returns the evaluation value at the given line number, `line_no`. If
866
- # `line_no` is a negative, the return value `line_no` many lines before the
867
- # most recent return value.
868
- #
869
- #
870
- # ## Restrictions
871
- #
872
- # Ruby code typed into IRB behaves the same as Ruby code in a file, except that:
873
- #
874
- # * Because IRB evaluates input immediately after it is syntactically
875
- # complete, some results may be slightly different.
876
- # * Forking may not be well behaved.
877
- #
878
28
  module IRB
879
29
 
880
30
  # An exception raised by IRB.irb_abort
881
- class Abort < Exception;end
31
+ class Abort < Exception;end # :nodoc:
882
32
 
883
- # The current IRB::Context of the session, see IRB.conf
884
- #
885
- # irb
886
- # irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
887
- # foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
888
- def IRB.CurrentContext # :nodoc:
889
- IRB.conf[:MAIN_CONTEXT]
890
- end
33
+ class << self
34
+ # The current IRB::Context of the session, see IRB.conf
35
+ #
36
+ # irb
37
+ # irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
38
+ # foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
39
+ def CurrentContext # :nodoc:
40
+ conf[:MAIN_CONTEXT]
41
+ end
891
42
 
892
- # Initializes IRB and creates a new Irb.irb object at the `TOPLEVEL_BINDING`
893
- def IRB.start(ap_path = nil)
894
- STDOUT.sync = true
895
- $0 = File::basename(ap_path, ".rb") if ap_path
43
+ # Initializes IRB and creates a new Irb.irb object at the `TOPLEVEL_BINDING`
44
+ def start(ap_path = nil)
45
+ STDOUT.sync = true
46
+ $0 = File::basename(ap_path, ".rb") if ap_path
896
47
 
897
- IRB.setup(ap_path)
48
+ setup(ap_path)
898
49
 
899
- if @CONF[:SCRIPT]
900
- irb = Irb.new(nil, @CONF[:SCRIPT])
901
- else
902
- irb = Irb.new
50
+ if @CONF[:SCRIPT]
51
+ irb = Irb.new(nil, @CONF[:SCRIPT])
52
+ else
53
+ irb = Irb.new
54
+
55
+ # Only display the banner in the irb executable
56
+ if @CONF[:SHOW_BANNER] && ap_path&.end_with?("exe/irb")
57
+ StartupMessage.display
58
+ end
59
+ end
60
+
61
+ irb.run(@CONF)
903
62
  end
904
- irb.run(@CONF)
905
- end
906
63
 
907
- # Quits irb
908
- def IRB.irb_exit(*) # :nodoc:
909
- throw :IRB_EXIT, false
910
- end
64
+ # Quits irb
65
+ def irb_exit(*) # :nodoc:
66
+ throw :IRB_EXIT, false
67
+ end
911
68
 
912
- # Aborts then interrupts irb.
913
- #
914
- # Will raise an Abort exception, or the given `exception`.
915
- def IRB.irb_abort(irb, exception = Abort) # :nodoc:
916
- irb.context.thread.raise exception, "abort then interrupt!"
69
+ # Aborts then interrupts irb.
70
+ #
71
+ # Will raise an Abort exception, or the given `exception`.
72
+ def irb_abort(irb, exception = Abort) # :nodoc:
73
+ irb.context.thread.raise exception, "abort then interrupt!"
74
+ end
917
75
  end
918
76
 
919
77
  class Irb
@@ -926,6 +84,15 @@ module IRB
926
84
  PROMPT_MAIN_TRUNCATE_OMISSION = '...'
927
85
  CONTROL_CHARACTERS_PATTERN = "\x00-\x1F"
928
86
 
87
+ # Track the nesting depth of run loops. This is used for history management
88
+ # only the outermost run loop should load/save history.
89
+ @run_nesting_depth = 0
90
+
91
+ class << self
92
+ # TODO: When refactoring to v2.0, find a better way to manage and track nesting sessions.
93
+ attr_accessor :run_nesting_depth
94
+ end
95
+
929
96
  # Returns the current context of this irb session
930
97
  attr_reader :context
931
98
  # The lexer used by this irb session
@@ -936,6 +103,7 @@ module IRB
936
103
  # Creates a new irb session
937
104
  def initialize(workspace = nil, input_method = nil, from_binding: false)
938
105
  @from_binding = from_binding
106
+ @prompt_part_cache = nil
939
107
  @context = Context.new(self, workspace, input_method)
940
108
  @context.workspace.load_helper_methods_to_main
941
109
  @signal_status = :IN_IRB
@@ -970,7 +138,7 @@ module IRB
970
138
  # debugger.
971
139
  input = nil
972
140
  forced_exit = catch(:IRB_EXIT) do
973
- if IRB.conf[:SAVE_HISTORY] && context.io.support_history_saving?
141
+ if History.save_history? && context.io.support_history_saving?
974
142
  # Previous IRB session's history has been saved when `Irb#run` is exited We need
975
143
  # to make sure the saved history is not saved again by resetting the counter
976
144
  context.io.reset_history_counter
@@ -996,14 +164,18 @@ module IRB
996
164
  end
997
165
 
998
166
  def run(conf = IRB.conf)
999
- in_nested_session = !!conf[:MAIN_CONTEXT]
167
+ # Use run_nesting_depth to determine if we're in a nested session.
168
+ in_nested_session = Irb.run_nesting_depth > 0
169
+ Irb.run_nesting_depth += 1
170
+
1000
171
  conf[:IRB_RC].call(context) if conf[:IRB_RC]
1001
172
  prev_context = conf[:MAIN_CONTEXT]
1002
173
  conf[:MAIN_CONTEXT] = context
1003
174
 
1004
- save_history = !in_nested_session && conf[:SAVE_HISTORY] && context.io.support_history_saving?
175
+ load_history = !in_nested_session && context.io.support_history_saving?
176
+ save_history = load_history && History.save_history?
1005
177
 
1006
- if save_history
178
+ if load_history
1007
179
  context.io.load_history
1008
180
  end
1009
181
 
@@ -1021,6 +193,8 @@ module IRB
1021
193
  eval_input
1022
194
  end
1023
195
  ensure
196
+ Irb.run_nesting_depth -= 1
197
+
1024
198
  # Do not restore to nil. It will cause IRB crash when used with threads.
1025
199
  IRB.conf[:MAIN_CONTEXT] = prev_context if prev_context
1026
200
 
@@ -1086,13 +260,7 @@ module IRB
1086
260
  end
1087
261
  end
1088
262
 
1089
- def readmultiline
1090
- prompt = generate_prompt([], false, 0)
1091
-
1092
- # multiline
1093
- return read_input(prompt) if @context.io.respond_to?(:check_termination)
1094
-
1095
- # nomultiline
263
+ def read_input_nomultiline(prompt)
1096
264
  code = +''
1097
265
  line_offset = 0
1098
266
  loop do
@@ -1104,69 +272,51 @@ module IRB
1104
272
  code << line
1105
273
  return code if command?(code)
1106
274
 
1107
- tokens, opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
275
+ continue, opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
1108
276
  return code if terminated
1109
277
 
1110
278
  line_offset += 1
1111
- continue = @scanner.should_continue?(tokens)
1112
279
  prompt = generate_prompt(opens, continue, line_offset)
1113
280
  end
1114
281
  end
1115
282
 
283
+ def readmultiline
284
+ with_prompt_part_cached do
285
+ prompt = generate_prompt([], false, 0)
286
+
287
+ if @context.io.respond_to?(:check_termination)
288
+ # multiline
289
+ read_input(prompt)
290
+ else
291
+ # nomultiline
292
+ read_input_nomultiline(prompt)
293
+ end
294
+ end
295
+ end
296
+
1116
297
  def each_top_level_statement
1117
298
  loop do
1118
299
  code = readmultiline
1119
300
  break unless code
1120
- yield build_statement(code), @line_no
301
+ yield parse_input(code), @line_no
1121
302
  @line_no += code.count("\n")
1122
303
  rescue RubyLex::TerminateLineInput
1123
304
  end
1124
305
  end
1125
306
 
1126
- def build_statement(code)
307
+ def parse_input(code)
1127
308
  if code.match?(/\A\n*\z/)
1128
309
  return Statement::EmptyInput.new
1129
310
  end
1130
311
 
1131
- code.force_encoding(@context.io.encoding)
1132
- if (command, arg = parse_command(code))
1133
- command_class = Command.load_command(command)
1134
- Statement::Command.new(code, command_class, arg)
1135
- else
1136
- is_assignment_expression = @scanner.assignment_expression?(code, local_variables: @context.local_variables)
1137
- Statement::Expression.new(code, is_assignment_expression)
1138
- end
1139
- end
312
+ code = code.dup.force_encoding(@context.io.encoding)
313
+ is_assignment_expression = @scanner.assignment_expression?(code, local_variables: @context.local_variables)
1140
314
 
1141
- ASSIGN_OPERATORS_REGEXP = Regexp.union(%w[= += -= *= /= %= **= &= |= &&= ||= ^= <<= >>=])
1142
-
1143
- def parse_command(code)
1144
- command_name, arg = code.strip.split(/\s+/, 2)
1145
- return unless code.lines.size == 1 && command_name
1146
-
1147
- arg ||= ''
1148
- command = command_name.to_sym
1149
- # Command aliases are always command. example: $, @
1150
- if (alias_name = @context.command_aliases[command])
1151
- return [alias_name, arg]
1152
- end
1153
-
1154
- # Assignment-like expression is not a command
1155
- return if arg.start_with?(ASSIGN_OPERATORS_REGEXP) && !arg.start_with?(/==|=~/)
1156
-
1157
- # Local variable have precedence over command
1158
- return if @context.local_variables.include?(command)
1159
-
1160
- # Check visibility
1161
- public_method = !!Kernel.instance_method(:public_method).bind_call(@context.main, command) rescue false
1162
- private_method = !public_method && !!Kernel.instance_method(:method).bind_call(@context.main, command) rescue false
1163
- if Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
1164
- [command, arg]
1165
- end
315
+ @context.parse_input(code, is_assignment_expression)
1166
316
  end
1167
317
 
1168
318
  def command?(code)
1169
- !!parse_command(code)
319
+ parse_input(code).is_a?(Statement::Command)
1170
320
  end
1171
321
 
1172
322
  def configure_io
@@ -1186,23 +336,25 @@ module IRB
1186
336
  else
1187
337
  next true if command?(code)
1188
338
 
1189
- _tokens, _opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
339
+ _continue, _opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
1190
340
  terminated
1191
341
  end
1192
342
  end
1193
343
  end
1194
344
  if @context.io.respond_to?(:dynamic_prompt)
1195
345
  @context.io.dynamic_prompt do |lines|
1196
- tokens = RubyLex.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, local_variables: @context.local_variables)
1197
- line_results = IRB::NestingParser.parse_by_line(tokens)
346
+ code = lines.map{ |l| l + "\n" }.join
347
+ parse_lex_result = Prism.parse_lex(code, scopes: [@context.local_variables])
348
+ line_results = IRB::NestingParser.parse_by_line(parse_lex_result)
349
+
350
+ tokens = parse_lex_result.value[1].map(&:first)
351
+ tokens_by_line = tokens.group_by {|t| t.location.start_line - 1 }
352
+
1198
353
  tokens_until_line = []
1199
- line_results.map.with_index do |(line_tokens, _prev_opens, next_opens, _min_depth), line_num_offset|
1200
- line_tokens.each do |token, _s|
1201
- # Avoid appending duplicated token. Tokens that include "n" like multiline
1202
- # tstring_content can exist in multiple lines.
1203
- tokens_until_line << token if token != tokens_until_line.last
1204
- end
1205
- continue = @scanner.should_continue?(tokens_until_line)
354
+ line_results.map.with_index do |(_prev_opens, next_opens, _min_depth), line_num_offset|
355
+ line = lines[line_num_offset]
356
+ tokens_until_line.concat(tokens_by_line[line_num_offset] || [])
357
+ continue = @scanner.should_continue?(tokens_until_line, line, line_num_offset + 1)
1206
358
  generate_prompt(next_opens, continue, line_num_offset)
1207
359
  end
1208
360
  end
@@ -1214,8 +366,8 @@ module IRB
1214
366
  next nil if !is_newline && lines[line_index]&.byteslice(0, byte_pointer)&.match?(/\A\s*\z/)
1215
367
 
1216
368
  code = lines[0..line_index].map { |l| "#{l}\n" }.join
1217
- tokens = RubyLex.ripper_lex_without_warning(code, local_variables: @context.local_variables)
1218
- @scanner.process_indent_level(tokens, lines, line_index, is_newline)
369
+ parse_lex_result = Prism.parse_lex(code, scopes: [@context.local_variables])
370
+ @scanner.process_indent_level(parse_lex_result, lines, line_index, is_newline)
1219
371
  end
1220
372
  end
1221
373
  end
@@ -1305,7 +457,10 @@ module IRB
1305
457
  # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
1306
458
  message = message.gsub(/\(irb\):(?<num>\d+):in (?<open_quote>[`'])<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in #{$~[:open_quote]}<main>'" }
1307
459
  puts message
1308
- puts 'Maybe IRB bug!' if irb_bug
460
+
461
+ if irb_bug
462
+ puts "This may be an issue with IRB. If you believe this is an unexpected behavior, please report it to https://github.com/ruby/irb/issues"
463
+ end
1309
464
  rescue Exception => handler_exc
1310
465
  begin
1311
466
  puts exc.inspect
@@ -1392,40 +547,36 @@ module IRB
1392
547
  end
1393
548
 
1394
549
  def output_value(omit = false) # :nodoc:
1395
- str = @context.inspect_last_value
1396
- multiline_p = str.include?("\n")
1397
- if omit
1398
- winwidth = @context.io.winsize.last
1399
- if multiline_p
1400
- first_line = str.split("\n").first
1401
- result = @context.newline_before_multiline_output? ? (@context.return_format % first_line) : first_line
1402
- output_width = Reline::Unicode.calculate_width(result, true)
1403
- diff_size = output_width - Reline::Unicode.calculate_width(first_line, true)
1404
- if diff_size.positive? and output_width > winwidth
1405
- lines, _ = Reline::Unicode.split_by_width(first_line, winwidth - diff_size - 3)
1406
- str = "%s..." % lines.first
1407
- str += "\e[0m" if Color.colorable?
1408
- multiline_p = false
1409
- else
1410
- str = str.gsub(/(\A.*?\n).*/m, "\\1...")
1411
- str += "\e[0m" if Color.colorable?
1412
- end
1413
- else
1414
- output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)
1415
- diff_size = output_width - Reline::Unicode.calculate_width(str, true)
1416
- if diff_size.positive? and output_width > winwidth
1417
- lines, _ = Reline::Unicode.split_by_width(str, winwidth - diff_size - 3)
1418
- str = "%s..." % lines.first
1419
- str += "\e[0m" if Color.colorable?
1420
- end
1421
- end
550
+ unless @context.return_format.include?('%')
551
+ puts @context.return_format
552
+ return
1422
553
  end
1423
554
 
1424
- if multiline_p && @context.newline_before_multiline_output?
1425
- str = "\n" + str
555
+ winheight, winwidth = @context.io.winsize
556
+ if omit
557
+ content, overflow = Pager.take_first_page(winwidth, 1) do |out|
558
+ @context.inspect_last_value(out)
559
+ end
560
+ if overflow
561
+ content = "\n#{content}" if @context.newline_before_multiline_output?
562
+ content = "#{content}..."
563
+ content = "#{content}\e[0m" if Color.colorable?
564
+ end
565
+ puts format(@context.return_format, content.chomp)
566
+ elsif Pager.should_page? && @context.inspector_support_stream_output?
567
+ formatter_proc = ->(content, multipage) do
568
+ content = content.chomp
569
+ content = "\n#{content}" if @context.newline_before_multiline_output? && (multipage || content.include?("\n"))
570
+ format(@context.return_format, content)
571
+ end
572
+ Pager.page_with_preview(winwidth, winheight, formatter_proc) do |out|
573
+ @context.inspect_last_value(out)
574
+ end
575
+ else
576
+ content = @context.inspect_last_value.chomp
577
+ content = "\n#{content}" if @context.newline_before_multiline_output? && content.include?("\n")
578
+ Pager.page_content(format(@context.return_format, content), retain_content: true)
1426
579
  end
1427
-
1428
- Pager.page_content(format(@context.return_format, str), retain_content: true)
1429
580
  end
1430
581
 
1431
582
  # Outputs the local variables to this current session, including #signal_status
@@ -1447,8 +598,15 @@ module IRB
1447
598
 
1448
599
  private
1449
600
 
601
+ def with_prompt_part_cached
602
+ @prompt_part_cache = {}
603
+ yield
604
+ ensure
605
+ @prompt_part_cache = nil
606
+ end
607
+
1450
608
  def generate_prompt(opens, continue, line_offset)
1451
- ltype = @scanner.ltype_from_open_tokens(opens)
609
+ ltype = @scanner.ltype_from_open_nestings(opens)
1452
610
  indent = @scanner.calc_indent_level(opens)
1453
611
  continue = opens.any? || continue
1454
612
  line_no = @line_no + line_offset
@@ -1478,25 +636,29 @@ module IRB
1478
636
  end
1479
637
 
1480
638
  def truncate_prompt_main(str) # :nodoc:
1481
- str = str.tr(CONTROL_CHARACTERS_PATTERN, ' ')
1482
- if str.size <= PROMPT_MAIN_TRUNCATE_LENGTH
1483
- str
1484
- else
1485
- str[0, PROMPT_MAIN_TRUNCATE_LENGTH - PROMPT_MAIN_TRUNCATE_OMISSION.size] + PROMPT_MAIN_TRUNCATE_OMISSION
639
+ if str.size > PROMPT_MAIN_TRUNCATE_LENGTH
640
+ str = str[0, PROMPT_MAIN_TRUNCATE_LENGTH - PROMPT_MAIN_TRUNCATE_OMISSION.size] + PROMPT_MAIN_TRUNCATE_OMISSION
1486
641
  end
642
+ str.tr(CONTROL_CHARACTERS_PATTERN, ' ')
1487
643
  end
1488
644
 
1489
645
  def format_prompt(format, ltype, indent, line_no) # :nodoc:
646
+ # @prompt_part_cache could be nil in unit tests
647
+ part_cache = @prompt_part_cache || {}
1490
648
  format.gsub(/%([0-9]+)?([a-zA-Z%])/) do
1491
649
  case $2
1492
650
  when "N"
1493
651
  @context.irb_name
1494
652
  when "m"
1495
- main_str = @context.main.to_s rescue "!#{$!.class}"
1496
- truncate_prompt_main(main_str)
653
+ part_cache[:m] ||= (
654
+ main_str = "#{@context.safe_method_call_on_main(:to_s)}" rescue "!#{$!.class}"
655
+ truncate_prompt_main(main_str)
656
+ )
1497
657
  when "M"
1498
- main_str = @context.main.inspect rescue "!#{$!.class}"
1499
- truncate_prompt_main(main_str)
658
+ part_cache[:M] ||= (
659
+ main_str = "#{@context.safe_method_call_on_main(:inspect)}" rescue "!#{$!.class}"
660
+ truncate_prompt_main(main_str)
661
+ )
1500
662
  when "l"
1501
663
  ltype
1502
664
  when "i"