irb 1.4.1 → 1.4.3

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 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