From 8a2a5822caa7a9fc146d7de4db679986603d7a4f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 27 May 2019 19:59:17 +0900 Subject: Colorize error part --- lib/irb/color.rb | 18 ++++++++++++++++-- test/irb/test_color.rb | 4 +++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/irb/color.rb b/lib/irb/color.rb index de91f29a12..aa4c60aa12 100644 --- a/lib/irb/color.rb +++ b/lib/irb/color.rb @@ -7,6 +7,7 @@ module IRB # :nodoc: CLEAR = 0 BOLD = 1 UNDERLINE = 4 + REVERSE = 7 RED = 31 GREEN = 32 YELLOW = 33 @@ -55,6 +56,7 @@ module IRB # :nodoc: on_tstring_content: [[RED], ALL], on_tstring_end: [[RED], ALL], on_words_beg: [[RED], ALL], + on_parse_error: [[RED, REVERSE], ALL], } rescue NameError # Give up highlighting Ripper-incompatible older Ruby @@ -62,6 +64,14 @@ module IRB # :nodoc: end private_constant :TOKEN_SEQ_EXPRS + class Lexer < Ripper::Lexer + if method_defined?(:token) + def on_parse_error(mesg) + @buf.push Elem.new([lineno(), column()], __callee__, token(), state()) + end + end + end + class << self def colorable? $stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb')) @@ -101,11 +111,15 @@ module IRB # :nodoc: colored = +'' length = 0 - Ripper.lex(code).each do |(_line, _col), token, str, expr| + Lexer.new(code).parse.sort_by(&:pos).each do |elem| + token = elem.event + str = elem.tok + expr = elem.state in_symbol = symbol_state.scan_token(token) if seq = dispatch_seq(token, expr, str, in_symbol: in_symbol) Reline::Unicode.escape_for_print(str).each_line do |line| - colored << "#{seq.map { |s| "\e[#{s}m" }.join('')}#{line.sub(/\n?\z/, "#{clear}\\0")}" + colored << seq.map { |s| "\e[#{s}m" }.join('') + colored << line.sub(/\Z/, clear) end else colored << Reline::Unicode.escape_for_print(str) diff --git a/test/irb/test_color.rb b/test/irb/test_color.rb index 4342a7ca6f..8059b81430 100644 --- a/test/irb/test_color.rb +++ b/test/irb/test_color.rb @@ -9,6 +9,7 @@ module TestIRB CLEAR = "\e[0m" BOLD = "\e[1m" UNDERLINE = "\e[4m" + REVERSE = "\e[7m" RED = "\e[31m" GREEN = "\e[32m" YELLOW = "\e[33m" @@ -37,7 +38,7 @@ module TestIRB '"foo#{a} #{b}"' => "#{RED}\"#{CLEAR}#{RED}foo#{CLEAR}#{RED}\#{#{CLEAR}a#{RED}}#{CLEAR}#{RED} #{CLEAR}#{RED}\#{#{CLEAR}b#{RED}}#{CLEAR}#{RED}\"#{CLEAR}", '/r#{e}g/' => "#{RED}#{BOLD}/#{CLEAR}#{RED}r#{CLEAR}#{RED}\#{#{CLEAR}e#{RED}}#{CLEAR}#{RED}g#{CLEAR}#{RED}#{BOLD}/#{CLEAR}", "'a\nb'" => "#{RED}'#{CLEAR}#{RED}a#{CLEAR}\n#{RED}b#{CLEAR}#{RED}'#{CLEAR}", - "4.5.6" => "4.5.6", + "4.5.6" => "#{MAGENTA}#{BOLD}4.5#{CLEAR}#{RED}#{REVERSE}.6#{CLEAR}", "[1]]]" => "[1]]]", "\e[0m\n" => "^[[#{BLUE}#{BOLD}0#{CLEAR}m\n", "%w[a b]" => "#{RED}%w[#{CLEAR}#{RED}a#{CLEAR} #{RED}b#{CLEAR}#{RED}]#{CLEAR}", @@ -111,6 +112,7 @@ module TestIRB .gsub(CLEAR, '@@@{CLEAR}') .gsub(BOLD, '@@@{BOLD}') .gsub(UNDERLINE, '@@@{UNDERLINE}') + .gsub(REVERSE, '@@@{REVERSE}') .gsub(RED, '@@@{RED}') .gsub(GREEN, '@@@{GREEN}') .gsub(YELLOW, '@@@{YELLOW}') -- cgit v1.2.3