lsp: Use available workspace folders in initialize params (#25753)
Closes https://github.com/zed-industries/zed/issues/25743 Closes https://github.com/biomejs/biome-zed/issues/73 Release Notes: - Fixed issues with launching Svelte/Biome language servers
This commit is contained in:
parent
5c400dac8d
commit
2e98bc17cb
5 changed files with 34 additions and 19 deletions
|
@ -475,6 +475,7 @@ impl Copilot {
|
||||||
binary,
|
binary,
|
||||||
root_path,
|
root_path,
|
||||||
None,
|
None,
|
||||||
|
Default::default(),
|
||||||
cx.clone(),
|
cx.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use futures::StreamExt;
|
||||||
use gpui::{App, AsyncApp, Task};
|
use gpui::{App, AsyncApp, Task};
|
||||||
use http_client::github::latest_github_release;
|
use http_client::github::latest_github_release;
|
||||||
pub use language::*;
|
pub use language::*;
|
||||||
use lsp::{InitializeParams, LanguageServerBinary, LanguageServerName};
|
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||||
use project::Fs;
|
use project::Fs;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
@ -373,14 +373,6 @@ impl super::LspAdapter for GoLspAdapter {
|
||||||
filter_range,
|
filter_range,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn prepare_initialize_params(
|
|
||||||
&self,
|
|
||||||
mut original: InitializeParams,
|
|
||||||
) -> Result<InitializeParams> {
|
|
||||||
#[allow(deprecated)]
|
|
||||||
let _ = original.root_uri.take();
|
|
||||||
Ok(original)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_version_output(output: &Output) -> Result<&str> {
|
fn parse_version_output(output: &Output) -> Result<&str> {
|
||||||
|
|
|
@ -329,6 +329,7 @@ impl lsp_types::notification::Notification for ServerStatus {
|
||||||
|
|
||||||
impl LanguageServer {
|
impl LanguageServer {
|
||||||
/// Starts a language server process.
|
/// Starts a language server process.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
stderr_capture: Arc<Mutex<Option<String>>>,
|
stderr_capture: Arc<Mutex<Option<String>>>,
|
||||||
server_id: LanguageServerId,
|
server_id: LanguageServerId,
|
||||||
|
@ -336,6 +337,7 @@ impl LanguageServer {
|
||||||
binary: LanguageServerBinary,
|
binary: LanguageServerBinary,
|
||||||
root_path: &Path,
|
root_path: &Path,
|
||||||
code_action_kinds: Option<Vec<CodeActionKind>>,
|
code_action_kinds: Option<Vec<CodeActionKind>>,
|
||||||
|
workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
|
||||||
cx: AsyncApp,
|
cx: AsyncApp,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let working_dir = if root_path.is_dir() {
|
let working_dir = if root_path.is_dir() {
|
||||||
|
@ -383,6 +385,7 @@ impl LanguageServer {
|
||||||
code_action_kinds,
|
code_action_kinds,
|
||||||
binary,
|
binary,
|
||||||
root_uri,
|
root_uri,
|
||||||
|
workspace_folders,
|
||||||
cx,
|
cx,
|
||||||
move |notification| {
|
move |notification| {
|
||||||
log::info!(
|
log::info!(
|
||||||
|
@ -409,6 +412,7 @@ impl LanguageServer {
|
||||||
code_action_kinds: Option<Vec<CodeActionKind>>,
|
code_action_kinds: Option<Vec<CodeActionKind>>,
|
||||||
binary: LanguageServerBinary,
|
binary: LanguageServerBinary,
|
||||||
root_uri: Url,
|
root_uri: Url,
|
||||||
|
workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
|
||||||
cx: AsyncApp,
|
cx: AsyncApp,
|
||||||
on_unhandled_notification: F,
|
on_unhandled_notification: F,
|
||||||
) -> Self
|
) -> Self
|
||||||
|
@ -491,7 +495,7 @@ impl LanguageServer {
|
||||||
io_tasks: Mutex::new(Some((input_task, output_task))),
|
io_tasks: Mutex::new(Some((input_task, output_task))),
|
||||||
output_done_rx: Mutex::new(Some(output_done_rx)),
|
output_done_rx: Mutex::new(Some(output_done_rx)),
|
||||||
server: Arc::new(Mutex::new(server)),
|
server: Arc::new(Mutex::new(server)),
|
||||||
workspace_folders: Default::default(),
|
workspace_folders,
|
||||||
root_uri,
|
root_uri,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -617,6 +621,16 @@ impl LanguageServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_initialize_params(&self, cx: &App) -> InitializeParams {
|
pub fn default_initialize_params(&self, cx: &App) -> InitializeParams {
|
||||||
|
let workspace_folders = self
|
||||||
|
.workspace_folders
|
||||||
|
.lock()
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(|uri| WorkspaceFolder {
|
||||||
|
name: Default::default(),
|
||||||
|
uri,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
InitializeParams {
|
InitializeParams {
|
||||||
process_id: None,
|
process_id: None,
|
||||||
|
@ -791,7 +805,7 @@ impl LanguageServer {
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
trace: None,
|
trace: None,
|
||||||
workspace_folders: Some(vec![]),
|
workspace_folders: Some(workspace_folders),
|
||||||
client_info: release_channel::ReleaseChannel::try_global(cx).map(|release_channel| {
|
client_info: release_channel::ReleaseChannel::try_global(cx).map(|release_channel| {
|
||||||
ClientInfo {
|
ClientInfo {
|
||||||
name: release_channel.display_name().to_string(),
|
name: release_channel.display_name().to_string(),
|
||||||
|
@ -1260,24 +1274,27 @@ impl LanguageServer {
|
||||||
}
|
}
|
||||||
pub fn set_workspace_folders(&self, folders: BTreeSet<Url>) {
|
pub fn set_workspace_folders(&self, folders: BTreeSet<Url>) {
|
||||||
let mut workspace_folders = self.workspace_folders.lock();
|
let mut workspace_folders = self.workspace_folders.lock();
|
||||||
|
|
||||||
|
let old_workspace_folders = std::mem::take(&mut *workspace_folders);
|
||||||
let added: Vec<_> = folders
|
let added: Vec<_> = folders
|
||||||
.iter()
|
.difference(&old_workspace_folders)
|
||||||
.map(|uri| WorkspaceFolder {
|
.map(|uri| WorkspaceFolder {
|
||||||
uri: uri.clone(),
|
uri: uri.clone(),
|
||||||
name: String::default(),
|
name: String::default(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let removed: Vec<_> = std::mem::replace(&mut *workspace_folders, folders)
|
let removed: Vec<_> = old_workspace_folders
|
||||||
.into_iter()
|
.difference(&folders)
|
||||||
.map(|uri| WorkspaceFolder {
|
.map(|uri| WorkspaceFolder {
|
||||||
uri: uri.clone(),
|
uri: uri.clone(),
|
||||||
name: String::default(),
|
name: String::default(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let should_notify = !added.is_empty() || !removed.is_empty();
|
let should_notify = !added.is_empty() || !removed.is_empty();
|
||||||
|
|
||||||
if should_notify {
|
if should_notify {
|
||||||
|
*workspace_folders = folders;
|
||||||
|
drop(workspace_folders);
|
||||||
let params = DidChangeWorkspaceFoldersParams {
|
let params = DidChangeWorkspaceFoldersParams {
|
||||||
event: WorkspaceFoldersChangeEvent { added, removed },
|
event: WorkspaceFoldersChangeEvent { added, removed },
|
||||||
};
|
};
|
||||||
|
@ -1392,6 +1409,7 @@ impl FakeLanguageServer {
|
||||||
let server_name = LanguageServerName(name.clone().into());
|
let server_name = LanguageServerName(name.clone().into());
|
||||||
let process_name = Arc::from(name.as_str());
|
let process_name = Arc::from(name.as_str());
|
||||||
let root = Self::root_path();
|
let root = Self::root_path();
|
||||||
|
let workspace_folders: Arc<Mutex<BTreeSet<Url>>> = Default::default();
|
||||||
let mut server = LanguageServer::new_internal(
|
let mut server = LanguageServer::new_internal(
|
||||||
server_id,
|
server_id,
|
||||||
server_name.clone(),
|
server_name.clone(),
|
||||||
|
@ -1403,6 +1421,7 @@ impl FakeLanguageServer {
|
||||||
None,
|
None,
|
||||||
binary.clone(),
|
binary.clone(),
|
||||||
root,
|
root,
|
||||||
|
workspace_folders.clone(),
|
||||||
cx.clone(),
|
cx.clone(),
|
||||||
|_| {},
|
|_| {},
|
||||||
);
|
);
|
||||||
|
@ -1421,6 +1440,7 @@ impl FakeLanguageServer {
|
||||||
None,
|
None,
|
||||||
binary,
|
binary,
|
||||||
Self::root_path(),
|
Self::root_path(),
|
||||||
|
workspace_folders,
|
||||||
cx.clone(),
|
cx.clone(),
|
||||||
move |msg| {
|
move |msg| {
|
||||||
notifications_tx
|
notifications_tx
|
||||||
|
|
|
@ -279,6 +279,7 @@ impl Prettier {
|
||||||
server_binary,
|
server_binary,
|
||||||
&prettier_dir,
|
&prettier_dir,
|
||||||
None,
|
None,
|
||||||
|
Default::default(),
|
||||||
cx.clone(),
|
cx.clone(),
|
||||||
)
|
)
|
||||||
.context("prettier server creation")?;
|
.context("prettier server creation")?;
|
||||||
|
|
|
@ -206,14 +206,14 @@ impl LocalLspStore {
|
||||||
);
|
);
|
||||||
|
|
||||||
let binary = self.get_language_server_binary(adapter.clone(), delegate.clone(), true, cx);
|
let binary = self.get_language_server_binary(adapter.clone(), delegate.clone(), true, cx);
|
||||||
|
let pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>> = Default::default();
|
||||||
let pending_server = cx.spawn({
|
let pending_server = cx.spawn({
|
||||||
let adapter = adapter.clone();
|
let adapter = adapter.clone();
|
||||||
let server_name = adapter.name.clone();
|
let server_name = adapter.name.clone();
|
||||||
let stderr_capture = stderr_capture.clone();
|
let stderr_capture = stderr_capture.clone();
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
let lsp_store = self.weak.clone();
|
let lsp_store = self.weak.clone();
|
||||||
|
let pending_workspace_folders = pending_workspace_folders.clone();
|
||||||
move |cx| async move {
|
move |cx| async move {
|
||||||
let binary = binary.await?;
|
let binary = binary.await?;
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
@ -239,12 +239,12 @@ impl LocalLspStore {
|
||||||
binary,
|
binary,
|
||||||
&root_path,
|
&root_path,
|
||||||
adapter.code_action_kinds(),
|
adapter.code_action_kinds(),
|
||||||
|
pending_workspace_folders,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>> = Default::default();
|
|
||||||
let startup = {
|
let startup = {
|
||||||
let server_name = adapter.name.0.clone();
|
let server_name = adapter.name.0.clone();
|
||||||
let delegate = delegate as Arc<dyn LspAdapterDelegate>;
|
let delegate = delegate as Arc<dyn LspAdapterDelegate>;
|
||||||
|
@ -7551,10 +7551,11 @@ impl LspStore {
|
||||||
|
|
||||||
// Update language_servers collection with Running variant of LanguageServerState
|
// Update language_servers collection with Running variant of LanguageServerState
|
||||||
// indicating that the server is up and running and ready
|
// indicating that the server is up and running and ready
|
||||||
|
let workspace_folders = workspace_folders.lock().clone();
|
||||||
local.language_servers.insert(
|
local.language_servers.insert(
|
||||||
server_id,
|
server_id,
|
||||||
LanguageServerState::running(
|
LanguageServerState::running(
|
||||||
workspace_folders.lock().clone(),
|
workspace_folders,
|
||||||
adapter.clone(),
|
adapter.clone(),
|
||||||
language_server.clone(),
|
language_server.clone(),
|
||||||
None,
|
None,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue