irb 1.13.2 → 1.15.2
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 +2 -0
- data/README.md +13 -293
- data/Rakefile +4 -6
- data/irb.gemspec +5 -3
- data/lib/irb/color.rb +1 -0
- data/lib/irb/color_printer.rb +10 -9
- data/lib/irb/command/base.rb +12 -14
- data/lib/irb/command/cd.rb +51 -0
- data/lib/irb/command/copy.rb +73 -0
- data/lib/irb/command/debug.rb +8 -6
- data/lib/irb/command/help.rb +1 -1
- data/lib/irb/command/history.rb +1 -1
- data/lib/irb/command/internal_helpers.rb +1 -1
- data/lib/irb/command/ls.rb +23 -11
- data/lib/irb/completion.rb +41 -14
- data/lib/irb/context.rb +131 -54
- data/lib/irb/debug/ui.rb +2 -4
- data/lib/irb/debug.rb +7 -10
- data/lib/irb/default_commands.rb +22 -8
- data/lib/irb/easter-egg.rb +10 -6
- data/lib/irb/history.rb +84 -55
- data/lib/irb/init.rb +4 -2
- data/lib/irb/input-method.rb +31 -24
- data/lib/irb/inspector.rb +42 -36
- data/lib/irb/lc/ja/help-message +4 -4
- data/lib/irb/nesting_parser.rb +196 -194
- data/lib/irb/pager.rb +129 -7
- data/lib/irb/ruby-lex.rb +84 -82
- data/lib/irb/ruby_logo.aa +75 -37
- data/lib/irb/source_finder.rb +3 -4
- data/lib/irb/statement.rb +22 -1
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +13 -31
- data/lib/irb.rb +75 -947
- data/man/irb.1 +37 -2
- metadata +20 -8
- data/.document +0 -4
data/lib/irb/command/history.rb
CHANGED
@@ -19,7 +19,7 @@ module IRB
|
|
19
19
|
# Use throw and catch to handle arg that includes `;`
|
20
20
|
# For example: "1, kw: (2; 3); 4" will be parsed to [[1], { kw: 3 }]
|
21
21
|
catch(:EXTRACT_RUBY_ARGS) do
|
22
|
-
@irb_context.workspace.binding.eval "IRB::Command.extract_ruby_args #{arg}"
|
22
|
+
@irb_context.workspace.binding.eval "::IRB::Command.extract_ruby_args #{arg}"
|
23
23
|
end || [[], {}]
|
24
24
|
end
|
25
25
|
end
|
data/lib/irb/command/ls.rb
CHANGED
@@ -11,7 +11,7 @@ module IRB
|
|
11
11
|
|
12
12
|
module Command
|
13
13
|
class Ls < Base
|
14
|
-
|
14
|
+
class EvaluationError < StandardError; end
|
15
15
|
|
16
16
|
category "Context"
|
17
17
|
description "Show methods, constants, and variables."
|
@@ -22,24 +22,35 @@ module IRB
|
|
22
22
|
-g [query] Filter the output with a query.
|
23
23
|
HELP_MESSAGE
|
24
24
|
|
25
|
+
def evaluate(code)
|
26
|
+
@irb_context.workspace.binding.eval(code)
|
27
|
+
rescue Exception => e
|
28
|
+
puts "#{e.class}: #{e.message}"
|
29
|
+
raise EvaluationError
|
30
|
+
end
|
31
|
+
|
25
32
|
def execute(arg)
|
26
33
|
if match = arg.match(/\A(?<target>.+\s|)(-g|-G)\s+(?<grep>.+)$/)
|
27
|
-
|
28
|
-
use_main = true
|
29
|
-
else
|
30
|
-
obj = @irb_context.workspace.binding.eval(match[:target])
|
31
|
-
end
|
34
|
+
target = match[:target]
|
32
35
|
grep = Regexp.new(match[:grep])
|
36
|
+
elsif match = arg.match(/\A((?<target>.+),|)\s*grep:(?<grep>.+)/)
|
37
|
+
# Legacy style `ls obj, grep: /regexp/`
|
38
|
+
# Evaluation order should be eval(target) then eval(grep)
|
39
|
+
target = match[:target] || ''
|
40
|
+
grep_regexp_code = match[:grep]
|
33
41
|
else
|
34
|
-
|
35
|
-
use_main = args.empty?
|
36
|
-
obj = args.first
|
37
|
-
grep = kwargs[:grep]
|
42
|
+
target = arg.strip
|
38
43
|
end
|
39
44
|
|
40
|
-
if
|
45
|
+
if target.empty?
|
41
46
|
obj = irb_context.workspace.main
|
42
47
|
locals = irb_context.workspace.binding.local_variables
|
48
|
+
else
|
49
|
+
obj = evaluate(target)
|
50
|
+
end
|
51
|
+
|
52
|
+
if grep_regexp_code
|
53
|
+
grep = evaluate(grep_regexp_code)
|
43
54
|
end
|
44
55
|
|
45
56
|
o = Output.new(grep: grep)
|
@@ -52,6 +63,7 @@ module IRB
|
|
52
63
|
o.dump("class variables", klass.class_variables)
|
53
64
|
o.dump("locals", locals) if locals
|
54
65
|
o.print_result
|
66
|
+
rescue EvaluationError
|
55
67
|
end
|
56
68
|
|
57
69
|
def dump_methods(o, klass, obj)
|
data/lib/irb/completion.rb
CHANGED
@@ -33,6 +33,8 @@ module IRB
|
|
33
33
|
yield
|
34
34
|
]
|
35
35
|
|
36
|
+
HELP_COMMAND_PREPOSING = /\Ahelp\s+/
|
37
|
+
|
36
38
|
def completion_candidates(preposing, target, postposing, bind:)
|
37
39
|
raise NotImplementedError
|
38
40
|
end
|
@@ -86,8 +88,8 @@ module IRB
|
|
86
88
|
)
|
87
89
|
end
|
88
90
|
|
89
|
-
def
|
90
|
-
if
|
91
|
+
def command_candidates(target)
|
92
|
+
if !target.empty?
|
91
93
|
IRB::Command.command_names.select { _1.start_with?(target) }
|
92
94
|
else
|
93
95
|
[]
|
@@ -111,8 +113,18 @@ module IRB
|
|
111
113
|
end
|
112
114
|
|
113
115
|
def completion_candidates(preposing, target, _postposing, bind:)
|
114
|
-
|
116
|
+
# When completing the argument of `help` command, only commands should be candidates
|
117
|
+
return command_candidates(target) if preposing.match?(HELP_COMMAND_PREPOSING)
|
118
|
+
|
119
|
+
commands = if preposing.empty?
|
120
|
+
command_candidates(target)
|
121
|
+
# It doesn't make sense to propose commands with other preposing
|
122
|
+
else
|
123
|
+
[]
|
124
|
+
end
|
125
|
+
|
115
126
|
result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
|
127
|
+
|
116
128
|
return commands unless result
|
117
129
|
|
118
130
|
commands | result.completion_candidates.map { target + _1 }
|
@@ -125,26 +137,33 @@ module IRB
|
|
125
137
|
end
|
126
138
|
|
127
139
|
class RegexpCompletor < BaseCompletor # :nodoc:
|
140
|
+
KERNEL_METHODS = ::Kernel.instance_method(:methods)
|
141
|
+
KERNEL_PRIVATE_METHODS = ::Kernel.instance_method(:private_methods)
|
142
|
+
KERNEL_INSTANCE_VARIABLES = ::Kernel.instance_method(:instance_variables)
|
143
|
+
OBJECT_CLASS_INSTANCE_METHOD = ::Object.instance_method(:class)
|
144
|
+
MODULE_CONSTANTS_INSTANCE_METHOD = ::Module.instance_method(:constants)
|
145
|
+
|
128
146
|
using Module.new {
|
129
147
|
refine ::Binding do
|
130
148
|
def eval_methods
|
131
|
-
|
149
|
+
KERNEL_METHODS.bind_call(receiver)
|
132
150
|
end
|
133
151
|
|
134
152
|
def eval_private_methods
|
135
|
-
|
153
|
+
KERNEL_PRIVATE_METHODS.bind_call(receiver)
|
136
154
|
end
|
137
155
|
|
138
156
|
def eval_instance_variables
|
139
|
-
|
157
|
+
KERNEL_INSTANCE_VARIABLES.bind_call(receiver)
|
140
158
|
end
|
141
159
|
|
142
160
|
def eval_global_variables
|
143
|
-
::Kernel.
|
161
|
+
::Kernel.global_variables
|
144
162
|
end
|
145
163
|
|
146
164
|
def eval_class_constants
|
147
|
-
|
165
|
+
klass = OBJECT_CLASS_INSTANCE_METHOD.bind_call(receiver)
|
166
|
+
MODULE_CONSTANTS_INSTANCE_METHOD.bind_call(klass)
|
148
167
|
end
|
149
168
|
end
|
150
169
|
}
|
@@ -187,12 +206,20 @@ module IRB
|
|
187
206
|
end
|
188
207
|
|
189
208
|
def completion_candidates(preposing, target, postposing, bind:)
|
190
|
-
if preposing
|
191
|
-
result
|
192
|
-
return result if result
|
209
|
+
if result = complete_require_path(target, preposing, postposing)
|
210
|
+
return result
|
193
211
|
end
|
194
|
-
|
195
|
-
commands
|
212
|
+
|
213
|
+
commands = command_candidates(target)
|
214
|
+
|
215
|
+
# When completing the argument of `help` command, only commands should be candidates
|
216
|
+
return commands if preposing.match?(HELP_COMMAND_PREPOSING)
|
217
|
+
|
218
|
+
# It doesn't make sense to propose commands with other preposing
|
219
|
+
commands = [] unless preposing.empty?
|
220
|
+
|
221
|
+
completion_data = retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
|
222
|
+
commands | completion_data
|
196
223
|
end
|
197
224
|
|
198
225
|
def doc_namespace(_preposing, matched, _postposing, bind:)
|
@@ -470,7 +497,7 @@ module IRB
|
|
470
497
|
end
|
471
498
|
end
|
472
499
|
CompletionProc = ->(target, preposing = nil, postposing = nil) {
|
473
|
-
regexp_completor.completion_candidates(preposing, target, postposing, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding)
|
500
|
+
regexp_completor.completion_candidates(preposing || '', target, postposing || '', bind: IRB.conf[:MAIN_CONTEXT].workspace.binding)
|
474
501
|
}
|
475
502
|
end
|
476
503
|
deprecate_constant :InputCompletor
|
data/lib/irb/context.rb
CHANGED
@@ -13,6 +13,10 @@ module IRB
|
|
13
13
|
# A class that wraps the current state of the irb session, including the
|
14
14
|
# configuration of IRB.conf.
|
15
15
|
class Context
|
16
|
+
KERNEL_PUBLIC_METHOD = ::Kernel.instance_method(:public_method)
|
17
|
+
KERNEL_METHOD = ::Kernel.instance_method(:method)
|
18
|
+
|
19
|
+
ASSIGN_OPERATORS_REGEXP = Regexp.union(%w[= += -= *= /= %= **= &= |= &&= ||= ^= <<= >>=])
|
16
20
|
# Creates a new IRB context.
|
17
21
|
#
|
18
22
|
# The optional +input_method+ argument:
|
@@ -148,26 +152,9 @@ module IRB
|
|
148
152
|
@newline_before_multiline_output = true
|
149
153
|
end
|
150
154
|
|
151
|
-
@
|
152
|
-
@command_aliases = @user_aliases.merge(KEYWORD_ALIASES)
|
153
|
-
end
|
154
|
-
|
155
|
-
private def term_interactive?
|
156
|
-
return true if ENV['TEST_IRB_FORCE_INTERACTIVE']
|
157
|
-
STDIN.tty? && ENV['TERM'] != 'dumb'
|
155
|
+
@command_aliases = IRB.conf[:COMMAND_ALIASES].dup
|
158
156
|
end
|
159
157
|
|
160
|
-
# because all input will eventually be evaluated as Ruby code,
|
161
|
-
# command names that conflict with Ruby keywords need special workaround
|
162
|
-
# we can remove them once we implemented a better command system for IRB
|
163
|
-
KEYWORD_ALIASES = {
|
164
|
-
:break => :irb_break,
|
165
|
-
:catch => :irb_catch,
|
166
|
-
:next => :irb_next,
|
167
|
-
}.freeze
|
168
|
-
|
169
|
-
private_constant :KEYWORD_ALIASES
|
170
|
-
|
171
158
|
def use_tracer=(val)
|
172
159
|
require_relative "ext/tracer" if val
|
173
160
|
IRB.conf[:USE_TRACER] = val
|
@@ -185,39 +172,6 @@ module IRB
|
|
185
172
|
__send__(__method__, val)
|
186
173
|
end
|
187
174
|
|
188
|
-
private def build_completor
|
189
|
-
completor_type = IRB.conf[:COMPLETOR]
|
190
|
-
case completor_type
|
191
|
-
when :regexp
|
192
|
-
return RegexpCompletor.new
|
193
|
-
when :type
|
194
|
-
completor = build_type_completor
|
195
|
-
return completor if completor
|
196
|
-
else
|
197
|
-
warn "Invalid value for IRB.conf[:COMPLETOR]: #{completor_type}"
|
198
|
-
end
|
199
|
-
# Fallback to RegexpCompletor
|
200
|
-
RegexpCompletor.new
|
201
|
-
end
|
202
|
-
|
203
|
-
private def build_type_completor
|
204
|
-
if RUBY_ENGINE == 'truffleruby'
|
205
|
-
# Avoid SyntaxError. truffleruby does not support endless method definition yet.
|
206
|
-
warn 'TypeCompletor is not supported on TruffleRuby yet'
|
207
|
-
return
|
208
|
-
end
|
209
|
-
|
210
|
-
begin
|
211
|
-
require 'repl_type_completor'
|
212
|
-
rescue LoadError => e
|
213
|
-
warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}"
|
214
|
-
return
|
215
|
-
end
|
216
|
-
|
217
|
-
ReplTypeCompletor.preload_rbs
|
218
|
-
TypeCompletor.new(self)
|
219
|
-
end
|
220
|
-
|
221
175
|
def save_history=(val)
|
222
176
|
IRB.conf[:SAVE_HISTORY] = val
|
223
177
|
end
|
@@ -310,6 +264,8 @@ module IRB
|
|
310
264
|
attr_reader :use_autocomplete
|
311
265
|
# A copy of the default <code>IRB.conf[:INSPECT_MODE]</code>
|
312
266
|
attr_reader :inspect_mode
|
267
|
+
# Inspector for the current context
|
268
|
+
attr_reader :inspect_method
|
313
269
|
|
314
270
|
# A copy of the default <code>IRB.conf[:PROMPT_MODE]</code>
|
315
271
|
attr_reader :prompt_mode
|
@@ -602,7 +558,8 @@ module IRB
|
|
602
558
|
set_last_value(result)
|
603
559
|
when Statement::Command
|
604
560
|
statement.command_class.execute(self, statement.arg)
|
605
|
-
|
561
|
+
when Statement::IncorrectAlias
|
562
|
+
warn statement.message
|
606
563
|
end
|
607
564
|
|
608
565
|
nil
|
@@ -636,8 +593,77 @@ module IRB
|
|
636
593
|
result
|
637
594
|
end
|
638
595
|
|
639
|
-
def
|
640
|
-
|
596
|
+
def parse_input(code, is_assignment_expression)
|
597
|
+
command_name, arg = code.strip.split(/\s+/, 2)
|
598
|
+
arg ||= ''
|
599
|
+
|
600
|
+
# command can only be 1 line
|
601
|
+
if code.lines.size != 1 ||
|
602
|
+
# command name is required
|
603
|
+
command_name.nil? ||
|
604
|
+
# local variable have precedence over command
|
605
|
+
local_variables.include?(command_name.to_sym) ||
|
606
|
+
# assignment expression is not a command
|
607
|
+
(is_assignment_expression ||
|
608
|
+
(arg.start_with?(ASSIGN_OPERATORS_REGEXP) && !arg.start_with?(/==|=~/)))
|
609
|
+
return Statement::Expression.new(code, is_assignment_expression)
|
610
|
+
end
|
611
|
+
|
612
|
+
command = command_name.to_sym
|
613
|
+
|
614
|
+
# Check command aliases
|
615
|
+
if aliased_name = command_aliases[command]
|
616
|
+
if command_class = Command.load_command(aliased_name)
|
617
|
+
command = aliased_name
|
618
|
+
elsif HelperMethod.helper_methods[aliased_name]
|
619
|
+
message = <<~MESSAGE
|
620
|
+
Using command alias `#{command}` for helper method `#{aliased_name}` is not supported.
|
621
|
+
Please check the value of `IRB.conf[:COMMAND_ALIASES]`.
|
622
|
+
MESSAGE
|
623
|
+
return Statement::IncorrectAlias.new(message)
|
624
|
+
else
|
625
|
+
message = <<~MESSAGE
|
626
|
+
You're trying to use command alias `#{command}` for command `#{aliased_name}`, but `#{aliased_name}` does not exist.
|
627
|
+
Please check the value of `IRB.conf[:COMMAND_ALIASES]`.
|
628
|
+
MESSAGE
|
629
|
+
return Statement::IncorrectAlias.new(message)
|
630
|
+
end
|
631
|
+
else
|
632
|
+
command_class = Command.load_command(command)
|
633
|
+
end
|
634
|
+
|
635
|
+
# Check visibility
|
636
|
+
public_method = !!KERNEL_PUBLIC_METHOD.bind_call(main, command) rescue false
|
637
|
+
private_method = !public_method && !!KERNEL_METHOD.bind_call(main, command) rescue false
|
638
|
+
if command_class && Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
|
639
|
+
Statement::Command.new(code, command_class, arg)
|
640
|
+
else
|
641
|
+
Statement::Expression.new(code, is_assignment_expression)
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
def colorize_input(input, complete:)
|
646
|
+
if IRB.conf[:USE_COLORIZE] && IRB::Color.colorable?
|
647
|
+
lvars = local_variables || []
|
648
|
+
parsed_input = parse_input(input, false)
|
649
|
+
if parsed_input.is_a?(Statement::Command)
|
650
|
+
name, sep, arg = input.split(/(\s+)/, 2)
|
651
|
+
arg = IRB::Color.colorize_code(arg, complete: complete, local_variables: lvars)
|
652
|
+
"#{IRB::Color.colorize(name, [:BOLD])}\e[m#{sep}#{arg}"
|
653
|
+
else
|
654
|
+
IRB::Color.colorize_code(input, complete: complete, local_variables: lvars)
|
655
|
+
end
|
656
|
+
else
|
657
|
+
Reline::Unicode.escape_for_print(input)
|
658
|
+
end
|
659
|
+
end
|
660
|
+
|
661
|
+
def inspect_last_value(output = +'') # :nodoc:
|
662
|
+
@inspect_method.inspect_value(@last_value, output)
|
663
|
+
end
|
664
|
+
|
665
|
+
def inspector_support_stream_output?
|
666
|
+
@inspect_method.support_stream_output?
|
641
667
|
end
|
642
668
|
|
643
669
|
NOPRINTING_IVARS = ["@last_value"] # :nodoc:
|
@@ -670,5 +696,56 @@ module IRB
|
|
670
696
|
def local_variables # :nodoc:
|
671
697
|
workspace.binding.local_variables
|
672
698
|
end
|
699
|
+
|
700
|
+
def safe_method_call_on_main(method_name)
|
701
|
+
main_object = main
|
702
|
+
Object === main_object ? main_object.__send__(method_name) : Object.instance_method(method_name).bind_call(main_object)
|
703
|
+
end
|
704
|
+
|
705
|
+
private
|
706
|
+
|
707
|
+
def term_interactive?
|
708
|
+
return true if ENV['TEST_IRB_FORCE_INTERACTIVE']
|
709
|
+
STDIN.tty? && ENV['TERM'] != 'dumb'
|
710
|
+
end
|
711
|
+
|
712
|
+
def build_completor
|
713
|
+
completor_type = IRB.conf[:COMPLETOR]
|
714
|
+
|
715
|
+
# Gem repl_type_completor is added to bundled gems in Ruby 3.4.
|
716
|
+
# Use :type as default completor only in Ruby 3.4 or later.
|
717
|
+
verbose = !!completor_type
|
718
|
+
completor_type ||= RUBY_VERSION >= '3.4' ? :type : :regexp
|
719
|
+
|
720
|
+
case completor_type
|
721
|
+
when :regexp
|
722
|
+
return RegexpCompletor.new
|
723
|
+
when :type
|
724
|
+
completor = build_type_completor(verbose: verbose)
|
725
|
+
return completor if completor
|
726
|
+
else
|
727
|
+
warn "Invalid value for IRB.conf[:COMPLETOR]: #{completor_type}"
|
728
|
+
end
|
729
|
+
# Fallback to RegexpCompletor
|
730
|
+
RegexpCompletor.new
|
731
|
+
end
|
732
|
+
|
733
|
+
def build_type_completor(verbose:)
|
734
|
+
if RUBY_ENGINE == 'truffleruby'
|
735
|
+
# Avoid SyntaxError. truffleruby does not support endless method definition yet.
|
736
|
+
warn 'TypeCompletor is not supported on TruffleRuby yet' if verbose
|
737
|
+
return
|
738
|
+
end
|
739
|
+
|
740
|
+
begin
|
741
|
+
require 'repl_type_completor'
|
742
|
+
rescue LoadError => e
|
743
|
+
warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}" if verbose
|
744
|
+
return
|
745
|
+
end
|
746
|
+
|
747
|
+
ReplTypeCompletor.preload_rbs
|
748
|
+
TypeCompletor.new(self)
|
749
|
+
end
|
673
750
|
end
|
674
751
|
end
|
data/lib/irb/debug/ui.rb
CHANGED
@@ -45,9 +45,7 @@ module IRB
|
|
45
45
|
$stdout.puts line.chomp
|
46
46
|
}
|
47
47
|
when String
|
48
|
-
str
|
49
|
-
$stdout.puts line.chomp
|
50
|
-
}
|
48
|
+
Pager.page_content(str, retain_content: true)
|
51
49
|
when nil
|
52
50
|
$stdout.puts
|
53
51
|
end
|
@@ -56,7 +54,7 @@ module IRB
|
|
56
54
|
def readline _
|
57
55
|
setup_interrupt do
|
58
56
|
tc = DEBUGGER__::SESSION.instance_variable_get(:@tc)
|
59
|
-
cmd = @irb.debug_readline(tc.current_frame.
|
57
|
+
cmd = @irb.debug_readline(tc.current_frame.eval_binding || TOPLEVEL_BINDING)
|
60
58
|
|
61
59
|
case cmd
|
62
60
|
when nil # when user types C-d
|
data/lib/irb/debug.rb
CHANGED
@@ -57,22 +57,18 @@ module IRB
|
|
57
57
|
DEBUGGER__::ThreadClient.prepend(SkipPathHelperForIRB)
|
58
58
|
end
|
59
59
|
|
60
|
-
if
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
unless output.strip.empty?
|
65
|
-
cmd = output.split(/\s/, 2).first
|
60
|
+
if !DEBUGGER__::CONFIG[:no_hint] && irb.context.io.is_a?(RelineInputMethod)
|
61
|
+
Reline.output_modifier_proc = proc do |input, complete:|
|
62
|
+
unless input.strip.empty?
|
63
|
+
cmd = input.split(/\s/, 2).first
|
66
64
|
|
67
65
|
if !complete && DEBUGGER__.commands.key?(cmd)
|
68
|
-
|
66
|
+
input = input.sub(/\n$/, " # debug command\n")
|
69
67
|
end
|
70
68
|
end
|
71
69
|
|
72
|
-
|
70
|
+
irb.context.colorize_input(input, complete: complete)
|
73
71
|
end
|
74
|
-
|
75
|
-
@output_modifier_defined = true
|
76
72
|
end
|
77
73
|
|
78
74
|
true
|
@@ -85,6 +81,7 @@ module IRB
|
|
85
81
|
IRB.instance_variable_set(:@debugger_irb, irb)
|
86
82
|
irb.context.with_debugger = true
|
87
83
|
irb.context.irb_name += ":rdbg"
|
84
|
+
irb.context.io.load_history if irb.context.io.class < HistorySavingAbility
|
88
85
|
end
|
89
86
|
|
90
87
|
module SkipPathHelperForIRB
|
data/lib/irb/default_commands.rb
CHANGED
@@ -5,9 +5,11 @@ require_relative "command/internal_helpers"
|
|
5
5
|
require_relative "command/backtrace"
|
6
6
|
require_relative "command/break"
|
7
7
|
require_relative "command/catch"
|
8
|
+
require_relative "command/cd"
|
8
9
|
require_relative "command/chws"
|
9
10
|
require_relative "command/context"
|
10
11
|
require_relative "command/continue"
|
12
|
+
require_relative "command/copy"
|
11
13
|
require_relative "command/debug"
|
12
14
|
require_relative "command/delete"
|
13
15
|
require_relative "command/disable_irb"
|
@@ -180,9 +182,15 @@ module IRB
|
|
180
182
|
[:edit, NO_OVERRIDE]
|
181
183
|
)
|
182
184
|
|
183
|
-
_register_with_aliases(:irb_break, Command::Break
|
184
|
-
|
185
|
-
|
185
|
+
_register_with_aliases(:irb_break, Command::Break,
|
186
|
+
[:break, OVERRIDE_ALL]
|
187
|
+
)
|
188
|
+
_register_with_aliases(:irb_catch, Command::Catch,
|
189
|
+
[:catch, OVERRIDE_PRIVATE_ONLY]
|
190
|
+
)
|
191
|
+
_register_with_aliases(:irb_next, Command::Next,
|
192
|
+
[:next, OVERRIDE_ALL]
|
193
|
+
)
|
186
194
|
_register_with_aliases(:irb_delete, Command::Delete,
|
187
195
|
[:delete, NO_OVERRIDE]
|
188
196
|
)
|
@@ -211,7 +219,8 @@ module IRB
|
|
211
219
|
)
|
212
220
|
|
213
221
|
_register_with_aliases(:irb_show_doc, Command::ShowDoc,
|
214
|
-
[:show_doc, NO_OVERRIDE]
|
222
|
+
[:show_doc, NO_OVERRIDE],
|
223
|
+
[:ri, NO_OVERRIDE]
|
215
224
|
)
|
216
225
|
|
217
226
|
_register_with_aliases(:irb_info, Command::IrbInfo)
|
@@ -240,6 +249,9 @@ module IRB
|
|
240
249
|
_register_with_aliases(:irb_disable_irb, Command::DisableIrb,
|
241
250
|
[:disable_irb, NO_OVERRIDE]
|
242
251
|
)
|
252
|
+
|
253
|
+
register(:cd, Command::CD)
|
254
|
+
register(:copy, Command::Copy)
|
243
255
|
end
|
244
256
|
|
245
257
|
ExtendCommand = Command
|
@@ -256,10 +268,12 @@ module IRB
|
|
256
268
|
# Deprecated. Doesn't have any effect.
|
257
269
|
@EXTEND_COMMANDS = []
|
258
270
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
271
|
+
class << self
|
272
|
+
# Drepcated. Use Command.regiser instead.
|
273
|
+
def def_extend_command(cmd_name, cmd_class, _, *aliases)
|
274
|
+
Command._register_with_aliases(cmd_name, cmd_class, *aliases)
|
275
|
+
Command.class_variable_set(:@@command_override_policies, nil)
|
276
|
+
end
|
263
277
|
end
|
264
278
|
end
|
265
279
|
end
|
data/lib/irb/easter-egg.rb
CHANGED
@@ -100,19 +100,21 @@ module IRB
|
|
100
100
|
|
101
101
|
private def easter_egg_logo(type)
|
102
102
|
@easter_egg_logos ||= File.read(File.join(__dir__, 'ruby_logo.aa'), encoding: 'UTF-8:UTF-8')
|
103
|
-
.split(/TYPE: ([A-
|
103
|
+
.split(/TYPE: ([A-Z_]+)\n/)[1..]
|
104
104
|
.each_slice(2)
|
105
105
|
.to_h
|
106
106
|
@easter_egg_logos[type.to_s.upcase]
|
107
107
|
end
|
108
108
|
|
109
109
|
private def easter_egg(type = nil)
|
110
|
+
print "\e[?1049h"
|
110
111
|
type ||= [:logo, :dancing].sample
|
111
112
|
case type
|
112
113
|
when :logo
|
113
|
-
|
114
|
-
|
115
|
-
io.write easter_egg_logo(
|
114
|
+
Pager.page do |io|
|
115
|
+
logo_type = STDOUT.external_encoding == Encoding::UTF_8 ? :unicode_large : :ascii_large
|
116
|
+
io.write easter_egg_logo(logo_type)
|
117
|
+
STDIN.raw { STDIN.getc } if io == STDOUT
|
116
118
|
end
|
117
119
|
when :dancing
|
118
120
|
STDOUT.cooked do
|
@@ -123,7 +125,7 @@ module IRB
|
|
123
125
|
canvas = Canvas.new(Reline.get_screen_size)
|
124
126
|
end
|
125
127
|
ruby_model = RubyModel.new
|
126
|
-
print "\e[?
|
128
|
+
print "\e[?25l" # hide cursor
|
127
129
|
0.step do |i| # TODO (0..).each needs Ruby 2.6 or later
|
128
130
|
buff = canvas.draw do
|
129
131
|
ruby_model.render_frame(i) do |p1, p2|
|
@@ -137,10 +139,12 @@ module IRB
|
|
137
139
|
end
|
138
140
|
rescue Interrupt
|
139
141
|
ensure
|
140
|
-
print "\e[
|
142
|
+
print "\e[?25h" # show cursor
|
141
143
|
trap("SIGINT", prev_trap)
|
142
144
|
end
|
143
145
|
end
|
146
|
+
ensure
|
147
|
+
print "\e[0m\e[?1049l"
|
144
148
|
end
|
145
149
|
end
|
146
150
|
end
|