Skip to content

Commit a86fe6b

Browse files
authored
Merge pull request #196 from SublimeLinter/format-json
Experiment: Use JSON format and provided endLine and endColumn for highlights
2 parents 018178b + 8ac4270 commit a86fe6b

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

linter.py

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
"""This module exports the ESLint plugin class."""
1212

13+
import json
1314
import logging
1415
import re
1516
from SublimeLinter.lint import NodeLinter
@@ -22,13 +23,8 @@ class ESLint(NodeLinter):
2223
"""Provides an interface to the eslint executable."""
2324

2425
npm_name = 'eslint'
25-
cmd = ('eslint', '--format', 'compact', '--stdin', '--stdin-filename', '@')
26+
cmd = ('eslint', '--format', 'json', '--stdin', '--stdin-filename', '@')
2627

27-
regex = (
28-
r'^.+?: line (?P<line>\d+), col (?P<col>\d+), '
29-
r'(?:(?P<error>Error)|(?P<warning>Warning)) - '
30-
r'(?P<message>.+)'
31-
)
3228
crash_regex = re.compile(
3329
r'^(.*?)\r?\n\w*(Oops! Something went wrong!)',
3430
re.DOTALL
@@ -46,17 +42,44 @@ def find_errors(self, output):
4642
match = self.crash_regex.match(output)
4743
if match:
4844
logger.error(output)
49-
return []
45+
return
5046

51-
return super().find_errors(output)
47+
content = json.loads(output)
5248

53-
def split_match(self, match):
54-
"""Extract and return values from match.
49+
if logger.isEnabledFor(logging.INFO):
50+
import pprint
51+
logger.info(
52+
'{} output:\n{}'.format(self.name, pprint.pformat(content)))
5553

56-
Return 'no match' for ignored files
57-
"""
58-
match, line, col, error, warning, message, near = super().split_match(match)
59-
if message and message.startswith('File ignored'):
60-
return match, None, None, None, None, '', None
54+
for entry in content:
55+
for match in entry['messages']:
56+
if match['message'].startswith('File ignored'):
57+
continue
58+
59+
yield (
60+
match,
61+
match['line'] - 1, # apply line_col_base manually
62+
match['column'] - 1,
63+
match['ruleId'] if match['severity'] == 2 else '',
64+
match['ruleId'] if match['severity'] == 1 else '',
65+
match['message'],
66+
None # near
67+
)
68+
69+
def reposition_match(self, line, col, m, vv):
70+
match = m.match
71+
if match.get('fatal', False): # parse error
72+
text = vv.select_line(line)
73+
return line, 0, len(text) # select whole line?
74+
return super().reposition_match(line, col, m, vv)
75+
76+
# apply line_col_base manually
77+
end_line = match.get('endLine', line + 1) - 1
78+
# to ensure a length of 1, add 2 to the starting col
79+
end_column = match.get('endColumn', col + 2) - 1
80+
81+
for _line in range(line, end_line):
82+
text = vv.select_line(_line)
83+
end_column += len(text)
6184

62-
return match, line, col, error, warning, message, near
85+
return line, col, end_column

0 commit comments

Comments
 (0)