irb 1.7.1 → 1.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.document +1 -1
  3. data/Gemfile +10 -1
  4. data/README.md +265 -20
  5. data/Rakefile +13 -10
  6. data/doc/irb/irb.rd.ja +1 -3
  7. data/irb.gemspec +2 -1
  8. data/lib/irb/cmd/nop.rb +3 -52
  9. data/lib/irb/color.rb +4 -2
  10. data/lib/irb/command/backtrace.rb +17 -0
  11. data/lib/irb/command/base.rb +62 -0
  12. data/lib/irb/command/break.rb +17 -0
  13. data/lib/irb/command/catch.rb +17 -0
  14. data/lib/irb/command/chws.rb +40 -0
  15. data/lib/irb/command/context.rb +16 -0
  16. data/lib/irb/{cmd → command}/continue.rb +3 -3
  17. data/lib/irb/command/debug.rb +71 -0
  18. data/lib/irb/{cmd → command}/delete.rb +3 -3
  19. data/lib/irb/command/disable_irb.rb +19 -0
  20. data/lib/irb/command/edit.rb +63 -0
  21. data/lib/irb/command/exit.rb +18 -0
  22. data/lib/irb/{cmd → command}/finish.rb +3 -3
  23. data/lib/irb/command/force_exit.rb +18 -0
  24. data/lib/irb/command/help.rb +83 -0
  25. data/lib/irb/command/history.rb +45 -0
  26. data/lib/irb/command/info.rb +17 -0
  27. data/lib/irb/command/internal_helpers.rb +27 -0
  28. data/lib/irb/{cmd → command}/irb_info.rb +7 -7
  29. data/lib/irb/{cmd → command}/load.rb +23 -8
  30. data/lib/irb/{cmd → command}/ls.rb +42 -19
  31. data/lib/irb/{cmd → command}/measure.rb +18 -17
  32. data/lib/irb/{cmd → command}/next.rb +3 -3
  33. data/lib/irb/command/pushws.rb +65 -0
  34. data/lib/irb/command/show_doc.rb +51 -0
  35. data/lib/irb/command/show_source.rb +74 -0
  36. data/lib/irb/{cmd → command}/step.rb +3 -3
  37. data/lib/irb/command/subirb.rb +123 -0
  38. data/lib/irb/{cmd → command}/whereami.rb +3 -5
  39. data/lib/irb/command.rb +23 -0
  40. data/lib/irb/completion.rb +133 -102
  41. data/lib/irb/context.rb +182 -66
  42. data/lib/irb/debug/ui.rb +103 -0
  43. data/lib/irb/{cmd/debug.rb → debug.rb} +53 -59
  44. data/lib/irb/default_commands.rb +265 -0
  45. data/lib/irb/easter-egg.rb +16 -6
  46. data/lib/irb/ext/change-ws.rb +6 -8
  47. data/lib/irb/ext/{history.rb → eval_history.rb} +7 -7
  48. data/lib/irb/ext/loader.rb +4 -4
  49. data/lib/irb/ext/multi-irb.rb +5 -5
  50. data/lib/irb/ext/tracer.rb +12 -51
  51. data/lib/irb/ext/use-loader.rb +6 -8
  52. data/lib/irb/ext/workspaces.rb +10 -34
  53. data/lib/irb/frame.rb +1 -1
  54. data/lib/irb/help.rb +3 -3
  55. data/lib/irb/helper_method/base.rb +16 -0
  56. data/lib/irb/helper_method/conf.rb +11 -0
  57. data/lib/irb/helper_method.rb +29 -0
  58. data/lib/irb/{ext/save-history.rb → history.rb} +20 -58
  59. data/lib/irb/init.rb +154 -58
  60. data/lib/irb/input-method.rb +238 -203
  61. data/lib/irb/inspector.rb +3 -3
  62. data/lib/irb/lc/error.rb +1 -11
  63. data/lib/irb/lc/help-message +4 -0
  64. data/lib/irb/lc/ja/error.rb +1 -11
  65. data/lib/irb/lc/ja/help-message +13 -0
  66. data/lib/irb/locale.rb +2 -2
  67. data/lib/irb/nesting_parser.rb +13 -3
  68. data/lib/irb/notifier.rb +1 -1
  69. data/lib/irb/output-method.rb +2 -8
  70. data/lib/irb/pager.rb +91 -0
  71. data/lib/irb/ruby-lex.rb +391 -471
  72. data/lib/irb/ruby_logo.aa +43 -0
  73. data/lib/irb/source_finder.rb +139 -0
  74. data/lib/irb/statement.rb +80 -0
  75. data/lib/irb/version.rb +3 -3
  76. data/lib/irb/workspace.rb +24 -4
  77. data/lib/irb/ws-for-case-2.rb +1 -1
  78. data/lib/irb/xmp.rb +3 -3
  79. data/lib/irb.rb +1232 -604
  80. data/man/irb.1 +7 -0
  81. metadata +60 -32
  82. data/lib/irb/cmd/backtrace.rb +0 -21
  83. data/lib/irb/cmd/break.rb +0 -21
  84. data/lib/irb/cmd/catch.rb +0 -21
  85. data/lib/irb/cmd/chws.rb +0 -36
  86. data/lib/irb/cmd/edit.rb +0 -61
  87. data/lib/irb/cmd/help.rb +0 -23
  88. data/lib/irb/cmd/info.rb +0 -21
  89. data/lib/irb/cmd/pushws.rb +0 -45
  90. data/lib/irb/cmd/show_cmds.rb +0 -39
  91. data/lib/irb/cmd/show_doc.rb +0 -48
  92. data/lib/irb/cmd/show_source.rb +0 -113
  93. data/lib/irb/cmd/subirb.rb +0 -66
  94. data/lib/irb/extend-command.rb +0 -356
  95. data/lib/irb/src_encoding.rb +0 -7
data/lib/irb.rb CHANGED
@@ -1,5 +1,6 @@
1
- # frozen_string_literal: false
2
- #
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
3
4
  # irb.rb - irb main module
4
5
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
6
  #
@@ -9,399 +10,886 @@ require "reline"
9
10
 
10
11
  require_relative "irb/init"
11
12
  require_relative "irb/context"
12
- require_relative "irb/extend-command"
13
+ require_relative "irb/default_commands"
13
14
 
14
15
  require_relative "irb/ruby-lex"
16
+ require_relative "irb/statement"
15
17
  require_relative "irb/input-method"
16
18
  require_relative "irb/locale"
17
19
  require_relative "irb/color"
18
20
 
19
21
  require_relative "irb/version"
20
22
  require_relative "irb/easter-egg"
23
+ require_relative "irb/debug"
24
+ require_relative "irb/pager"
21
25
 
22
- # IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby
23
- # expressions read from the standard input.
26
+ # ## IRB
24
27
  #
25
- # The +irb+ command from your shell will start the interpreter.
28
+ # Module IRB ("Interactive Ruby") provides a shell-like interface that supports
29
+ # user interaction with the Ruby interpreter.
26
30
  #
27
- # == Usage
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:
28
34
  #
29
- # Use of irb is easy if you know Ruby.
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).
30
41
  #
31
- # When executing irb, prompts are displayed as follows. Then, enter the Ruby
32
- # expression. An input is executed when it is syntactically complete.
42
+ #
43
+ # Example:
33
44
  #
34
45
  # $ irb
35
- # irb(main):001:0> 1+2
36
- # #=> 3
37
- # irb(main):002:0> class Foo
38
- # irb(main):003:1> def foo
39
- # irb(main):004:2> print 1
40
- # irb(main):005:2> end
41
- # irb(main):006:1> end
42
- # #=> nil
43
- #
44
- # The singleline editor module or multiline editor module can be used with irb.
45
- # Use of multiline editor is default if it's installed.
46
- #
47
- # == Command line options
48
- #
49
- # :include: ./irb/lc/help-message
50
- #
51
- # == Commands
52
- #
53
- # The following commands are available on IRB.
54
- #
55
- # * cwws
56
- # * Show the current workspace.
57
- # * cb, cws, chws
58
- # * Change the current workspace to an object.
59
- # * bindings, workspaces
60
- # * Show workspaces.
61
- # * pushb, pushws
62
- # * Push an object to the workspace stack.
63
- # * popb, popws
64
- # * Pop a workspace from the workspace stack.
65
- # * load
66
- # * Load a Ruby file.
67
- # * require
68
- # * Require a Ruby file.
69
- # * source
70
- # * Loads a given file in the current session.
71
- # * irb
72
- # * Start a child IRB.
73
- # * jobs
74
- # * List of current sessions.
75
- # * fg
76
- # * Switches to the session of the given number.
77
- # * kill
78
- # * Kills the session with the given number.
79
- # * help
80
- # * Enter the mode to look up RI documents.
81
- # * irb_info
82
- # * Show information about IRB.
83
- # * ls
84
- # * Show methods, constants, and variables.
85
- # -g [query] or -G [query] allows you to filter out the output.
86
- # * measure
87
- # * measure enables the mode to measure processing time. measure :off disables it.
88
- # * $, show_source
89
- # * Show the source code of a given method or constant.
90
- # * @, whereami
91
- # * Show the source code around binding.irb again.
92
- # * debug
93
- # * Start the debugger of debug.gem.
94
- # * break, delete, next, step, continue, finish, backtrace, info, catch
95
- # * Start the debugger of debug.gem and run the command on it.
96
- #
97
- # == Configuration
98
- #
99
- # IRB reads a personal initialization file when it's invoked.
100
- # IRB searches a file in the following order and loads the first one found.
101
- #
102
- # * <tt>$IRBRC</tt> (if <tt>$IRBRC</tt> is set)
103
- # * <tt>$XDG_CONFIG_HOME/irb/irbrc</tt> (if <tt>$XDG_CONFIG_HOME</tt> is set)
104
- # * <tt>~/.irbrc</tt>
105
- # * +.config/irb/irbrc+
106
- # * +.irbrc+
107
- # * +irb.rc+
108
- # * +_irbrc+
109
- # * <code>$irbrc</code>
110
- #
111
- # The following are alternatives to the command line options. To use them type
112
- # as follows in an +irb+ session:
113
- #
114
- # IRB.conf[:IRB_NAME]="irb"
115
- # IRB.conf[:INSPECT_MODE]=nil
116
- # IRB.conf[:IRB_RC] = nil
117
- # IRB.conf[:BACK_TRACE_LIMIT]=16
118
- # IRB.conf[:USE_LOADER] = false
119
- # IRB.conf[:USE_MULTILINE] = nil
120
- # IRB.conf[:USE_SINGLELINE] = nil
121
- # IRB.conf[:USE_COLORIZE] = true
122
- # IRB.conf[:USE_TRACER] = false
123
- # IRB.conf[:USE_AUTOCOMPLETE] = true
124
- # IRB.conf[:IGNORE_SIGINT] = true
125
- # IRB.conf[:IGNORE_EOF] = false
126
- # IRB.conf[:PROMPT_MODE] = :DEFAULT
127
- # IRB.conf[:PROMPT] = {...}
128
- #
129
- # === Auto indentation
130
- #
131
- # To disable auto-indent mode in irb, add the following to your +.irbrc+:
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:
132
306
  #
133
307
  # IRB.conf[:AUTO_INDENT] = false
134
308
  #
135
- # === Autocompletion
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`).
136
398
  #
137
- # To disable autocompletion for irb, add the following to your +.irbrc+:
399
+ # By default, IRB formats returned values by calling method `inspect`.
138
400
  #
139
- # IRB.conf[:USE_AUTOCOMPLETE] = false
401
+ # You can change the initial behavior by:
140
402
  #
141
- # === History
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`.)
142
406
  #
143
- # By default, irb will store the last 1000 commands you used in
144
- # <code>IRB.conf[:HISTORY_FILE]</code> (<code>~/.irb_history</code> by default).
145
407
  #
146
- # If you want to disable history, add the following to your +.irbrc+:
408
+ # During the session, you can change the setting using method
409
+ # `conf.inspect_mode=`.
147
410
  #
148
- # IRB.conf[:SAVE_HISTORY] = nil
411
+ # ### Multiline Output
149
412
  #
150
- # See IRB::Context#save_history= for more information.
413
+ # By default, IRB prefixes a newline to a multiline response.
151
414
  #
152
- # The history of _results_ of commands evaluated is not stored by default,
153
- # but can be turned on to be stored with this +.irbrc+ setting:
415
+ # You can change the initial default value by adding to the configuration file:
154
416
  #
155
- # IRB.conf[:EVAL_HISTORY] = <number>
417
+ # IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT] = false
156
418
  #
157
- # See IRB::Context#eval_history= and History class. The history of command
158
- # results is not permanently saved in any file.
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=`.
159
422
  #
160
- # == Customizing the IRB Prompt
423
+ # Examples:
161
424
  #
162
- # In order to customize the prompt, you can change the following Hash:
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
163
436
  #
164
- # IRB.conf[:PROMPT]
437
+ # ### Evaluation History
165
438
  #
166
- # This example can be used in your +.irbrc+
439
+ # By default, IRB saves no history of evaluations (returned values), and the
440
+ # related methods `conf.eval_history`, `_`, and `__` are undefined.
167
441
  #
168
- # IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode
169
- # :AUTO_INDENT => false, # disables auto-indent mode
170
- # :PROMPT_I => ">> ", # simple prompt
171
- # :PROMPT_S => nil, # prompt for continuated strings
172
- # :PROMPT_C => nil, # prompt for continuated statement
173
- # :RETURN => " ==>%s\n" # format to return value
174
- # }
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:
175
635
  #
176
636
  # IRB.conf[:PROMPT_MODE] = :MY_PROMPT
177
637
  #
178
- # Or, invoke irb with the above prompt mode by:
179
- #
180
- # irb --prompt my-prompt
181
- #
182
- # Constants +PROMPT_I+, +PROMPT_S+ and +PROMPT_C+ specify the format. In the
183
- # prompt specification, some special strings are available:
184
- #
185
- # %N # command name which is running
186
- # %m # to_s of main object (self)
187
- # %M # inspect of main object (self)
188
- # %l # type of string(", ', /, ]), `]' is inner %w[...]
189
- # %NNi # indent level. NN is digits and means as same as printf("%NNd").
190
- # # It can be omitted
191
- # %NNn # line number.
192
- # %% # %
193
- #
194
- # For instance, the default prompt mode is defined as follows:
195
- #
196
- # IRB.conf[:PROMPT_MODE][:DEFAULT] = {
197
- # :PROMPT_I => "%N(%m):%03n:%i> ",
198
- # :PROMPT_N => "%N(%m):%03n:%i> ",
199
- # :PROMPT_S => "%N(%m):%03n:%i%l ",
200
- # :PROMPT_C => "%N(%m):%03n:%i* ",
201
- # :RETURN => "%s\n" # used to printf
202
- # }
203
- #
204
- # irb comes with a number of available modes:
205
- #
206
- # # :NULL:
207
- # # :PROMPT_I:
208
- # # :PROMPT_N:
209
- # # :PROMPT_S:
210
- # # :PROMPT_C:
211
- # # :RETURN: |
212
- # # %s
213
- # # :DEFAULT:
214
- # # :PROMPT_I: ! '%N(%m):%03n:%i> '
215
- # # :PROMPT_N: ! '%N(%m):%03n:%i> '
216
- # # :PROMPT_S: ! '%N(%m):%03n:%i%l '
217
- # # :PROMPT_C: ! '%N(%m):%03n:%i* '
218
- # # :RETURN: |
219
- # # => %s
220
- # # :CLASSIC:
221
- # # :PROMPT_I: ! '%N(%m):%03n:%i> '
222
- # # :PROMPT_N: ! '%N(%m):%03n:%i> '
223
- # # :PROMPT_S: ! '%N(%m):%03n:%i%l '
224
- # # :PROMPT_C: ! '%N(%m):%03n:%i* '
225
- # # :RETURN: |
226
- # # %s
227
- # # :SIMPLE:
228
- # # :PROMPT_I: ! '>> '
229
- # # :PROMPT_N: ! '>> '
230
- # # :PROMPT_S:
231
- # # :PROMPT_C: ! '?> '
232
- # # :RETURN: |
233
- # # => %s
234
- # # :INF_RUBY:
235
- # # :PROMPT_I: ! '%N(%m):%03n:%i> '
236
- # # :PROMPT_N:
237
- # # :PROMPT_S:
238
- # # :PROMPT_C:
239
- # # :RETURN: |
240
- # # %s
241
- # # :AUTO_INDENT: true
242
- # # :XMP:
243
- # # :PROMPT_I:
244
- # # :PROMPT_N:
245
- # # :PROMPT_S:
246
- # # :PROMPT_C:
247
- # # :RETURN: |2
248
- # # ==>%s
249
- #
250
- # == Restrictions
251
- #
252
- # Because irb evaluates input immediately after it is syntactically complete,
253
- # the results may be slightly different than directly using Ruby.
254
- #
255
- # == IRB Sessions
638
+ # Regardless of where it's defined, you can make it the current prompt in a
639
+ # session:
256
640
  #
257
- # IRB has a special feature, that allows you to manage many sessions at once.
641
+ # conf.prompt_mode = :MY_PROMPT
258
642
  #
259
- # You can create new sessions with Irb.irb, and get a list of current sessions
260
- # with the +jobs+ command in the prompt.
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.
261
803
  #
262
- # === Commands
804
+ # The default initial value is `'irb'`:
263
805
  #
264
- # JobManager provides commands to handle the current sessions:
806
+ # irb(main):001> conf.ap_name
807
+ # => "irb"
265
808
  #
266
- # jobs # List of current sessions
267
- # fg # Switches to the session of the given number
268
- # kill # Kills the session with the given number
809
+ # You can set the default initial value via hash entry `IRB.conf[:AP_NAME] =
810
+ # *string*`:
269
811
  #
270
- # The +exit+ command, or ::irb_exit, will quit the current session and call any
271
- # exit hooks with IRB.irb_at_exit.
812
+ # IRB.conf[:AP_NAME] = 'my_ap_name'
272
813
  #
273
- # A few commands for loading files within the session are also available:
814
+ # ### Configuration Monitor
274
815
  #
275
- # +source+::
276
- # Loads a given file in the current session and displays the source lines,
277
- # see IrbLoader#source_file
278
- # +irb_load+::
279
- # Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
280
- # +irb_require+::
281
- # Loads the given file similarly to Kernel#require
816
+ # You can monitor changes to the configuration by assigning a proc to
817
+ # `IRB.conf[:IRB_RC]` in the configuration file:
282
818
  #
283
- # === Configuration
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
284
843
  #
285
844
  # The command line options, or IRB.conf, specify the default behavior of
286
845
  # Irb.irb.
287
846
  #
288
- # On the other hand, each conf in IRB@Command+line+options is used to
847
+ # On the other hand, each conf in IRB@Command-Line+Options is used to
289
848
  # individually configure IRB.irb.
290
849
  #
291
- # If a proc is set for <code>IRB.conf[:IRB_RC]</code>, its will be invoked after execution
850
+ # If a proc is set for `IRB.conf[:IRB_RC]`, its will be invoked after execution
292
851
  # of that proc with the context of the current session as its argument. Each
293
852
  # session can be configured using this mechanism.
294
853
  #
295
- # === Session variables
854
+ # #### Session variables
296
855
  #
297
856
  # There are a few variables in every Irb session that can come in handy:
298
857
  #
299
- # <code>_</code>::
300
- # The value command executed, as a local variable
301
- # <code>__</code>::
302
- # The history of evaluated commands. Available only if
303
- # <code>IRB.conf[:EVAL_HISTORY]</code> is not +nil+ (which is the default).
304
- # See also IRB::Context#eval_history= and IRB::History.
305
- # <code>__[line_no]</code>::
306
- # Returns the evaluation value at the given line number, +line_no+.
307
- # If +line_no+ is a negative, the return value +line_no+ many lines before
308
- # the most recent return value.
309
- #
310
- # === Example using IRB Sessions
311
- #
312
- # # invoke a new session
313
- # irb(main):001:0> irb
314
- # # list open sessions
315
- # irb.1(main):001:0> jobs
316
- # #0->irb on main (#<Thread:0x400fb7e4> : stop)
317
- # #1->irb#1 on main (#<Thread:0x40125d64> : running)
318
- #
319
- # # change the active session
320
- # irb.1(main):002:0> fg 0
321
- # # define class Foo in top-level session
322
- # irb(main):002:0> class Foo;end
323
- # # invoke a new session with the context of Foo
324
- # irb(main):003:0> irb Foo
325
- # # define Foo#foo
326
- # irb.2(Foo):001:0> def foo
327
- # irb.2(Foo):002:1> print 1
328
- # irb.2(Foo):003:1> end
329
- #
330
- # # change the active session
331
- # irb.2(Foo):004:0> fg 0
332
- # # list open sessions
333
- # irb(main):004:0> jobs
334
- # #0->irb on main (#<Thread:0x400fb7e4> : running)
335
- # #1->irb#1 on main (#<Thread:0x40125d64> : stop)
336
- # #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
337
- # # check if Foo#foo is available
338
- # irb(main):005:0> Foo.instance_methods #=> [:foo, ...]
339
- #
340
- # # change the active session
341
- # irb(main):006:0> fg 2
342
- # # define Foo#bar in the context of Foo
343
- # irb.2(Foo):005:0> def bar
344
- # irb.2(Foo):006:1> print "bar"
345
- # irb.2(Foo):007:1> end
346
- # irb.2(Foo):010:0> Foo.instance_methods #=> [:bar, :foo, ...]
347
- #
348
- # # change the active session
349
- # irb.2(Foo):011:0> fg 0
350
- # irb(main):007:0> f = Foo.new #=> #<Foo:0x4010af3c>
351
- # # invoke a new session with the context of f (instance of Foo)
352
- # irb(main):008:0> irb f
353
- # # list open sessions
354
- # irb.3(<Foo:0x4010af3c>):001:0> jobs
355
- # #0->irb on main (#<Thread:0x400fb7e4> : stop)
356
- # #1->irb#1 on main (#<Thread:0x40125d64> : stop)
357
- # #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
358
- # #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running)
359
- # # evaluate f.foo
360
- # irb.3(<Foo:0x4010af3c>):002:0> foo #=> 1 => nil
361
- # # evaluate f.bar
362
- # irb.3(<Foo:0x4010af3c>):003:0> bar #=> bar => nil
363
- # # kill jobs 1, 2, and 3
364
- # irb.3(<Foo:0x4010af3c>):004:0> kill 1, 2, 3
365
- # # list open sessions, should only include main session
366
- # irb(main):009:0> jobs
367
- # #0->irb on main (#<Thread:0x400fb7e4> : running)
368
- # # quit irb
369
- # irb(main):010:0> exit
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
+ #
370
878
  module IRB
371
879
 
372
880
  # An exception raised by IRB.irb_abort
373
881
  class Abort < Exception;end
374
882
 
375
- @CONF = {}
376
-
377
-
378
- # Displays current configuration.
379
- #
380
- # Modifying the configuration is achieved by sending a message to IRB.conf.
381
- #
382
- # See IRB@Configuration for more information.
383
- def IRB.conf
384
- @CONF
385
- end
386
-
387
- # Returns the current version of IRB, including release version and last
388
- # updated date.
389
- def IRB.version
390
- if v = @CONF[:VERSION] then return v end
391
-
392
- @CONF[:VERSION] = format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE)
393
- end
394
-
395
883
  # The current IRB::Context of the session, see IRB.conf
396
884
  #
397
- # irb
398
- # irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
399
- # foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
400
- def IRB.CurrentContext
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:
401
889
  IRB.conf[:MAIN_CONTEXT]
402
890
  end
403
891
 
404
- # Initializes IRB and creates a new Irb.irb object at the +TOPLEVEL_BINDING+
892
+ # Initializes IRB and creates a new Irb.irb object at the `TOPLEVEL_BINDING`
405
893
  def IRB.start(ap_path = nil)
406
894
  STDOUT.sync = true
407
895
  $0 = File::basename(ap_path, ".rb") if ap_path
@@ -417,62 +905,48 @@ module IRB
417
905
  end
418
906
 
419
907
  # Quits irb
420
- def IRB.irb_exit(irb, ret)
421
- throw :IRB_EXIT, ret
908
+ def IRB.irb_exit(*) # :nodoc:
909
+ throw :IRB_EXIT, false
422
910
  end
423
911
 
424
912
  # Aborts then interrupts irb.
425
913
  #
426
- # Will raise an Abort exception, or the given +exception+.
427
- def IRB.irb_abort(irb, exception = Abort)
914
+ # Will raise an Abort exception, or the given `exception`.
915
+ def IRB.irb_abort(irb, exception = Abort) # :nodoc:
428
916
  irb.context.thread.raise exception, "abort then interrupt!"
429
917
  end
430
918
 
431
919
  class Irb
432
- ASSIGNMENT_NODE_TYPES = [
433
- # Local, instance, global, class, constant, instance, and index assignment:
434
- # "foo = bar",
435
- # "@foo = bar",
436
- # "$foo = bar",
437
- # "@@foo = bar",
438
- # "::Foo = bar",
439
- # "a::Foo = bar",
440
- # "Foo = bar"
441
- # "foo.bar = 1"
442
- # "foo[1] = bar"
443
- :assign,
444
-
445
- # Operation assignment:
446
- # "foo += bar"
447
- # "foo -= bar"
448
- # "foo ||= bar"
449
- # "foo &&= bar"
450
- :opassign,
451
-
452
- # Multiple assignment:
453
- # "foo, bar = 1, 2
454
- :massign,
455
- ]
456
920
  # Note: instance and index assignment expressions could also be written like:
457
- # "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former
458
- # be parsed as :assign and echo will be suppressed, but the latter is
459
- # parsed as a :method_add_arg and the output won't be suppressed
921
+ # "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former be
922
+ # parsed as :assign and echo will be suppressed, but the latter is parsed as a
923
+ # :method_add_arg and the output won't be suppressed
460
924
 
461
925
  PROMPT_MAIN_TRUNCATE_LENGTH = 32
462
- PROMPT_MAIN_TRUNCATE_OMISSION = '...'.freeze
463
- CONTROL_CHARACTERS_PATTERN = "\x00-\x1F".freeze
926
+ PROMPT_MAIN_TRUNCATE_OMISSION = '...'
927
+ CONTROL_CHARACTERS_PATTERN = "\x00-\x1F"
928
+
929
+ # Returns the current context of this irb session
930
+ attr_reader :context
931
+ # The lexer used by this irb session
932
+ attr_accessor :scanner
933
+
934
+ attr_reader :from_binding
464
935
 
465
936
  # Creates a new irb session
466
- def initialize(workspace = nil, input_method = nil)
937
+ def initialize(workspace = nil, input_method = nil, from_binding: false)
938
+ @from_binding = from_binding
467
939
  @context = Context.new(self, workspace, input_method)
468
- @context.main.extend ExtendCommandBundle
940
+ @context.workspace.load_helper_methods_to_main
469
941
  @signal_status = :IN_IRB
470
- @scanner = RubyLex.new(@context)
942
+ @scanner = RubyLex.new
943
+ @line_no = 1
471
944
  end
472
945
 
473
- # A hook point for `debug` command's TracePoint after :IRB_EXIT as well as its clean-up
946
+ # A hook point for `debug` command's breakpoint after :IRB_EXIT as well as its
947
+ # clean-up
474
948
  def debug_break
475
- # it means the debug command is executed
949
+ # it means the debug integration has been activated
476
950
  if defined?(DEBUGGER__) && DEBUGGER__.respond_to?(:capture_frames_without_irb)
477
951
  # after leaving this initial breakpoint, revert the capture_frames patch
478
952
  DEBUGGER__.singleton_class.send(:alias_method, :capture_frames, :capture_frames_without_irb)
@@ -481,89 +955,101 @@ module IRB
481
955
  end
482
956
  end
483
957
 
958
+ def debug_readline(binding)
959
+ workspace = IRB::WorkSpace.new(binding)
960
+ context.replace_workspace(workspace)
961
+ context.workspace.load_helper_methods_to_main
962
+ @line_no += 1
963
+
964
+ # When users run:
965
+ # 1. Debugging commands, like `step 2`
966
+ # 2. Any input that's not irb-command, like `foo = 123`
967
+ #
968
+ #
969
+ # Irb#eval_input will simply return the input, and we need to pass it to the
970
+ # debugger.
971
+ input = nil
972
+ forced_exit = catch(:IRB_EXIT) do
973
+ if IRB.conf[:SAVE_HISTORY] && context.io.support_history_saving?
974
+ # Previous IRB session's history has been saved when `Irb#run` is exited We need
975
+ # to make sure the saved history is not saved again by resetting the counter
976
+ context.io.reset_history_counter
977
+
978
+ begin
979
+ input = eval_input
980
+ ensure
981
+ context.io.save_history
982
+ end
983
+ else
984
+ input = eval_input
985
+ end
986
+ false
987
+ end
988
+
989
+ Kernel.exit if forced_exit
990
+
991
+ if input&.include?("\n")
992
+ @line_no += input.count("\n") - 1
993
+ end
994
+
995
+ input
996
+ end
997
+
484
998
  def run(conf = IRB.conf)
999
+ in_nested_session = !!conf[:MAIN_CONTEXT]
485
1000
  conf[:IRB_RC].call(context) if conf[:IRB_RC]
1001
+ prev_context = conf[:MAIN_CONTEXT]
486
1002
  conf[:MAIN_CONTEXT] = context
487
1003
 
1004
+ save_history = !in_nested_session && conf[:SAVE_HISTORY] && context.io.support_history_saving?
1005
+
1006
+ if save_history
1007
+ context.io.load_history
1008
+ end
1009
+
488
1010
  prev_trap = trap("SIGINT") do
489
1011
  signal_handle
490
1012
  end
491
1013
 
492
1014
  begin
493
- catch(:IRB_EXIT) do
1015
+ if defined?(RubyVM.keep_script_lines)
1016
+ keep_script_lines_backup = RubyVM.keep_script_lines
1017
+ RubyVM.keep_script_lines = true
1018
+ end
1019
+
1020
+ forced_exit = catch(:IRB_EXIT) do
494
1021
  eval_input
495
1022
  end
496
1023
  ensure
1024
+ # Do not restore to nil. It will cause IRB crash when used with threads.
1025
+ IRB.conf[:MAIN_CONTEXT] = prev_context if prev_context
1026
+
1027
+ RubyVM.keep_script_lines = keep_script_lines_backup if defined?(RubyVM.keep_script_lines)
497
1028
  trap("SIGINT", prev_trap)
498
1029
  conf[:AT_EXIT].each{|hook| hook.call}
1030
+
1031
+ context.io.save_history if save_history
1032
+ Kernel.exit if forced_exit
499
1033
  end
500
1034
  end
501
1035
 
502
- # Returns the current context of this irb session
503
- attr_reader :context
504
- # The lexer used by this irb session
505
- attr_accessor :scanner
506
-
507
1036
  # Evaluates input for this session.
508
1037
  def eval_input
509
- @scanner.set_prompt do
510
- |ltype, indent, continue, line_no|
511
- if ltype
512
- f = @context.prompt_s
513
- elsif continue
514
- f = @context.prompt_c
515
- elsif indent > 0
516
- f = @context.prompt_n
517
- else
518
- f = @context.prompt_i
519
- end
520
- f = "" unless f
521
- if @context.prompting?
522
- @context.io.prompt = p = prompt(f, ltype, indent, line_no)
523
- else
524
- @context.io.prompt = p = ""
525
- end
526
- if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent)
527
- unless ltype
528
- prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i
529
- ind = prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size +
530
- indent * 2 - p.size
531
- ind += 2 if continue
532
- @context.io.prompt = p + " " * ind if ind > 0
533
- end
534
- end
535
- @context.io.prompt
536
- end
537
-
538
- @scanner.set_input do
539
- signal_status(:IN_INPUT) do
540
- if l = @context.io.gets
541
- print l if @context.verbose?
542
- else
543
- if @context.ignore_eof? and @context.io.readable_after_eof?
544
- l = "\n"
545
- if @context.verbose?
546
- printf "Use \"exit\" to leave %s\n", @context.ap_name
547
- end
548
- else
549
- print "\n" if @context.prompting?
550
- end
551
- end
552
- l
553
- end
554
- end
1038
+ configure_io
555
1039
 
556
- @scanner.configure_io(@context.io)
557
-
558
- @scanner.each_top_level_statement do |line, line_no|
1040
+ each_top_level_statement do |statement, line_no|
559
1041
  signal_status(:IN_EVAL) do
560
1042
  begin
561
- # Assignment expression check should be done before evaluate_line to handle code like `a /2#/ if false; a = 1`
562
- is_assignment = assignment_expression?(line)
563
- evaluate_line(line, line_no)
1043
+ # If the integration with debugger is activated, we return certain input if it
1044
+ # should be dealt with by debugger
1045
+ if @context.with_debugger && statement.should_be_handled_by_debugger?
1046
+ return statement.code
1047
+ end
564
1048
 
565
- if @context.echo?
566
- if is_assignment
1049
+ @context.evaluate(statement, line_no)
1050
+
1051
+ if @context.echo? && !statement.suppresses_echo?
1052
+ if statement.is_assignment?
567
1053
  if @context.echo_on_assignment?
568
1054
  output_value(@context.echo_on_assignment? == :truncate)
569
1055
  end
@@ -581,21 +1067,149 @@ module IRB
581
1067
  end
582
1068
  end
583
1069
 
584
- def evaluate_line(line, line_no)
585
- # Transform a non-identifier alias (@, $) or keywords (next, break)
586
- command, args = line.split(/\s/, 2)
587
- if original = @context.command_aliases[command.to_sym]
588
- line = line.gsub(/\A#{Regexp.escape(command)}/, original.to_s)
589
- command = original
1070
+ def read_input(prompt)
1071
+ signal_status(:IN_INPUT) do
1072
+ @context.io.prompt = prompt
1073
+ if l = @context.io.gets
1074
+ print l if @context.verbose?
1075
+ else
1076
+ if @context.ignore_eof? and @context.io.readable_after_eof?
1077
+ l = "\n"
1078
+ if @context.verbose?
1079
+ printf "Use \"exit\" to leave %s\n", @context.ap_name
1080
+ end
1081
+ else
1082
+ print "\n" if @context.prompting?
1083
+ end
1084
+ end
1085
+ l
590
1086
  end
1087
+ end
1088
+
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
1096
+ code = +''
1097
+ line_offset = 0
1098
+ loop do
1099
+ line = read_input(prompt)
1100
+ unless line
1101
+ return code.empty? ? nil : code
1102
+ end
1103
+
1104
+ code << line
1105
+ return code if command?(code)
591
1106
 
592
- # Hook command-specific transformation
593
- command_class = ExtendCommandBundle.load_command(command)
594
- if command_class&.respond_to?(:transform_args)
595
- line = "#{command} #{command_class.transform_args(args)}"
1107
+ tokens, opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
1108
+ return code if terminated
1109
+
1110
+ line_offset += 1
1111
+ continue = @scanner.should_continue?(tokens)
1112
+ prompt = generate_prompt(opens, continue, line_offset)
596
1113
  end
1114
+ end
597
1115
 
598
- @context.evaluate(line, line_no)
1116
+ def each_top_level_statement
1117
+ loop do
1118
+ code = readmultiline
1119
+ break unless code
1120
+ yield build_statement(code), @line_no
1121
+ @line_no += code.count("\n")
1122
+ rescue RubyLex::TerminateLineInput
1123
+ end
1124
+ end
1125
+
1126
+ def build_statement(code)
1127
+ if code.match?(/\A\n*\z/)
1128
+ return Statement::EmptyInput.new
1129
+ end
1130
+
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
1140
+
1141
+ def parse_command(code)
1142
+ command_name, arg = code.strip.split(/\s+/, 2)
1143
+ return unless code.lines.size == 1 && command_name
1144
+
1145
+ arg ||= ''
1146
+ command = command_name.to_sym
1147
+ # Command aliases are always command. example: $, @
1148
+ if (alias_name = @context.command_aliases[command])
1149
+ return [alias_name, arg]
1150
+ end
1151
+
1152
+ # Check visibility
1153
+ public_method = !!Kernel.instance_method(:public_method).bind_call(@context.main, command) rescue false
1154
+ private_method = !public_method && !!Kernel.instance_method(:method).bind_call(@context.main, command) rescue false
1155
+ if Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
1156
+ [command, arg]
1157
+ end
1158
+ end
1159
+
1160
+ def command?(code)
1161
+ !!parse_command(code)
1162
+ end
1163
+
1164
+ def configure_io
1165
+ if @context.io.respond_to?(:check_termination)
1166
+ @context.io.check_termination do |code|
1167
+ if Reline::IOGate.in_pasting?
1168
+ rest = @scanner.check_termination_in_prev_line(code, local_variables: @context.local_variables)
1169
+ if rest
1170
+ Reline.delete_text
1171
+ rest.bytes.reverse_each do |c|
1172
+ Reline.ungetc(c)
1173
+ end
1174
+ true
1175
+ else
1176
+ false
1177
+ end
1178
+ else
1179
+ next true if command?(code)
1180
+
1181
+ _tokens, _opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
1182
+ terminated
1183
+ end
1184
+ end
1185
+ end
1186
+ if @context.io.respond_to?(:dynamic_prompt)
1187
+ @context.io.dynamic_prompt do |lines|
1188
+ tokens = RubyLex.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, local_variables: @context.local_variables)
1189
+ line_results = IRB::NestingParser.parse_by_line(tokens)
1190
+ tokens_until_line = []
1191
+ line_results.map.with_index do |(line_tokens, _prev_opens, next_opens, _min_depth), line_num_offset|
1192
+ line_tokens.each do |token, _s|
1193
+ # Avoid appending duplicated token. Tokens that include "n" like multiline
1194
+ # tstring_content can exist in multiple lines.
1195
+ tokens_until_line << token if token != tokens_until_line.last
1196
+ end
1197
+ continue = @scanner.should_continue?(tokens_until_line)
1198
+ generate_prompt(next_opens, continue, line_num_offset)
1199
+ end
1200
+ end
1201
+ end
1202
+
1203
+ if @context.io.respond_to?(:auto_indent) and @context.auto_indent_mode
1204
+ @context.io.auto_indent do |lines, line_index, byte_pointer, is_newline|
1205
+ next nil if lines == [nil] # Workaround for exit IRB with CTRL+d
1206
+ next nil if !is_newline && lines[line_index]&.byteslice(0, byte_pointer)&.match?(/\A\s*\z/)
1207
+
1208
+ code = lines[0..line_index].map { |l| "#{l}\n" }.join
1209
+ tokens = RubyLex.ripper_lex_without_warning(code, local_variables: @context.local_variables)
1210
+ @scanner.process_indent_level(tokens, lines, line_index, is_newline)
1211
+ end
1212
+ end
599
1213
  end
600
1214
 
601
1215
  def convert_invalid_byte_sequence(str, enc)
@@ -628,60 +1242,75 @@ module IRB
628
1242
  end
629
1243
 
630
1244
  def handle_exception(exc)
631
- if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
1245
+ if exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
632
1246
  !(SyntaxError === exc) && !(EncodingError === exc)
633
1247
  # The backtrace of invalid encoding hash (ex. {"\xAE": 1}) raises EncodingError without lineno.
634
1248
  irb_bug = true
635
1249
  else
636
1250
  irb_bug = false
637
- end
1251
+ # To support backtrace filtering while utilizing Exception#full_message, we need to clone
1252
+ # the exception to avoid modifying the original exception's backtrace.
1253
+ exc = exc.clone
1254
+ filtered_backtrace = exc.backtrace.map { |l| @context.workspace.filter_backtrace(l) }.compact
1255
+ backtrace_filter = IRB.conf[:BACKTRACE_FILTER]
638
1256
 
639
- if exc.backtrace
640
- order = nil
641
- if RUBY_VERSION < '3.0.0'
642
- if STDOUT.tty?
643
- message = exc.full_message(order: :bottom)
644
- order = :bottom
1257
+ if backtrace_filter
1258
+ if backtrace_filter.respond_to?(:call)
1259
+ filtered_backtrace = backtrace_filter.call(filtered_backtrace)
645
1260
  else
646
- message = exc.full_message(order: :top)
647
- order = :top
1261
+ warn "IRB.conf[:BACKTRACE_FILTER] #{backtrace_filter} should respond to `call` method"
648
1262
  end
1263
+ end
1264
+
1265
+ exc.set_backtrace(filtered_backtrace)
1266
+ end
1267
+
1268
+ highlight = Color.colorable?
1269
+
1270
+ order =
1271
+ if RUBY_VERSION < '3.0.0'
1272
+ STDOUT.tty? ? :bottom : :top
649
1273
  else # '3.0.0' <= RUBY_VERSION
650
- message = exc.full_message(order: :top)
651
- order = :top
1274
+ :top
652
1275
  end
653
- message = convert_invalid_byte_sequence(message, exc.message.encoding)
654
- message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
655
- message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
656
- case order
657
- when :top
658
- lines = m.split("\n")
659
- when :bottom
660
- lines = m.split("\n").reverse
661
- end
662
- unless irb_bug
663
- lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact
664
- if lines.size > @context.back_trace_limit
665
- omit = lines.size - @context.back_trace_limit
666
- lines = lines[0..(@context.back_trace_limit - 1)]
667
- lines << "\t... %d levels..." % omit
668
- end
1276
+
1277
+ message = exc.full_message(order: order, highlight: highlight)
1278
+ message = convert_invalid_byte_sequence(message, exc.message.encoding)
1279
+ message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
1280
+ message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
1281
+ case order
1282
+ when :top
1283
+ lines = m.split("\n")
1284
+ when :bottom
1285
+ lines = m.split("\n").reverse
1286
+ end
1287
+ unless irb_bug
1288
+ if lines.size > @context.back_trace_limit
1289
+ omit = lines.size - @context.back_trace_limit
1290
+ lines = lines[0..(@context.back_trace_limit - 1)]
1291
+ lines << "\t... %d levels..." % omit
669
1292
  end
670
- lines = lines.reverse if order == :bottom
671
- lines.map{ |l| l + "\n" }.join
672
- }
673
- # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
674
- message = message.gsub(/\(irb\):(?<num>\d+):in `<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in `<main>'" }
675
- puts message
676
- end
677
- print "Maybe IRB bug!\n" if irb_bug
1293
+ end
1294
+ lines = lines.reverse if order == :bottom
1295
+ lines.map{ |l| l + "\n" }.join
1296
+ }
1297
+ # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
1298
+ message = message.gsub(/\(irb\):(?<num>\d+):in (?<open_quote>[`'])<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in #{$~[:open_quote]}<main>'" }
1299
+ puts message
1300
+ puts 'Maybe IRB bug!' if irb_bug
1301
+ rescue Exception => handler_exc
1302
+ begin
1303
+ puts exc.inspect
1304
+ puts "backtraces are hidden because #{handler_exc} was raised when processing them"
1305
+ rescue Exception
1306
+ puts 'Uninspectable exception occurred'
1307
+ end
678
1308
  end
679
1309
 
680
- # Evaluates the given block using the given +path+ as the Context#irb_path
681
- # and +name+ as the Context#irb_name.
1310
+ # Evaluates the given block using the given `path` as the Context#irb_path and
1311
+ # `name` as the Context#irb_name.
682
1312
  #
683
- # Used by the irb command +source+, see IRB@IRB+Sessions for more
684
- # information.
1313
+ # Used by the irb command `source`, see IRB@IRB+Sessions for more information.
685
1314
  def suspend_name(path = nil, name = nil)
686
1315
  @context.irb_path, back_path = path, @context.irb_path if path
687
1316
  @context.irb_name, back_name = name, @context.irb_name if name
@@ -693,25 +1322,22 @@ module IRB
693
1322
  end
694
1323
  end
695
1324
 
696
- # Evaluates the given block using the given +workspace+ as the
1325
+ # Evaluates the given block using the given `workspace` as the
697
1326
  # Context#workspace.
698
1327
  #
699
- # Used by the irb command +irb_load+, see IRB@IRB+Sessions for more
700
- # information.
1328
+ # Used by the irb command `irb_load`, see IRB@IRB+Sessions for more information.
701
1329
  def suspend_workspace(workspace)
702
- @context.workspace, back_workspace = workspace, @context.workspace
703
- begin
704
- yield back_workspace
705
- ensure
706
- @context.workspace = back_workspace
707
- end
1330
+ current_workspace = @context.workspace
1331
+ @context.replace_workspace(workspace)
1332
+ yield
1333
+ ensure
1334
+ @context.replace_workspace current_workspace
708
1335
  end
709
1336
 
710
- # Evaluates the given block using the given +input_method+ as the
711
- # Context#io.
1337
+ # Evaluates the given block using the given `input_method` as the Context#io.
712
1338
  #
713
- # Used by the irb commands +source+ and +irb_load+, see IRB@IRB+Sessions
714
- # for more information.
1339
+ # Used by the irb commands `source` and `irb_load`, see IRB@IRB+Sessions for
1340
+ # more information.
715
1341
  def suspend_input_method(input_method)
716
1342
  back_io = @context.io
717
1343
  @context.instance_eval{@io = input_method}
@@ -722,16 +1348,6 @@ module IRB
722
1348
  end
723
1349
  end
724
1350
 
725
- # Evaluates the given block using the given +context+ as the Context.
726
- def suspend_context(context)
727
- @context, back_context = context, @context
728
- begin
729
- yield back_context
730
- ensure
731
- @context = back_context
732
- end
733
- end
734
-
735
1351
  # Handler for the signal SIGINT, see Kernel#trap for more information.
736
1352
  def signal_handle
737
1353
  unless @context.ignore_sigint?
@@ -754,7 +1370,7 @@ module IRB
754
1370
  end
755
1371
  end
756
1372
 
757
- # Evaluates the given block using the given +status+.
1373
+ # Evaluates the given block using the given `status`.
758
1374
  def signal_status(status)
759
1375
  return yield if @signal_status == :IN_LOAD
760
1376
 
@@ -767,54 +1383,6 @@ module IRB
767
1383
  end
768
1384
  end
769
1385
 
770
- def truncate_prompt_main(str) # :nodoc:
771
- str = str.tr(CONTROL_CHARACTERS_PATTERN, ' ')
772
- if str.size <= PROMPT_MAIN_TRUNCATE_LENGTH
773
- str
774
- else
775
- str[0, PROMPT_MAIN_TRUNCATE_LENGTH - PROMPT_MAIN_TRUNCATE_OMISSION.size] + PROMPT_MAIN_TRUNCATE_OMISSION
776
- end
777
- end
778
-
779
- def prompt(prompt, ltype, indent, line_no) # :nodoc:
780
- p = prompt.dup
781
- p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
782
- case $2
783
- when "N"
784
- @context.irb_name
785
- when "m"
786
- truncate_prompt_main(@context.main.to_s)
787
- when "M"
788
- truncate_prompt_main(@context.main.inspect)
789
- when "l"
790
- ltype
791
- when "i"
792
- if indent < 0
793
- if $1
794
- "-".rjust($1.to_i)
795
- else
796
- "-"
797
- end
798
- else
799
- if $1
800
- format("%" + $1 + "d", indent)
801
- else
802
- indent.to_s
803
- end
804
- end
805
- when "n"
806
- if $1
807
- format("%" + $1 + "d", line_no)
808
- else
809
- line_no.to_s
810
- end
811
- when "%"
812
- "%"
813
- end
814
- end
815
- p
816
- end
817
-
818
1386
  def output_value(omit = false) # :nodoc:
819
1387
  str = @context.inspect_last_value
820
1388
  multiline_p = str.include?("\n")
@@ -844,15 +1412,16 @@ module IRB
844
1412
  end
845
1413
  end
846
1414
  end
1415
+
847
1416
  if multiline_p && @context.newline_before_multiline_output?
848
- printf @context.return_format, "\n#{str}"
849
- else
850
- printf @context.return_format, str
1417
+ str = "\n" + str
851
1418
  end
1419
+
1420
+ Pager.page_content(format(@context.return_format, str), retain_content: true)
852
1421
  end
853
1422
 
854
- # Outputs the local variables to this current session, including
855
- # #signal_status and #context, using IRB::Locale.
1423
+ # Outputs the local variables to this current session, including #signal_status
1424
+ # and #context, using IRB::Locale.
856
1425
  def inspect
857
1426
  ary = []
858
1427
  for iv in instance_variables
@@ -868,55 +1437,94 @@ module IRB
868
1437
  format("#<%s: %s>", self.class, ary.join(", "))
869
1438
  end
870
1439
 
871
- def assignment_expression?(line)
872
- # Try to parse the line and check if the last of possibly multiple
873
- # expressions is an assignment type.
874
-
875
- # If the expression is invalid, Ripper.sexp should return nil which will
876
- # result in false being returned. Any valid expression should return an
877
- # s-expression where the second element of the top level array is an
878
- # array of parsed expressions. The first element of each expression is the
879
- # expression's type.
880
- verbose, $VERBOSE = $VERBOSE, nil
881
- code = "#{RubyLex.generate_local_variables_assign_code(@context.local_variables) || 'nil;'}\n#{line}"
882
- # Get the last node_type of the line. drop(1) is to ignore the local_variables_assign_code part.
883
- node_type = Ripper.sexp(code)&.dig(1)&.drop(1)&.dig(-1, 0)
884
- ASSIGNMENT_NODE_TYPES.include?(node_type)
885
- ensure
886
- $VERBOSE = verbose
1440
+ private
1441
+
1442
+ def generate_prompt(opens, continue, line_offset)
1443
+ ltype = @scanner.ltype_from_open_tokens(opens)
1444
+ indent = @scanner.calc_indent_level(opens)
1445
+ continue = opens.any? || continue
1446
+ line_no = @line_no + line_offset
1447
+
1448
+ if ltype
1449
+ f = @context.prompt_s
1450
+ elsif continue
1451
+ f = @context.prompt_c
1452
+ else
1453
+ f = @context.prompt_i
1454
+ end
1455
+ f = "" unless f
1456
+ if @context.prompting?
1457
+ p = format_prompt(f, ltype, indent, line_no)
1458
+ else
1459
+ p = ""
1460
+ end
1461
+ if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent)
1462
+ unless ltype
1463
+ prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i
1464
+ ind = format_prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size +
1465
+ indent * 2 - p.size
1466
+ p += " " * ind if ind > 0
1467
+ end
1468
+ end
1469
+ p
887
1470
  end
888
- end
889
1471
 
890
- def @CONF.inspect
891
- IRB.version unless self[:VERSION]
892
-
893
- array = []
894
- for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
895
- case k
896
- when :MAIN_CONTEXT, :__TMP__EHV__
897
- array.push format("CONF[:%s]=...myself...", k.id2name)
898
- when :PROMPT
899
- s = v.collect{
900
- |kk, vv|
901
- ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
902
- format(":%s=>{%s}", kk.id2name, ss.join(", "))
903
- }
904
- array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
1472
+ def truncate_prompt_main(str) # :nodoc:
1473
+ str = str.tr(CONTROL_CHARACTERS_PATTERN, ' ')
1474
+ if str.size <= PROMPT_MAIN_TRUNCATE_LENGTH
1475
+ str
905
1476
  else
906
- array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
1477
+ str[0, PROMPT_MAIN_TRUNCATE_LENGTH - PROMPT_MAIN_TRUNCATE_OMISSION.size] + PROMPT_MAIN_TRUNCATE_OMISSION
1478
+ end
1479
+ end
1480
+
1481
+ def format_prompt(format, ltype, indent, line_no) # :nodoc:
1482
+ format.gsub(/%([0-9]+)?([a-zA-Z%])/) do
1483
+ case $2
1484
+ when "N"
1485
+ @context.irb_name
1486
+ when "m"
1487
+ main_str = @context.main.to_s rescue "!#{$!.class}"
1488
+ truncate_prompt_main(main_str)
1489
+ when "M"
1490
+ main_str = @context.main.inspect rescue "!#{$!.class}"
1491
+ truncate_prompt_main(main_str)
1492
+ when "l"
1493
+ ltype
1494
+ when "i"
1495
+ if indent < 0
1496
+ if $1
1497
+ "-".rjust($1.to_i)
1498
+ else
1499
+ "-"
1500
+ end
1501
+ else
1502
+ if $1
1503
+ format("%" + $1 + "d", indent)
1504
+ else
1505
+ indent.to_s
1506
+ end
1507
+ end
1508
+ when "n"
1509
+ if $1
1510
+ format("%" + $1 + "d", line_no)
1511
+ else
1512
+ line_no.to_s
1513
+ end
1514
+ when "%"
1515
+ "%" unless $1
1516
+ end
907
1517
  end
908
1518
  end
909
- array.join("\n")
910
1519
  end
911
1520
  end
912
1521
 
913
1522
  class Binding
914
- # Opens an IRB session where +binding.irb+ is called which allows for
915
- # interactive debugging. You can call any methods or variables available in
916
- # the current scope, and mutate state if you need to.
917
- #
1523
+ # Opens an IRB session where `binding.irb` is called which allows for
1524
+ # interactive debugging. You can call any methods or variables available in the
1525
+ # current scope, and mutate state if you need to.
918
1526
  #
919
- # Given a Ruby file called +potato.rb+ containing the following code:
1527
+ # Given a Ruby file called `potato.rb` containing the following code:
920
1528
  #
921
1529
  # class Potato
922
1530
  # def initialize
@@ -928,8 +1536,8 @@ class Binding
928
1536
  #
929
1537
  # Potato.new
930
1538
  #
931
- # Running <code>ruby potato.rb</code> will open an IRB session where
932
- # +binding.irb+ is called, and you will see the following:
1539
+ # Running `ruby potato.rb` will open an IRB session where `binding.irb` is
1540
+ # called, and you will see the following:
933
1541
  #
934
1542
  # $ ruby potato.rb
935
1543
  #
@@ -959,22 +1567,42 @@ class Binding
959
1567
  # irb(#<Potato:0x00007feea1916670>):004:0> @cooked = true
960
1568
  # => true
961
1569
  #
962
- # You can exit the IRB session with the +exit+ command. Note that exiting will
963
- # resume execution where +binding.irb+ had paused it, as you can see from the
1570
+ # You can exit the IRB session with the `exit` command. Note that exiting will
1571
+ # resume execution where `binding.irb` had paused it, as you can see from the
964
1572
  # output printed to standard output in this example:
965
1573
  #
966
1574
  # irb(#<Potato:0x00007feea1916670>):005:0> exit
967
1575
  # Cooked potato: true
968
1576
  #
969
- #
970
- # See IRB@IRB+Usage for more information.
1577
+ # See IRB for more information.
971
1578
  def irb(show_code: true)
972
- IRB.setup(source_location[0], argv: [])
1579
+ # Setup IRB with the current file's path and no command line arguments
1580
+ IRB.setup(source_location[0], argv: []) unless IRB.initialized?
1581
+ # Create a new workspace using the current binding
973
1582
  workspace = IRB::WorkSpace.new(self)
1583
+ # Print the code around the binding if show_code is true
974
1584
  STDOUT.print(workspace.code_around_binding) if show_code
975
- binding_irb = IRB::Irb.new(workspace)
976
- binding_irb.context.irb_path = File.expand_path(source_location[0])
977
- binding_irb.run(IRB.conf)
978
- binding_irb.debug_break
1585
+ # Get the original IRB instance
1586
+ debugger_irb = IRB.instance_variable_get(:@debugger_irb)
1587
+
1588
+ irb_path = File.expand_path(source_location[0])
1589
+
1590
+ if debugger_irb
1591
+ # If we're already in a debugger session, set the workspace and irb_path for the original IRB instance
1592
+ debugger_irb.context.replace_workspace(workspace)
1593
+ debugger_irb.context.irb_path = irb_path
1594
+ # If we've started a debugger session and hit another binding.irb, we don't want
1595
+ # to start an IRB session instead, we want to resume the irb:rdbg session.
1596
+ IRB::Debug.setup(debugger_irb)
1597
+ IRB::Debug.insert_debug_break
1598
+ debugger_irb.debug_break
1599
+ else
1600
+ # If we're not in a debugger session, create a new IRB instance with the current
1601
+ # workspace
1602
+ binding_irb = IRB::Irb.new(workspace, from_binding: true)
1603
+ binding_irb.context.irb_path = irb_path
1604
+ binding_irb.run(IRB.conf)
1605
+ binding_irb.debug_break
1606
+ end
979
1607
  end
980
1608
  end