Class: FoodCritic::ContextOutput

Inherits:
Output
  • Object
show all
Defined in:
lib/foodcritic/output.rb

Overview

Display rule matches with surrounding context.

Instance Method Summary collapse

Methods inherited from Output

#initialize, #puts

Constructor Details

This class inherits a constructor from FoodCritic::Output

Instance Method Details

#output(review) ⇒ Object

Output the review showing matching lines with context.

Parameters:

  • review (Review)

    The review to output.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/foodcritic/output.rb', line 34

def output(review)
  unless review.respond_to?(:warnings)
    puts review; return
  end

  context = 3

  print_fn = lambda { |fn| ansi_print(fn, :red, nil, :bold) }
  print_rule = lambda { |warn| ansi_print(warn, :cyan, nil, :bold) }
  print_line = lambda { |line| ansi_print(line, nil, :red, :bold) }

  key_by_file_and_line(review).each do |fn, warnings|
    print_fn.call fn
    unless File.exist?(fn)
      print_rule.call warnings[1].to_a.join("\n")
      next
    end

    # Set of line numbers with warnings
    warn_lines = warnings.keys.to_set
    # Moving set of line numbers within the context of our position
    context_set = (0..context).to_set
    # The last line number we printed a warning for
    last_warn = -1

    File.open(fn) do |file|
      file.each do |line|
        context_set.add(file.lineno + context)
        context_set.delete(file.lineno - context - 1)

        # Find the first warning within our context
        context_warns = context_set & warn_lines
        next_warn = context_warns.min
        # We may need to interrupt the trailing context
        # of a previous warning
        next_warn = file.lineno if warn_lines.include? file.lineno

        # Display a warning
        if next_warn && next_warn > last_warn
          print_rule.call warnings[next_warn].to_a.join("\n")
          last_warn = next_warn
        end

        # Display any relevant lines
        if warn_lines.include? file.lineno
          print "%4i|" % file.lineno
          print_line.call line.chomp
        elsif not context_warns.empty?
          print "%4i|" % file.lineno
          puts line.chomp
        end
      end
    end
  end
end