Skip to content

Commit 9122596

Browse files
authored
Add support for resolving workspaceDirectories (sublimelsp#30)
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
2 parents b82f9cf + a0237c0 commit 9122596

File tree

3 files changed

+82
-8
lines changed

3 files changed

+82
-8
lines changed

LSP-eslint.sublime-settings

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,15 @@
3535
"enable": true,
3636
"mode": "all"
3737
},
38+
// An optional list of working directories or a setting on how those are auto-resolved.
39+
//
40+
// This setting will normally only be set per-project to provide a list of working
41+
// directories. The server will consider those as bases for resolving // the eslint configuration.
42+
//
43+
// Refer to the `eslint.workingDirectories` documentation at https://github.com/Microsoft/vscode-eslint
44+
// for more info.
45+
//
46+
// NOTE that the `{ "pattern": glob pattern }` variant is not supported in LSP-eslint.
47+
"workingDirectories": null
3848
}
3949
}

README.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,13 @@ Open configuration file using command palette with `Preferences: LSP-eslint Sett
1313

1414
Configuration file contains multiple configuration keys:
1515

16-
#### scopes
16+
#### languages
1717

18-
Defines which scopes ESLint can run in.
19-
20-
#### syntaxes
21-
22-
Defines which syntax files ESLint can run in.
18+
Defines on which types of files the ESLint server will run.
2319

2420
#### settings
2521

26-
ESLint configuration options. Refer to [documentation for VSCode extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint).
22+
ESLint configuration options. Refer to [documentation for VSCode extension](https://github.com/Microsoft/vscode-eslint).
2723

2824
### FAQ
2925

plugin.py

Lines changed: 69 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

@@ -33,7 +37,71 @@ def on_workspace_configuration(self, params, configuration) -> None:
3337
if session:
3438
scope_uri = params.get('scopeUri')
3539
if scope_uri:
40+
workspace_folder = None
3641
for folder in session.get_workspace_folders():
3742
if folder.includes_uri(scope_uri):
38-
configuration['workspaceFolder'] = folder.to_lsp()
43+
workspace_folder = folder
3944
break
45+
if workspace_folder:
46+
configuration['workspaceFolder'] = workspace_folder.to_lsp()
47+
self.resolve_working_directory(configuration, scope_uri, workspace_folder)
48+
49+
def resolve_working_directory(self, configuration, scope_uri, workspace_folder) -> None:
50+
working_directories = configuration.get('workingDirectories', None)
51+
if isinstance(working_directories, list):
52+
working_directory = None
53+
workspace_folder_path = workspace_folder.path if workspace_folder else None
54+
for entry in working_directories:
55+
directory = None
56+
no_cwd = False
57+
if isinstance(entry, str):
58+
directory = entry
59+
elif self.is_working_directory_item(entry, 'directory'):
60+
directory = entry.directory
61+
if isinstance(entry.get('!cwd', None), bool):
62+
no_cwd = entry['!cwd']
63+
elif self.is_working_directory_item(entry, 'pattern'):
64+
print('LSP-eslint: workingDirectories configuration that uses "pattern" is not supported')
65+
continue
66+
elif self.is_mode_item(entry):
67+
working_directory = entry
68+
continue
69+
70+
directory_value = None
71+
if directory:
72+
file_path = uri_to_filename(scope_uri)
73+
if directory:
74+
directory = self.to_os_path(directory)
75+
if not os.path.isabs(directory) and workspace_folder_path:
76+
# Trailing '' will add trailing slash if missing.
77+
directory = os.path.join(workspace_folder_path, directory, '')
78+
if file_path.startswith(directory):
79+
directory_value = directory
80+
81+
if directory_value:
82+
if not working_directory or self.is_mode_item(working_directory):
83+
working_directory = { 'directory': directory_value, '!cwd': no_cwd }
84+
else:
85+
if len(working_directory['directory']) < len(directory_value):
86+
working_directory['directory'] = directory_value
87+
working_directory['!cwd'] = no_cwd
88+
configuration['workingDirectory'] = working_directory
89+
configuration.pop('workingDirectories', None)
90+
91+
def is_working_directory_item(self, item, configuration_key) -> bool:
92+
if isinstance(item, dict):
93+
value = item.get(configuration_key, None)
94+
not_cwd = item.get('!cwd', None)
95+
return isinstance(value, str) and (isinstance(not_cwd, bool) or not_cwd == None)
96+
return False
97+
98+
def is_mode_item(self, item) -> bool:
99+
if isinstance(item, dict):
100+
mode = item.get('mode', None)
101+
return isinstance(mode, str) and mode in ('auto', 'location')
102+
return False
103+
104+
def to_os_path(self, path) -> str:
105+
if sublime.platform == 'windows':
106+
path = re.sub(r'^\/(\w)\/', r'\1:\\', path)
107+
return os.path.normpath(path);

0 commit comments

Comments
 (0)