forked from SublimeLinter/SublimeLinter-annotations
-
Notifications
You must be signed in to change notification settings - Fork 0
/
linter.py
103 lines (73 loc) · 2.76 KB
/
linter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#
# linter.py
# Linter for SublimeLinter3, a code checking framework for Sublime Text 3
#
# Written by Aparajita Fishman
# Copyright (c) 2013 Aparajita Fishman
#
# License: MIT
#
"""This module exports the Annotations plugin class."""
import os
import re
from SublimeLinter.lint import highlight, Linter, persist
class Annotations(Linter):
"""Discovers and marks TODO, README, FIXME annotations."""
syntax = '*'
cmd = None
regex = '.*' # Placeholder so that linter will activate
# We use this to do the matching
match_re = r'^.*?(?P<message>(?:(?P<warning>{warnings})|(?P<error>{errors})).*)'
# We are only interested in comments
selectors = {
'*': 'comment'
}
defaults = {
'-errors:,': ['FIXME'],
'-warnings:,': ['TODO', 'README']
}
def run(self, cmd, code):
"""
Search code for annotations, mark lines that contain them.
We do the marking here since there is no point in searching
the lines twice.
We return nothing (None) to abort any further processing.
"""
options = {}
type_map = {
'errors': [],
'warnings': []
}
self.build_options(options, type_map)
for option in options:
values = []
for value in options[option]:
if value:
# Add \b word separator fences around the value
# if it begins or ends with a word character.
value = re.escape(value)
if value[0].isalnum() or value[0] == '_':
value = r'\b' + value
if value[-1].isalnum() or value[-1] == '_':
value += r'\b'
values.append(value)
options[option] = '|'.join(values)
regex = re.compile(self.match_re.format_map(options))
output = []
for i, line in enumerate(code.splitlines()):
match = regex.match(line)
if match:
col = match.start('message')
word = match.group('error')
message = match.group('message')
if word:
error_type = highlight.ERROR
else:
word = match.group('warning')
error_type = highlight.WARNING
if persist.debug_mode():
output.append('line {}, col {}: {}'.format(i + 1, col + 1, message))
self.highlight.range(i, col, length=len(word), error_type=error_type)
self.error(i, col, message, error_type)
if output and persist.debug_mode():
persist.printf('{}: {} output:\n{}'.format(self.name, os.path.basename(self.filename), '\n'.join(output)))