Avoid re-querying language server completions when possible (#31872)
Also adds reuse of the markdown documentation cache even when completions are re-queried, so that markdown documentation doesn't flicker when `is_incomplete: true` (completions provided by rust analyzer always set this) Release Notes: - Added support for filtering language server completions instead of re-querying.
This commit is contained in:
parent
b7ec437b13
commit
17cf865d1e
17 changed files with 1221 additions and 720 deletions
|
@ -3,8 +3,8 @@ pub mod lsp_ext_command;
|
|||
pub mod rust_analyzer_ext;
|
||||
|
||||
use crate::{
|
||||
CodeAction, Completion, CompletionSource, CoreCompletion, Hover, InlayHint, LspAction,
|
||||
ProjectItem, ProjectPath, ProjectTransaction, ResolveState, Symbol, ToolchainStore,
|
||||
CodeAction, Completion, CompletionResponse, CompletionSource, CoreCompletion, Hover, InlayHint,
|
||||
LspAction, ProjectItem, ProjectPath, ProjectTransaction, ResolveState, Symbol, ToolchainStore,
|
||||
buffer_store::{BufferStore, BufferStoreEvent},
|
||||
environment::ProjectEnvironment,
|
||||
lsp_command::{self, *},
|
||||
|
@ -998,7 +998,7 @@ impl LocalLspStore {
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
async move {
|
||||
futures::future::join_all(shutdown_futures).await;
|
||||
join_all(shutdown_futures).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5081,7 +5081,7 @@ impl LspStore {
|
|||
position: PointUtf16,
|
||||
context: CompletionContext,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Option<Vec<Completion>>>> {
|
||||
) -> Task<Result<Vec<CompletionResponse>>> {
|
||||
let language_registry = self.languages.clone();
|
||||
|
||||
if let Some((upstream_client, project_id)) = self.upstream_client() {
|
||||
|
@ -5105,11 +5105,17 @@ impl LspStore {
|
|||
});
|
||||
|
||||
cx.foreground_executor().spawn(async move {
|
||||
let completions = task.await?;
|
||||
let mut result = Vec::new();
|
||||
populate_labels_for_completions(completions, language, lsp_adapter, &mut result)
|
||||
.await;
|
||||
Ok(Some(result))
|
||||
let completion_response = task.await?;
|
||||
let completions = populate_labels_for_completions(
|
||||
completion_response.completions,
|
||||
language,
|
||||
lsp_adapter,
|
||||
)
|
||||
.await;
|
||||
Ok(vec![CompletionResponse {
|
||||
completions,
|
||||
is_incomplete: completion_response.is_incomplete,
|
||||
}])
|
||||
})
|
||||
} else if let Some(local) = self.as_local() {
|
||||
let snapshot = buffer.read(cx).snapshot();
|
||||
|
@ -5123,7 +5129,7 @@ impl LspStore {
|
|||
)
|
||||
.completions;
|
||||
if !completion_settings.lsp {
|
||||
return Task::ready(Ok(None));
|
||||
return Task::ready(Ok(Vec::new()));
|
||||
}
|
||||
|
||||
let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
|
||||
|
@ -5190,25 +5196,23 @@ impl LspStore {
|
|||
}
|
||||
})?;
|
||||
|
||||
let mut has_completions_returned = false;
|
||||
let mut completions = Vec::new();
|
||||
for (lsp_adapter, task) in tasks {
|
||||
if let Ok(Some(new_completions)) = task.await {
|
||||
has_completions_returned = true;
|
||||
populate_labels_for_completions(
|
||||
new_completions,
|
||||
let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
|
||||
let completion_response = task.await.ok()??;
|
||||
let completions = populate_labels_for_completions(
|
||||
completion_response.completions,
|
||||
language.clone(),
|
||||
lsp_adapter,
|
||||
&mut completions,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
if has_completions_returned {
|
||||
Ok(Some(completions))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
Some(CompletionResponse {
|
||||
completions,
|
||||
is_incomplete: completion_response.is_incomplete,
|
||||
})
|
||||
});
|
||||
|
||||
let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
|
||||
|
||||
Ok(responses.into_iter().flatten().collect())
|
||||
})
|
||||
} else {
|
||||
Task::ready(Err(anyhow!("No upstream client or local language server")))
|
||||
|
@ -9547,8 +9551,7 @@ async fn populate_labels_for_completions(
|
|||
new_completions: Vec<CoreCompletion>,
|
||||
language: Option<Arc<Language>>,
|
||||
lsp_adapter: Option<Arc<CachedLspAdapter>>,
|
||||
completions: &mut Vec<Completion>,
|
||||
) {
|
||||
) -> Vec<Completion> {
|
||||
let lsp_completions = new_completions
|
||||
.iter()
|
||||
.filter_map(|new_completion| {
|
||||
|
@ -9572,6 +9575,7 @@ async fn populate_labels_for_completions(
|
|||
.into_iter()
|
||||
.fuse();
|
||||
|
||||
let mut completions = Vec::new();
|
||||
for completion in new_completions {
|
||||
match completion.source.lsp_completion(true) {
|
||||
Some(lsp_completion) => {
|
||||
|
@ -9612,6 +9616,7 @@ async fn populate_labels_for_completions(
|
|||
}
|
||||
}
|
||||
}
|
||||
completions
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue