All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
3 This script checks for missing or forbidden blank lines before or after
4 particular Vim commands. This script ensures that VimL scripts are padded
5 correctly, so they are easier to read.
11 INDENTATION_RE = re.compile(r'^ *')
12 COMMENT_LINE_RE = re.compile(r'^ *"')
13 COMMAND_RE = re.compile(r'^ *([a-zA-Z\\]+)')
14 OPERATOR_END_RE = re.compile(r'(&&|\|\||\+|-|\*\| /)$')
16 START_BLOCKS = set(['if', 'for', 'while', 'try', 'function'])
17 END_BLOCKS = set(['endif', 'endfor', 'endwhile', 'endtry', 'endfunction'])
18 MIDDLE_BLOCKS = set(['else', 'elseif', 'catch', 'finally'])
19 TERMINATORS = set(['return', 'throw'])
21 WHITESPACE_BEFORE_SET = START_BLOCKS | TERMINATORS
22 WHITESPACE_FORBIDDEN_BEFORE_SET = END_BLOCKS | MIDDLE_BLOCKS
23 WHITESPACE_AFTER_SET = END_BLOCKS
24 WHITESPACE_FORBIDDEN_AFTER_SET = START_BLOCKS | MIDDLE_BLOCKS
25 SAME_INDENTATION_SET = set(['\\'])
28 def remove_comment_lines(line_iter):
29 for line_number, line in enumerate(line_iter, 1):
30 if not COMMENT_LINE_RE.match(line):
31 yield (line_number, line)
34 def check_lines(line_iter):
35 previous_indentation_level = None
36 previous_command = None
37 previous_line_blank = False
39 for line_number, line in remove_comment_lines(line_iter):
41 # Check for commands where we shouldn't have blank lines after
42 # them, like `else` or the start of blocks like `function`.
44 previous_command is not None
45 and previous_command in WHITESPACE_FORBIDDEN_AFTER_SET
49 'Blank line forbidden after `%s`' % (previous_command,)
52 previous_line_blank = True
53 previous_command = None
55 indentation_level = INDENTATION_RE.match(line).end()
56 command_match = COMMAND_RE.match(line)
59 command = command_match.group(1)
62 command in SAME_INDENTATION_SET
63 and previous_indentation_level is not None
64 and indentation_level != previous_indentation_level
68 'Line continuation should match previous indentation'
72 previous_indentation_level is not None
73 and indentation_level != previous_indentation_level
74 and abs(indentation_level - previous_indentation_level) != 4 # noqa
78 'Indentation should be 4 spaces'
81 # Check for commands requiring blank lines before them, if they
82 # aren't at the start of a block.
84 command in WHITESPACE_BEFORE_SET
85 and previous_indentation_level is not None
86 and indentation_level == previous_indentation_level
87 and previous_line_blank is False
91 'Blank line required before `%s`' % (command,)
94 # Check for commands where we shouldn't have blank lines before
95 # them, like `else` or the end of blocks like `endfunction`.
97 command in WHITESPACE_FORBIDDEN_BEFORE_SET
98 and previous_line_blank is True
102 'Blank line forbidden before `%s`' % (command,)
105 # Check for commands requiring blank lines after them, if they
106 # aren't at the end of a block.
108 previous_command is not None
109 and previous_command in WHITESPACE_AFTER_SET
110 and previous_indentation_level is not None
111 and indentation_level == previous_indentation_level
112 and previous_line_blank is False
116 'Blank line required after `%s`' % (command,)
119 previous_command = command
120 previous_line_blank = False
121 previous_indentation_level = indentation_level
123 if OPERATOR_END_RE.search(line):
126 'Put operators at the start of lines instead'
133 for filename in sys.argv[1:]:
134 with open(filename) as vim_file:
135 line_iter = (line.rstrip() for line in vim_file)
137 for line_number, message in check_lines(line_iter):
138 print('%s:%d %s' % (filename, line_number, message))
144 if __name__ == "__main__":