Skip to content

Commit 1c53023

Browse files
authored
Centralize coloring control (#374)
* Use colorable: argument as the only coloring control * Centalize color controling logic at Color.colorable? There are 2 requirements for coloring output: 1. It's supported on the platform 2. The user wants it: `IRB.conf[:USE_COLORIZE] == true` Right now we check 1 and 2 separately whenever we colorize things. But it's error-prone because while 1 is the default of `colorable` parameter, 2 always need to manually checked. When 2 is overlooked, it causes issues like #362 And there's 0 case where we may want to colorize even when the user disables it. So I think we should merge 2 into `Color.colorable?` so it can be automatically picked up. * Add tests for all inspect modes * Simplify inspectors' coloring logic * Replace use_colorize? with Color.colorable? * Remove Context#use_colorize cause it's redundant
1 parent 7db93f9 commit 1c53023

File tree

9 files changed

+46
-58
lines changed

9 files changed

+46
-58
lines changed

lib/irb.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -828,19 +828,19 @@ def output_value(omit = false) # :nodoc:
828828
if diff_size.positive? and output_width > winwidth
829829
lines, _ = Reline::Unicode.split_by_width(first_line, winwidth - diff_size - 3)
830830
str = "%s..." % lines.first
831-
str += "\e[0m" if @context.use_colorize
831+
str += "\e[0m" if Color.colorable?
832832
multiline_p = false
833833
else
834834
str = str.gsub(/(\A.*?\n).*/m, "\\1...")
835-
str += "\e[0m" if @context.use_colorize
835+
str += "\e[0m" if Color.colorable?
836836
end
837837
else
838838
output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)
839839
diff_size = output_width - Reline::Unicode.calculate_width(str, true)
840840
if diff_size.positive? and output_width > winwidth
841841
lines, _ = Reline::Unicode.split_by_width(str, winwidth - diff_size - 3)
842842
str = "%s..." % lines.first
843-
str += "\e[0m" if @context.use_colorize
843+
str += "\e[0m" if Color.colorable?
844844
end
845845
end
846846
end

lib/irb/cmd/ls.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module IRB
1010
module ExtendCommand
1111
class Ls < Nop
1212
def execute(*arg, grep: nil)
13-
o = Output.new(grep: grep, colorable: colorable)
13+
o = Output.new(grep: grep)
1414

1515
obj = arg.empty? ? irb_context.workspace.main : arg.first
1616
locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
@@ -45,8 +45,7 @@ def class_method_map(classes)
4545
class Output
4646
MARGIN = " "
4747

48-
def initialize(grep: nil, colorable: true)
49-
@colorable = colorable
48+
def initialize(grep: nil)
5049
@grep = grep
5150
@line_width = screen_width - MARGIN.length # right padding
5251
end
@@ -57,7 +56,7 @@ def dump(name, strs)
5756
return if strs.empty?
5857

5958
# Attempt a single line
60-
print "#{Color.colorize(name, [:BOLD, :BLUE], colorable: @colorable)}: "
59+
print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
6160
if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
6261
puts strs.join(MARGIN)
6362
return

lib/irb/cmd/nop.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,9 @@ def self.execute(conf, *opts, &block)
2929

3030
def initialize(conf)
3131
@irb_context = conf
32-
@colorable = Color.colorable? && conf.use_colorize
3332
end
3433

35-
attr_reader :irb_context, :colorable
34+
attr_reader :irb_context
3635

3736
def irb
3837
@irb_context.irb

lib/irb/cmd/show_source.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def show_source(source)
3030
puts
3131
puts "#{bold("From")}: #{source.file}:#{source.first_line}"
3232
puts
33-
code = IRB::Color.colorize_code(File.read(source.file), colorable: colorable)
33+
code = IRB::Color.colorize_code(File.read(source.file))
3434
puts code.lines[(source.first_line - 1)...source.last_line].join
3535
puts
3636
end
@@ -78,7 +78,7 @@ def find_end(file, first_line)
7878
end
7979

8080
def bold(str)
81-
Color.colorize(str, [:BOLD], colorable: colorable)
81+
Color.colorize(str, [:BOLD])
8282
end
8383

8484
Source = Struct.new(

lib/irb/color.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ module Color
7777

7878
class << self
7979
def colorable?
80-
$stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
80+
$stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb')) && IRB.conf.fetch(:USE_COLORIZE, true)
8181
end
8282

8383
def inspect_colorable?(obj, seen: {}.compare_by_identity)

lib/irb/context.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ def initialize(irb, workspace = nil, input_method = nil)
5353
else
5454
@use_multiline = nil
5555
end
56-
@use_colorize = IRB.conf[:USE_COLORIZE]
5756
@use_autocomplete = IRB.conf[:USE_AUTOCOMPLETE]
5857
@verbose = IRB.conf[:VERBOSE]
5958
@io = nil
@@ -186,8 +185,6 @@ def main
186185
attr_reader :use_singleline
187186
# Whether colorization is enabled or not.
188187
#
189-
# A copy of the default <code>IRB.conf[:USE_COLORIZE]</code>
190-
attr_reader :use_colorize
191188
# A copy of the default <code>IRB.conf[:USE_AUTOCOMPLETE]</code>
192189
attr_reader :use_autocomplete
193190
# A copy of the default <code>IRB.conf[:INSPECT_MODE]</code>
@@ -332,8 +329,6 @@ def main
332329
alias use_readline use_singleline
333330
# backward compatibility
334331
alias use_readline? use_singleline
335-
# Alias for #use_colorize
336-
alias use_colorize? use_colorize
337332
# Alias for #use_autocomplete
338333
alias use_autocomplete? use_autocomplete
339334
# Alias for #rc

lib/irb/inspector.rb

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,10 @@ def inspect_value(v)
108108

109109
Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s}
110110
Inspector.def_inspector([:p, :inspect]){|v|
111-
result = v.inspect
112-
if IRB.conf[:MAIN_CONTEXT]&.use_colorize? && Color.inspect_colorable?(v)
113-
result = Color.colorize_code(result)
114-
end
115-
result
111+
Color.colorize_code(v.inspect, colorable: Color.colorable? && Color.inspect_colorable?(v))
116112
}
117113
Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require_relative "color_printer"}){|v|
118-
if IRB.conf[:MAIN_CONTEXT]&.use_colorize?
119-
IRB::ColorPrinter.pp(v, '').chomp
120-
else
121-
v.pretty_inspect.chomp
122-
end
114+
IRB::ColorPrinter.pp(v, '').chomp
123115
}
124116
Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
125117
begin

lib/irb/workspace.rb

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -158,27 +158,20 @@ def code_around_binding
158158
end
159159
end
160160

161-
# NOT using #use_colorize? of IRB.conf[:MAIN_CONTEXT] because this method may be called before IRB::Irb#run
162-
use_colorize = IRB.conf.fetch(:USE_COLORIZE, true)
163-
if use_colorize
164-
lines = Color.colorize_code(code).lines
165-
else
166-
lines = code.lines
167-
end
161+
lines = Color.colorize_code(code).lines
168162
pos -= 1
169163

170164
start_pos = [pos - 5, 0].max
171165
end_pos = [pos + 5, lines.size - 1].min
172166

173-
if use_colorize
174-
fmt = " %2s #{Color.colorize("%#{end_pos.to_s.length}d", [:BLUE, :BOLD])}: %s"
175-
else
176-
fmt = " %2s %#{end_pos.to_s.length}d: %s"
177-
end
167+
line_number_fmt = Color.colorize("%#{end_pos.to_s.length}d", [:BLUE, :BOLD])
168+
fmt = " %2s #{line_number_fmt}: %s"
169+
178170
body = (start_pos..end_pos).map do |current_pos|
179171
sprintf(fmt, pos == current_pos ? '=>' : '', current_pos + 1, lines[current_pos])
180172
end.join("")
181-
"\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear if use_colorize}\n"
173+
174+
"\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear}\n"
182175
end
183176

184177
def IRB.delete_caller

test/irb/test_context.rb

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -145,30 +145,40 @@ def test_output_to_pipe
145145
assert_equal "=> 1\n", out
146146
end
147147

148-
def test_eval_object_without_inspect_method
149-
verbose, $VERBOSE = $VERBOSE, nil
150-
all_assertions do |all|
151-
IRB::Inspector::INSPECTORS.invert.each_value do |mode|
152-
all.for(mode) do
153-
input = TestInputMethod.new([
154-
"[BasicObject.new, Class.new]\n",
155-
])
156-
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
157-
irb.context.inspect_mode = mode
158-
out, err = capture_output do
159-
irb.eval_input
160-
end
161-
assert_empty err
162-
assert_match(/\(Object doesn't support #inspect\)\n(=> )?\n/, out)
148+
{
149+
successful: [
150+
[false, "class Foo < Struct.new(:bar); end; Foo.new(123)\n", /#<struct bar=123>/],
151+
[:p, "class Foo < Struct.new(:bar); end; Foo.new(123)\n", /#<struct bar=123>/],
152+
[true, "class Foo < Struct.new(:bar); end; Foo.new(123)\n", /#<struct #<Class:.*>::Foo bar=123>/],
153+
[:yaml, "123", /--- 123\n/],
154+
[:marshal, "123", Marshal.dump(123)],
155+
],
156+
failed: [
157+
[false, "BasicObject.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
158+
[:p, "class Foo; undef inspect ;end; Foo.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
159+
[true, "BasicObject.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
160+
[:yaml, "BasicObject.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
161+
[:marshal, "[Object.new, Class.new]", /\(Object doesn't support #inspect\)\n(=> )?\n/]
162+
]
163+
}.each do |scenario, cases|
164+
cases.each do |inspect_mode, input, expected|
165+
define_method "test_#{inspect_mode}_inspect_mode_#{scenario}" do
166+
pend if RUBY_ENGINE == 'truffleruby'
167+
verbose, $VERBOSE = $VERBOSE, nil
168+
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), TestInputMethod.new([input]))
169+
irb.context.inspect_mode = inspect_mode
170+
out, err = capture_output do
171+
irb.eval_input
163172
end
173+
assert_empty err
174+
assert_match(expected, out)
175+
ensure
176+
$VERBOSE = verbose
164177
end
165178
end
166-
ensure
167-
$VERBOSE = verbose
168179
end
169180

170181
def test_default_config
171-
assert_equal(true, @context.use_colorize?)
172182
assert_equal(true, @context.use_autocomplete?)
173183
end
174184

0 commit comments

Comments
 (0)