Skip to content

Commit

Permalink
Implement lint and return LintError directly
Browse files Browse the repository at this point in the history
Instead of creating and then parsing a string with a regular expression,
we can instead build and return a list of `LintError`s (a typed dict)
directly and skip some indirection.

I am not sure if `lint` is *supposed* to be overridden like this, but I
do remember advocating for it a couple years ago when the change for a
proper data structure for lint results was discussed. It just now
happened to be a convenient way to implement end markers for the
highlighted region.

In this particular instance, it allows us to specify a full region for
marking the error, where we now specify the entire match including the
remainder of the comment instead of just the trigger word. This can be
changed, of course, but I figured it wouldn't be a bad idea initially.
  • Loading branch information
FichteFoll committed Dec 19, 2021
1 parent 3ed8124 commit e926483
Showing 1 changed file with 28 additions and 12 deletions.
40 changes: 28 additions & 12 deletions linter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"""This module exports the Annotations plugin class."""

import re
from SublimeLinter.lint import Linter, ERROR, WARNING

import sublime
from SublimeLinter.lint import Linter, ERROR, WARNING, util


def _escape_words(values):
Expand All @@ -37,11 +39,6 @@ class Annotations(Linter):

cmd = None
line_col_base = (0, 0)
regex = (
r'^(?P<line>\d+):(?P<col>\d+):'
r' (?P<error_type>.+?) \((?P<code>.+)\):'
r' (?P<message>.*)'
)

# We use this to do the matching
mark_regex_template = r'(?:(?P<info>{infos})|(?P<warning>{warnings})|(?P<error>{errors})):?\s*(?P<message>.*)'
Expand All @@ -54,7 +51,13 @@ class Annotations(Linter):
'infos': ['NOTE', 'README', 'INFO'],
}

def run(self, cmd, code):
def lint(self, _code, _view_has_changed):
self.logger.info(
"%s: linting '%s'",
self.name,
util.canonical_filename(self.view),
)

options = {}
for option in ('errors', 'warnings', 'infos'):
words = self.settings.get(option)
Expand All @@ -63,7 +66,7 @@ def run(self, cmd, code):
mark_regex = re.compile(self.mark_regex_template.format_map(options))

output = []
regions = self.view.find_by_selector('comment - punctuation.definition.comment')
regions = self.view.find_by_selector(self.settings['comment_selector'])

for region in regions:
region_offset = self.view.rowcol(region.a)
Expand All @@ -76,6 +79,7 @@ def run(self, cmd, code):
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)
match_region = sublime.Region(region.a + match.start(), region.a + match.end())
message = match.group('message').strip() or '<no message>'
word = match.group('error')
if word:
Expand All @@ -88,7 +92,19 @@ def run(self, cmd, code):
word = match.group('info')
error_type = 'info'

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

return '\n'.join(output)
output.append(dict(
line=row,
start=col,
region=match_region,
# linter=,
error_type=error_type,
code=word,
msg=message,
filename=util.get_filename(self.view),
# uid=,
# priority=,
# panel_line=,
offending_text=word,
))

return output

0 comments on commit e926483

Please sign in to comment.