Skip to content

Initialize workspaces from the initialize request #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ __pycache__/
*.py[cod]
*$py.class

# Mypy cache
.mypy_cache/

# IntelliJ
*.iml
*.ipr
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ All configuration options are described in [`CONFIGURATION.md`](https://github.c

To run the test suite:

```
pip install .[test] && pytest
```sh
pip install '.[test]' && pytest
```

After adding configuration options to `schema.json`, refresh the `CONFIGURATION.md` file with
Expand Down
16 changes: 15 additions & 1 deletion pylsp/python_lsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ def capabilities(self):
log.info('Server capabilities: %s', server_capabilities)
return server_capabilities

def m_initialize(self, processId=None, rootUri=None, rootPath=None, initializationOptions=None, **_kwargs):
def m_initialize(self, processId=None, rootUri=None, rootPath=None,
initializationOptions=None, workspaceFolders=None, **_kwargs):
log.debug('Language server initialized with %s %s %s %s', processId, rootUri, rootPath, initializationOptions)
if rootUri is None:
rootUri = uris.from_fs_path(rootPath) if rootPath is not None else ''
Expand All @@ -210,6 +211,19 @@ def m_initialize(self, processId=None, rootUri=None, rootPath=None, initializati
processId, _kwargs.get('capabilities', {}))
self.workspace = Workspace(rootUri, self._endpoint, self.config)
self.workspaces[rootUri] = self.workspace
if workspaceFolders:
for folder in workspaceFolders:
uri = folder['uri']
if uri == rootUri:
# Already created
continue
workspace_config = config.Config(
uri, self.config._init_opts,
self.config._process_id, self.config._capabilities)
workspace_config.update(self.config._settings)
self.workspaces[uri] = Workspace(
uri, self._endpoint, workspace_config)

self._dispatchers = self._hook('pylsp_dispatchers')
self._hook('pylsp_initialize')

Expand Down
28 changes: 28 additions & 0 deletions test/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,34 @@ def pylsp(tmpdir):
return ls


@pytest.fixture
def pylsp_w_workspace_folders(tmpdir):
""" Return an initialized python LS """
ls = PythonLSPServer(StringIO, StringIO)

folder1 = tmpdir.mkdir('folder1')
folder2 = tmpdir.mkdir('folder2')

ls.m_initialize(
processId=1,
rootUri=uris.from_fs_path(str(folder1)),
initializationOptions={},
workspaceFolders=[
{
'uri': uris.from_fs_path(str(folder1)),
'name': 'folder1'
},
{
'uri': uris.from_fs_path(str(folder2)),
'name': 'folder2'
}
]
)

workspace_folders = [folder1, folder2]
return (ls, workspace_folders)


@pytest.fixture
def workspace(tmpdir):
"""Return a workspace."""
Expand Down
39 changes: 39 additions & 0 deletions test/test_workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,45 @@ def test_root_project_with_no_setup_py(pylsp):
assert workspace_root in test_doc.sys_path()


def test_multiple_workspaces_from_initialize(pylsp_w_workspace_folders):
pylsp, workspace_folders = pylsp_w_workspace_folders

assert len(pylsp.workspaces) == 2

folders_uris = [uris.from_fs_path(str(folder)) for folder in workspace_folders]

for folder_uri in folders_uris:
assert folder_uri in pylsp.workspaces

assert folders_uris[0] == pylsp.root_uri

# Create file in the first workspace folder.
file1 = workspace_folders[0].join('file1.py')
file1.write('import os')
msg1 = {
'uri': path_as_uri(str(file1)),
'version': 1,
'text': 'import os'
}

pylsp.m_text_document__did_open(textDocument=msg1)
assert msg1['uri'] in pylsp.workspace._docs
assert msg1['uri'] in pylsp.workspaces[folders_uris[0]]._docs

# Create file in the second workspace folder.
file2 = workspace_folders[1].join('file2.py')
file2.write('import sys')
msg2 = {
'uri': path_as_uri(str(file2)),
'version': 1,
'text': 'import sys'
}

pylsp.m_text_document__did_open(textDocument=msg2)
assert msg2['uri'] not in pylsp.workspace._docs
assert msg2['uri'] in pylsp.workspaces[folders_uris[1]]._docs


def test_multiple_workspaces(tmpdir, pylsp):
workspace1_dir = tmpdir.mkdir('workspace1')
workspace2_dir = tmpdir.mkdir('workspace2')
Expand Down