aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-05-28 18:19:59 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-05-29 12:12:19 +0900
commitc7f3c222c9b82736c993419daa6bfb643e5c0793 (patch)
treefad75ae38f6742360160076ef4670ffdd83698ef
parent34fe1f7d719d556cd7eda16d4df7cc64ce25dcfa (diff)
downloadruby-c7f3c222c9b82736c993419daa6bfb643e5c0793.tar.gz
Colorize error part more
Colorize `compile_error` parts as well as `on_parse_error` parts.
-rw-r--r--lib/irb/color.rb39
1 files changed, 28 insertions, 11 deletions
diff --git a/lib/irb/color.rb b/lib/irb/color.rb
index aa4c60aa12..df3c4ff63d 100644
--- a/lib/irb/color.rb
+++ b/lib/irb/color.rb
@@ -56,7 +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],
+ ERROR: [[RED, REVERSE], ALL],
}
rescue NameError
# Give up highlighting Ripper-incompatible older Ruby
@@ -66,9 +66,16 @@ module IRB # :nodoc:
class Lexer < Ripper::Lexer
if method_defined?(:token)
- def on_parse_error(mesg)
- @buf.push Elem.new([lineno(), column()], __callee__, token(), state())
+ def self.lex(code)
+ new(code).parse.sort_by {|elem| elem.pos.dup << elem.event}
end
+
+ def on_error(mesg)
+ # :ERROR comes before other :on_ symbols
+ @buf.push Elem.new([lineno(), column()], :ERROR, token(), state())
+ end
+ alias compile_error on_error
+ alias on_parse_error on_error
end
end
@@ -110,25 +117,33 @@ module IRB # :nodoc:
symbol_state = SymbolState.new
colored = +''
length = 0
+ pos = [1, 0]
- Lexer.new(code).parse.sort_by(&:pos).each do |elem|
+ Lexer.lex(code).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|
+ next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0
+ Reline::Unicode.escape_for_print(str).each_line do |line|
+ if seq = dispatch_seq(token, expr, str, in_symbol: in_symbol)
colored << seq.map { |s| "\e[#{s}m" }.join('')
colored << line.sub(/\Z/, clear)
+ else
+ colored << line
+ end
+ if line.end_with?("\n")
+ pos[0] += 1
+ pos[1] = 0
+ else
+ pos[1] += line.bytesize
end
- else
- colored << Reline::Unicode.escape_for_print(str)
end
- length += str.length
+ length += str.bytesize
end
# give up colorizing incomplete Ripper tokens
- return code if length != code.length
+ return code if length != code.bytesize
colored
end
@@ -136,7 +151,9 @@ module IRB # :nodoc:
private
def dispatch_seq(token, expr, str, in_symbol:)
- if in_symbol
+ if token == :ERROR
+ TOKEN_SEQ_EXPRS[token][0]
+ elsif in_symbol
[YELLOW]
elsif TOKEN_KEYWORDS.fetch(token, []).include?(str)
[CYAN, BOLD]