irb 1.7.1 → 1.13.2

Sign up to get free protection for your applications and to get access to all the features.
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