irb 1.4.1 → 1.4.3
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/README.md +4 -0
- data/Rakefile +25 -0
- data/irb.gemspec +3 -3
- data/lib/irb/cmd/chws.rb +4 -2
- data/lib/irb/cmd/fork.rb +5 -2
- data/lib/irb/cmd/help.rb +4 -2
- data/lib/irb/cmd/info.rb +4 -2
- data/lib/irb/cmd/load.rb +3 -2
- data/lib/irb/cmd/ls.rb +13 -2
- data/lib/irb/cmd/measure.rb +4 -2
- data/lib/irb/cmd/nop.rb +4 -2
- data/lib/irb/cmd/pushws.rb +4 -2
- data/lib/irb/cmd/show_source.rb +22 -2
- data/lib/irb/cmd/subirb.rb +4 -2
- data/lib/irb/cmd/whereami.rb +4 -2
- data/lib/irb/color.rb +49 -29
- data/lib/irb/color_printer.rb +4 -1
- data/lib/irb/completion.rb +89 -47
- data/lib/irb/context.rb +52 -16
- data/lib/irb/ext/multi-irb.rb +0 -1
- data/lib/irb/ext/save-history.rb +4 -4
- data/lib/irb/extend-command.rb +44 -25
- data/lib/irb/init.rb +32 -9
- data/lib/irb/input-method.rb +22 -9
- data/lib/irb/inspector.rb +3 -11
- data/lib/irb/lc/error.rb +4 -7
- data/lib/irb/lc/help-message +43 -53
- data/lib/irb/lc/ja/encoding_aliases.rb +4 -2
- data/lib/irb/lc/ja/error.rb +4 -7
- data/lib/irb/lc/ja/help-message +0 -12
- data/lib/irb/ruby-lex.rb +62 -57
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +6 -13
- data/lib/irb.rb +25 -68
- data/man/irb.1 +23 -2
- metadata +6 -4
data/lib/irb/completion.rb
CHANGED
@@ -11,7 +11,29 @@ require_relative 'ruby-lex'
|
|
11
11
|
|
12
12
|
module IRB
|
13
13
|
module InputCompletor # :nodoc:
|
14
|
+
using Module.new {
|
15
|
+
refine ::Binding do
|
16
|
+
def eval_methods
|
17
|
+
::Kernel.instance_method(:methods).bind(eval("self")).call
|
18
|
+
end
|
19
|
+
|
20
|
+
def eval_private_methods
|
21
|
+
::Kernel.instance_method(:private_methods).bind(eval("self")).call
|
22
|
+
end
|
14
23
|
|
24
|
+
def eval_instance_variables
|
25
|
+
::Kernel.instance_method(:instance_variables).bind(eval("self")).call
|
26
|
+
end
|
27
|
+
|
28
|
+
def eval_global_variables
|
29
|
+
::Kernel.instance_method(:global_variables).bind(eval("self")).call
|
30
|
+
end
|
31
|
+
|
32
|
+
def eval_class_constants
|
33
|
+
::Module.instance_method(:constants).bind(eval("self.class")).call
|
34
|
+
end
|
35
|
+
end
|
36
|
+
}
|
15
37
|
|
16
38
|
# Set of reserved words used by Ruby, you should not use these for
|
17
39
|
# constants or variables
|
@@ -42,25 +64,34 @@ module IRB
|
|
42
64
|
if File.respond_to?(:absolute_path?)
|
43
65
|
File.absolute_path?(p)
|
44
66
|
else
|
45
|
-
|
46
|
-
true
|
47
|
-
else
|
48
|
-
false
|
49
|
-
end
|
67
|
+
File.absolute_path(p) == p
|
50
68
|
end
|
51
69
|
end
|
52
70
|
|
71
|
+
GEM_PATHS =
|
72
|
+
if defined?(Gem::Specification)
|
73
|
+
Gem::Specification.latest_specs(true).map { |s|
|
74
|
+
s.require_paths.map { |p|
|
75
|
+
if absolute_path?(p)
|
76
|
+
p
|
77
|
+
else
|
78
|
+
File.join(s.full_gem_path, p)
|
79
|
+
end
|
80
|
+
}
|
81
|
+
}.flatten
|
82
|
+
else
|
83
|
+
[]
|
84
|
+
end.freeze
|
85
|
+
|
53
86
|
def self.retrieve_gem_and_system_load_path
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
}.flatten if defined?(Gem::Specification)
|
63
|
-
(gem_paths.to_a | $LOAD_PATH).sort
|
87
|
+
candidates = (GEM_PATHS | $LOAD_PATH)
|
88
|
+
candidates.map do |p|
|
89
|
+
if p.respond_to?(:to_path)
|
90
|
+
p.to_path
|
91
|
+
else
|
92
|
+
String(p) rescue nil
|
93
|
+
end
|
94
|
+
end.compact.sort
|
64
95
|
end
|
65
96
|
|
66
97
|
def self.retrieve_files_to_require_from_load_path
|
@@ -142,10 +173,10 @@ module IRB
|
|
142
173
|
receiver = $1
|
143
174
|
message = $3
|
144
175
|
|
145
|
-
candidates = String.instance_methods.collect{|m| m.to_s}
|
146
176
|
if doc_namespace
|
147
177
|
"String.#{message}"
|
148
178
|
else
|
179
|
+
candidates = String.instance_methods.collect{|m| m.to_s}
|
149
180
|
select_message(receiver, message, candidates)
|
150
181
|
end
|
151
182
|
|
@@ -154,10 +185,10 @@ module IRB
|
|
154
185
|
receiver = $1
|
155
186
|
message = $2
|
156
187
|
|
157
|
-
candidates = Regexp.instance_methods.collect{|m| m.to_s}
|
158
188
|
if doc_namespace
|
159
189
|
"Regexp.#{message}"
|
160
190
|
else
|
191
|
+
candidates = Regexp.instance_methods.collect{|m| m.to_s}
|
161
192
|
select_message(receiver, message, candidates)
|
162
193
|
end
|
163
194
|
|
@@ -166,10 +197,10 @@ module IRB
|
|
166
197
|
receiver = $1
|
167
198
|
message = $2
|
168
199
|
|
169
|
-
candidates = Array.instance_methods.collect{|m| m.to_s}
|
170
200
|
if doc_namespace
|
171
201
|
"Array.#{message}"
|
172
202
|
else
|
203
|
+
candidates = Array.instance_methods.collect{|m| m.to_s}
|
173
204
|
select_message(receiver, message, candidates)
|
174
205
|
end
|
175
206
|
|
@@ -178,29 +209,33 @@ module IRB
|
|
178
209
|
receiver = $1
|
179
210
|
message = $2
|
180
211
|
|
181
|
-
proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
|
182
|
-
hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
|
183
212
|
if doc_namespace
|
184
213
|
["Proc.#{message}", "Hash.#{message}"]
|
185
214
|
else
|
215
|
+
proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
|
216
|
+
hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
|
186
217
|
select_message(receiver, message, proc_candidates | hash_candidates)
|
187
218
|
end
|
188
219
|
|
189
220
|
when /^(:[^:.]*)$/
|
190
221
|
# Symbol
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
222
|
+
if doc_namespace
|
223
|
+
nil
|
224
|
+
else
|
225
|
+
sym = $1
|
226
|
+
candidates = Symbol.all_symbols.collect do |s|
|
227
|
+
":" + s.id2name.encode(Encoding.default_external)
|
228
|
+
rescue EncodingError
|
229
|
+
# ignore
|
230
|
+
end
|
231
|
+
candidates.grep(/^#{Regexp.quote(sym)}/)
|
197
232
|
end
|
198
|
-
candidates.grep(/^#{Regexp.quote(sym)}/)
|
199
|
-
|
200
233
|
when /^::([A-Z][^:\.\(\)]*)$/
|
201
234
|
# Absolute Constant or class methods
|
202
235
|
receiver = $1
|
236
|
+
|
203
237
|
candidates = Object.constants.collect{|m| m.to_s}
|
238
|
+
|
204
239
|
if doc_namespace
|
205
240
|
candidates.find { |i| i == receiver }
|
206
241
|
else
|
@@ -211,16 +246,18 @@ module IRB
|
|
211
246
|
# Constant or class methods
|
212
247
|
receiver = $1
|
213
248
|
message = $2
|
214
|
-
|
215
|
-
candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
|
216
|
-
candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
|
217
|
-
rescue Exception
|
218
|
-
candidates = []
|
219
|
-
end
|
249
|
+
|
220
250
|
if doc_namespace
|
221
251
|
"#{receiver}::#{message}"
|
222
252
|
else
|
223
|
-
|
253
|
+
begin
|
254
|
+
candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
|
255
|
+
candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
|
256
|
+
rescue Exception
|
257
|
+
candidates = []
|
258
|
+
end
|
259
|
+
|
260
|
+
select_message(receiver, message, candidates.sort, "::")
|
224
261
|
end
|
225
262
|
|
226
263
|
when /^(:[^:.]+)(\.|::)([^.]*)$/
|
@@ -229,10 +266,10 @@ module IRB
|
|
229
266
|
sep = $2
|
230
267
|
message = $3
|
231
268
|
|
232
|
-
candidates = Symbol.instance_methods.collect{|m| m.to_s}
|
233
269
|
if doc_namespace
|
234
270
|
"Symbol.#{message}"
|
235
271
|
else
|
272
|
+
candidates = Symbol.instance_methods.collect{|m| m.to_s}
|
236
273
|
select_message(receiver, message, candidates, sep)
|
237
274
|
end
|
238
275
|
|
@@ -244,6 +281,7 @@ module IRB
|
|
244
281
|
|
245
282
|
begin
|
246
283
|
instance = eval(receiver, bind)
|
284
|
+
|
247
285
|
if doc_namespace
|
248
286
|
"#{instance.class.name}.#{message}"
|
249
287
|
else
|
@@ -254,7 +292,7 @@ module IRB
|
|
254
292
|
if doc_namespace
|
255
293
|
nil
|
256
294
|
else
|
257
|
-
|
295
|
+
[]
|
258
296
|
end
|
259
297
|
end
|
260
298
|
|
@@ -276,7 +314,7 @@ module IRB
|
|
276
314
|
if doc_namespace
|
277
315
|
nil
|
278
316
|
else
|
279
|
-
|
317
|
+
[]
|
280
318
|
end
|
281
319
|
end
|
282
320
|
|
@@ -284,6 +322,7 @@ module IRB
|
|
284
322
|
# global var
|
285
323
|
gvar = $1
|
286
324
|
all_gvars = global_variables.collect{|m| m.to_s}
|
325
|
+
|
287
326
|
if doc_namespace
|
288
327
|
all_gvars.find{ |i| i == gvar }
|
289
328
|
else
|
@@ -296,10 +335,10 @@ module IRB
|
|
296
335
|
sep = $2
|
297
336
|
message = $3
|
298
337
|
|
299
|
-
gv =
|
300
|
-
lv =
|
301
|
-
iv =
|
302
|
-
cv =
|
338
|
+
gv = bind.eval_global_variables.collect{|m| m.to_s}.push("true", "false", "nil")
|
339
|
+
lv = bind.local_variables.collect{|m| m.to_s}
|
340
|
+
iv = bind.eval_instance_variables.collect{|m| m.to_s}
|
341
|
+
cv = bind.eval_class_constants.collect{|m| m.to_s}
|
303
342
|
|
304
343
|
if (gv | lv | iv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
|
305
344
|
# foo.func and foo is var. OR
|
@@ -322,11 +361,13 @@ module IRB
|
|
322
361
|
to_ignore = ignored_modules
|
323
362
|
ObjectSpace.each_object(Module){|m|
|
324
363
|
next if (to_ignore.include?(m) rescue true)
|
364
|
+
next unless m.respond_to?(:instance_methods) # JRuby has modules that represent java packages. They don't include many common ruby methods
|
325
365
|
candidates.concat m.instance_methods(false).collect{|x| x.to_s}
|
326
366
|
}
|
327
367
|
candidates.sort!
|
328
368
|
candidates.uniq!
|
329
369
|
end
|
370
|
+
|
330
371
|
if doc_namespace
|
331
372
|
rec_class = rec.is_a?(Module) ? rec : rec.class
|
332
373
|
"#{rec_class.name}#{sep}#{candidates.find{ |i| i == message }}"
|
@@ -341,27 +382,28 @@ module IRB
|
|
341
382
|
message = $1
|
342
383
|
|
343
384
|
candidates = String.instance_methods(true).collect{|m| m.to_s}
|
385
|
+
|
344
386
|
if doc_namespace
|
345
387
|
"String.#{candidates.find{ |i| i == message }}"
|
346
388
|
else
|
347
|
-
select_message(receiver, message, candidates)
|
389
|
+
select_message(receiver, message, candidates.sort)
|
348
390
|
end
|
349
391
|
|
350
392
|
else
|
351
393
|
if doc_namespace
|
352
|
-
vars =
|
394
|
+
vars = (bind.local_variables | bind.eval_instance_variables).collect{|m| m.to_s}
|
353
395
|
perfect_match_var = vars.find{|m| m.to_s == input}
|
354
396
|
if perfect_match_var
|
355
397
|
eval("#{perfect_match_var}.class.name", bind)
|
356
398
|
else
|
357
|
-
candidates =
|
399
|
+
candidates = (bind.eval_methods | bind.eval_private_methods | bind.local_variables | bind.eval_instance_variables | bind.eval_class_constants).collect{|m| m.to_s}
|
358
400
|
candidates |= ReservedWords
|
359
401
|
candidates.find{ |i| i == input }
|
360
402
|
end
|
361
403
|
else
|
362
|
-
candidates =
|
404
|
+
candidates = (bind.eval_methods | bind.eval_private_methods | bind.local_variables | bind.eval_instance_variables | bind.eval_class_constants).collect{|m| m.to_s}
|
363
405
|
candidates |= ReservedWords
|
364
|
-
candidates.grep(/^#{Regexp.quote(input)}/)
|
406
|
+
candidates.grep(/^#{Regexp.quote(input)}/).sort
|
365
407
|
end
|
366
408
|
end
|
367
409
|
end
|
data/lib/irb/context.rb
CHANGED
@@ -22,7 +22,7 @@ module IRB
|
|
22
22
|
#
|
23
23
|
# The optional +input_method+ argument:
|
24
24
|
#
|
25
|
-
# +nil+:: uses stdin or
|
25
|
+
# +nil+:: uses stdin or Reline or Readline
|
26
26
|
# +String+:: uses a File
|
27
27
|
# +other+:: uses this as InputMethod
|
28
28
|
def initialize(irb, workspace = nil, input_method = nil)
|
@@ -32,7 +32,7 @@ module IRB
|
|
32
32
|
else
|
33
33
|
@workspace = WorkSpace.new
|
34
34
|
end
|
35
|
-
@thread = Thread.current
|
35
|
+
@thread = Thread.current
|
36
36
|
|
37
37
|
# copy of default configuration
|
38
38
|
@ap_name = IRB.conf[:AP_NAME]
|
@@ -48,12 +48,19 @@ module IRB
|
|
48
48
|
end
|
49
49
|
if IRB.conf.has_key?(:USE_MULTILINE)
|
50
50
|
@use_multiline = IRB.conf[:USE_MULTILINE]
|
51
|
-
elsif IRB.conf.has_key?(:
|
51
|
+
elsif IRB.conf.has_key?(:USE_RELINE) # backward compatibility
|
52
|
+
warn <<~MSG.strip
|
53
|
+
USE_RELINE is deprecated, please use USE_MULTILINE instead.
|
54
|
+
MSG
|
55
|
+
@use_multiline = IRB.conf[:USE_RELINE]
|
56
|
+
elsif IRB.conf.has_key?(:USE_REIDLINE)
|
57
|
+
warn <<~MSG.strip
|
58
|
+
USE_REIDLINE is deprecated, please use USE_MULTILINE instead.
|
59
|
+
MSG
|
52
60
|
@use_multiline = IRB.conf[:USE_REIDLINE]
|
53
61
|
else
|
54
62
|
@use_multiline = nil
|
55
63
|
end
|
56
|
-
@use_colorize = IRB.conf[:USE_COLORIZE]
|
57
64
|
@use_autocomplete = IRB.conf[:USE_AUTOCOMPLETE]
|
58
65
|
@verbose = IRB.conf[:VERBOSE]
|
59
66
|
@io = nil
|
@@ -84,14 +91,14 @@ module IRB
|
|
84
91
|
when nil
|
85
92
|
if STDIN.tty? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_singleline?
|
86
93
|
# Both of multiline mode and singleline mode aren't specified.
|
87
|
-
@io =
|
94
|
+
@io = RelineInputMethod.new
|
88
95
|
else
|
89
96
|
@io = nil
|
90
97
|
end
|
91
98
|
when false
|
92
99
|
@io = nil
|
93
100
|
when true
|
94
|
-
@io =
|
101
|
+
@io = RelineInputMethod.new
|
95
102
|
end
|
96
103
|
unless @io
|
97
104
|
case use_singleline?
|
@@ -116,6 +123,10 @@ module IRB
|
|
116
123
|
end
|
117
124
|
@io = StdioInputMethod.new unless @io
|
118
125
|
|
126
|
+
when '-'
|
127
|
+
@io = FileInputMethod.new($stdin)
|
128
|
+
@irb_name = '-'
|
129
|
+
@irb_path = '-'
|
119
130
|
when String
|
120
131
|
@io = FileInputMethod.new(input_method)
|
121
132
|
@irb_name = File.basename(input_method)
|
@@ -141,6 +152,8 @@ module IRB
|
|
141
152
|
if @newline_before_multiline_output.nil?
|
142
153
|
@newline_before_multiline_output = true
|
143
154
|
end
|
155
|
+
|
156
|
+
@command_aliases = IRB.conf[:COMMAND_ALIASES]
|
144
157
|
end
|
145
158
|
|
146
159
|
# The top-level workspace, see WorkSpace#main
|
@@ -157,7 +170,7 @@ module IRB
|
|
157
170
|
# The current input method.
|
158
171
|
#
|
159
172
|
# Can be either StdioInputMethod, ReadlineInputMethod,
|
160
|
-
#
|
173
|
+
# RelineInputMethod, FileInputMethod or other specified when the
|
161
174
|
# context is created. See ::new for more # information on +input_method+.
|
162
175
|
attr_accessor :io
|
163
176
|
|
@@ -186,8 +199,6 @@ module IRB
|
|
186
199
|
attr_reader :use_singleline
|
187
200
|
# Whether colorization is enabled or not.
|
188
201
|
#
|
189
|
-
# A copy of the default <code>IRB.conf[:USE_COLORIZE]</code>
|
190
|
-
attr_reader :use_colorize
|
191
202
|
# A copy of the default <code>IRB.conf[:USE_AUTOCOMPLETE]</code>
|
192
203
|
attr_reader :use_autocomplete
|
193
204
|
# A copy of the default <code>IRB.conf[:INSPECT_MODE]</code>
|
@@ -320,20 +331,21 @@ module IRB
|
|
320
331
|
# See IRB@Command+line+options for more command line options.
|
321
332
|
attr_accessor :back_trace_limit
|
322
333
|
|
334
|
+
# User-defined IRB command aliases
|
335
|
+
attr_accessor :command_aliases
|
336
|
+
|
323
337
|
# Alias for #use_multiline
|
324
338
|
alias use_multiline? use_multiline
|
325
339
|
# Alias for #use_singleline
|
326
340
|
alias use_singleline? use_singleline
|
327
341
|
# backward compatibility
|
328
|
-
alias
|
342
|
+
alias use_reline use_multiline
|
329
343
|
# backward compatibility
|
330
|
-
alias
|
344
|
+
alias use_reline? use_multiline
|
331
345
|
# backward compatibility
|
332
346
|
alias use_readline use_singleline
|
333
347
|
# backward compatibility
|
334
348
|
alias use_readline? use_singleline
|
335
|
-
# Alias for #use_colorize
|
336
|
-
alias use_colorize? use_colorize
|
337
349
|
# Alias for #use_autocomplete
|
338
350
|
alias use_autocomplete? use_autocomplete
|
339
351
|
# Alias for #rc
|
@@ -347,7 +359,7 @@ module IRB
|
|
347
359
|
# Returns whether messages are displayed or not.
|
348
360
|
def verbose?
|
349
361
|
if @verbose.nil?
|
350
|
-
if @io.kind_of?(
|
362
|
+
if @io.kind_of?(RelineInputMethod)
|
351
363
|
false
|
352
364
|
elsif defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
|
353
365
|
false
|
@@ -362,11 +374,11 @@ module IRB
|
|
362
374
|
end
|
363
375
|
|
364
376
|
# Whether #verbose? is +true+, and +input_method+ is either
|
365
|
-
# StdioInputMethod or
|
377
|
+
# StdioInputMethod or RelineInputMethod or ReadlineInputMethod, see #io
|
366
378
|
# for more information.
|
367
379
|
def prompting?
|
368
380
|
verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
|
369
|
-
@io.kind_of?(
|
381
|
+
@io.kind_of?(RelineInputMethod) ||
|
370
382
|
(defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
|
371
383
|
end
|
372
384
|
|
@@ -473,6 +485,20 @@ module IRB
|
|
473
485
|
line = "begin ::Kernel.raise _; rescue _.class\n#{line}\n""end"
|
474
486
|
@workspace.local_variable_set(:_, exception)
|
475
487
|
end
|
488
|
+
|
489
|
+
# Transform a non-identifier alias (ex: @, $)
|
490
|
+
command, args = line.split(/\s/, 2)
|
491
|
+
if original = symbol_alias(command)
|
492
|
+
line = line.gsub(/\A#{Regexp.escape(command)}/, original.to_s)
|
493
|
+
command = original
|
494
|
+
end
|
495
|
+
|
496
|
+
# Hook command-specific transformation
|
497
|
+
command_class = ExtendCommandBundle.load_command(command)
|
498
|
+
if command_class&.respond_to?(:transform_args)
|
499
|
+
line = "#{command} #{command_class.transform_args(args)}"
|
500
|
+
end
|
501
|
+
|
476
502
|
set_last_value(@workspace.evaluate(self, line, irb_path, line_no))
|
477
503
|
end
|
478
504
|
|
@@ -514,5 +540,15 @@ module IRB
|
|
514
540
|
end
|
515
541
|
alias __to_s__ to_s
|
516
542
|
alias to_s inspect
|
543
|
+
|
544
|
+
def local_variables # :nodoc:
|
545
|
+
workspace.binding.local_variables
|
546
|
+
end
|
547
|
+
|
548
|
+
# Return a command name if it's aliased from the argument and it's not an identifier.
|
549
|
+
def symbol_alias(command)
|
550
|
+
return nil if command.match?(/\A\w+\z/)
|
551
|
+
command_aliases[command.to_sym]
|
552
|
+
end
|
517
553
|
end
|
518
554
|
end
|
data/lib/irb/ext/multi-irb.rb
CHANGED
data/lib/irb/ext/save-history.rb
CHANGED
@@ -73,7 +73,7 @@ module IRB
|
|
73
73
|
open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
|
74
74
|
f.each { |l|
|
75
75
|
l = l.chomp
|
76
|
-
if self.class ==
|
76
|
+
if self.class == RelineInputMethod and history.last&.end_with?("\\")
|
77
77
|
history.last.delete_suffix!("\\")
|
78
78
|
history.last << "\n" << l
|
79
79
|
else
|
@@ -107,13 +107,13 @@ module IRB
|
|
107
107
|
raise
|
108
108
|
end
|
109
109
|
|
110
|
-
if File.exist?(history_file) &&
|
110
|
+
if File.exist?(history_file) &&
|
111
111
|
File.mtime(history_file) != @loaded_history_mtime
|
112
|
-
history = history[@loaded_history_lines..-1]
|
112
|
+
history = history[@loaded_history_lines..-1] if @loaded_history_lines
|
113
113
|
append_history = true
|
114
114
|
end
|
115
115
|
|
116
|
-
open(history_file,
|
116
|
+
File.open(history_file, (append_history ? 'a' : 'w'), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f|
|
117
117
|
hist = history.map{ |l| l.split("\n").join("\\\n") }
|
118
118
|
unless append_history
|
119
119
|
begin
|
data/lib/irb/extend-command.rb
CHANGED
@@ -47,7 +47,7 @@ module IRB # :nodoc:
|
|
47
47
|
|
48
48
|
@EXTEND_COMMANDS = [
|
49
49
|
[
|
50
|
-
:irb_current_working_workspace, :CurrentWorkingWorkspace, "
|
50
|
+
:irb_current_working_workspace, :CurrentWorkingWorkspace, "cmd/chws",
|
51
51
|
[:irb_print_working_workspace, OVERRIDE_ALL],
|
52
52
|
[:irb_cwws, OVERRIDE_ALL],
|
53
53
|
[:irb_pwws, OVERRIDE_ALL],
|
@@ -59,7 +59,7 @@ module IRB # :nodoc:
|
|
59
59
|
[:irb_pwb, OVERRIDE_ALL],
|
60
60
|
],
|
61
61
|
[
|
62
|
-
:irb_change_workspace, :ChangeWorkspace, "
|
62
|
+
:irb_change_workspace, :ChangeWorkspace, "cmd/chws",
|
63
63
|
[:irb_chws, OVERRIDE_ALL],
|
64
64
|
[:irb_cws, OVERRIDE_ALL],
|
65
65
|
[:chws, NO_OVERRIDE],
|
@@ -70,13 +70,13 @@ module IRB # :nodoc:
|
|
70
70
|
],
|
71
71
|
|
72
72
|
[
|
73
|
-
:irb_workspaces, :Workspaces, "
|
73
|
+
:irb_workspaces, :Workspaces, "cmd/pushws",
|
74
74
|
[:workspaces, NO_OVERRIDE],
|
75
75
|
[:irb_bindings, OVERRIDE_ALL],
|
76
76
|
[:bindings, NO_OVERRIDE],
|
77
77
|
],
|
78
78
|
[
|
79
|
-
:irb_push_workspace, :PushWorkspace, "
|
79
|
+
:irb_push_workspace, :PushWorkspace, "cmd/pushws",
|
80
80
|
[:irb_pushws, OVERRIDE_ALL],
|
81
81
|
[:pushws, NO_OVERRIDE],
|
82
82
|
[:irb_push_binding, OVERRIDE_ALL],
|
@@ -84,7 +84,7 @@ module IRB # :nodoc:
|
|
84
84
|
[:pushb, NO_OVERRIDE],
|
85
85
|
],
|
86
86
|
[
|
87
|
-
:irb_pop_workspace, :PopWorkspace, "
|
87
|
+
:irb_pop_workspace, :PopWorkspace, "cmd/pushws",
|
88
88
|
[:irb_popws, OVERRIDE_ALL],
|
89
89
|
[:popws, NO_OVERRIDE],
|
90
90
|
[:irb_pop_binding, OVERRIDE_ALL],
|
@@ -93,60 +93,74 @@ module IRB # :nodoc:
|
|
93
93
|
],
|
94
94
|
|
95
95
|
[
|
96
|
-
:irb_load, :Load, "
|
96
|
+
:irb_load, :Load, "cmd/load"],
|
97
97
|
[
|
98
|
-
:irb_require, :Require, "
|
98
|
+
:irb_require, :Require, "cmd/load"],
|
99
99
|
[
|
100
|
-
:irb_source, :Source, "
|
100
|
+
:irb_source, :Source, "cmd/load",
|
101
101
|
[:source, NO_OVERRIDE],
|
102
102
|
],
|
103
103
|
|
104
104
|
[
|
105
|
-
:irb, :IrbCommand, "
|
105
|
+
:irb, :IrbCommand, "cmd/subirb"],
|
106
106
|
[
|
107
|
-
:irb_jobs, :Jobs, "
|
107
|
+
:irb_jobs, :Jobs, "cmd/subirb",
|
108
108
|
[:jobs, NO_OVERRIDE],
|
109
109
|
],
|
110
110
|
[
|
111
|
-
:irb_fg, :Foreground, "
|
111
|
+
:irb_fg, :Foreground, "cmd/subirb",
|
112
112
|
[:fg, NO_OVERRIDE],
|
113
113
|
],
|
114
114
|
[
|
115
|
-
:irb_kill, :Kill, "
|
115
|
+
:irb_kill, :Kill, "cmd/subirb",
|
116
116
|
[:kill, OVERRIDE_PRIVATE_ONLY],
|
117
117
|
],
|
118
118
|
|
119
119
|
[
|
120
|
-
:irb_help, :Help, "
|
120
|
+
:irb_help, :Help, "cmd/help",
|
121
121
|
[:help, NO_OVERRIDE],
|
122
122
|
],
|
123
123
|
|
124
124
|
[
|
125
|
-
:irb_info, :Info, "
|
125
|
+
:irb_info, :Info, "cmd/info"
|
126
126
|
],
|
127
127
|
|
128
128
|
[
|
129
|
-
:irb_ls, :Ls, "
|
129
|
+
:irb_ls, :Ls, "cmd/ls",
|
130
130
|
[:ls, NO_OVERRIDE],
|
131
131
|
],
|
132
132
|
|
133
133
|
[
|
134
|
-
:irb_measure, :Measure, "
|
134
|
+
:irb_measure, :Measure, "cmd/measure",
|
135
135
|
[:measure, NO_OVERRIDE],
|
136
136
|
],
|
137
137
|
|
138
138
|
[
|
139
|
-
:irb_show_source, :ShowSource, "
|
139
|
+
:irb_show_source, :ShowSource, "cmd/show_source",
|
140
140
|
[:show_source, NO_OVERRIDE],
|
141
141
|
],
|
142
142
|
|
143
143
|
[
|
144
|
-
:irb_whereami, :Whereami, "
|
144
|
+
:irb_whereami, :Whereami, "cmd/whereami",
|
145
145
|
[:whereami, NO_OVERRIDE],
|
146
146
|
],
|
147
147
|
|
148
148
|
]
|
149
149
|
|
150
|
+
# Convert a command name to its implementation class if such command exists
|
151
|
+
def self.load_command(command)
|
152
|
+
command = command.to_sym
|
153
|
+
@EXTEND_COMMANDS.each do |cmd_name, cmd_class, load_file, *aliases|
|
154
|
+
next if cmd_name != command && aliases.all? { |alias_name, _| alias_name != command }
|
155
|
+
|
156
|
+
if !defined?(ExtendCommand) || !ExtendCommand.const_defined?(cmd_class, false)
|
157
|
+
require_relative load_file
|
158
|
+
end
|
159
|
+
return ExtendCommand.const_get(cmd_class, false)
|
160
|
+
end
|
161
|
+
nil
|
162
|
+
end
|
163
|
+
|
150
164
|
# Installs the default irb commands:
|
151
165
|
#
|
152
166
|
# +irb_current_working_workspace+:: Context#main
|
@@ -162,6 +176,11 @@ module IRB # :nodoc:
|
|
162
176
|
# +irb_fg+:: JobManager#switch
|
163
177
|
# +irb_kill+:: JobManager#kill
|
164
178
|
# +irb_help+:: IRB@Command+line+options
|
179
|
+
# +irb_info+:: #inspect
|
180
|
+
# +irb_ls+:: Output#dump
|
181
|
+
# +irb_measure+:: IRB::unset_measure_callback
|
182
|
+
# +irb_show_source+:: #find_source, #show_source
|
183
|
+
# +irb_whereami+:: Workspace#code_around_binding
|
165
184
|
def self.install_extend_commands
|
166
185
|
for args in @EXTEND_COMMANDS
|
167
186
|
def_extend_command(*args)
|
@@ -187,7 +206,7 @@ module IRB # :nodoc:
|
|
187
206
|
kwargs = ", **kwargs" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
|
188
207
|
line = __LINE__; eval %[
|
189
208
|
def #{cmd_name}(*opts#{kwargs}, &b)
|
190
|
-
|
209
|
+
require_relative "#{load_file}"
|
191
210
|
arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
|
192
211
|
args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
|
193
212
|
args << "*opts#{kwargs}" if arity < 0
|
@@ -235,7 +254,7 @@ module IRB # :nodoc:
|
|
235
254
|
alias_method to, from
|
236
255
|
}
|
237
256
|
else
|
238
|
-
print "irb: warn: can't alias #{to} from #{from}.\n"
|
257
|
+
Kernel.print "irb: warn: can't alias #{to} from #{from}.\n"
|
239
258
|
end
|
240
259
|
end
|
241
260
|
|
@@ -262,10 +281,10 @@ module IRB # :nodoc:
|
|
262
281
|
CE = ContextExtender # :nodoc:
|
263
282
|
|
264
283
|
@EXTEND_COMMANDS = [
|
265
|
-
[:eval_history=, "
|
266
|
-
[:use_tracer=, "
|
267
|
-
[:use_loader=, "
|
268
|
-
[:save_history=, "
|
284
|
+
[:eval_history=, "ext/history.rb"],
|
285
|
+
[:use_tracer=, "ext/tracer.rb"],
|
286
|
+
[:use_loader=, "ext/use-loader.rb"],
|
287
|
+
[:save_history=, "ext/save-history.rb"],
|
269
288
|
]
|
270
289
|
|
271
290
|
# Installs the default context extensions as irb commands:
|
@@ -288,7 +307,7 @@ module IRB # :nodoc:
|
|
288
307
|
line = __LINE__; Context.module_eval %[
|
289
308
|
def #{cmd_name}(*opts, &b)
|
290
309
|
Context.module_eval {remove_method(:#{cmd_name})}
|
291
|
-
|
310
|
+
require_relative "#{load_file}"
|
292
311
|
__send__ :#{cmd_name}, *opts, &b
|
293
312
|
end
|
294
313
|
for ali in aliases
|