1010
1111"""This module exports the ESLint plugin class."""
1212
13+ import json
1314import logging
1415import re
1516from 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