Class: SCSSLint::Linter::Indentation

Inherits:
SCSSLint::Linter
  • Object
show all
Includes:
SCSSLint::LinterRegistry
Defined in:
lib/scss_lint/linter/indentation.rb

Overview

Checks for consistent indentation of nested declarations and rule sets.

Constant Summary

Constants included from Utils

Utils::COLOR_REGEX

Instance Attribute Summary

Attributes inherited from SCSSLint::Linter

#config, #engine, #lints

Instance Method Summary collapse

Methods included from SCSSLint::LinterRegistry

extract_linters_from, included

Methods inherited from SCSSLint::Linter

inherited, #initialize, #name, #run

Methods included from Utils

#color?, #color_hex?, #color_keyword?, #color_keyword_to_code, #else_node?, #extract_string_selectors, #node_ancestor, #node_siblings, #pluralize, #previous_node, #remove_quoted_strings, #same_position?

Methods included from SelectorVisitor

#visit_selector

Constructor Details

This class inherits a constructor from SCSSLint::Linter

Instance Method Details

#check_and_visit_children(node) ⇒ Object Also known as: visit_directive, visit_each, visit_for, visit_function, visit_media, visit_mixin, visit_mixindef, visit_prop, visit_rule, visit_supports, visit_while



22
23
24
25
26
27
28
29
30
31
# File 'lib/scss_lint/linter/indentation.rb', line 22

def check_and_visit_children(node)
  # Don't continue checking children as the moment a parent's indentation is
  # off it's likely the children will be as will. We don't display the child
  # indentation problems as that would likely make the lint too noisy.
  return if check_indentation(node)

  @indent += @indent_width
  yield
  @indent -= @indent_width
end

#check_indent_width(node) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/scss_lint/linter/indentation.rb', line 43

def check_indent_width(node)
  actual_indent = node_indent(node)

  if actual_indent.include?(@other_character)
    add_lint(node.line,
             "Line should be indented with #{@indent_character}s, " \
             "not #{@other_character_name}s")
    return true
  end

  if @allow_non_nested_indentation
    check_arbitrary_indent(node, actual_indent.length)
  else
    check_regular_indent(node, actual_indent.length)
  end
end

#check_indentation(node) ⇒ Object Also known as: visit_charset, visit_content, visit_cssimport, visit_extend, visit_return, visit_variable, visit_warn



33
34
35
36
37
38
39
40
41
# File 'lib/scss_lint/linter/indentation.rb', line 33

def check_indentation(node)
  return unless node.line

  # Ignore the case where the node is on the same line as its previous
  # sibling or its parent, as indentation isn't possible
  return if nodes_on_same_line?(previous_node(node), node)

  check_indent_width(node)
end

#visit_atroot(node, &block) ⇒ Object

Need to define this explicitly since @at-root directives can contain inline selectors which produces the same parse tree as if the selector was nested within it. For example:

@at-root {
  .something {
    ...
  }
}

…and…

@at-root .something {
  ...
}

…produce the same parse tree, but result in different indentation levels.



90
91
92
93
94
95
96
97
# File 'lib/scss_lint/linter/indentation.rb', line 90

def visit_atroot(node, &block)
  if at_root_contains_inline_selector?(node)
    return if check_indentation(node)
    yield
  else
    check_and_visit_children(node, &block)
  end
end

#visit_if(node) ⇒ Object

Deal with ‘else` statements, which require special care since they are considered children of `if` statements.



62
63
64
65
66
67
68
69
70
# File 'lib/scss_lint/linter/indentation.rb', line 62

def visit_if(node)
  check_indentation(node)

  if @allow_non_nested_indentation
    yield # Continue linting else statement
  else
    visit(node.else) if node.else
  end
end

#visit_import(node) ⇒ Object



99
100
101
102
103
# File 'lib/scss_lint/linter/indentation.rb', line 99

def visit_import(node)
  prev = previous_node(node)
  return if prev.is_a?(Sass::Tree::ImportNode) && source_from_range(prev.source_range) =~ /,$/
  check_indentation(node)
end

#visit_root(_node) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/scss_lint/linter/indentation.rb', line 6

def visit_root(_node)
  @indent_width = config['width'].to_i
  @indent_character = config['character'] || 'space'
  if @indent_character == 'tab'
    @other_character = ' '
    @other_character_name = 'space'
  else
    @other_character = "\t"
    @other_character_name = 'tab'
  end
  @allow_non_nested_indentation = config['allow_non_nested_indentation']
  @indent = 0
  @indentations = {}
  yield
end