Skip to content

Commit

Permalink
Merge pull request #18 from FichteForks/pr/word-as-code
Browse files Browse the repository at this point in the history
Various improvements and cleanups
  • Loading branch information
kaste authored Mar 23, 2018
2 parents a3f0473 + 71a2682 commit 7c5854d
Showing 1 changed file with 47 additions and 46 deletions.
93 changes: 47 additions & 46 deletions linter.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,73 +24,74 @@
WARNING = highlight.WARNING


def _escape_words(values):
if not values:
return
for value in values:
# 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'

yield value


class Annotations(Linter):
"""Discovers and marks FIXME, NOTE, README, TODO, @todo, and XXX annotations."""

syntax = '*'
cmd = None
regex = re.compile(r'^(?P<line>\d+):(?P<col>\d+): ((?P<warning>warning)|(?P<error>error)) (?P<message>.*)')
line_col_base = (0, 0)
regex = re.compile(r'^(?P<line>\d+):(?P<col>\d+):'
r' (warning \((?P<warning>.+?)\)|error \((?P<error>.+?)\)):'
r' (?P<message>.*)')

# 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'
}
mark_regex_template = r'(?:(?P<warning>{warnings})|(?P<error>{errors})):?\s*(?P<message>.*)'

# Words to look for
defaults = {
'-errors:,': ['FIXME'],
'-warnings:,': ['NOTE', 'README', 'TODO', '@todo', 'XXX', 'WIP']
'errors': ['FIXME'],
'warnings': ['NOTE', 'README', 'TODO', '@todo', 'XXX', 'WIP'],
}

def run(self, cmd, code):

settings = self.get_view_settings()
options = {}
type_map = {
'errors': [],
'warnings': []
}

self.build_options(options, type_map)
for option in ('errors', 'warnings'):
words = settings.get(option)
options[option] = '|'.join(_escape_words(words))

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)

match_regex = re.compile(self.match_re.format_map(options))
mark_regex = re.compile(self.mark_regex_template.format_map(options))

output = []

for i, line in enumerate(code.splitlines()):
match = match_regex.match(line)

if match:
col = match.start('message')
regions = self.view.find_by_selector('comment - punctuation.definition.comment')

for region in regions:
region_offset = self.view.rowcol(region.a)
region_text = self.view.substr(region)
for i, line in enumerate(region_text.splitlines()):
match = mark_regex.search(line)
if not match:
continue

row = region_offset[0] + i
# Need to account for region column offset only in first row
col = match.start() + (region_offset[1] if i == 0 else 0)
message = match.group('message').strip() or '<no message>'
word = match.group('error')
message = match.group('message')

if word:
error_type = ERROR
else:
word = match.group('warning')
error_type = WARNING

output.append('{}:{}: {} {}'.format(i + 1, col + 1, error_type, message))
output.append('{row}:{col}: {error_type} ({word}): {message}'
.format(**locals()))

return ''.join(output)
return '\n'.join(output)

0 comments on commit 7c5854d

Please sign in to comment.