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