lsp/python: Temporarily report just a singular workspace folder instead of all of the roots (#35243)

Temporarily fixes #29133

Co-authored-by: Cole <cole@zed.dev>

Release Notes:

- python: Zed now reports a slightly different set of workspace folders
for Python projects to work around quirks in handling of multi-lsp
projects with virtual environment. This behavior will be revisited in a
near future.

Co-authored-by: Cole <cole@zed.dev>
This commit is contained in:
Piotr Osiewicz 2025-07-29 02:10:32 +02:00 committed by GitHub
parent d2ef287791
commit e5269212ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 76 additions and 27 deletions

View file

@ -29,7 +29,7 @@ use std::{
ffi::{OsStr, OsString},
fmt,
io::Write,
ops::{Deref, DerefMut},
ops::DerefMut,
path::PathBuf,
pin::Pin,
sync::{
@ -100,7 +100,7 @@ pub struct LanguageServer {
io_tasks: Mutex<Option<(Task<Option<()>>, Task<Option<()>>)>>,
output_done_rx: Mutex<Option<barrier::Receiver>>,
server: Arc<Mutex<Option<Child>>>,
workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
workspace_folders: Option<Arc<Mutex<BTreeSet<Url>>>>,
root_uri: Url,
}
@ -307,7 +307,7 @@ impl LanguageServer {
binary: LanguageServerBinary,
root_path: &Path,
code_action_kinds: Option<Vec<CodeActionKind>>,
workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
workspace_folders: Option<Arc<Mutex<BTreeSet<Url>>>>,
cx: &mut AsyncApp,
) -> Result<Self> {
let working_dir = if root_path.is_dir() {
@ -381,7 +381,7 @@ impl LanguageServer {
code_action_kinds: Option<Vec<CodeActionKind>>,
binary: LanguageServerBinary,
root_uri: Url,
workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
workspace_folders: Option<Arc<Mutex<BTreeSet<Url>>>>,
cx: &mut AsyncApp,
on_unhandled_notification: F,
) -> Self
@ -595,16 +595,26 @@ impl LanguageServer {
}
pub fn default_initialize_params(&self, pull_diagnostics: bool, cx: &App) -> InitializeParams {
let workspace_folders = self
.workspace_folders
.lock()
.iter()
.cloned()
.map(|uri| WorkspaceFolder {
name: Default::default(),
uri,
})
.collect::<Vec<_>>();
let workspace_folders = self.workspace_folders.as_ref().map_or_else(
|| {
vec![WorkspaceFolder {
name: Default::default(),
uri: self.root_uri.clone(),
}]
},
|folders| {
folders
.lock()
.iter()
.cloned()
.map(|uri| WorkspaceFolder {
name: Default::default(),
uri,
})
.collect()
},
);
#[allow(deprecated)]
InitializeParams {
process_id: None,
@ -1315,7 +1325,10 @@ impl LanguageServer {
return;
}
let is_new_folder = self.workspace_folders.lock().insert(uri.clone());
let Some(workspace_folders) = self.workspace_folders.as_ref() else {
return;
};
let is_new_folder = workspace_folders.lock().insert(uri.clone());
if is_new_folder {
let params = DidChangeWorkspaceFoldersParams {
event: WorkspaceFoldersChangeEvent {
@ -1345,7 +1358,10 @@ impl LanguageServer {
{
return;
}
let was_removed = self.workspace_folders.lock().remove(&uri);
let Some(workspace_folders) = self.workspace_folders.as_ref() else {
return;
};
let was_removed = workspace_folders.lock().remove(&uri);
if was_removed {
let params = DidChangeWorkspaceFoldersParams {
event: WorkspaceFoldersChangeEvent {
@ -1360,7 +1376,10 @@ impl LanguageServer {
}
}
pub fn set_workspace_folders(&self, folders: BTreeSet<Url>) {
let mut workspace_folders = self.workspace_folders.lock();
let Some(workspace_folders) = self.workspace_folders.as_ref() else {
return;
};
let mut workspace_folders = workspace_folders.lock();
let old_workspace_folders = std::mem::take(&mut *workspace_folders);
let added: Vec<_> = folders
@ -1389,8 +1408,11 @@ impl LanguageServer {
}
}
pub fn workspace_folders(&self) -> impl Deref<Target = BTreeSet<Url>> + '_ {
self.workspace_folders.lock()
pub fn workspace_folders(&self) -> BTreeSet<Url> {
self.workspace_folders.as_ref().map_or_else(
|| BTreeSet::from_iter([self.root_uri.clone()]),
|folders| folders.lock().clone(),
)
}
pub fn register_buffer(
@ -1535,7 +1557,7 @@ impl FakeLanguageServer {
None,
binary.clone(),
root,
workspace_folders.clone(),
Some(workspace_folders.clone()),
cx,
|_| {},
);
@ -1554,7 +1576,7 @@ impl FakeLanguageServer {
None,
binary,
Self::root_path(),
workspace_folders,
Some(workspace_folders),
cx,
move |msg| {
notifications_tx