Class: ErrorHighlight::DefaultFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/error_highlight/formatter.rb

Constant Summary collapse

MIN_SNIPPET_WIDTH =
20

Class Method Summary collapse

Class Method Details

.max_snippet_widthObject



39
40
41
42
43
# File 'lib/error_highlight/formatter.rb', line 39

def self.max_snippet_width
  return if Ractor.current[:__error_highlight_max_snippet_width__] == :disabled

  Ractor.current[:__error_highlight_max_snippet_width__] ||= terminal_width
end

.max_snippet_width=(width) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/error_highlight/formatter.rb', line 45

def self.max_snippet_width=(width)
  return Ractor.current[:__error_highlight_max_snippet_width__] = :disabled if width.nil?

  width = width.to_i

  if width < MIN_SNIPPET_WIDTH
    warn "'max_snippet_width' adjusted to minimum value of #{MIN_SNIPPET_WIDTH}."
    width = MIN_SNIPPET_WIDTH
  end

  Ractor.current[:__error_highlight_max_snippet_width__] = width
end

.message_for(spot) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/error_highlight/formatter.rb', line 5

def self.message_for(spot)
  # currently only a one-line code snippet is supported
  return "" unless spot[:first_lineno] == spot[:last_lineno]

  snippet      = spot[:snippet]
  first_column = spot[:first_column]
  last_column  = spot[:last_column]
  ellipsis     = "..."

  # truncate snippet to fit in the viewport
  if max_snippet_width && snippet.size > max_snippet_width
    available_width = max_snippet_width - ellipsis.size
    center          = first_column - max_snippet_width / 2

    visible_start  = last_column < available_width ? 0 : [center, 0].max
    visible_end    = visible_start + max_snippet_width
    visible_start  = snippet.size - max_snippet_width if visible_end > snippet.size

    prefix = visible_start.positive?    ? ellipsis : ""
    suffix = visible_end < snippet.size ? ellipsis : ""

    snippet = prefix + snippet[(visible_start + prefix.size)...(visible_end - suffix.size)] + suffix
    snippet << "\n" unless snippet.end_with?("\n")

    first_column -= visible_start
    last_column  = [last_column - visible_start, snippet.size - 1].min
  end

  indent = snippet[0...first_column].gsub(/[^\t]/, " ")
  marker = indent + "^" * (last_column - first_column)

  "\n\n#{ snippet }#{ marker }"
end

.terminal_widthObject



58
59
60
61
62
63
64
# File 'lib/error_highlight/formatter.rb', line 58

def self.terminal_width
  # lazy load io/console, so it's not loaded when 'max_snippet_width' is set
  require "io/console"
  STDERR.winsize[1] if STDERR.tty?
rescue LoadError, NoMethodError, SystemCallError
  # do not truncate when window size is not available
end