diff --git a/lib/irb/color.rb b/lib/irb/color.rb index 0f49291d85..56f5c4c625 100644 --- a/lib/irb/color.rb +++ b/lib/irb/color.rb @@ -107,7 +107,7 @@ module IRB # :nodoc: # If `complete` is false (code is incomplete), this does not warn compile_error. # This option is needed to avoid warning a user when the compile_error is happening # because the input is not wrong but just incomplete. - def colorize_code(code, complete: true) + def colorize_code(code, complete: true, ignore_error: false) return code unless colorable? symbol_state = SymbolState.new @@ -118,7 +118,7 @@ module IRB # :nodoc: in_symbol = symbol_state.scan_token(token) str.each_line do |line| line = Reline::Unicode.escape_for_print(line) - if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol) + if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol, ignore_error: ignore_error) colored << seq.map { |s| "\e[#{s}m" }.join('') colored << line.sub(/\Z/, clear) else @@ -183,9 +183,9 @@ module IRB # :nodoc: $VERBOSE = verbose end - def dispatch_seq(token, expr, str, in_symbol:) + def dispatch_seq(token, expr, str, in_symbol:, ignore_error:) if token == :on_parse_error or token == :compile_error - TOKEN_SEQ_EXPRS[token][0] + ignore_error ? nil : TOKEN_SEQ_EXPRS[token][0] elsif in_symbol [YELLOW] elsif TOKEN_KEYWORDS.fetch(token, []).include?(str) diff --git a/lib/irb/color_printer.rb b/lib/irb/color_printer.rb new file mode 100644 index 0000000000..187c337187 --- /dev/null +++ b/lib/irb/color_printer.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true +require 'pp' + +module IRB + class ColorPrinter < ::PP + def self.pp(obj, out = $>, width = 79) + q = ColorPrinter.new(out, width) + q.guard_inspect_key {q.pp obj} + q.flush + out + end + + def text(str, width = str.length) + case str + when /\A#' + super(Color.colorize(str, [:GREEN]), width) + else + super(Color.colorize_code(str, ignore_error: true), width) + end + end + end +end diff --git a/lib/irb/inspector.rb b/lib/irb/inspector.rb index 671b32b6e8..66837f1390 100644 --- a/lib/irb/inspector.rb +++ b/lib/irb/inspector.rb @@ -104,7 +104,7 @@ module IRB # :nodoc: end Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s} - Inspector.def_inspector([true, :p, :inspect]){|v| + Inspector.def_inspector([:p, :inspect]){|v| begin result = v.inspect if IRB.conf[:MAIN_CONTEXT]&.use_colorize? && Color.inspect_colorable?(v) @@ -116,12 +116,12 @@ module IRB # :nodoc: '' end } - Inspector.def_inspector([:pp, :pretty_inspect], proc{require "pp"}){|v| - result = v.pretty_inspect.chomp - if IRB.conf[:MAIN_CONTEXT]&.use_colorize? && Color.inspect_colorable?(v) - result = Color.colorize_code(result) + Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require "irb/color_printer"}){|v| + if IRB.conf[:MAIN_CONTEXT]&.use_colorize? + IRB::ColorPrinter.pp(v, '') + else + v.pretty_inspect.chomp end - result } Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v| begin