module SyntaxErrorSearch # Used for formatting invalid blocks class DisplayInvalidBlocks attr_reader :filename def initialize(block_array, io: $stderr, filename: nil) @filename = filename @io = io @blocks = block_array @lines = @blocks.map(&:lines).flatten @digit_count = @lines.last.line_number.to_s.length @code_lines = @blocks.first.code_lines @invalid_line_hash = @lines.each_with_object({}) {|line, h| h[line] = true} end def call @io.puts <<~EOM SyntaxSuggest: A syntax error was detected This code has an unmatched `end` this is caused by either missing a syntax keyword (`def`, `do`, etc.) or inclusion of an extra `end` line: EOM @io.puts(<<~EOM) if filename file: #{filename} EOM @io.puts <<~EOM #{code_with_filename} EOM end def filename def code_with_filename string = String.new("") string << "```\n" string << "#".rjust(@digit_count) + " filename: #{filename}\n\n" if filename string << code_with_lines string << "```\n" string end def code_with_lines @code_lines.map do |line| next if line.hidden? number = line.line_number.to_s.rjust(@digit_count) if line.empty? "#{number.to_s}#{line}" else string = String.new string << "\e[1;3m" if @invalid_line_hash[line] # Bold, italics string << "#{number.to_s} " string << line.to_s string << "\e[0m" string end end.join end end end