|
16 | 16 | import logging |
17 | 17 | import os |
18 | 18 | import shutil |
| 19 | +import re |
19 | 20 | import tempfile |
20 | 21 | import time |
21 | 22 | import threading |
|
26 | 27 |
|
27 | 28 | MYPY = False |
28 | 29 | if MYPY: |
29 | | - from typing import Dict, DefaultDict, Iterator, List, Optional, Protocol |
| 30 | + from typing import Dict, DefaultDict, Iterator, List, Optional, Protocol, Tuple |
| 31 | + from SublimeLinter.lint.linter import VirtualView |
30 | 32 |
|
31 | 33 | class TemporaryDirectory(Protocol): |
32 | 34 | name = None # type: str |
@@ -154,6 +156,31 @@ def find_errors(self, output): |
154 | 156 | errors.append(error) |
155 | 157 | yield from errors |
156 | 158 |
|
| 159 | + def reposition_match(self, line, col, m, vv): |
| 160 | + # type: (int, Optional[int], LintMatch, VirtualView) -> Tuple[int, int, int] |
| 161 | + message = m['message'] |
| 162 | + if message.startswith('Unused "type: ignore'): |
| 163 | + text = vv.select_line(line) |
| 164 | + # Search for the type comment on the actual line in the buffer |
| 165 | + match = re.search(r"#\s*type:\s*ignore(\[.+])?", text) |
| 166 | + if match: |
| 167 | + # Probably select the whole type comment |
| 168 | + a, b = match.span() |
| 169 | + # When we have a specific rule in the error, |
| 170 | + # e.g. 'Unused "type: ignore[import]" comment' |
| 171 | + match = re.search(r"type:\s*ignore\[([^,]+)]", message) |
| 172 | + if match: |
| 173 | + # Grab the rulename, |
| 174 | + rulename = match.group(1) |
| 175 | + try: |
| 176 | + # ... and find it in the type comment |
| 177 | + a = text[a:b].index(rulename) + a |
| 178 | + b = a + len(rulename) |
| 179 | + except ValueError: |
| 180 | + pass |
| 181 | + return line, a, b |
| 182 | + return super().reposition_match(line, col, m, vv) |
| 183 | + |
157 | 184 |
|
158 | 185 | class FakeTemporaryDirectory: |
159 | 186 | def __init__(self, name): |
|
0 commit comments