Fix wrong unreachable chunk remove when jump destination label is unremovable
[ruby.git] / lib / syntax_suggest / display_code_with_line_numbers.rb
bloba18d62e54b35205bdf94ab6a8a2dd160388bc3e7
1 # frozen_string_literal: true
3 module SyntaxSuggest
4   # Outputs code with highlighted lines
5   #
6   # Whatever is passed to this class will be rendered
7   # even if it is "marked invisible" any filtering of
8   # output should be done before calling this class.
9   #
10   #   DisplayCodeWithLineNumbers.new(
11   #     lines: lines,
12   #     highlight_lines: [lines[2], lines[3]]
13   #   ).call
14   #   # =>
15   #       1
16   #       2  def cat
17   #     > 3    Dir.chdir
18   #     > 4    end
19   #       5  end
20   #       6
21   class DisplayCodeWithLineNumbers
22     TERMINAL_HIGHLIGHT = "\e[1;3m" # Bold, italics
23     TERMINAL_END = "\e[0m"
25     def initialize(lines:, highlight_lines: [], terminal: false)
26       @lines = Array(lines).sort
27       @terminal = terminal
28       @highlight_line_hash = Array(highlight_lines).each_with_object({}) { |line, h| h[line] = true }
29       @digit_count = @lines.last&.line_number.to_s.length
30     end
32     def call
33       @lines.map do |line|
34         format_line(line)
35       end.join
36     end
38     private def format_line(code_line)
39       # Handle trailing slash lines
40       code_line.original.lines.map.with_index do |contents, i|
41         format(
42           empty: code_line.empty?,
43           number: (code_line.number + i).to_s,
44           contents: contents,
45           highlight: @highlight_line_hash[code_line]
46         )
47       end.join
48     end
50     private def format(contents:, number:, empty:, highlight: false)
51       string = +""
52       string << if highlight
53         "> "
54       else
55         "  "
56       end
58       string << number.rjust(@digit_count).to_s
59       if empty
60         string << contents
61       else
62         string << "  "
63         string << TERMINAL_HIGHLIGHT if @terminal && highlight
64         string << contents
65         string << TERMINAL_END if @terminal
66       end
67       string
68     end
69   end
70 end