irb 1.11.1 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +11 -9
  4. data/Rakefile +1 -1
  5. data/lib/irb/cmd/nop.rb +3 -52
  6. data/lib/irb/{cmd → command}/backtrace.rb +1 -1
  7. data/lib/irb/command/base.rb +64 -0
  8. data/lib/irb/{cmd → command}/break.rb +1 -1
  9. data/lib/irb/{cmd → command}/catch.rb +1 -1
  10. data/lib/irb/{cmd → command}/chws.rb +4 -6
  11. data/lib/irb/{cmd → command}/continue.rb +1 -1
  12. data/lib/irb/{cmd → command}/debug.rb +3 -4
  13. data/lib/irb/{cmd → command}/delete.rb +1 -1
  14. data/lib/irb/command/edit.rb +70 -0
  15. data/lib/irb/{cmd → command}/exit.rb +2 -4
  16. data/lib/irb/{cmd → command}/finish.rb +1 -1
  17. data/lib/irb/command/force_exit.rb +20 -0
  18. data/lib/irb/command/help.rb +84 -0
  19. data/lib/irb/{cmd → command}/history.rb +3 -3
  20. data/lib/irb/{cmd → command}/info.rb +1 -1
  21. data/lib/irb/{cmd → command}/irb_info.rb +5 -6
  22. data/lib/irb/{cmd → command}/load.rb +3 -5
  23. data/lib/irb/{cmd → command}/ls.rb +10 -4
  24. data/lib/irb/{cmd → command}/measure.rb +2 -4
  25. data/lib/irb/{cmd → command}/next.rb +1 -1
  26. data/lib/irb/{cmd → command}/pushws.rb +20 -5
  27. data/lib/irb/{cmd → command}/show_doc.rb +17 -5
  28. data/lib/irb/{cmd → command}/show_source.rb +26 -10
  29. data/lib/irb/{cmd → command}/step.rb +1 -1
  30. data/lib/irb/{cmd → command}/subirb.rb +3 -5
  31. data/lib/irb/{cmd → command}/whereami.rb +2 -4
  32. data/lib/irb/{extend-command.rb → command.rb} +50 -86
  33. data/lib/irb/completion.rb +1 -1
  34. data/lib/irb/context.rb +63 -20
  35. data/lib/irb/ext/change-ws.rb +4 -4
  36. data/lib/irb/ext/eval_history.rb +3 -3
  37. data/lib/irb/ext/loader.rb +4 -4
  38. data/lib/irb/ext/multi-irb.rb +1 -1
  39. data/lib/irb/ext/tracer.rb +12 -51
  40. data/lib/irb/ext/use-loader.rb +6 -8
  41. data/lib/irb/ext/workspaces.rb +11 -34
  42. data/lib/irb/frame.rb +1 -1
  43. data/lib/irb/help.rb +1 -1
  44. data/lib/irb/history.rb +12 -4
  45. data/lib/irb/init.rb +28 -17
  46. data/lib/irb/input-method.rb +18 -2
  47. data/lib/irb/inspector.rb +3 -3
  48. data/lib/irb/lc/error.rb +1 -6
  49. data/lib/irb/lc/ja/error.rb +1 -6
  50. data/lib/irb/locale.rb +2 -2
  51. data/lib/irb/nesting_parser.rb +13 -3
  52. data/lib/irb/notifier.rb +1 -1
  53. data/lib/irb/output-method.rb +2 -8
  54. data/lib/irb/ruby-lex.rb +2 -2
  55. data/lib/irb/source_finder.rb +98 -38
  56. data/lib/irb/statement.rb +25 -3
  57. data/lib/irb/version.rb +3 -3
  58. data/lib/irb/workspace.rb +4 -4
  59. data/lib/irb/ws-for-case-2.rb +1 -1
  60. data/lib/irb/xmp.rb +1 -1
  61. data/lib/irb.rb +38 -32
  62. metadata +30 -29
  63. data/lib/irb/cmd/edit.rb +0 -60
  64. data/lib/irb/cmd/help.rb +0 -23
  65. data/lib/irb/cmd/show_cmds.rb +0 -59
@@ -1,22 +1,37 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # change-ws.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
5
  #
6
6
 
7
- require_relative "nop"
8
7
  require_relative "../ext/workspaces"
9
8
 
10
9
  module IRB
11
10
  # :stopdoc:
12
11
 
13
- module ExtendCommand
14
- class Workspaces < Nop
12
+ module Command
13
+ class Workspaces < Base
15
14
  category "Workspace"
16
15
  description "Show workspaces."
17
16
 
18
17
  def execute(*obj)
19
- irb_context.workspaces.collect{|ws| ws.main}
18
+ inspection_resuls = irb_context.instance_variable_get(:@workspace_stack).map do |ws|
19
+ truncated_inspect(ws.main)
20
+ end
21
+
22
+ puts "[" + inspection_resuls.join(", ") + "]"
23
+ end
24
+
25
+ private
26
+
27
+ def truncated_inspect(obj)
28
+ obj_inspection = obj.inspect
29
+
30
+ if obj_inspection.size > 20
31
+ obj_inspection = obj_inspection[0, 19] + "...>"
32
+ end
33
+
34
+ obj_inspection
20
35
  end
21
36
  end
22
37
 
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "nop"
4
-
5
3
  module IRB
6
- module ExtendCommand
7
- class ShowDoc < Nop
4
+ module Command
5
+ class ShowDoc < Base
8
6
  class << self
9
7
  def transform_args(args)
10
8
  # Return a string literal as is for backward compatibility
@@ -17,7 +15,21 @@ module IRB
17
15
  end
18
16
 
19
17
  category "Context"
20
- description "Enter the mode to look up RI documents."
18
+ description "Look up documentation with RI."
19
+
20
+ help_message <<~HELP_MESSAGE
21
+ Usage: show_doc [name]
22
+
23
+ When name is provided, IRB will look up the documentation for the given name.
24
+ When no name is provided, a RI session will be started.
25
+
26
+ Examples:
27
+
28
+ show_doc
29
+ show_doc Array
30
+ show_doc Array#each
31
+
32
+ HELP_MESSAGE
21
33
 
22
34
  def execute(*names)
23
35
  require 'rdoc/ri/driver'
@@ -1,15 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "nop"
4
3
  require_relative "../source_finder"
5
4
  require_relative "../pager"
6
5
  require_relative "../color"
7
6
 
8
7
  module IRB
9
- module ExtendCommand
10
- class ShowSource < Nop
8
+ module Command
9
+ class ShowSource < Base
11
10
  category "Context"
12
- description "Show the source code of a given method or constant."
11
+ description "Show the source code of a given method, class/module, or constant."
12
+
13
+ help_message <<~HELP_MESSAGE
14
+ Usage: show_source [target] [-s]
15
+
16
+ -s Show the super method. You can stack it like `-ss` to show the super of the super, etc.
17
+
18
+ Examples:
19
+
20
+ show_source Foo
21
+ show_source Foo#bar
22
+ show_source Foo#bar -s
23
+ show_source Foo.baz
24
+ show_source Foo::BAR
25
+ HELP_MESSAGE
13
26
 
14
27
  class << self
15
28
  def transform_args(args)
@@ -45,15 +58,18 @@ module IRB
45
58
  private
46
59
 
47
60
  def show_source(source)
48
- file_content = IRB::Color.colorize_code(File.read(source.file))
49
- code = file_content.lines[(source.first_line - 1)...source.last_line].join
50
- content = <<~CONTENT
61
+ if source.binary_file?
62
+ content = "\n#{bold('Defined in binary file')}: #{source.file}\n\n"
63
+ else
64
+ code = source.colorized_content || 'Source not available'
65
+ content = <<~CONTENT
51
66
 
52
- #{bold("From")}: #{source.file}:#{source.first_line}
67
+ #{bold("From")}: #{source.file}:#{source.line}
53
68
 
54
- #{code}
55
- CONTENT
69
+ #{code.chomp}
56
70
 
71
+ CONTENT
72
+ end
57
73
  Pager.page_content(content)
58
74
  end
59
75
 
@@ -5,7 +5,7 @@ require_relative "debug"
5
5
  module IRB
6
6
  # :stopdoc:
7
7
 
8
- module ExtendCommand
8
+ module Command
9
9
  class Step < DebugCommand
10
10
  def execute(*args)
11
11
  super(do_cmds: ["step", *args].join(" "))
@@ -1,16 +1,14 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # multi.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
5
  #
6
6
 
7
- require_relative "nop"
8
-
9
7
  module IRB
10
8
  # :stopdoc:
11
9
 
12
- module ExtendCommand
13
- class MultiIRBCommand < Nop
10
+ module Command
11
+ class MultiIRBCommand < Base
14
12
  def execute(*args)
15
13
  extend_irb_context
16
14
  end
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "nop"
4
-
5
3
  module IRB
6
4
  # :stopdoc:
7
5
 
8
- module ExtendCommand
9
- class Whereami < Nop
6
+ module Command
7
+ class Whereami < Base
10
8
  category "Context"
11
9
  description "Show the source code around binding.irb again."
12
10
 
@@ -1,10 +1,15 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
- # irb/extend-command.rb - irb extend command
3
+ # irb/command.rb - irb command
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
5
  #
6
6
 
7
+ require_relative "command/base"
8
+
7
9
  module IRB # :nodoc:
10
+ module Command; end
11
+ ExtendCommand = Command
12
+
8
13
  # Installs the default irb extensions command bundle.
9
14
  module ExtendCommandBundle
10
15
  EXCB = ExtendCommandBundle # :nodoc:
@@ -31,13 +36,18 @@ module IRB # :nodoc:
31
36
 
32
37
  @EXTEND_COMMANDS = [
33
38
  [
34
- :irb_exit, :Exit, "cmd/exit",
39
+ :irb_exit, :Exit, "command/exit",
35
40
  [:exit, OVERRIDE_PRIVATE_ONLY],
36
41
  [:quit, OVERRIDE_PRIVATE_ONLY],
37
42
  [:irb_quit, OVERRIDE_PRIVATE_ONLY],
38
43
  ],
39
44
  [
40
- :irb_current_working_workspace, :CurrentWorkingWorkspace, "cmd/chws",
45
+ :irb_exit!, :ForceExit, "command/force_exit",
46
+ [:exit!, OVERRIDE_PRIVATE_ONLY],
47
+ ],
48
+
49
+ [
50
+ :irb_current_working_workspace, :CurrentWorkingWorkspace, "command/chws",
41
51
  [:cwws, NO_OVERRIDE],
42
52
  [:pwws, NO_OVERRIDE],
43
53
  [:irb_print_working_workspace, OVERRIDE_ALL],
@@ -49,7 +59,7 @@ module IRB # :nodoc:
49
59
  [:irb_pwb, OVERRIDE_ALL],
50
60
  ],
51
61
  [
52
- :irb_change_workspace, :ChangeWorkspace, "cmd/chws",
62
+ :irb_change_workspace, :ChangeWorkspace, "command/chws",
53
63
  [:chws, NO_OVERRIDE],
54
64
  [:cws, NO_OVERRIDE],
55
65
  [:irb_chws, OVERRIDE_ALL],
@@ -60,13 +70,13 @@ module IRB # :nodoc:
60
70
  ],
61
71
 
62
72
  [
63
- :irb_workspaces, :Workspaces, "cmd/pushws",
73
+ :irb_workspaces, :Workspaces, "command/pushws",
64
74
  [:workspaces, NO_OVERRIDE],
65
75
  [:irb_bindings, OVERRIDE_ALL],
66
76
  [:bindings, NO_OVERRIDE],
67
77
  ],
68
78
  [
69
- :irb_push_workspace, :PushWorkspace, "cmd/pushws",
79
+ :irb_push_workspace, :PushWorkspace, "command/pushws",
70
80
  [:pushws, NO_OVERRIDE],
71
81
  [:irb_pushws, OVERRIDE_ALL],
72
82
  [:irb_push_binding, OVERRIDE_ALL],
@@ -74,7 +84,7 @@ module IRB # :nodoc:
74
84
  [:pushb, NO_OVERRIDE],
75
85
  ],
76
86
  [
77
- :irb_pop_workspace, :PopWorkspace, "cmd/pushws",
87
+ :irb_pop_workspace, :PopWorkspace, "command/pushws",
78
88
  [:popws, NO_OVERRIDE],
79
89
  [:irb_popws, OVERRIDE_ALL],
80
90
  [:irb_pop_binding, OVERRIDE_ALL],
@@ -83,112 +93,107 @@ module IRB # :nodoc:
83
93
  ],
84
94
 
85
95
  [
86
- :irb_load, :Load, "cmd/load"],
96
+ :irb_load, :Load, "command/load"],
87
97
  [
88
- :irb_require, :Require, "cmd/load"],
98
+ :irb_require, :Require, "command/load"],
89
99
  [
90
- :irb_source, :Source, "cmd/load",
100
+ :irb_source, :Source, "command/load",
91
101
  [:source, NO_OVERRIDE],
92
102
  ],
93
103
 
94
104
  [
95
- :irb, :IrbCommand, "cmd/subirb"],
105
+ :irb, :IrbCommand, "command/subirb"],
96
106
  [
97
- :irb_jobs, :Jobs, "cmd/subirb",
107
+ :irb_jobs, :Jobs, "command/subirb",
98
108
  [:jobs, NO_OVERRIDE],
99
109
  ],
100
110
  [
101
- :irb_fg, :Foreground, "cmd/subirb",
111
+ :irb_fg, :Foreground, "command/subirb",
102
112
  [:fg, NO_OVERRIDE],
103
113
  ],
104
114
  [
105
- :irb_kill, :Kill, "cmd/subirb",
115
+ :irb_kill, :Kill, "command/subirb",
106
116
  [:kill, OVERRIDE_PRIVATE_ONLY],
107
117
  ],
108
118
 
109
119
  [
110
- :irb_debug, :Debug, "cmd/debug",
120
+ :irb_debug, :Debug, "command/debug",
111
121
  [:debug, NO_OVERRIDE],
112
122
  ],
113
123
  [
114
- :irb_edit, :Edit, "cmd/edit",
124
+ :irb_edit, :Edit, "command/edit",
115
125
  [:edit, NO_OVERRIDE],
116
126
  ],
117
127
  [
118
- :irb_break, :Break, "cmd/break",
128
+ :irb_break, :Break, "command/break",
119
129
  ],
120
130
  [
121
- :irb_catch, :Catch, "cmd/catch",
131
+ :irb_catch, :Catch, "command/catch",
122
132
  ],
123
133
  [
124
- :irb_next, :Next, "cmd/next"
134
+ :irb_next, :Next, "command/next"
125
135
  ],
126
136
  [
127
- :irb_delete, :Delete, "cmd/delete",
137
+ :irb_delete, :Delete, "command/delete",
128
138
  [:delete, NO_OVERRIDE],
129
139
  ],
130
140
  [
131
- :irb_step, :Step, "cmd/step",
141
+ :irb_step, :Step, "command/step",
132
142
  [:step, NO_OVERRIDE],
133
143
  ],
134
144
  [
135
- :irb_continue, :Continue, "cmd/continue",
145
+ :irb_continue, :Continue, "command/continue",
136
146
  [:continue, NO_OVERRIDE],
137
147
  ],
138
148
  [
139
- :irb_finish, :Finish, "cmd/finish",
149
+ :irb_finish, :Finish, "command/finish",
140
150
  [:finish, NO_OVERRIDE],
141
151
  ],
142
152
  [
143
- :irb_backtrace, :Backtrace, "cmd/backtrace",
153
+ :irb_backtrace, :Backtrace, "command/backtrace",
144
154
  [:backtrace, NO_OVERRIDE],
145
155
  [:bt, NO_OVERRIDE],
146
156
  ],
147
157
  [
148
- :irb_debug_info, :Info, "cmd/info",
158
+ :irb_debug_info, :Info, "command/info",
149
159
  [:info, NO_OVERRIDE],
150
160
  ],
151
161
 
152
162
  [
153
- :irb_help, :Help, "cmd/help",
163
+ :irb_help, :Help, "command/help",
154
164
  [:help, NO_OVERRIDE],
165
+ [:show_cmds, NO_OVERRIDE],
155
166
  ],
156
167
 
157
168
  [
158
- :irb_show_doc, :ShowDoc, "cmd/show_doc",
169
+ :irb_show_doc, :ShowDoc, "command/show_doc",
159
170
  [:show_doc, NO_OVERRIDE],
160
171
  ],
161
172
 
162
173
  [
163
- :irb_info, :IrbInfo, "cmd/irb_info"
174
+ :irb_info, :IrbInfo, "command/irb_info"
164
175
  ],
165
176
 
166
177
  [
167
- :irb_ls, :Ls, "cmd/ls",
178
+ :irb_ls, :Ls, "command/ls",
168
179
  [:ls, NO_OVERRIDE],
169
180
  ],
170
181
 
171
182
  [
172
- :irb_measure, :Measure, "cmd/measure",
183
+ :irb_measure, :Measure, "command/measure",
173
184
  [:measure, NO_OVERRIDE],
174
185
  ],
175
186
 
176
187
  [
177
- :irb_show_source, :ShowSource, "cmd/show_source",
188
+ :irb_show_source, :ShowSource, "command/show_source",
178
189
  [:show_source, NO_OVERRIDE],
179
190
  ],
180
-
181
191
  [
182
- :irb_whereami, :Whereami, "cmd/whereami",
192
+ :irb_whereami, :Whereami, "command/whereami",
183
193
  [:whereami, NO_OVERRIDE],
184
194
  ],
185
195
  [
186
- :irb_show_cmds, :ShowCmds, "cmd/show_cmds",
187
- [:show_cmds, NO_OVERRIDE],
188
- ],
189
-
190
- [
191
- :irb_history, :History, "cmd/history",
196
+ :irb_history, :History, "command/history",
192
197
  [:history, NO_OVERRIDE],
193
198
  [:hist, NO_OVERRIDE],
194
199
  ]
@@ -205,11 +210,11 @@ module IRB # :nodoc:
205
210
  end
206
211
 
207
212
  @EXTEND_COMMANDS.each do |cmd_name, cmd_class, load_file, *aliases|
208
- if !defined?(ExtendCommand) || !ExtendCommand.const_defined?(cmd_class, false)
213
+ if !defined?(Command) || !Command.const_defined?(cmd_class, false)
209
214
  require_relative load_file
210
215
  end
211
216
 
212
- klass = ExtendCommand.const_get(cmd_class, false)
217
+ klass = Command.const_get(cmd_class, false)
213
218
  aliases = aliases.map { |a| a.first }
214
219
 
215
220
  if additional_aliases = user_aliases[cmd_name]
@@ -229,10 +234,10 @@ module IRB # :nodoc:
229
234
  @EXTEND_COMMANDS.each do |cmd_name, cmd_class, load_file, *aliases|
230
235
  next if cmd_name != command && aliases.all? { |alias_name, _| alias_name != command }
231
236
 
232
- if !defined?(ExtendCommand) || !ExtendCommand.const_defined?(cmd_class, false)
237
+ if !defined?(Command) || !Command.const_defined?(cmd_class, false)
233
238
  require_relative load_file
234
239
  end
235
- return ExtendCommand.const_get(cmd_class, false)
240
+ return Command.const_get(cmd_class, false)
236
241
  end
237
242
  nil
238
243
  end
@@ -262,7 +267,7 @@ module IRB # :nodoc:
262
267
  line = __LINE__; eval %[
263
268
  def #{cmd_name}(*opts, **kwargs, &b)
264
269
  Kernel.require_relative "#{load_file}"
265
- ::IRB::ExtendCommand::#{cmd_class}.execute(irb_context, *opts, **kwargs, &b)
270
+ ::IRB::Command::#{cmd_class}.execute(irb_context, *opts, **kwargs, &b)
266
271
  end
267
272
  ], nil, __FILE__, line
268
273
 
@@ -310,45 +315,4 @@ module IRB # :nodoc:
310
315
 
311
316
  install_extend_commands
312
317
  end
313
-
314
- # Extends methods for the Context module
315
- module ContextExtender
316
- CE = ContextExtender # :nodoc:
317
-
318
- @EXTEND_COMMANDS = [
319
- [:eval_history=, "ext/eval_history.rb"],
320
- [:use_tracer=, "ext/tracer.rb"],
321
- [:use_loader=, "ext/use-loader.rb"],
322
- ]
323
-
324
- # Installs the default context extensions as irb commands:
325
- #
326
- # Context#eval_history=:: +irb/ext/history.rb+
327
- # Context#use_tracer=:: +irb/ext/tracer.rb+
328
- # Context#use_loader=:: +irb/ext/use-loader.rb+
329
- def self.install_extend_commands
330
- for args in @EXTEND_COMMANDS
331
- def_extend_command(*args)
332
- end
333
- end
334
-
335
- # Evaluate the given +command+ from the given +load_file+ on the Context
336
- # module.
337
- #
338
- # Will also define any given +aliases+ for the method.
339
- def self.def_extend_command(cmd_name, load_file, *aliases)
340
- line = __LINE__; Context.module_eval %[
341
- def #{cmd_name}(*opts, &b)
342
- Context.module_eval {remove_method(:#{cmd_name})}
343
- require_relative "#{load_file}"
344
- __send__ :#{cmd_name}, *opts, &b
345
- end
346
- for ali in aliases
347
- alias_method ali, cmd_name
348
- end
349
- ], __FILE__, line
350
- end
351
-
352
- CE.install_extend_commands
353
- end
354
318
  end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/completion.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ishitsuka.com)
data/lib/irb/context.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/context.rb - irb context
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -22,10 +22,11 @@ module IRB
22
22
  # +other+:: uses this as InputMethod
23
23
  def initialize(irb, workspace = nil, input_method = nil)
24
24
  @irb = irb
25
+ @workspace_stack = []
25
26
  if workspace
26
- @workspace = workspace
27
+ @workspace_stack << workspace
27
28
  else
28
- @workspace = WorkSpace.new
29
+ @workspace_stack << WorkSpace.new
29
30
  end
30
31
  @thread = Thread.current
31
32
 
@@ -61,7 +62,7 @@ module IRB
61
62
  @io = nil
62
63
 
63
64
  self.inspect_mode = IRB.conf[:INSPECT_MODE]
64
- self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER]
65
+ self.use_tracer = IRB.conf[:USE_TRACER]
65
66
  self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER]
66
67
  self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY]
67
68
 
@@ -77,7 +78,7 @@ module IRB
77
78
  else
78
79
  @irb_name = IRB.conf[:IRB_NAME]+"#"+IRB.JobManager.n_jobs.to_s
79
80
  end
80
- @irb_path = "(" + @irb_name + ")"
81
+ self.irb_path = "(" + @irb_name + ")"
81
82
 
82
83
  case input_method
83
84
  when nil
@@ -121,11 +122,11 @@ module IRB
121
122
  when '-'
122
123
  @io = FileInputMethod.new($stdin)
123
124
  @irb_name = '-'
124
- @irb_path = '-'
125
+ self.irb_path = '-'
125
126
  when String
126
127
  @io = FileInputMethod.new(input_method)
127
128
  @irb_name = File.basename(input_method)
128
- @irb_path = input_method
129
+ self.irb_path = input_method
129
130
  else
130
131
  @io = input_method
131
132
  end
@@ -161,6 +162,23 @@ module IRB
161
162
 
162
163
  private_constant :KEYWORD_ALIASES
163
164
 
165
+ def use_tracer=(val)
166
+ require_relative "ext/tracer" if val
167
+ IRB.conf[:USE_TRACER] = val
168
+ end
169
+
170
+ def eval_history=(val)
171
+ self.class.remove_method(__method__)
172
+ require_relative "ext/eval_history"
173
+ __send__(__method__, val)
174
+ end
175
+
176
+ def use_loader=(val)
177
+ self.class.remove_method(__method__)
178
+ require_relative "ext/use-loader"
179
+ __send__(__method__, val)
180
+ end
181
+
164
182
  private def build_completor
165
183
  completor_type = IRB.conf[:COMPLETOR]
166
184
  case completor_type
@@ -178,7 +196,7 @@ module IRB
178
196
 
179
197
  private def build_type_completor
180
198
  if RUBY_ENGINE == 'truffleruby'
181
- # Avoid SynatxError. truffleruby does not support endless method definition yet.
199
+ # Avoid SyntaxError. truffleruby does not support endless method definition yet.
182
200
  warn 'TypeCompletor is not supported on TruffleRuby yet'
183
201
  return
184
202
  end
@@ -212,15 +230,24 @@ module IRB
212
230
  IRB.conf[:HISTORY_FILE] = hist
213
231
  end
214
232
 
233
+ # Workspace in the current context.
234
+ def workspace
235
+ @workspace_stack.last
236
+ end
237
+
238
+ # Replace the current workspace with the given +workspace+.
239
+ def replace_workspace(workspace)
240
+ @workspace_stack.pop
241
+ @workspace_stack.push(workspace)
242
+ end
243
+
215
244
  # The top-level workspace, see WorkSpace#main
216
245
  def main
217
- @workspace.main
246
+ workspace.main
218
247
  end
219
248
 
220
249
  # The toplevel workspace, see #home_workspace
221
250
  attr_reader :workspace_home
222
- # WorkSpace in the current context.
223
- attr_accessor :workspace
224
251
  # The current thread in this context.
225
252
  attr_reader :thread
226
253
  # The current input method.
@@ -241,9 +268,27 @@ module IRB
241
268
  # Can be either name from <code>IRB.conf[:IRB_NAME]</code>, or the number of
242
269
  # the current job set by JobManager, such as <code>irb#2</code>
243
270
  attr_accessor :irb_name
244
- # Can be either the #irb_name surrounded by parenthesis, or the
245
- # +input_method+ passed to Context.new
246
- attr_accessor :irb_path
271
+
272
+ # Can be one of the following:
273
+ # - the #irb_name surrounded by parenthesis
274
+ # - the +input_method+ passed to Context.new
275
+ # - the file path of the current IRB context in a binding.irb session
276
+ attr_reader :irb_path
277
+
278
+ # Sets @irb_path to the given +path+ as well as @eval_path
279
+ # @eval_path is used for evaluating code in the context of IRB session
280
+ # It's the same as irb_path, but with the IRB name postfix
281
+ # This makes sure users can distinguish the methods defined in the IRB session
282
+ # from the methods defined in the current file's context, especially with binding.irb
283
+ def irb_path=(path)
284
+ @irb_path = path
285
+
286
+ if File.exist?(path)
287
+ @eval_path = "#{path}(#{IRB.conf[:IRB_NAME]})"
288
+ else
289
+ @eval_path = path
290
+ end
291
+ end
247
292
 
248
293
  # Whether multiline editor mode is enabled or not.
249
294
  #
@@ -444,9 +489,7 @@ module IRB
444
489
  # StdioInputMethod or RelineInputMethod or ReadlineInputMethod, see #io
445
490
  # for more information.
446
491
  def prompting?
447
- verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
448
- @io.kind_of?(RelineInputMethod) ||
449
- (defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
492
+ verbose? || @io.prompting?
450
493
  end
451
494
 
452
495
  # The return value of the last statement evaluated.
@@ -456,7 +499,7 @@ module IRB
456
499
  # to #last_value.
457
500
  def set_last_value(value)
458
501
  @last_value = value
459
- @workspace.local_variable_set :_, value
502
+ workspace.local_variable_set :_, value
460
503
  end
461
504
 
462
505
  # Sets the +mode+ of the prompt in this context.
@@ -552,7 +595,7 @@ module IRB
552
595
 
553
596
  if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
554
597
  last_proc = proc do
555
- result = @workspace.evaluate(line, irb_path, line_no)
598
+ result = workspace.evaluate(line, @eval_path, line_no)
556
599
  end
557
600
  IRB.conf[:MEASURE_CALLBACKS].inject(last_proc) do |chain, item|
558
601
  _name, callback, arg = item
@@ -563,7 +606,7 @@ module IRB
563
606
  end
564
607
  end.call
565
608
  else
566
- result = @workspace.evaluate(line, irb_path, line_no)
609
+ result = workspace.evaluate(line, @eval_path, line_no)
567
610
  end
568
611
 
569
612
  set_last_value(result)
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/ext/cb.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -12,7 +12,7 @@ module IRB # :nodoc:
12
12
  if defined? @home_workspace
13
13
  @home_workspace
14
14
  else
15
- @home_workspace = @workspace
15
+ @home_workspace = workspace
16
16
  end
17
17
  end
18
18
 
@@ -25,11 +25,11 @@ module IRB # :nodoc:
25
25
  # See IRB::WorkSpace.new for more information.
26
26
  def change_workspace(*_main)
27
27
  if _main.empty?
28
- @workspace = home_workspace
28
+ replace_workspace(home_workspace)
29
29
  return main
30
30
  end
31
31
 
32
- @workspace = WorkSpace.new(_main[0])
32
+ replace_workspace(WorkSpace.new(_main[0]))
33
33
 
34
34
  if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
35
35
  main.extend ExtendCommandBundle