irb 1.4.2 → 1.5.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/Gemfile +1 -0
- data/README.md +60 -0
- data/Rakefile +25 -0
- data/irb.gemspec +1 -1
- data/lib/irb/cmd/backtrace.rb +21 -0
- data/lib/irb/cmd/break.rb +21 -0
- data/lib/irb/cmd/catch.rb +21 -0
- data/lib/irb/cmd/continue.rb +17 -0
- data/lib/irb/cmd/debug.rb +112 -0
- data/lib/irb/cmd/delete.rb +17 -0
- data/lib/irb/cmd/edit.rb +65 -0
- data/lib/irb/cmd/finish.rb +17 -0
- data/lib/irb/cmd/info.rb +9 -22
- data/lib/irb/cmd/irb_info.rb +34 -0
- data/lib/irb/cmd/ls.rb +9 -0
- data/lib/irb/cmd/next.rb +17 -0
- data/lib/irb/cmd/show_source.rb +62 -43
- data/lib/irb/cmd/step.rb +18 -0
- data/lib/irb/color.rb +9 -2
- data/lib/irb/completion.rb +53 -40
- data/lib/irb/context.rb +40 -2
- data/lib/irb/ext/save-history.rb +1 -1
- data/lib/irb/extend-command.rb +59 -16
- data/lib/irb/init.rb +25 -5
- data/lib/irb/input-method.rb +9 -8
- data/lib/irb/ruby-lex.rb +40 -23
- data/lib/irb/version.rb +2 -2
- data/lib/irb.rb +72 -13
- data/man/irb.1 +23 -2
- metadata +15 -4
data/lib/irb/ruby-lex.rb
CHANGED
@@ -48,7 +48,7 @@ class RubyLex
|
|
48
48
|
end
|
49
49
|
|
50
50
|
# io functions
|
51
|
-
def set_input(io, p = nil, context
|
51
|
+
def set_input(io, p = nil, context:, &block)
|
52
52
|
@io = io
|
53
53
|
if @io.respond_to?(:check_termination)
|
54
54
|
@io.check_termination do |code|
|
@@ -65,6 +65,12 @@ class RubyLex
|
|
65
65
|
false
|
66
66
|
end
|
67
67
|
else
|
68
|
+
# Accept any single-line input for symbol aliases or commands that transform args
|
69
|
+
command = code.split(/\s/, 2).first
|
70
|
+
if context.symbol_alias?(command) || context.transform_args?(command)
|
71
|
+
next true
|
72
|
+
end
|
73
|
+
|
68
74
|
code.gsub!(/\s*\z/, '').concat("\n")
|
69
75
|
ltype, indent, continue, code_block_open = check_state(code, context: context)
|
70
76
|
if ltype or indent > 0 or continue or code_block_open
|
@@ -136,16 +142,18 @@ class RubyLex
|
|
136
142
|
:on_param_error
|
137
143
|
]
|
138
144
|
|
145
|
+
def self.generate_local_variables_assign_code(local_variables)
|
146
|
+
"#{local_variables.join('=')}=nil;" unless local_variables.empty?
|
147
|
+
end
|
148
|
+
|
139
149
|
def self.ripper_lex_without_warning(code, context: nil)
|
140
150
|
verbose, $VERBOSE = $VERBOSE, nil
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
line_no = 1
|
148
|
-
end
|
151
|
+
lvars_code = generate_local_variables_assign_code(context&.local_variables || [])
|
152
|
+
if lvars_code
|
153
|
+
code = "#{lvars_code}\n#{code}"
|
154
|
+
line_no = 0
|
155
|
+
else
|
156
|
+
line_no = 1
|
149
157
|
end
|
150
158
|
|
151
159
|
compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no|
|
@@ -162,7 +170,7 @@ class RubyLex
|
|
162
170
|
end
|
163
171
|
end
|
164
172
|
else
|
165
|
-
lexer.parse.reject { |it| it.pos.first == 0 }
|
173
|
+
lexer.parse.reject { |it| it.pos.first == 0 }.sort_by(&:pos)
|
166
174
|
end
|
167
175
|
end
|
168
176
|
ensure
|
@@ -214,6 +222,8 @@ class RubyLex
|
|
214
222
|
ltype = process_literal_type(tokens)
|
215
223
|
indent = process_nesting_level(tokens)
|
216
224
|
continue = process_continue(tokens)
|
225
|
+
lvars_code = self.class.generate_local_variables_assign_code(context.local_variables)
|
226
|
+
code = "#{lvars_code}\n#{code}" if lvars_code
|
217
227
|
code_block_open = check_code_block(code, tokens)
|
218
228
|
[ltype, indent, continue, code_block_open]
|
219
229
|
end
|
@@ -233,13 +243,13 @@ class RubyLex
|
|
233
243
|
@code_block_open = false
|
234
244
|
end
|
235
245
|
|
236
|
-
def each_top_level_statement
|
246
|
+
def each_top_level_statement(context)
|
237
247
|
initialize_input
|
238
248
|
catch(:TERM_INPUT) do
|
239
249
|
loop do
|
240
250
|
begin
|
241
251
|
prompt
|
242
|
-
unless l = lex
|
252
|
+
unless l = lex(context)
|
243
253
|
throw :TERM_INPUT if @line == ''
|
244
254
|
else
|
245
255
|
@line_no += l.count("\n")
|
@@ -269,18 +279,15 @@ class RubyLex
|
|
269
279
|
end
|
270
280
|
end
|
271
281
|
|
272
|
-
def lex
|
282
|
+
def lex(context)
|
273
283
|
line = @input.call
|
274
284
|
if @io.respond_to?(:check_termination)
|
275
285
|
return line # multiline
|
276
286
|
end
|
277
287
|
code = @line + (line.nil? ? '' : line)
|
278
288
|
code.gsub!(/\s*\z/, '').concat("\n")
|
279
|
-
@tokens = self.class.ripper_lex_without_warning(code)
|
280
|
-
@continue =
|
281
|
-
@code_block_open = check_code_block(code)
|
282
|
-
@indent = process_nesting_level
|
283
|
-
@ltype = process_literal_type
|
289
|
+
@tokens = self.class.ripper_lex_without_warning(code, context: context)
|
290
|
+
@ltype, @indent, @continue, @code_block_open = check_state(code, @tokens, context: context)
|
284
291
|
line
|
285
292
|
end
|
286
293
|
|
@@ -706,6 +713,7 @@ class RubyLex
|
|
706
713
|
i = 0
|
707
714
|
start_token = []
|
708
715
|
end_type = []
|
716
|
+
pending_heredocs = []
|
709
717
|
while i < tokens.size
|
710
718
|
t = tokens[i]
|
711
719
|
case t.event
|
@@ -729,18 +737,27 @@ class RubyLex
|
|
729
737
|
end
|
730
738
|
end
|
731
739
|
when :on_backtick
|
732
|
-
|
733
|
-
|
740
|
+
if t.state.allbits?(Ripper::EXPR_BEG)
|
741
|
+
start_token << t
|
742
|
+
end_type << :on_tstring_end
|
743
|
+
end
|
734
744
|
when :on_qwords_beg, :on_words_beg, :on_qsymbols_beg, :on_symbols_beg
|
735
745
|
start_token << t
|
736
746
|
end_type << :on_tstring_end
|
737
747
|
when :on_heredoc_beg
|
738
|
-
|
739
|
-
|
748
|
+
pending_heredocs << t
|
749
|
+
end
|
750
|
+
|
751
|
+
if pending_heredocs.any? && t.tok.include?("\n")
|
752
|
+
pending_heredocs.reverse_each do |t|
|
753
|
+
start_token << t
|
754
|
+
end_type << :on_heredoc_end
|
755
|
+
end
|
756
|
+
pending_heredocs = []
|
740
757
|
end
|
741
758
|
i += 1
|
742
759
|
end
|
743
|
-
|
760
|
+
pending_heredocs.first || start_token.last
|
744
761
|
end
|
745
762
|
|
746
763
|
def process_literal_type(tokens = @tokens)
|
data/lib/irb/version.rb
CHANGED
data/lib/irb.rb
CHANGED
@@ -53,6 +53,52 @@ require_relative "irb/easter-egg"
|
|
53
53
|
#
|
54
54
|
# :include: ./irb/lc/help-message
|
55
55
|
#
|
56
|
+
# == Commands
|
57
|
+
#
|
58
|
+
# The following commands are available on IRB.
|
59
|
+
#
|
60
|
+
# * cwws
|
61
|
+
# * Show the current workspace.
|
62
|
+
# * cb, cws, chws
|
63
|
+
# * Change the current workspace to an object.
|
64
|
+
# * bindings, workspaces
|
65
|
+
# * Show workspaces.
|
66
|
+
# * pushb, pushws
|
67
|
+
# * Push an object to the workspace stack.
|
68
|
+
# * popb, popws
|
69
|
+
# * Pop a workspace from the workspace stack.
|
70
|
+
# * load
|
71
|
+
# * Load a Ruby file.
|
72
|
+
# * require
|
73
|
+
# * Require a Ruby file.
|
74
|
+
# * source
|
75
|
+
# * Loads a given file in the current session.
|
76
|
+
# * irb
|
77
|
+
# * Start a child IRB.
|
78
|
+
# * jobs
|
79
|
+
# * List of current sessions.
|
80
|
+
# * fg
|
81
|
+
# * Switches to the session of the given number.
|
82
|
+
# * kill
|
83
|
+
# * Kills the session with the given number.
|
84
|
+
# * help
|
85
|
+
# * Enter the mode to look up RI documents.
|
86
|
+
# * irb_info
|
87
|
+
# * Show information about IRB.
|
88
|
+
# * ls
|
89
|
+
# * Show methods, constants, and variables.
|
90
|
+
# -g [query] or -G [query] allows you to filter out the output.
|
91
|
+
# * measure
|
92
|
+
# * measure enables the mode to measure processing time. measure :off disables it.
|
93
|
+
# * $, show_source
|
94
|
+
# * Show the source code of a given method or constant.
|
95
|
+
# * @, whereami
|
96
|
+
# * Show the source code around binding.irb again.
|
97
|
+
# * debug
|
98
|
+
# * Start the debugger of debug.gem.
|
99
|
+
# * break, delete, next, step, continue, finish, backtrace, info, catch
|
100
|
+
# * Start the debugger of debug.gem and run the command on it.
|
101
|
+
#
|
56
102
|
# == Configuration
|
57
103
|
#
|
58
104
|
# IRB reads a personal initialization file when it's invoked.
|
@@ -93,9 +139,9 @@ require_relative "irb/easter-egg"
|
|
93
139
|
#
|
94
140
|
# === Autocompletion
|
95
141
|
#
|
96
|
-
# To
|
142
|
+
# To disable autocompletion for irb, add the following to your +.irbrc+:
|
97
143
|
#
|
98
|
-
#
|
144
|
+
# IRB.conf[:USE_AUTOCOMPLETE] = false
|
99
145
|
#
|
100
146
|
# === History
|
101
147
|
#
|
@@ -430,6 +476,17 @@ module IRB
|
|
430
476
|
@scanner = RubyLex.new
|
431
477
|
end
|
432
478
|
|
479
|
+
# A hook point for `debug` command's TracePoint after :IRB_EXIT as well as its clean-up
|
480
|
+
def debug_break
|
481
|
+
# it means the debug command is executed
|
482
|
+
if defined?(DEBUGGER__) && DEBUGGER__.respond_to?(:capture_frames_without_irb)
|
483
|
+
# after leaving this initial breakpoint, revert the capture_frames patch
|
484
|
+
DEBUGGER__.singleton_class.send(:alias_method, :capture_frames, :capture_frames_without_irb)
|
485
|
+
# and remove the redundant method
|
486
|
+
DEBUGGER__.singleton_class.send(:undef_method, :capture_frames_without_irb)
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
433
490
|
def run(conf = IRB.conf)
|
434
491
|
conf[:IRB_RC].call(context) if conf[:IRB_RC]
|
435
492
|
conf[:MAIN_CONTEXT] = context
|
@@ -506,13 +563,15 @@ module IRB
|
|
506
563
|
|
507
564
|
@scanner.set_auto_indent(@context) if @context.auto_indent_mode
|
508
565
|
|
509
|
-
@scanner.each_top_level_statement do |line, line_no|
|
566
|
+
@scanner.each_top_level_statement(@context) do |line, line_no|
|
510
567
|
signal_status(:IN_EVAL) do
|
511
568
|
begin
|
512
569
|
line.untaint if RUBY_VERSION < '2.7'
|
513
570
|
if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
|
514
571
|
IRB.set_measure_callback
|
515
572
|
end
|
573
|
+
# Assignment expression check should be done before @context.evaluate to handle code like `a /2#/ if false; a = 1`
|
574
|
+
is_assignment = assignment_expression?(line)
|
516
575
|
if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
|
517
576
|
result = nil
|
518
577
|
last_proc = proc{ result = @context.evaluate(line, line_no, exception: exc) }
|
@@ -529,7 +588,7 @@ module IRB
|
|
529
588
|
@context.evaluate(line, line_no, exception: exc)
|
530
589
|
end
|
531
590
|
if @context.echo?
|
532
|
-
if
|
591
|
+
if is_assignment
|
533
592
|
if @context.echo_on_assignment?
|
534
593
|
output_value(@context.echo_on_assignment? == :truncate)
|
535
594
|
end
|
@@ -592,11 +651,7 @@ module IRB
|
|
592
651
|
|
593
652
|
if exc.backtrace
|
594
653
|
order = nil
|
595
|
-
if '
|
596
|
-
# Exception#full_message doesn't have keyword arguments.
|
597
|
-
message = exc.full_message # the same of (highlight: true, order: bottom)
|
598
|
-
order = :bottom
|
599
|
-
elsif '2.5.1' <= RUBY_VERSION && RUBY_VERSION < '3.0.0'
|
654
|
+
if RUBY_VERSION < '3.0.0'
|
600
655
|
if STDOUT.tty?
|
601
656
|
message = exc.full_message(order: :bottom)
|
602
657
|
order = :bottom
|
@@ -827,9 +882,12 @@ module IRB
|
|
827
882
|
# array of parsed expressions. The first element of each expression is the
|
828
883
|
# expression's type.
|
829
884
|
verbose, $VERBOSE = $VERBOSE, nil
|
830
|
-
|
885
|
+
code = "#{RubyLex.generate_local_variables_assign_code(@context.local_variables) || 'nil;'}\n#{line}"
|
886
|
+
# Get the last node_type of the line. drop(1) is to ignore the local_variables_assign_code part.
|
887
|
+
node_type = Ripper.sexp(code)&.dig(1)&.drop(1)&.dig(-1, 0)
|
888
|
+
ASSIGNMENT_NODE_TYPES.include?(node_type)
|
889
|
+
ensure
|
831
890
|
$VERBOSE = verbose
|
832
|
-
result
|
833
891
|
end
|
834
892
|
|
835
893
|
ATTR_TTY = "\e[%sm"
|
@@ -919,12 +977,13 @@ class Binding
|
|
919
977
|
#
|
920
978
|
#
|
921
979
|
# See IRB@IRB+Usage for more information.
|
922
|
-
def irb
|
980
|
+
def irb(show_code: true)
|
923
981
|
IRB.setup(source_location[0], argv: [])
|
924
982
|
workspace = IRB::WorkSpace.new(self)
|
925
|
-
STDOUT.print(workspace.code_around_binding)
|
983
|
+
STDOUT.print(workspace.code_around_binding) if show_code
|
926
984
|
binding_irb = IRB::Irb.new(workspace)
|
927
985
|
binding_irb.context.irb_path = File.expand_path(source_location[0])
|
928
986
|
binding_irb.run(IRB.conf)
|
987
|
+
binding_irb.debug_break
|
929
988
|
end
|
930
989
|
end
|
data/man/irb.1
CHANGED
@@ -173,8 +173,19 @@ The default value is 16.
|
|
173
173
|
.El
|
174
174
|
.Pp
|
175
175
|
.Sh ENVIRONMENT
|
176
|
-
.Bl -tag -compact
|
176
|
+
.Bl -tag -compact -width "XDG_CONFIG_HOME"
|
177
|
+
.It Ev IRB_LANG
|
178
|
+
The locale used for
|
179
|
+
.Nm .
|
180
|
+
.Pp
|
177
181
|
.It Ev IRBRC
|
182
|
+
The path to the personal initialization file.
|
183
|
+
.Pp
|
184
|
+
.It Ev XDG_CONFIG_HOME
|
185
|
+
.Nm
|
186
|
+
respects XDG_CONFIG_HOME. If this is set, load
|
187
|
+
.Pa $XDG_CONFIG_HOME/irb/irbrc
|
188
|
+
as a personal initialization file.
|
178
189
|
.Pp
|
179
190
|
.El
|
180
191
|
.Pp
|
@@ -186,7 +197,17 @@ depends on same variables as
|
|
186
197
|
.Sh FILES
|
187
198
|
.Bl -tag -compact
|
188
199
|
.It Pa ~/.irbrc
|
189
|
-
Personal irb initialization.
|
200
|
+
Personal irb initialization. If
|
201
|
+
.Ev IRBRC
|
202
|
+
is set, read
|
203
|
+
.Pa $IRBRC
|
204
|
+
instead. If
|
205
|
+
.Ev IRBRC
|
206
|
+
is not set and
|
207
|
+
.Ev XDG_CONFIG_HOME
|
208
|
+
is set,
|
209
|
+
.Pa $XDG_CONFIG_HOME/irb/irbrc
|
210
|
+
is loaded.
|
190
211
|
.Pp
|
191
212
|
.El
|
192
213
|
.Pp
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: irb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-11-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: reline
|
@@ -46,16 +46,27 @@ files:
|
|
46
46
|
- exe/irb
|
47
47
|
- irb.gemspec
|
48
48
|
- lib/irb.rb
|
49
|
+
- lib/irb/cmd/backtrace.rb
|
50
|
+
- lib/irb/cmd/break.rb
|
51
|
+
- lib/irb/cmd/catch.rb
|
49
52
|
- lib/irb/cmd/chws.rb
|
53
|
+
- lib/irb/cmd/continue.rb
|
54
|
+
- lib/irb/cmd/debug.rb
|
55
|
+
- lib/irb/cmd/delete.rb
|
56
|
+
- lib/irb/cmd/edit.rb
|
57
|
+
- lib/irb/cmd/finish.rb
|
50
58
|
- lib/irb/cmd/fork.rb
|
51
59
|
- lib/irb/cmd/help.rb
|
52
60
|
- lib/irb/cmd/info.rb
|
61
|
+
- lib/irb/cmd/irb_info.rb
|
53
62
|
- lib/irb/cmd/load.rb
|
54
63
|
- lib/irb/cmd/ls.rb
|
55
64
|
- lib/irb/cmd/measure.rb
|
65
|
+
- lib/irb/cmd/next.rb
|
56
66
|
- lib/irb/cmd/nop.rb
|
57
67
|
- lib/irb/cmd/pushws.rb
|
58
68
|
- lib/irb/cmd/show_source.rb
|
69
|
+
- lib/irb/cmd/step.rb
|
59
70
|
- lib/irb/cmd/subirb.rb
|
60
71
|
- lib/irb/cmd/whereami.rb
|
61
72
|
- lib/irb/color.rb
|
@@ -107,14 +118,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
107
118
|
requirements:
|
108
119
|
- - ">="
|
109
120
|
- !ruby/object:Gem::Version
|
110
|
-
version: '2.
|
121
|
+
version: '2.6'
|
111
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
123
|
requirements:
|
113
124
|
- - ">="
|
114
125
|
- !ruby/object:Gem::Version
|
115
126
|
version: '0'
|
116
127
|
requirements: []
|
117
|
-
rubygems_version: 3.
|
128
|
+
rubygems_version: 3.3.26
|
118
129
|
signing_key:
|
119
130
|
specification_version: 4
|
120
131
|
summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
|