|
22 | 22 |
|
23 | 23 | MYPY = False
|
24 | 24 | if MYPY:
|
25 |
| - from typing import List, Union |
| 25 | + from typing import List, Optional, Union |
26 | 26 |
|
27 | 27 |
|
28 | 28 | logger = logging.getLogger('SublimeLinter.plugin.eslint')
|
|
37 | 37 | '@angular-eslint/eslint-plugin': 'text.html',
|
38 | 38 | '@typescript-eslint/parser': 'source.ts, source.tsx',
|
39 | 39 | 'tsdx': 'source.ts, source.tsx',
|
| 40 | + 'eslint-plugin-yml': 'source.yaml', |
| 41 | + 'eslint-plugin-yaml': 'source.yaml', |
40 | 42 | }
|
41 | 43 | OPTIMISTIC_SELECTOR = ', '.join({STANDARD_SELECTOR} | set(PLUGINS.values()))
|
42 | 44 |
|
| 45 | +BUFFER_FILE_STEM = '__buffer__' |
| 46 | +BUFFER_FILE_EXTENSIONS = { |
| 47 | + 'source.js': 'js', |
| 48 | + 'source.jsx': 'jsx', |
| 49 | + 'text.html': 'html', |
| 50 | + 'text.html.vue': 'vue', |
| 51 | + 'source.ts': 'ts', |
| 52 | + 'source.tsx': 'tsx', |
| 53 | + 'source.json': 'json', |
| 54 | + 'source.yaml': 'yaml', |
| 55 | +} |
| 56 | + |
43 | 57 |
|
44 | 58 | class ESLint(NodeLinter):
|
45 | 59 | """Provides an interface to the eslint executable."""
|
46 | 60 |
|
47 |
| - cmd = 'eslint --format json --stdin' |
48 |
| - |
49 | 61 | missing_config_regex = re.compile(
|
50 | 62 | r'^(.*?)\r?\n\w*(ESLint couldn\'t find a configuration file.)',
|
51 | 63 | re.DOTALL
|
52 | 64 | )
|
53 | 65 | line_col_base = (1, 1)
|
54 | 66 | defaults = {
|
55 | 67 | 'selector': OPTIMISTIC_SELECTOR,
|
56 |
| - '--stdin-filename': '${file}', |
57 | 68 | 'prefer_eslint_d': True,
|
58 | 69 | }
|
59 | 70 |
|
| 71 | + def cmd(self): |
| 72 | + cmd = ['eslint', '--format=json', '--stdin'] |
| 73 | + stdin_filename = self.get_stdin_filename() |
| 74 | + if stdin_filename: |
| 75 | + cmd.append('--stdin-filename=' + stdin_filename) |
| 76 | + return cmd |
| 77 | + |
60 | 78 | def run(self, cmd, code):
|
61 | 79 | # Workaround eslint bug https://github.com/eslint/eslint/issues/9515
|
62 | 80 | # Fixed in eslint 4.10.0
|
@@ -120,6 +138,17 @@ def ensure_plugin_installed(self) -> bool:
|
120 | 138 | self.notify_unassign() # Abort linting without popping error dialog
|
121 | 139 | raise PermanentError()
|
122 | 140 |
|
| 141 | + def get_stdin_filename(self): |
| 142 | + # type: () -> Optional[str] |
| 143 | + filename = self.view.file_name() |
| 144 | + if filename is None: |
| 145 | + view_selectors = set(self.view.scope_name(0).split(' ')) |
| 146 | + for selector in BUFFER_FILE_EXTENSIONS.keys(): |
| 147 | + if selector in view_selectors: |
| 148 | + filename = '.'.join([BUFFER_FILE_STEM, BUFFER_FILE_EXTENSIONS[selector]]) |
| 149 | + break |
| 150 | + return filename |
| 151 | + |
123 | 152 | def find_local_executable(self, start_dir, npm_name):
|
124 | 153 | # type: (str, str) -> Union[None, str, List[str]]
|
125 | 154 | """Automatically switch to `eslint_d` if available (and wanted)."""
|
@@ -177,6 +206,8 @@ def find_errors(self, output):
|
177 | 206 | filename = entry.get('filePath', None)
|
178 | 207 | if filename == '<text>':
|
179 | 208 | filename = 'stdin'
|
| 209 | + elif filename and os.path.basename(filename).startswith(BUFFER_FILE_STEM + '.'): |
| 210 | + filename = 'stdin' |
180 | 211 |
|
181 | 212 | for match in entry['messages']:
|
182 | 213 | if match['message'].startswith('File ignored'):
|
|
0 commit comments