1010
1111"""This module exports the ESLint plugin class."""
1212
13+ import json
1314import logging
1415import re
1516from SublimeLinter .lint import NodeLinter
@@ -23,13 +24,8 @@ class ESLint(NodeLinter):
2324
2425 syntax = ('javascript' , 'html' )
2526 npm_name = 'eslint'
26- cmd = ('eslint' , '--format' , 'compact ' , '--stdin' , '--stdin-filename' , '@' )
27+ cmd = ('eslint' , '--format' , 'json ' , '--stdin' , '--stdin-filename' , '@' )
2728
28- regex = (
29- r'^.+?: line (?P<line>\d+), col (?P<col>\d+), '
30- r'(?:(?P<error>Error)|(?P<warning>Warning)) - '
31- r'(?P<message>.+)'
32- )
3329 crash_regex = re .compile (
3430 r'^(.*?)\r?\n\w*(Oops! Something went wrong!)' ,
3531 re .DOTALL
@@ -47,17 +43,44 @@ def find_errors(self, output):
4743 match = self .crash_regex .match (output )
4844 if match :
4945 logger .error (output )
50- return []
46+ return
5147
52- return super (). find_errors (output )
48+ content = json . loads (output )
5349
54- def split_match (self , match ):
55- """Extract and return values from match.
50+ if logger .isEnabledFor (logging .INFO ):
51+ import pprint
52+ logger .info (
53+ '{} output:\n {}' .format (self .name , pprint .pformat (content )))
5654
57- Return 'no match' for ignored files
58- """
59- match , line , col , error , warning , message , near = super ().split_match (match )
60- if message and message .startswith ('File ignored' ):
61- return match , None , None , None , None , '' , None
55+ for entry in content :
56+ for match in entry ['messages' ]:
57+ if match ['message' ].startswith ('File ignored' ):
58+ continue
59+
60+ yield (
61+ match ,
62+ match ['line' ] - 1 , # apply line_col_base manually
63+ match ['column' ] - 1 ,
64+ match ['ruleId' ] if match ['severity' ] == 2 else '' ,
65+ match ['ruleId' ] if match ['severity' ] == 1 else '' ,
66+ match ['message' ],
67+ None # near
68+ )
69+
70+ def reposition_match (self , line , col , m , vv ):
71+ match = m .match
72+ if match .get ('fatal' , False ): # parse error
73+ text = vv .select_line (line )
74+ return line , 0 , len (text ) # select whole line?
75+ return super ().reposition_match (line , col , m , vv )
76+
77+ # apply line_col_base manually
78+ end_line = match .get ('endLine' , line + 1 ) - 1
79+ # to ensure a length of 1, add 2 to the starting col
80+ end_column = match .get ('endColumn' , col + 2 ) - 1
81+
82+ for _line in range (line , end_line ):
83+ text = vv .select_line (_line )
84+ end_column += len (text )
6285
63- return match , line , col , error , warning , message , near
86+ return line , col , end_column
0 commit comments