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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be0bdb184f8483785b83b91bc57339e994a15b2d1435720e8f17b9f04b2b924e
4
- data.tar.gz: 02ca5b9f06cedc077c79f07ad33765225736f9d7ffa9bb93671cf739131a2d9c
3
+ metadata.gz: 025d4dccc426fe09dc77b79d7efb8157abc559b89a7455249e5d7e9b2ff1562c
4
+ data.tar.gz: fd2cffe5c013c56a5d454ce81331ac1c24b6826c81db6ae6f2240e6e2d5f8c06
5
5
  SHA512:
6
- metadata.gz: faa52653f45b98a0ce82b215110376e3cac3faefa34928a50067e101c3171a0fbc492ba3b7a23334ac81f23448526e6931fca45925a07ab914aa2634c8e1de9a
7
- data.tar.gz: 4da73a1293f021bcb3a0ed996ac4f48f3c73884d34efa438987b230cda72ce3aa0c6ac67865e57655cdcc8ffd49cb6ca267c564711345247ed889857f60156c1
6
+ metadata.gz: 582d9176beb3f3b9a016f6d44b90b9d781066230f4c64dec93ba5d645ae54df8f7f6f1a5dcaab20899390cd048050eaed6db9b45fdcf44c55a57098013855aa9
7
+ data.tar.gz: ab9b30b770c677778cc4871b249a0967177805e543bd8576077099be7d3a5d93e2ef33c35362326cd7f889cd1f855d956c2cb9bd992560029e152c6293720a94
data/Gemfile CHANGED
@@ -10,4 +10,5 @@ group :development do
10
10
  gem "rake"
11
11
  gem "stackprof" if is_unix && !is_truffleruby
12
12
  gem "test-unit"
13
+ gem "reline", github: "ruby/reline" if ENV["WITH_LATEST_RELINE"] == "true"
13
14
  end
data/README.md CHANGED
@@ -40,6 +40,10 @@ irb(main):006:1> end
40
40
 
41
41
  The Readline extension module can be used with irb. Use of Readline is default if it's installed.
42
42
 
43
+ ## Documentation
44
+
45
+ https://docs.ruby-lang.org/en/master/IRB.html
46
+
43
47
  ## Development
44
48
 
45
49
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/Rakefile CHANGED
@@ -8,6 +8,31 @@ Rake::TestTask.new(:test) do |t|
8
8
  t.test_files = FileList["test/irb/test_*.rb"]
9
9
  end
10
10
 
11
+ # To make sure they have been correctly setup for Ruby CI.
12
+ desc "Run each irb test file in isolation."
13
+ task :test_in_isolation do
14
+ failed = false
15
+
16
+ FileList["test/irb/test_*.rb"].each do |test_file|
17
+ ENV["TEST"] = test_file
18
+ begin
19
+ Rake::Task["test"].execute
20
+ rescue => e
21
+ failed = true
22
+ msg = "Test '#{test_file}' failed when being executed in isolation. Please make sure 'rake test TEST=#{test_file}' passes."
23
+ separation_line = '=' * msg.length
24
+
25
+ puts <<~MSG
26
+ #{separation_line}
27
+ #{msg}
28
+ #{separation_line}
29
+ MSG
30
+ end
31
+ end
32
+
33
+ fail "Some tests failed when being executed in isolation" if failed
34
+ end
35
+
11
36
  Rake::TestTask.new(:test_yamatanooroti) do |t|
12
37
  t.libs << 'test' << "test/lib"
13
38
  t.libs << 'lib'
data/irb.gemspec CHANGED
@@ -8,8 +8,8 @@ end
8
8
  Gem::Specification.new do |spec|
9
9
  spec.name = "irb"
10
10
  spec.version = IRB::VERSION
11
- spec.authors = ["Keiju ISHITSUKA"]
12
- spec.email = ["keiju@ruby-lang.org"]
11
+ spec.authors = ["aycabta", "Keiju ISHITSUKA"]
12
+ spec.email = ["aycabta@gmail.com", "keiju@ruby-lang.org"]
13
13
 
14
14
  spec.summary = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).}
15
15
  spec.description = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).}
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
35
  spec.require_paths = ["lib"]
36
36
 
37
- spec.required_ruby_version = Gem::Requirement.new(">= 2.5")
37
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6")
38
38
 
39
39
  spec.add_dependency "reline", ">= 0.3.0"
40
40
  end
data/lib/irb/cmd/chws.rb CHANGED
@@ -13,8 +13,9 @@
13
13
  require_relative "nop"
14
14
  require_relative "../ext/change-ws"
15
15
 
16
- # :stopdoc:
17
16
  module IRB
17
+ # :stopdoc:
18
+
18
19
  module ExtendCommand
19
20
 
20
21
  class CurrentWorkingWorkspace < Nop
@@ -30,5 +31,6 @@ module IRB
30
31
  end
31
32
  end
32
33
  end
34
+
35
+ # :startdoc:
33
36
  end
34
- # :startdoc:
data/lib/irb/cmd/fork.rb CHANGED
@@ -10,9 +10,11 @@
10
10
  #
11
11
  #
12
12
 
13
+ require_relative "nop"
13
14
 
14
- # :stopdoc:
15
15
  module IRB
16
+ # :stopdoc:
17
+
16
18
  module ExtendCommand
17
19
  class Fork < Nop
18
20
  def execute
@@ -33,5 +35,6 @@ module IRB
33
35
  end
34
36
  end
35
37
  end
38
+
39
+ # :startdoc:
36
40
  end
37
- # :startdoc:
data/lib/irb/cmd/help.rb CHANGED
@@ -11,8 +11,9 @@
11
11
 
12
12
  require_relative "nop"
13
13
 
14
- # :stopdoc:
15
14
  module IRB
15
+ # :stopdoc:
16
+
16
17
  module ExtendCommand
17
18
  class Help < Nop
18
19
  def execute(*names)
@@ -43,5 +44,6 @@ module IRB
43
44
  end
44
45
  end
45
46
  end
47
+
48
+ # :startdoc:
46
49
  end
47
- # :startdoc:
data/lib/irb/cmd/info.rb CHANGED
@@ -2,8 +2,9 @@
2
2
 
3
3
  require_relative "nop"
4
4
 
5
- # :stopdoc:
6
5
  module IRB
6
+ # :stopdoc:
7
+
7
8
  module ExtendCommand
8
9
  class Info < Nop
9
10
  def execute
@@ -28,5 +29,6 @@ module IRB
28
29
  end
29
30
  end
30
31
  end
32
+
33
+ # :startdoc:
31
34
  end
32
- # :startdoc:
data/lib/irb/cmd/load.rb CHANGED
@@ -13,8 +13,9 @@
13
13
  require_relative "nop"
14
14
  require_relative "../ext/loader"
15
15
 
16
- # :stopdoc:
17
16
  module IRB
17
+ # :stopdoc:
18
+
18
19
  module ExtendCommand
19
20
  class Load < Nop
20
21
  include IrbLoader
@@ -63,5 +64,5 @@ module IRB
63
64
  end
64
65
  end
65
66
 
67
+ # :startdoc:
66
68
  end
67
- # :startdoc:
data/lib/irb/cmd/ls.rb CHANGED
@@ -4,10 +4,20 @@ require "reline"
4
4
  require_relative "nop"
5
5
  require_relative "../color"
6
6
 
7
- # :stopdoc:
8
7
  module IRB
8
+ # :stopdoc:
9
+
9
10
  module ExtendCommand
10
11
  class Ls < Nop
12
+ def self.transform_args(args)
13
+ if match = args&.match(/\A(?<args>.+\s|)(-g|-G)\s+(?<grep>[^\s]+)\s*\n\z/)
14
+ args = match[:args]
15
+ "#{args}#{',' unless args.chomp.empty?} grep: /#{match[:grep]}/"
16
+ else
17
+ args
18
+ end
19
+ end
20
+
11
21
  def execute(*arg, grep: nil)
12
22
  o = Output.new(grep: grep)
13
23
 
@@ -97,5 +107,6 @@ module IRB
97
107
  private_constant :Output
98
108
  end
99
109
  end
110
+
111
+ # :startdoc:
100
112
  end
101
- # :startdoc:
@@ -1,7 +1,8 @@
1
1
  require_relative "nop"
2
2
 
3
- # :stopdoc:
4
3
  module IRB
4
+ # :stopdoc:
5
+
5
6
  module ExtendCommand
6
7
  class Measure < Nop
7
8
  def initialize(*args)
@@ -39,5 +40,6 @@ module IRB
39
40
  end
40
41
  end
41
42
  end
43
+
44
+ # :startdoc:
42
45
  end
43
- # :startdoc:
data/lib/irb/cmd/nop.rb CHANGED
@@ -9,8 +9,9 @@
9
9
  #
10
10
  #
11
11
  #
12
- # :stopdoc:
13
12
  module IRB
13
+ # :stopdoc:
14
+
14
15
  module ExtendCommand
15
16
  class Nop
16
17
 
@@ -41,5 +42,6 @@ module IRB
41
42
  end
42
43
  end
43
44
  end
45
+
46
+ # :startdoc:
44
47
  end
45
- # :startdoc:
@@ -13,8 +13,9 @@
13
13
  require_relative "nop"
14
14
  require_relative "../ext/workspaces"
15
15
 
16
- # :stopdoc:
17
16
  module IRB
17
+ # :stopdoc:
18
+
18
19
  module ExtendCommand
19
20
  class Workspaces < Nop
20
21
  def execute(*obj)
@@ -36,5 +37,6 @@ module IRB
36
37
  end
37
38
  end
38
39
  end
40
+
41
+ # :startdoc:
39
42
  end
40
- # :startdoc:
@@ -4,10 +4,29 @@ require_relative "nop"
4
4
  require_relative "../color"
5
5
  require_relative "../ruby-lex"
6
6
 
7
- # :stopdoc:
8
7
  module IRB
8
+ # :stopdoc:
9
+
9
10
  module ExtendCommand
10
11
  class ShowSource < Nop
12
+ class << self
13
+ def transform_args(args)
14
+ # Return a string literal as is for backward compatibility
15
+ if args.empty? || string_literal?(args)
16
+ args
17
+ else # Otherwise, consider the input as a String for convenience
18
+ args.strip.dump
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def string_literal?(args)
25
+ sexp = Ripper.sexp(args)
26
+ sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
27
+ end
28
+ end
29
+
11
30
  def execute(str = nil)
12
31
  unless str.is_a?(String)
13
32
  puts "Error: Expected a string but got #{str.inspect}"
@@ -89,5 +108,6 @@ module IRB
89
108
  private_constant :Source
90
109
  end
91
110
  end
111
+
112
+ # :startdoc:
92
113
  end
93
- # :startdoc:
@@ -12,8 +12,9 @@
12
12
  require_relative "nop"
13
13
  require_relative "../ext/multi-irb"
14
14
 
15
- # :stopdoc:
16
15
  module IRB
16
+ # :stopdoc:
17
+
17
18
  module ExtendCommand
18
19
  class IrbCommand < Nop
19
20
  def execute(*obj)
@@ -39,5 +40,6 @@ module IRB
39
40
  end
40
41
  end
41
42
  end
43
+
44
+ # :startdoc:
42
45
  end
43
- # :startdoc:
@@ -2,8 +2,9 @@
2
2
 
3
3
  require_relative "nop"
4
4
 
5
- # :stopdoc:
6
5
  module IRB
6
+ # :stopdoc:
7
+
7
8
  module ExtendCommand
8
9
  class Whereami < Nop
9
10
  def execute(*)
@@ -16,5 +17,6 @@ module IRB
16
17
  end
17
18
  end
18
19
  end
20
+
21
+ # :startdoc:
19
22
  end
20
- # :startdoc:
data/lib/irb/color.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require 'reline'
3
3
  require 'ripper'
4
- require 'irb/ruby-lex'
4
+ require_relative 'ruby-lex'
5
5
 
6
6
  module IRB # :nodoc:
7
7
  module Color
@@ -77,7 +77,15 @@ module IRB # :nodoc:
77
77
 
78
78
  class << self
79
79
  def colorable?
80
- $stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
80
+ supported = $stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
81
+
82
+ # because ruby/debug also uses irb's color module selectively,
83
+ # irb won't be activated in that case.
84
+ if IRB.respond_to?(:conf)
85
+ supported && IRB.conf.fetch(:USE_COLORIZE, true)
86
+ else
87
+ supported
88
+ end
81
89
  end
82
90
 
83
91
  def inspect_colorable?(obj, seen: {}.compare_by_identity)
@@ -115,15 +123,21 @@ module IRB # :nodoc:
115
123
  # If `complete` is false (code is incomplete), this does not warn compile_error.
116
124
  # This option is needed to avoid warning a user when the compile_error is happening
117
125
  # because the input is not wrong but just incomplete.
118
- def colorize_code(code, complete: true, ignore_error: false, colorable: colorable?)
126
+ def colorize_code(code, complete: true, ignore_error: false, colorable: colorable?, local_variables: [])
119
127
  return code unless colorable
120
128
 
121
129
  symbol_state = SymbolState.new
122
130
  colored = +''
123
- length = 0
124
- end_seen = false
131
+ lvars_code = RubyLex.generate_local_variables_assign_code(local_variables)
132
+ code_with_lvars = lvars_code ? "#{lvars_code}\n#{code}" : code
133
+
134
+ scan(code_with_lvars, allow_last_error: !complete) do |token, str, expr|
135
+ # handle uncolorable code
136
+ if token.nil?
137
+ colored << Reline::Unicode.escape_for_print(str)
138
+ next
139
+ end
125
140
 
126
- scan(code, allow_last_error: !complete) do |token, str, expr|
127
141
  # IRB::ColorPrinter skips colorizing fragments with any invalid token
128
142
  if ignore_error && ERROR_TOKENS.include?(token)
129
143
  return Reline::Unicode.escape_for_print(code)
@@ -139,15 +153,12 @@ module IRB # :nodoc:
139
153
  colored << line
140
154
  end
141
155
  end
142
- length += str.bytesize
143
- end_seen = true if token == :on___end__
144
156
  end
145
157
 
146
- # give up colorizing incomplete Ripper tokens
147
- unless end_seen or length == code.bytesize
148
- return Reline::Unicode.escape_for_print(code)
158
+ if lvars_code
159
+ raise "#{lvars_code.dump} should have no \\n" if lvars_code.include?("\n")
160
+ colored.sub!(/\A.+\n/, '') # delete_prefix lvars_code with colors
149
161
  end
150
-
151
162
  colored
152
163
  end
153
164
 
@@ -162,33 +173,42 @@ module IRB # :nodoc:
162
173
  end
163
174
 
164
175
  def scan(code, allow_last_error:)
165
- pos = [1, 0]
166
-
167
176
  verbose, $VERBOSE = $VERBOSE, nil
168
177
  RubyLex.compile_with_errors_suppressed(code) do |inner_code, line_no|
169
178
  lexer = Ripper::Lexer.new(inner_code, '(ripper)', line_no)
170
- if lexer.respond_to?(:scan) # Ruby 2.7+
171
- lexer.scan.each do |elem|
172
- str = elem.tok
173
- next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
174
- next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0
179
+ byte_pos = 0
180
+ line_positions = [0]
181
+ inner_code.lines.each do |line|
182
+ line_positions << line_positions.last + line.bytesize
183
+ end
184
+
185
+ on_scan = proc do |elem|
186
+ start_pos = line_positions[elem.pos[0] - 1] + elem.pos[1]
175
187
 
176
- str.each_line do |line|
177
- if line.end_with?("\n")
178
- pos[0] += 1
179
- pos[1] = 0
180
- else
181
- pos[1] += line.bytesize
182
- end
183
- end
188
+ # yield uncolorable code
189
+ if byte_pos < start_pos
190
+ yield(nil, inner_code.byteslice(byte_pos...start_pos), nil)
191
+ end
184
192
 
193
+ if byte_pos <= start_pos
194
+ str = elem.tok
185
195
  yield(elem.event, str, elem.state)
196
+ byte_pos = start_pos + str.bytesize
197
+ end
198
+ end
199
+
200
+ if lexer.respond_to?(:scan) # Ruby 2.7+
201
+ lexer.scan.each do |elem|
202
+ next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
203
+ on_scan.call(elem)
186
204
  end
187
205
  else
188
- lexer.parse.each do |elem|
189
- yield(elem.event, elem.tok, elem.state)
206
+ lexer.parse.sort_by(&:pos).each do |elem|
207
+ on_scan.call(elem)
190
208
  end
191
209
  end
210
+ # yield uncolorable DATA section
211
+ yield(nil, inner_code.byteslice(byte_pos...inner_code.bytesize), nil) if byte_pos < inner_code.bytesize
192
212
  end
193
213
  ensure
194
214
  $VERBOSE = verbose
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'pp'
3
- require 'irb/color'
3
+ require_relative 'color'
4
4
 
5
5
  module IRB
6
6
  class ColorPrinter < ::PP
@@ -37,6 +37,9 @@ module IRB
37
37
  width ||= str.length
38
38
 
39
39
  case str
40
+ when ''
41
+ when ',', '=>', '[', ']', '{', '}', '..', '...', /\A@\w+\z/
42
+ super(str, width)
40
43
  when /\A#</, '=', '>'
41
44
  super(Color.colorize(str, [:GREEN]), width)
42
45
  else