diff --git a/CHANGELOG.md b/CHANGELOG.md index 7229020e..33ab95d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [Unreleased] -## [1.0.0] +## [1.1.0] - 2021-12-08 + +### Added + +- Better handling for formatting files with errors. +- Colorize the output snippet using IRB. + +## [1.0.0] - 2021-12-08 ### Added diff --git a/Gemfile.lock b/Gemfile.lock index 4094a6c8..0059156b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - syntax_tree (1.0.0) + syntax_tree (1.1.0) GEM remote: https://rubygems.org/ diff --git a/lib/syntax_tree/cli.rb b/lib/syntax_tree/cli.rb index b57b84c4..eb68214d 100644 --- a/lib/syntax_tree/cli.rb +++ b/lib/syntax_tree/cli.rb @@ -126,6 +126,9 @@ def run(filepath, source) delta = ((Time.now - start) * 1000).round puts "\r#{color} #{delta}ms" + rescue + puts "\r#{filepath}" + raise end end @@ -177,25 +180,12 @@ def run(argv) action.run(filepath, source) rescue ParseError => error warn("Error: #{error.message}") - lines = source.lines - - maximum = [error.lineno + 3, lines.length].min - digits = Math.log10(maximum).ceil - - ([error.lineno - 3, 0].max...maximum).each do |line_index| - line_number = line_index + 1 - if line_number == error.lineno - part1 = Color.red(">") - part2 = Color.gray("%#{digits}d |" % line_number) - warn("#{part1} #{part2} #{lines[line_index]}") - - part3 = Color.gray(" %#{digits}s |" % " ") - warn("#{part3} #{" " * error.column}#{Color.red("^")}") - else - prefix = Color.gray(" %#{digits}d |" % line_number) - warn("#{prefix} #{lines[line_index]}") - end + if error.lineno + highlight_error(error, source) + else + warn(error.message) + warn(error.backtrace) end errored = true @@ -232,6 +222,36 @@ def source_for(filepath) File.read(filepath, encoding: encoding) end + + # Highlights a snippet from a source and parse error. + def highlight_error(error, source) + lines = source.lines + + maximum = [error.lineno + 3, lines.length].min + digits = Math.log10(maximum).ceil + + ([error.lineno - 3, 0].max...maximum).each do |line_index| + line_number = line_index + 1 + + if line_number == error.lineno + part1 = Color.red(">") + part2 = Color.gray("%#{digits}d |" % line_number) + warn("#{part1} #{part2} #{colorize_line(lines[line_index])}") + + part3 = Color.gray(" %#{digits}s |" % " ") + warn("#{part3} #{" " * error.column}#{Color.red("^")}") + else + prefix = Color.gray(" %#{digits}d |" % line_number) + warn("#{prefix} #{colorize_line(lines[line_index])}") + end + end + end + + # Take a line of Ruby source and colorize the output. + def colorize_line(line) + require "irb" + IRB::Color.colorize_code(line, complete: false, ignore_error: true) + end end end end diff --git a/lib/syntax_tree/version.rb b/lib/syntax_tree/version.rb index 166791b6..a0428314 100644 --- a/lib/syntax_tree/version.rb +++ b/lib/syntax_tree/version.rb @@ -3,5 +3,5 @@ require "ripper" class SyntaxTree < Ripper - VERSION = "1.0.0" + VERSION = "1.1.0" end