irb 1.8.3 → 1.13.1
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/.document +1 -1
- data/Gemfile +9 -1
- data/README.md +149 -25
- data/Rakefile +13 -3
- data/irb.gemspec +2 -2
- data/lib/irb/cmd/nop.rb +3 -52
- data/lib/irb/color.rb +2 -2
- data/lib/irb/command/backtrace.rb +17 -0
- data/lib/irb/command/base.rb +62 -0
- data/lib/irb/command/break.rb +17 -0
- data/lib/irb/command/catch.rb +17 -0
- data/lib/irb/command/chws.rb +40 -0
- data/lib/irb/command/context.rb +16 -0
- data/lib/irb/{cmd → command}/continue.rb +3 -3
- data/lib/irb/{cmd → command}/debug.rb +11 -20
- data/lib/irb/{cmd → command}/delete.rb +3 -3
- data/lib/irb/command/disable_irb.rb +19 -0
- data/lib/irb/command/edit.rb +63 -0
- data/lib/irb/command/exit.rb +18 -0
- data/lib/irb/{cmd → command}/finish.rb +3 -3
- data/lib/irb/command/force_exit.rb +18 -0
- data/lib/irb/command/help.rb +83 -0
- data/lib/irb/command/history.rb +45 -0
- data/lib/irb/command/info.rb +17 -0
- data/lib/irb/command/internal_helpers.rb +27 -0
- data/lib/irb/{cmd → command}/irb_info.rb +7 -7
- data/lib/irb/{cmd → command}/load.rb +23 -8
- data/lib/irb/{cmd → command}/ls.rb +30 -14
- data/lib/irb/{cmd → command}/measure.rb +18 -17
- data/lib/irb/{cmd → command}/next.rb +3 -3
- data/lib/irb/command/pushws.rb +65 -0
- data/lib/irb/command/show_doc.rb +51 -0
- data/lib/irb/command/show_source.rb +74 -0
- data/lib/irb/{cmd → command}/step.rb +3 -3
- data/lib/irb/{cmd → command}/subirb.rb +31 -17
- data/lib/irb/{cmd → command}/whereami.rb +3 -5
- data/lib/irb/command.rb +23 -0
- data/lib/irb/completion.rb +74 -31
- data/lib/irb/context.rb +144 -57
- data/lib/irb/debug.rb +18 -0
- data/lib/irb/default_commands.rb +260 -0
- data/lib/irb/easter-egg.rb +16 -6
- data/lib/irb/ext/change-ws.rb +6 -8
- data/lib/irb/ext/eval_history.rb +3 -3
- data/lib/irb/ext/loader.rb +4 -4
- data/lib/irb/ext/multi-irb.rb +5 -5
- data/lib/irb/ext/tracer.rb +12 -51
- data/lib/irb/ext/use-loader.rb +6 -8
- data/lib/irb/ext/workspaces.rb +10 -34
- data/lib/irb/frame.rb +1 -1
- data/lib/irb/help.rb +3 -3
- data/lib/irb/helper_method/base.rb +16 -0
- data/lib/irb/helper_method/conf.rb +11 -0
- data/lib/irb/helper_method.rb +29 -0
- data/lib/irb/history.rb +15 -4
- data/lib/irb/init.rb +119 -52
- data/lib/irb/input-method.rb +77 -27
- data/lib/irb/inspector.rb +3 -3
- data/lib/irb/lc/error.rb +1 -11
- data/lib/irb/lc/help-message +4 -0
- data/lib/irb/lc/ja/error.rb +1 -11
- data/lib/irb/lc/ja/help-message +13 -0
- data/lib/irb/locale.rb +2 -2
- data/lib/irb/nesting_parser.rb +13 -3
- data/lib/irb/notifier.rb +1 -1
- data/lib/irb/output-method.rb +2 -8
- data/lib/irb/pager.rb +16 -11
- data/lib/irb/ruby-lex.rb +2 -2
- data/lib/irb/ruby_logo.aa +43 -0
- data/lib/irb/source_finder.rb +112 -37
- data/lib/irb/statement.rb +24 -24
- data/lib/irb/version.rb +3 -3
- data/lib/irb/workspace.rb +22 -6
- data/lib/irb/ws-for-case-2.rb +1 -1
- data/lib/irb/xmp.rb +3 -3
- data/lib/irb.rb +1071 -556
- data/man/irb.1 +7 -0
- metadata +41 -31
- data/lib/irb/cmd/backtrace.rb +0 -21
- data/lib/irb/cmd/break.rb +0 -21
- data/lib/irb/cmd/catch.rb +0 -21
- data/lib/irb/cmd/chws.rb +0 -36
- data/lib/irb/cmd/edit.rb +0 -60
- data/lib/irb/cmd/help.rb +0 -23
- data/lib/irb/cmd/info.rb +0 -21
- data/lib/irb/cmd/pushws.rb +0 -45
- data/lib/irb/cmd/show_cmds.rb +0 -53
- data/lib/irb/cmd/show_doc.rb +0 -48
- data/lib/irb/cmd/show_source.rb +0 -61
- data/lib/irb/extend-command.rb +0 -354
data/lib/irb/context.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal:
|
|
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
|
-
@
|
|
27
|
+
@workspace_stack << workspace
|
|
27
28
|
else
|
|
28
|
-
@
|
|
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]
|
|
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,28 +78,28 @@ module IRB
|
|
|
77
78
|
else
|
|
78
79
|
@irb_name = IRB.conf[:IRB_NAME]+"#"+IRB.JobManager.n_jobs.to_s
|
|
79
80
|
end
|
|
80
|
-
|
|
81
|
+
self.irb_path = "(" + @irb_name + ")"
|
|
81
82
|
|
|
82
83
|
case input_method
|
|
83
84
|
when nil
|
|
84
85
|
@io = nil
|
|
85
86
|
case use_multiline?
|
|
86
87
|
when nil
|
|
87
|
-
if
|
|
88
|
+
if term_interactive? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_singleline?
|
|
88
89
|
# Both of multiline mode and singleline mode aren't specified.
|
|
89
|
-
@io = RelineInputMethod.new
|
|
90
|
+
@io = RelineInputMethod.new(build_completor)
|
|
90
91
|
else
|
|
91
92
|
@io = nil
|
|
92
93
|
end
|
|
93
94
|
when false
|
|
94
95
|
@io = nil
|
|
95
96
|
when true
|
|
96
|
-
@io = RelineInputMethod.new
|
|
97
|
+
@io = RelineInputMethod.new(build_completor)
|
|
97
98
|
end
|
|
98
99
|
unless @io
|
|
99
100
|
case use_singleline?
|
|
100
101
|
when nil
|
|
101
|
-
if (defined?(ReadlineInputMethod) &&
|
|
102
|
+
if (defined?(ReadlineInputMethod) && term_interactive? &&
|
|
102
103
|
IRB.conf[:PROMPT_MODE] != :INF_RUBY)
|
|
103
104
|
@io = ReadlineInputMethod.new
|
|
104
105
|
else
|
|
@@ -121,11 +122,11 @@ module IRB
|
|
|
121
122
|
when '-'
|
|
122
123
|
@io = FileInputMethod.new($stdin)
|
|
123
124
|
@irb_name = '-'
|
|
124
|
-
|
|
125
|
+
self.irb_path = '-'
|
|
125
126
|
when String
|
|
126
127
|
@io = FileInputMethod.new(input_method)
|
|
127
128
|
@irb_name = File.basename(input_method)
|
|
128
|
-
|
|
129
|
+
self.irb_path = input_method
|
|
129
130
|
else
|
|
130
131
|
@io = input_method
|
|
131
132
|
end
|
|
@@ -146,7 +147,74 @@ module IRB
|
|
|
146
147
|
@newline_before_multiline_output = true
|
|
147
148
|
end
|
|
148
149
|
|
|
149
|
-
@
|
|
150
|
+
@user_aliases = IRB.conf[:COMMAND_ALIASES].dup
|
|
151
|
+
@command_aliases = @user_aliases.merge(KEYWORD_ALIASES)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
private def term_interactive?
|
|
155
|
+
return true if ENV['TEST_IRB_FORCE_INTERACTIVE']
|
|
156
|
+
STDIN.tty? && ENV['TERM'] != 'dumb'
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# because all input will eventually be evaluated as Ruby code,
|
|
160
|
+
# command names that conflict with Ruby keywords need special workaround
|
|
161
|
+
# we can remove them once we implemented a better command system for IRB
|
|
162
|
+
KEYWORD_ALIASES = {
|
|
163
|
+
:break => :irb_break,
|
|
164
|
+
:catch => :irb_catch,
|
|
165
|
+
:next => :irb_next,
|
|
166
|
+
}.freeze
|
|
167
|
+
|
|
168
|
+
private_constant :KEYWORD_ALIASES
|
|
169
|
+
|
|
170
|
+
def use_tracer=(val)
|
|
171
|
+
require_relative "ext/tracer" if val
|
|
172
|
+
IRB.conf[:USE_TRACER] = val
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def eval_history=(val)
|
|
176
|
+
self.class.remove_method(__method__)
|
|
177
|
+
require_relative "ext/eval_history"
|
|
178
|
+
__send__(__method__, val)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def use_loader=(val)
|
|
182
|
+
self.class.remove_method(__method__)
|
|
183
|
+
require_relative "ext/use-loader"
|
|
184
|
+
__send__(__method__, val)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
private def build_completor
|
|
188
|
+
completor_type = IRB.conf[:COMPLETOR]
|
|
189
|
+
case completor_type
|
|
190
|
+
when :regexp
|
|
191
|
+
return RegexpCompletor.new
|
|
192
|
+
when :type
|
|
193
|
+
completor = build_type_completor
|
|
194
|
+
return completor if completor
|
|
195
|
+
else
|
|
196
|
+
warn "Invalid value for IRB.conf[:COMPLETOR]: #{completor_type}"
|
|
197
|
+
end
|
|
198
|
+
# Fallback to RegexpCompletor
|
|
199
|
+
RegexpCompletor.new
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
private def build_type_completor
|
|
203
|
+
if RUBY_ENGINE == 'truffleruby'
|
|
204
|
+
# Avoid SyntaxError. truffleruby does not support endless method definition yet.
|
|
205
|
+
warn 'TypeCompletor is not supported on TruffleRuby yet'
|
|
206
|
+
return
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
begin
|
|
210
|
+
require 'repl_type_completor'
|
|
211
|
+
rescue LoadError => e
|
|
212
|
+
warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}"
|
|
213
|
+
return
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
ReplTypeCompletor.preload_rbs
|
|
217
|
+
TypeCompletor.new(self)
|
|
150
218
|
end
|
|
151
219
|
|
|
152
220
|
def save_history=(val)
|
|
@@ -167,15 +235,24 @@ module IRB
|
|
|
167
235
|
IRB.conf[:HISTORY_FILE] = hist
|
|
168
236
|
end
|
|
169
237
|
|
|
238
|
+
# Workspace in the current context.
|
|
239
|
+
def workspace
|
|
240
|
+
@workspace_stack.last
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Replace the current workspace with the given +workspace+.
|
|
244
|
+
def replace_workspace(workspace)
|
|
245
|
+
@workspace_stack.pop
|
|
246
|
+
@workspace_stack.push(workspace)
|
|
247
|
+
end
|
|
248
|
+
|
|
170
249
|
# The top-level workspace, see WorkSpace#main
|
|
171
250
|
def main
|
|
172
|
-
|
|
251
|
+
workspace.main
|
|
173
252
|
end
|
|
174
253
|
|
|
175
254
|
# The toplevel workspace, see #home_workspace
|
|
176
255
|
attr_reader :workspace_home
|
|
177
|
-
# WorkSpace in the current context.
|
|
178
|
-
attr_accessor :workspace
|
|
179
256
|
# The current thread in this context.
|
|
180
257
|
attr_reader :thread
|
|
181
258
|
# The current input method.
|
|
@@ -196,9 +273,27 @@ module IRB
|
|
|
196
273
|
# Can be either name from <code>IRB.conf[:IRB_NAME]</code>, or the number of
|
|
197
274
|
# the current job set by JobManager, such as <code>irb#2</code>
|
|
198
275
|
attr_accessor :irb_name
|
|
199
|
-
|
|
200
|
-
#
|
|
201
|
-
|
|
276
|
+
|
|
277
|
+
# Can be one of the following:
|
|
278
|
+
# - the #irb_name surrounded by parenthesis
|
|
279
|
+
# - the +input_method+ passed to Context.new
|
|
280
|
+
# - the file path of the current IRB context in a binding.irb session
|
|
281
|
+
attr_reader :irb_path
|
|
282
|
+
|
|
283
|
+
# Sets @irb_path to the given +path+ as well as @eval_path
|
|
284
|
+
# @eval_path is used for evaluating code in the context of IRB session
|
|
285
|
+
# It's the same as irb_path, but with the IRB name postfix
|
|
286
|
+
# This makes sure users can distinguish the methods defined in the IRB session
|
|
287
|
+
# from the methods defined in the current file's context, especially with binding.irb
|
|
288
|
+
def irb_path=(path)
|
|
289
|
+
@irb_path = path
|
|
290
|
+
|
|
291
|
+
if File.exist?(path)
|
|
292
|
+
@eval_path = "#{path}(#{IRB.conf[:IRB_NAME]})"
|
|
293
|
+
else
|
|
294
|
+
@eval_path = path
|
|
295
|
+
end
|
|
296
|
+
end
|
|
202
297
|
|
|
203
298
|
# Whether multiline editor mode is enabled or not.
|
|
204
299
|
#
|
|
@@ -219,15 +314,15 @@ module IRB
|
|
|
219
314
|
attr_reader :prompt_mode
|
|
220
315
|
# Standard IRB prompt.
|
|
221
316
|
#
|
|
222
|
-
# See IRB@
|
|
317
|
+
# See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
|
|
223
318
|
attr_accessor :prompt_i
|
|
224
319
|
# IRB prompt for continuated strings.
|
|
225
320
|
#
|
|
226
|
-
# See IRB@
|
|
321
|
+
# See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
|
|
227
322
|
attr_accessor :prompt_s
|
|
228
323
|
# IRB prompt for continuated statement. (e.g. immediately after an +if+)
|
|
229
324
|
#
|
|
230
|
-
# See IRB@
|
|
325
|
+
# See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
|
|
231
326
|
attr_accessor :prompt_c
|
|
232
327
|
|
|
233
328
|
# TODO: Remove this when developing v2.0
|
|
@@ -349,8 +444,6 @@ module IRB
|
|
|
349
444
|
# The default value is 16.
|
|
350
445
|
#
|
|
351
446
|
# Can also be set using the +--back-trace-limit+ command line option.
|
|
352
|
-
#
|
|
353
|
-
# See IRB@Command+line+options for more command line options.
|
|
354
447
|
attr_accessor :back_trace_limit
|
|
355
448
|
|
|
356
449
|
# User-defined IRB command aliases
|
|
@@ -401,9 +494,7 @@ module IRB
|
|
|
401
494
|
# StdioInputMethod or RelineInputMethod or ReadlineInputMethod, see #io
|
|
402
495
|
# for more information.
|
|
403
496
|
def prompting?
|
|
404
|
-
verbose? ||
|
|
405
|
-
@io.kind_of?(RelineInputMethod) ||
|
|
406
|
-
(defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
|
|
497
|
+
verbose? || @io.prompting?
|
|
407
498
|
end
|
|
408
499
|
|
|
409
500
|
# The return value of the last statement evaluated.
|
|
@@ -413,12 +504,12 @@ module IRB
|
|
|
413
504
|
# to #last_value.
|
|
414
505
|
def set_last_value(value)
|
|
415
506
|
@last_value = value
|
|
416
|
-
|
|
507
|
+
workspace.local_variable_set :_, value
|
|
417
508
|
end
|
|
418
509
|
|
|
419
510
|
# Sets the +mode+ of the prompt in this context.
|
|
420
511
|
#
|
|
421
|
-
# See IRB@
|
|
512
|
+
# See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
|
|
422
513
|
def prompt_mode=(mode)
|
|
423
514
|
@prompt_mode = mode
|
|
424
515
|
pconf = IRB.conf[:PROMPT][mode]
|
|
@@ -456,8 +547,6 @@ module IRB
|
|
|
456
547
|
#
|
|
457
548
|
# Can also be set using the +--inspect+ and +--noinspect+ command line
|
|
458
549
|
# options.
|
|
459
|
-
#
|
|
460
|
-
# See IRB@Command+line+options for more command line options.
|
|
461
550
|
def inspect_mode=(opt)
|
|
462
551
|
|
|
463
552
|
if i = Inspector::INSPECTORS[opt]
|
|
@@ -501,45 +590,55 @@ module IRB
|
|
|
501
590
|
@inspect_mode
|
|
502
591
|
end
|
|
503
592
|
|
|
504
|
-
def evaluate(
|
|
593
|
+
def evaluate(statement, line_no) # :nodoc:
|
|
505
594
|
@line_no = line_no
|
|
506
|
-
result = nil
|
|
507
595
|
|
|
596
|
+
case statement
|
|
597
|
+
when Statement::EmptyInput
|
|
598
|
+
return
|
|
599
|
+
when Statement::Expression
|
|
600
|
+
result = evaluate_expression(statement.code, line_no)
|
|
601
|
+
set_last_value(result)
|
|
602
|
+
when Statement::Command
|
|
603
|
+
statement.command_class.execute(self, statement.arg)
|
|
604
|
+
set_last_value(nil)
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
nil
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
def from_binding?
|
|
611
|
+
@irb.from_binding
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
def evaluate_expression(code, line_no) # :nodoc:
|
|
615
|
+
result = nil
|
|
508
616
|
if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
|
|
509
617
|
IRB.set_measure_callback
|
|
510
618
|
end
|
|
511
619
|
|
|
512
620
|
if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
|
|
513
621
|
last_proc = proc do
|
|
514
|
-
result =
|
|
622
|
+
result = workspace.evaluate(code, @eval_path, line_no)
|
|
515
623
|
end
|
|
516
624
|
IRB.conf[:MEASURE_CALLBACKS].inject(last_proc) do |chain, item|
|
|
517
625
|
_name, callback, arg = item
|
|
518
626
|
proc do
|
|
519
|
-
callback.(self,
|
|
627
|
+
callback.(self, code, line_no, arg) do
|
|
520
628
|
chain.call
|
|
521
629
|
end
|
|
522
630
|
end
|
|
523
631
|
end.call
|
|
524
632
|
else
|
|
525
|
-
result =
|
|
633
|
+
result = workspace.evaluate(code, @eval_path, line_no)
|
|
526
634
|
end
|
|
527
|
-
|
|
528
|
-
set_last_value(result)
|
|
635
|
+
result
|
|
529
636
|
end
|
|
530
637
|
|
|
531
638
|
def inspect_last_value # :nodoc:
|
|
532
639
|
@inspect_method.inspect_value(@last_value)
|
|
533
640
|
end
|
|
534
641
|
|
|
535
|
-
alias __exit__ exit
|
|
536
|
-
# Exits the current session, see IRB.irb_exit
|
|
537
|
-
def exit(ret = 0)
|
|
538
|
-
IRB.irb_exit(@irb, ret)
|
|
539
|
-
rescue UncaughtThrowError
|
|
540
|
-
super
|
|
541
|
-
end
|
|
542
|
-
|
|
543
642
|
NOPRINTING_IVARS = ["@last_value"] # :nodoc:
|
|
544
643
|
NO_INSPECTING_IVARS = ["@irb", "@io"] # :nodoc:
|
|
545
644
|
IDNAME_IVARS = ["@prompt_mode"] # :nodoc:
|
|
@@ -570,17 +669,5 @@ module IRB
|
|
|
570
669
|
def local_variables # :nodoc:
|
|
571
670
|
workspace.binding.local_variables
|
|
572
671
|
end
|
|
573
|
-
|
|
574
|
-
# Return true if it's aliased from the argument and it's not an identifier.
|
|
575
|
-
def symbol_alias?(command)
|
|
576
|
-
return nil if command.match?(/\A\w+\z/)
|
|
577
|
-
command_aliases.key?(command.to_sym)
|
|
578
|
-
end
|
|
579
|
-
|
|
580
|
-
# Return true if the command supports transforming args
|
|
581
|
-
def transform_args?(command)
|
|
582
|
-
command = command_aliases.fetch(command.to_sym, command)
|
|
583
|
-
ExtendCommandBundle.load_command(command)&.respond_to?(:transform_args)
|
|
584
|
-
end
|
|
585
672
|
end
|
|
586
673
|
end
|
data/lib/irb/debug.rb
CHANGED
|
@@ -57,6 +57,24 @@ module IRB
|
|
|
57
57
|
DEBUGGER__::ThreadClient.prepend(SkipPathHelperForIRB)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
if !@output_modifier_defined && !DEBUGGER__::CONFIG[:no_hint]
|
|
61
|
+
irb_output_modifier_proc = Reline.output_modifier_proc
|
|
62
|
+
|
|
63
|
+
Reline.output_modifier_proc = proc do |output, complete:|
|
|
64
|
+
unless output.strip.empty?
|
|
65
|
+
cmd = output.split(/\s/, 2).first
|
|
66
|
+
|
|
67
|
+
if !complete && DEBUGGER__.commands.key?(cmd)
|
|
68
|
+
output = output.sub(/\n$/, " # debug command\n")
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
irb_output_modifier_proc.call(output, complete: complete)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
@output_modifier_defined = true
|
|
76
|
+
end
|
|
77
|
+
|
|
60
78
|
true
|
|
61
79
|
end
|
|
62
80
|
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "command"
|
|
4
|
+
require_relative "command/internal_helpers"
|
|
5
|
+
require_relative "command/context"
|
|
6
|
+
require_relative "command/exit"
|
|
7
|
+
require_relative "command/force_exit"
|
|
8
|
+
require_relative "command/chws"
|
|
9
|
+
require_relative "command/pushws"
|
|
10
|
+
require_relative "command/subirb"
|
|
11
|
+
require_relative "command/load"
|
|
12
|
+
require_relative "command/debug"
|
|
13
|
+
require_relative "command/edit"
|
|
14
|
+
require_relative "command/break"
|
|
15
|
+
require_relative "command/catch"
|
|
16
|
+
require_relative "command/next"
|
|
17
|
+
require_relative "command/delete"
|
|
18
|
+
require_relative "command/step"
|
|
19
|
+
require_relative "command/continue"
|
|
20
|
+
require_relative "command/finish"
|
|
21
|
+
require_relative "command/backtrace"
|
|
22
|
+
require_relative "command/info"
|
|
23
|
+
require_relative "command/help"
|
|
24
|
+
require_relative "command/show_doc"
|
|
25
|
+
require_relative "command/irb_info"
|
|
26
|
+
require_relative "command/ls"
|
|
27
|
+
require_relative "command/measure"
|
|
28
|
+
require_relative "command/show_source"
|
|
29
|
+
require_relative "command/whereami"
|
|
30
|
+
require_relative "command/history"
|
|
31
|
+
|
|
32
|
+
module IRB
|
|
33
|
+
module Command
|
|
34
|
+
NO_OVERRIDE = 0
|
|
35
|
+
OVERRIDE_PRIVATE_ONLY = 0x01
|
|
36
|
+
OVERRIDE_ALL = 0x02
|
|
37
|
+
|
|
38
|
+
class << self
|
|
39
|
+
# This API is for IRB's internal use only and may change at any time.
|
|
40
|
+
# Please do NOT use it.
|
|
41
|
+
def _register_with_aliases(name, command_class, *aliases)
|
|
42
|
+
@commands[name.to_sym] = [command_class, aliases]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def all_commands_info
|
|
46
|
+
user_aliases = IRB.CurrentContext.command_aliases.each_with_object({}) do |(alias_name, target), result|
|
|
47
|
+
result[target] ||= []
|
|
48
|
+
result[target] << alias_name
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
commands.map do |command_name, (command_class, aliases)|
|
|
52
|
+
aliases = aliases.map { |a| a.first }
|
|
53
|
+
|
|
54
|
+
if additional_aliases = user_aliases[command_name]
|
|
55
|
+
aliases += additional_aliases
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
display_name = aliases.shift || command_name
|
|
59
|
+
{
|
|
60
|
+
display_name: display_name,
|
|
61
|
+
description: command_class.description,
|
|
62
|
+
category: command_class.category
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def command_override_policies
|
|
68
|
+
@@command_override_policies ||= commands.flat_map do |cmd_name, (cmd_class, aliases)|
|
|
69
|
+
[[cmd_name, OVERRIDE_ALL]] + aliases
|
|
70
|
+
end.to_h
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def execute_as_command?(name, public_method:, private_method:)
|
|
74
|
+
case command_override_policies[name]
|
|
75
|
+
when OVERRIDE_ALL
|
|
76
|
+
true
|
|
77
|
+
when OVERRIDE_PRIVATE_ONLY
|
|
78
|
+
!public_method
|
|
79
|
+
when NO_OVERRIDE
|
|
80
|
+
!public_method && !private_method
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def command_names
|
|
85
|
+
command_override_policies.keys.map(&:to_s)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Convert a command name to its implementation class if such command exists
|
|
89
|
+
def load_command(command)
|
|
90
|
+
command = command.to_sym
|
|
91
|
+
commands.each do |command_name, (command_class, aliases)|
|
|
92
|
+
if command_name == command || aliases.any? { |alias_name, _| alias_name == command }
|
|
93
|
+
return command_class
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
nil
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
_register_with_aliases(:irb_context, Command::Context,
|
|
101
|
+
[:context, NO_OVERRIDE]
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
_register_with_aliases(:irb_exit, Command::Exit,
|
|
105
|
+
[:exit, OVERRIDE_PRIVATE_ONLY],
|
|
106
|
+
[:quit, OVERRIDE_PRIVATE_ONLY],
|
|
107
|
+
[:irb_quit, OVERRIDE_PRIVATE_ONLY]
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
_register_with_aliases(:irb_exit!, Command::ForceExit,
|
|
111
|
+
[:exit!, OVERRIDE_PRIVATE_ONLY]
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
_register_with_aliases(:irb_current_working_workspace, Command::CurrentWorkingWorkspace,
|
|
115
|
+
[:cwws, NO_OVERRIDE],
|
|
116
|
+
[:pwws, NO_OVERRIDE],
|
|
117
|
+
[:irb_print_working_workspace, OVERRIDE_ALL],
|
|
118
|
+
[:irb_cwws, OVERRIDE_ALL],
|
|
119
|
+
[:irb_pwws, OVERRIDE_ALL],
|
|
120
|
+
[:irb_current_working_binding, OVERRIDE_ALL],
|
|
121
|
+
[:irb_print_working_binding, OVERRIDE_ALL],
|
|
122
|
+
[:irb_cwb, OVERRIDE_ALL],
|
|
123
|
+
[:irb_pwb, OVERRIDE_ALL],
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
_register_with_aliases(:irb_change_workspace, Command::ChangeWorkspace,
|
|
127
|
+
[:chws, NO_OVERRIDE],
|
|
128
|
+
[:cws, NO_OVERRIDE],
|
|
129
|
+
[:irb_chws, OVERRIDE_ALL],
|
|
130
|
+
[:irb_cws, OVERRIDE_ALL],
|
|
131
|
+
[:irb_change_binding, OVERRIDE_ALL],
|
|
132
|
+
[:irb_cb, OVERRIDE_ALL],
|
|
133
|
+
[:cb, NO_OVERRIDE],
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
_register_with_aliases(:irb_workspaces, Command::Workspaces,
|
|
137
|
+
[:workspaces, NO_OVERRIDE],
|
|
138
|
+
[:irb_bindings, OVERRIDE_ALL],
|
|
139
|
+
[:bindings, NO_OVERRIDE],
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
_register_with_aliases(:irb_push_workspace, Command::PushWorkspace,
|
|
143
|
+
[:pushws, NO_OVERRIDE],
|
|
144
|
+
[:irb_pushws, OVERRIDE_ALL],
|
|
145
|
+
[:irb_push_binding, OVERRIDE_ALL],
|
|
146
|
+
[:irb_pushb, OVERRIDE_ALL],
|
|
147
|
+
[:pushb, NO_OVERRIDE],
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
_register_with_aliases(:irb_pop_workspace, Command::PopWorkspace,
|
|
151
|
+
[:popws, NO_OVERRIDE],
|
|
152
|
+
[:irb_popws, OVERRIDE_ALL],
|
|
153
|
+
[:irb_pop_binding, OVERRIDE_ALL],
|
|
154
|
+
[:irb_popb, OVERRIDE_ALL],
|
|
155
|
+
[:popb, NO_OVERRIDE],
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
_register_with_aliases(:irb_load, Command::Load)
|
|
159
|
+
_register_with_aliases(:irb_require, Command::Require)
|
|
160
|
+
_register_with_aliases(:irb_source, Command::Source,
|
|
161
|
+
[:source, NO_OVERRIDE]
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
_register_with_aliases(:irb, Command::IrbCommand)
|
|
165
|
+
_register_with_aliases(:irb_jobs, Command::Jobs,
|
|
166
|
+
[:jobs, NO_OVERRIDE]
|
|
167
|
+
)
|
|
168
|
+
_register_with_aliases(:irb_fg, Command::Foreground,
|
|
169
|
+
[:fg, NO_OVERRIDE]
|
|
170
|
+
)
|
|
171
|
+
_register_with_aliases(:irb_kill, Command::Kill,
|
|
172
|
+
[:kill, OVERRIDE_PRIVATE_ONLY]
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
_register_with_aliases(:irb_debug, Command::Debug,
|
|
176
|
+
[:debug, NO_OVERRIDE]
|
|
177
|
+
)
|
|
178
|
+
_register_with_aliases(:irb_edit, Command::Edit,
|
|
179
|
+
[:edit, NO_OVERRIDE]
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
_register_with_aliases(:irb_break, Command::Break)
|
|
183
|
+
_register_with_aliases(:irb_catch, Command::Catch)
|
|
184
|
+
_register_with_aliases(:irb_next, Command::Next)
|
|
185
|
+
_register_with_aliases(:irb_delete, Command::Delete,
|
|
186
|
+
[:delete, NO_OVERRIDE]
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
_register_with_aliases(:irb_step, Command::Step,
|
|
190
|
+
[:step, NO_OVERRIDE]
|
|
191
|
+
)
|
|
192
|
+
_register_with_aliases(:irb_continue, Command::Continue,
|
|
193
|
+
[:continue, NO_OVERRIDE]
|
|
194
|
+
)
|
|
195
|
+
_register_with_aliases(:irb_finish, Command::Finish,
|
|
196
|
+
[:finish, NO_OVERRIDE]
|
|
197
|
+
)
|
|
198
|
+
_register_with_aliases(:irb_backtrace, Command::Backtrace,
|
|
199
|
+
[:backtrace, NO_OVERRIDE],
|
|
200
|
+
[:bt, NO_OVERRIDE]
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
_register_with_aliases(:irb_debug_info, Command::Info,
|
|
204
|
+
[:info, NO_OVERRIDE]
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
_register_with_aliases(:irb_help, Command::Help,
|
|
208
|
+
[:help, NO_OVERRIDE],
|
|
209
|
+
[:show_cmds, NO_OVERRIDE]
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
_register_with_aliases(:irb_show_doc, Command::ShowDoc,
|
|
213
|
+
[:show_doc, NO_OVERRIDE]
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
_register_with_aliases(:irb_info, Command::IrbInfo)
|
|
217
|
+
|
|
218
|
+
_register_with_aliases(:irb_ls, Command::Ls,
|
|
219
|
+
[:ls, NO_OVERRIDE]
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
_register_with_aliases(:irb_measure, Command::Measure,
|
|
223
|
+
[:measure, NO_OVERRIDE]
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
_register_with_aliases(:irb_show_source, Command::ShowSource,
|
|
227
|
+
[:show_source, NO_OVERRIDE]
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
_register_with_aliases(:irb_whereami, Command::Whereami,
|
|
231
|
+
[:whereami, NO_OVERRIDE]
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
_register_with_aliases(:irb_history, Command::History,
|
|
235
|
+
[:history, NO_OVERRIDE],
|
|
236
|
+
[:hist, NO_OVERRIDE]
|
|
237
|
+
)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
ExtendCommand = Command
|
|
241
|
+
|
|
242
|
+
# For backward compatibility, we need to keep this module:
|
|
243
|
+
# - As a container of helper methods
|
|
244
|
+
# - As a place to register commands with the deprecated def_extend_command method
|
|
245
|
+
module ExtendCommandBundle
|
|
246
|
+
# For backward compatibility
|
|
247
|
+
NO_OVERRIDE = Command::NO_OVERRIDE
|
|
248
|
+
OVERRIDE_PRIVATE_ONLY = Command::OVERRIDE_PRIVATE_ONLY
|
|
249
|
+
OVERRIDE_ALL = Command::OVERRIDE_ALL
|
|
250
|
+
|
|
251
|
+
# Deprecated. Doesn't have any effect.
|
|
252
|
+
@EXTEND_COMMANDS = []
|
|
253
|
+
|
|
254
|
+
# Drepcated. Use Command.regiser instead.
|
|
255
|
+
def self.def_extend_command(cmd_name, cmd_class, _, *aliases)
|
|
256
|
+
Command._register_with_aliases(cmd_name, cmd_class, *aliases)
|
|
257
|
+
Command.class_variable_set(:@@command_override_policies, nil)
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
data/lib/irb/easter-egg.rb
CHANGED
|
@@ -98,18 +98,26 @@ module IRB
|
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
private def easter_egg_logo(type)
|
|
102
|
+
@easter_egg_logos ||= File.read(File.join(__dir__, 'ruby_logo.aa'), encoding: 'UTF-8:UTF-8')
|
|
103
|
+
.split(/TYPE: ([A-Z]+)\n/)[1..]
|
|
104
|
+
.each_slice(2)
|
|
105
|
+
.to_h
|
|
106
|
+
@easter_egg_logos[type.to_s.upcase]
|
|
107
|
+
end
|
|
108
|
+
|
|
101
109
|
private def easter_egg(type = nil)
|
|
102
110
|
type ||= [:logo, :dancing].sample
|
|
103
111
|
case type
|
|
104
112
|
when :logo
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
IO.copy_stream(f, io)
|
|
109
|
-
end
|
|
113
|
+
require "rdoc"
|
|
114
|
+
RDoc::RI::Driver.new.page do |io|
|
|
115
|
+
io.write easter_egg_logo(:large)
|
|
110
116
|
end
|
|
111
117
|
when :dancing
|
|
112
|
-
|
|
118
|
+
STDOUT.cooked do
|
|
119
|
+
interrupted = false
|
|
120
|
+
prev_trap = trap("SIGINT") { interrupted = true }
|
|
113
121
|
canvas = Canvas.new(Reline.get_screen_size)
|
|
114
122
|
Reline::IOGate.set_winch_handler do
|
|
115
123
|
canvas = Canvas.new(Reline.get_screen_size)
|
|
@@ -125,10 +133,12 @@ module IRB
|
|
|
125
133
|
buff[0, 20] = "\e[0mPress Ctrl+C to stop\e[31m\e[1m"
|
|
126
134
|
print "\e[H" + buff
|
|
127
135
|
sleep 0.05
|
|
136
|
+
break if interrupted
|
|
128
137
|
end
|
|
129
138
|
rescue Interrupt
|
|
130
139
|
ensure
|
|
131
140
|
print "\e[0m\e[?1049l"
|
|
141
|
+
trap("SIGINT", prev_trap)
|
|
132
142
|
end
|
|
133
143
|
end
|
|
134
144
|
end
|