Skip to content

Commit db9b055

Browse files
authored
Initialize workspaces from the initialize request (#49)
* Initialize workspaces from the initialize request Don't ignore workspace folders provided through the initialize request expecting that the client sends the workspace/didChangeWorkspaceFolders notification. Expecting that notification is a bug since it only needs to be sent when folders change, relative to the ones reported in initialize. Fixes #48 * fix reporter pylint issues
1 parent 7ddf562 commit db9b055

File tree

5 files changed

+87
-3
lines changed

5 files changed

+87
-3
lines changed

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ __pycache__/
33
*.py[cod]
44
*$py.class
55

6+
# Mypy cache
7+
.mypy_cache/
8+
69
# IntelliJ
710
*.iml
811
*.ipr

Diff for: README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ All configuration options are described in [`CONFIGURATION.md`](https://github.c
8484

8585
To run the test suite:
8686

87-
```
88-
pip install .[test] && pytest
87+
```sh
88+
pip install '.[test]' && pytest
8989
```
9090

9191
After adding configuration options to `schema.json`, refresh the `CONFIGURATION.md` file with

Diff for: pylsp/python_lsp.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ def capabilities(self):
199199
log.info('Server capabilities: %s', server_capabilities)
200200
return server_capabilities
201201

202-
def m_initialize(self, processId=None, rootUri=None, rootPath=None, initializationOptions=None, **_kwargs):
202+
def m_initialize(self, processId=None, rootUri=None, rootPath=None,
203+
initializationOptions=None, workspaceFolders=None, **_kwargs):
203204
log.debug('Language server initialized with %s %s %s %s', processId, rootUri, rootPath, initializationOptions)
204205
if rootUri is None:
205206
rootUri = uris.from_fs_path(rootPath) if rootPath is not None else ''
@@ -210,6 +211,19 @@ def m_initialize(self, processId=None, rootUri=None, rootPath=None, initializati
210211
processId, _kwargs.get('capabilities', {}))
211212
self.workspace = Workspace(rootUri, self._endpoint, self.config)
212213
self.workspaces[rootUri] = self.workspace
214+
if workspaceFolders:
215+
for folder in workspaceFolders:
216+
uri = folder['uri']
217+
if uri == rootUri:
218+
# Already created
219+
continue
220+
workspace_config = config.Config(
221+
uri, self.config._init_opts,
222+
self.config._process_id, self.config._capabilities)
223+
workspace_config.update(self.config._settings)
224+
self.workspaces[uri] = Workspace(
225+
uri, self._endpoint, workspace_config)
226+
213227
self._dispatchers = self._hook('pylsp_dispatchers')
214228
self._hook('pylsp_initialize')
215229

Diff for: test/fixtures.py

+28
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,34 @@ def pylsp(tmpdir):
3434
return ls
3535

3636

37+
@pytest.fixture
38+
def pylsp_w_workspace_folders(tmpdir):
39+
""" Return an initialized python LS """
40+
ls = PythonLSPServer(StringIO, StringIO)
41+
42+
folder1 = tmpdir.mkdir('folder1')
43+
folder2 = tmpdir.mkdir('folder2')
44+
45+
ls.m_initialize(
46+
processId=1,
47+
rootUri=uris.from_fs_path(str(folder1)),
48+
initializationOptions={},
49+
workspaceFolders=[
50+
{
51+
'uri': uris.from_fs_path(str(folder1)),
52+
'name': 'folder1'
53+
},
54+
{
55+
'uri': uris.from_fs_path(str(folder2)),
56+
'name': 'folder2'
57+
}
58+
]
59+
)
60+
61+
workspace_folders = [folder1, folder2]
62+
return (ls, workspace_folders)
63+
64+
3765
@pytest.fixture
3866
def workspace(tmpdir):
3967
"""Return a workspace."""

Diff for: test/test_workspace.py

+39
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,45 @@ def test_root_project_with_no_setup_py(pylsp):
6969
assert workspace_root in test_doc.sys_path()
7070

7171

72+
def test_multiple_workspaces_from_initialize(pylsp_w_workspace_folders):
73+
pylsp, workspace_folders = pylsp_w_workspace_folders
74+
75+
assert len(pylsp.workspaces) == 2
76+
77+
folders_uris = [uris.from_fs_path(str(folder)) for folder in workspace_folders]
78+
79+
for folder_uri in folders_uris:
80+
assert folder_uri in pylsp.workspaces
81+
82+
assert folders_uris[0] == pylsp.root_uri
83+
84+
# Create file in the first workspace folder.
85+
file1 = workspace_folders[0].join('file1.py')
86+
file1.write('import os')
87+
msg1 = {
88+
'uri': path_as_uri(str(file1)),
89+
'version': 1,
90+
'text': 'import os'
91+
}
92+
93+
pylsp.m_text_document__did_open(textDocument=msg1)
94+
assert msg1['uri'] in pylsp.workspace._docs
95+
assert msg1['uri'] in pylsp.workspaces[folders_uris[0]]._docs
96+
97+
# Create file in the second workspace folder.
98+
file2 = workspace_folders[1].join('file2.py')
99+
file2.write('import sys')
100+
msg2 = {
101+
'uri': path_as_uri(str(file2)),
102+
'version': 1,
103+
'text': 'import sys'
104+
}
105+
106+
pylsp.m_text_document__did_open(textDocument=msg2)
107+
assert msg2['uri'] not in pylsp.workspace._docs
108+
assert msg2['uri'] in pylsp.workspaces[folders_uris[1]]._docs
109+
110+
72111
def test_multiple_workspaces(tmpdir, pylsp):
73112
workspace1_dir = tmpdir.mkdir('workspace1')
74113
workspace2_dir = tmpdir.mkdir('workspace2')

0 commit comments

Comments
 (0)