[ruby/error_highlight] Handle very long lines
https://github.com/ruby/error_highlight/commit/383490a4b4
This commit is contained in:
parent
b39b998a17
commit
5aa8b9e3b5
@ -3,6 +3,8 @@ module ErrorHighlight
|
||||
def self.message_for(spot)
|
||||
# currently only a one-line code snippet is supported
|
||||
if spot[:first_lineno] == spot[:last_lineno]
|
||||
spot = truncate(spot)
|
||||
|
||||
indent = spot[:snippet][0...spot[:first_column]].gsub(/[^\t]/, " ")
|
||||
marker = indent + "^" * (spot[:last_column] - spot[:first_column])
|
||||
|
||||
@ -11,6 +13,47 @@ module ErrorHighlight
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def self.viewport_size
|
||||
Ractor.current[:__error_highlight_viewport_size__] || terminal_columns
|
||||
end
|
||||
|
||||
def self.viewport_size=(viewport_size)
|
||||
Ractor.current[:__error_highlight_viewport_size__] = viewport_size
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.truncate(spot)
|
||||
ellipsis = '...'
|
||||
snippet = spot[:snippet]
|
||||
diff = snippet.size - (viewport_size - ellipsis.size)
|
||||
|
||||
# snippet fits in the terminal
|
||||
return spot if diff.negative?
|
||||
|
||||
if spot[:first_column] < diff
|
||||
snippet = snippet[0...snippet.size - diff]
|
||||
{
|
||||
**spot,
|
||||
snippet: snippet + ellipsis + "\n",
|
||||
last_column: [spot[:last_column], snippet.size].min
|
||||
}
|
||||
else
|
||||
{
|
||||
**spot,
|
||||
snippet: ellipsis + snippet[diff..-1],
|
||||
first_column: spot[:first_column] - (diff - ellipsis.size),
|
||||
last_column: spot[:last_column] - (diff - ellipsis.size)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def self.terminal_columns
|
||||
# lazy load io/console in case viewport_size is set
|
||||
require "io/console"
|
||||
IO.console.winsize[1]
|
||||
end
|
||||
end
|
||||
|
||||
def self.formatter
|
||||
|
@ -12,6 +12,8 @@ class ErrorHighlightTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def setup
|
||||
ErrorHighlight::DefaultFormatter.viewport_size = 80
|
||||
|
||||
if defined?(DidYouMean)
|
||||
@did_you_mean_old_formatter = DidYouMean.formatter
|
||||
DidYouMean.formatter = DummyFormatter
|
||||
@ -1285,6 +1287,30 @@ undefined method `time' for #{ ONE_RECV_MESSAGE }
|
||||
end
|
||||
end
|
||||
|
||||
def test_errors_on_small_viewports_when_error_lives_at_the_end
|
||||
assert_error_message(NoMethodError, <<~END) do
|
||||
undefined method 'gsuub' for an instance of String
|
||||
|
||||
...ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo".gsuub(//, "")
|
||||
^^^^^^
|
||||
END
|
||||
|
||||
"fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo".gsuub(//, "")
|
||||
end
|
||||
end
|
||||
|
||||
def test_errors_on_small_viewports_when_error_lives_at_the_beginning
|
||||
assert_error_message(NoMethodError, <<~END) do
|
||||
undefined method 'gsuub' for an instance of Integer
|
||||
|
||||
1.gsuub(//, "fooooooooooooooooooooooooooooooooooooooooooooooooooooooooo...
|
||||
^^^^^^
|
||||
END
|
||||
|
||||
1.gsuub(//, "fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")
|
||||
end
|
||||
end
|
||||
|
||||
def test_simulate_funcallv_from_embedded_ruby
|
||||
assert_error_message(NoMethodError, <<~END) do
|
||||
undefined method `foo' for #{ NIL_RECV_MESSAGE }
|
||||
|
Loading…
x
Reference in New Issue
Block a user