Skip to content

Commit abca79a

Browse files
committed
Rewrite regex for newer rubys
ruby -wc now shows context lines and a prettier format for syntax errors. Adjust the regex for that. Note that ruby might emit "syntax errors" (plural!) for one line, and we just read and pass the first one.
1 parent 98d279a commit abca79a

File tree

1 file changed

+32
-25
lines changed

1 file changed

+32
-25
lines changed

linter.py

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#
22
# linter.py
3-
# Linter for SublimeLinter3, a code checking framework for Sublime Text 3
3+
# Linter for SublimeLinter, a code checking framework for Sublime Text
44
#
55
# Written by Aparajita Fishman
6-
# Copyright (c) 2015-2016 The SublimeLinter Community
6+
# Copyright (c) 2015-2025 The SublimeLinter Community
77
# Copyright (c) 2013-2014 Aparajita Fishman
88
#
99
# License: MIT
@@ -23,56 +23,63 @@ class Ruby(RubyLinter):
2323
}
2424

2525
cmd = 'ruby -wc'
26-
regex = (
27-
r'^(?P<file>.+?):(?P<line>\d+): (?:(?P<error>.*?error)|(?P<warning>warning))[,:] (?P<message>[^\r\n]+)\r?\n'
28-
r'(?:^[^\r\n]+\r?\n^(?P<col>.*?)\^)?'
29-
)
30-
multiline = True
31-
comment_re = r'\s*#'
26+
regex = r"""
27+
(?xm)
28+
^(?:(?P<exe>.*:\s)?)? # optional "C:/ruby...:" prefix
29+
(?P<filename>.+?):(?P<line>\d+): # file and line
30+
(?:\s?(?:(?P<error>.*?error)s?|(?P<warning>warning))) # "syntax error" or warning
31+
[,:]?\s(?P<message>[^\n]+) # headline message
32+
(?:\n # optional multiline block
33+
(?:
34+
(?:\s*\d+\s*\|[^\n]*\n)* # optional leading context lines
35+
>\s*(?P<culprit_line>\d+)\s*\|[^\n]*\n # culprit line
36+
\s*\|\s(?P<col>.*?)\^\s # caret line with message
37+
(?P<culprit_message>[^\n]*) # rest of caret line (error text)
38+
)?
39+
)?
40+
"""
3241
on_stderr = None
3342

3443
def split_match(self, match):
3544
"""
36-
Return the components of the match.
37-
38-
We override this because unrelated library files can throw errors,
39-
and we only want errors from the linted file.
45+
Return the error as matched by the regex.
4046
47+
We override this for a better error message.
4148
"""
4249

43-
if match:
44-
if match.group('file') != '-':
45-
match = None
46-
47-
match, line, col, error, warning, message, _ = super().split_match(match)
48-
near = self.search_token(message)
50+
error = super().split_match(match)
51+
if culprit_message := error.get("culprit_message", None):
52+
error["message"] = culprit_message
53+
error["near"] = self.search_token(error.message)
54+
if error.error:
55+
error["error"] = error.error.replace(" ", "-")
4956

50-
return match, line, col, error, warning, message, near
57+
return error
5158

5259
def search_token(self, message):
5360
"""Search text token to be highlighted."""
5461

5562
# First search for variable name enclosed in quotes
56-
m = re.search("(?<=`).*(?=')", message)
63+
m = re.search(r"(?<=`).*(?=')", message)
5764

5865
# Then search for variable name following a dash
5966
if m is None:
60-
m = re.search('(?<= - )\S+', message)
67+
m = re.search(r'(?<= - )\S+', message)
6168

6269
# Then search for mismatched indentation
6370
if m is None:
64-
m = re.search("(?<=mismatched indentations at ')end", message)
71+
m = re.search(r"(?<=mismatched indentations at ')end", message)
6572

6673
# Then search for equal operator in conditional
6774
if m is None:
68-
m = re.search('(?<=found )=(?= in conditional)', message)
75+
m = re.search(r'(?<=found )=(?= in conditional)', message)
6976

7077
# Then search for use of operator in void context
7178
if m is None:
72-
m = re.search('\S+(?= in void context)', message)
79+
m = re.search(r'\S+(?= in void context)', message)
7380

7481
# Then search for END in method
7582
if m is None:
76-
m = re.search('END(?= in method)', message)
83+
m = re.search(r'END(?= in method)', message)
7784

7885
return m.group(0) if m else None

0 commit comments

Comments
 (0)