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