@@ -2,55 +2,46 @@ module ErrorHighlight
22 class DefaultFormatter
33 def self . message_for ( spot )
44 # currently only a one-line code snippet is supported
5- if spot [ :first_lineno ] == spot [ :last_lineno ]
6- spot = truncate ( spot )
5+ return "" unless spot [ :first_lineno ] == spot [ :last_lineno ]
76
8- indent = spot [ :snippet ] [ 0 ...spot [ :first_column ] ] . gsub ( /[^\t ]/ , " " )
9- marker = indent + "^" * ( spot [ :last_column ] - spot [ :first_column ] )
7+ snippet = spot [ :snippet ]
8+ first_column = spot [ :first_column ]
9+ last_column = spot [ :last_column ]
1010
11- "\n \n #{ spot [ :snippet ] } #{ marker } "
12- else
13- ""
11+ # truncate snippet to fit in the viewport
12+ if snippet . size > viewport_size
13+ visible_start = [ first_column - viewport_size / 2 , 0 ] . max
14+ visible_end = visible_start + viewport_size
15+
16+ # avoid centering the snippet when the error is at the end of the line
17+ visible_start = snippet . size - viewport_size if visible_end > snippet . size
18+
19+ prefix = visible_start . positive? ? "..." : ""
20+ suffix = visible_end < snippet . size ? "..." : ""
21+
22+ snippet = prefix + snippet [ ( visible_start + prefix . size ) ...( visible_end - suffix . size ) ] + suffix
23+ snippet << "\n " unless snippet . end_with? ( "\n " )
24+
25+ first_column = first_column - visible_start
26+ last_column = [ last_column - visible_start , snippet . size - 1 ] . min
1427 end
28+
29+ indent = snippet [ 0 ...first_column ] . gsub ( /[^\t ]/ , " " )
30+ marker = indent + "^" * ( last_column - first_column )
31+
32+ "\n \n #{ snippet } #{ marker } "
1533 end
1634
1735 def self . viewport_size
18- Ractor . current [ :__error_highlight_viewport_size__ ] || terminal_columns
36+ Ractor . current [ :__error_highlight_viewport_size__ ] ||= terminal_columns
1937 end
2038
2139 def self . viewport_size = ( viewport_size )
2240 Ractor . current [ :__error_highlight_viewport_size__ ] = viewport_size
2341 end
2442
25- private
26-
27- def self . truncate ( spot )
28- ellipsis = '...'
29- snippet = spot [ :snippet ]
30- diff = snippet . size - ( viewport_size - ellipsis . size )
31-
32- # snippet fits in the terminal
33- return spot if diff . negative?
34-
35- if spot [ :first_column ] < diff
36- snippet = snippet [ 0 ...snippet . size - diff ]
37- {
38- **spot ,
39- snippet : snippet + ellipsis + "\n " ,
40- last_column : [ spot [ :last_column ] , snippet . size ] . min
41- }
42- else
43- {
44- **spot ,
45- snippet : ellipsis + snippet [ diff ..-1 ] ,
46- first_column : spot [ :first_column ] - ( diff - ellipsis . size ) ,
47- last_column : spot [ :last_column ] - ( diff - ellipsis . size )
48- }
49- end
50- end
51-
5243 def self . terminal_columns
53- # lazy load io/console in case viewport_size is set
44+ # lazy load io/console, so it's not loaded when viewport_size is set
5445 require "io/console"
5546 IO . console . winsize [ 1 ]
5647 end
0 commit comments