Skip to content

Commit 9772c0f

Browse files
committed
Add support for resolving workspaceDirectories into workingDirectory
Implements code for parsing user-supplied "workspaceDirectories" setting into "workingDirectory" that server receives. The relevant code from vscode-eslint extension is here: https://github.com/microsoft/vscode-eslint/blob/a296a01afc79089c49a4f5c9c2b75831a03494b0/client/src/extension.ts#L1183-L1255 Configuring "workspaceDirectories" using patterns (rather than paths) is not supported as there is some crazy parsing code that is required for that and I didn't feel like converting that to python: https://github.com/microsoft/vscode-eslint/blob/a296a01afc79089c49a4f5c9c2b75831a03494b0/client/src/utils.ts#L77-L228 Resolves sublimelsp#18
1 parent b82f9cf commit 9772c0f

File tree

1 file changed

+83
-1
lines changed

1 file changed

+83
-1
lines changed

plugin.py

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import os
2+
import posixpath
3+
import re
4+
import sublime
25
import webbrowser
36

7+
from LSP.plugin.core.url import uri_to_filename
48
from lsp_utils import NpmClientHandler
59

610

@@ -17,6 +21,14 @@ class LspEslintPlugin(NpmClientHandler):
1721
server_directory = 'language-server'
1822
server_binary_path = os.path.join(server_directory, 'out', 'eslintServer.js')
1923

24+
@classmethod
25+
def observe_file_changes(cls):
26+
return [
27+
'**/.eslintr{c.js,c.yaml,c.yml,c,c.json}',
28+
'**/.eslintignore',
29+
'**/package.json',
30+
]
31+
2032
def on_ready(self, api) -> None:
2133
api.on_notification('eslint/status', self.handle_status)
2234
api.on_request('eslint/openDoc', self.handle_open_doc)
@@ -33,7 +45,77 @@ def on_workspace_configuration(self, params, configuration) -> None:
3345
if session:
3446
scope_uri = params.get('scopeUri')
3547
if scope_uri:
48+
workspace_folder = None
3649
for folder in session.get_workspace_folders():
3750
if folder.includes_uri(scope_uri):
38-
configuration['workspaceFolder'] = folder.to_lsp()
51+
workspace_folder = folder
3952
break
53+
if workspace_folder:
54+
configuration['workspaceFolder'] = workspace_folder.to_lsp()
55+
self.resolve_working_directory(configuration, scope_uri, workspace_folder)
56+
57+
def resolve_working_directory(self, configuration, scope_uri, workspace_folder) -> None:
58+
working_directories = configuration.get('workingDirectories', None)
59+
if isinstance(working_directories, list):
60+
working_directory = None
61+
workspace_folder_path = workspace_folder.path if workspace_folder else None
62+
for entry in working_directories:
63+
directory = None
64+
no_cwd = False
65+
if isinstance(entry, str):
66+
directory = entry
67+
elif self.is_directory_item(entry):
68+
directory = entry.directory
69+
if isinstance(entry.get('!cwd', None), bool):
70+
no_cwd = entry['!cwd']
71+
elif self.is_pattern_item(entry):
72+
print('LSP-eslint: workingDirectories configuration that uses "pattern" is not supported')
73+
pass
74+
elif self.is_mode_item(entry):
75+
working_directory = entry
76+
continue
77+
78+
directory_value = None
79+
if directory:
80+
file_path = uri_to_filename(scope_uri)
81+
if directory:
82+
directory = self.to_os_path(directory)
83+
if not os.path.isabs(directory) and workspace_folder_path:
84+
# Trailing '' will add trailing slash if missing.
85+
directory = os.path.join(workspace_folder_path, directory, '')
86+
if file_path.startswith(directory):
87+
directory_value = directory
88+
89+
if directory_value:
90+
if not working_directory or self.is_mode_item(working_directory):
91+
working_directory = { 'directory': directory_value, '!cwd': no_cwd }
92+
else:
93+
if len(working_directory['directory']) < len(directory_value):
94+
working_directory['directory'] = directory_value
95+
working_directory['!cwd'] = no_cwd
96+
configuration['workingDirectory'] = working_directory
97+
98+
def is_directory_item(self, item) -> bool:
99+
if isinstance(item, dict):
100+
directory = item.get('directory', None)
101+
not_cwd = item.get('!cwd', None)
102+
return isinstance(directory, str) and (isinstance(not_cwd, bool) or not_cwd == None)
103+
return False
104+
105+
def is_pattern_item(self, item) -> bool:
106+
if isinstance(item, dict):
107+
pattern = item.get('pattern', None)
108+
not_cwd = item.get('!cwd', None)
109+
return isinstance(pattern, str) and (isinstance(not_cwd, bool) or not_cwd == None)
110+
return False
111+
112+
def is_mode_item(self, item) -> bool:
113+
if isinstance(item, dict):
114+
mode = item.get('mode', None)
115+
return isinstance(mode, str) and mode in ('auto', 'location')
116+
return False
117+
118+
def to_os_path(self, path) -> str:
119+
if sublime.platform == 'windows':
120+
path = re.sub(r'^\/(\w)\/', r'\1:\\', path)
121+
return os.path.normpath(path);

0 commit comments

Comments
 (0)