Support workspace/executeCommand
for actions' data (#26239)
Closes https://github.com/zed-industries/zed/issues/16746 Part of https://github.com/zed-extensions/deno/issues/2 Changes the action-related code so, that * `lsp::Command` as actions are supported, if server replies with them * actions with commands are filtered out based on servers' `executeCommandOptions` (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#executeCommandOptions) — commands that are not listed won't be executed and the corresponding actions will be hidden in Zed Release Notes: - Added support of `workspace/executeCommand` for actions' data --------- Co-authored-by: Peter Tripp <petertripp@gmail.com>
This commit is contained in:
parent
97c0a0a86e
commit
af5af9d7c5
9 changed files with 217 additions and 87 deletions
|
@ -2,9 +2,10 @@ mod signature_help;
|
|||
|
||||
use crate::{
|
||||
lsp_store::{LocalLspStore, LspStore},
|
||||
CodeAction, CoreCompletion, DocumentHighlight, Hover, HoverBlock, HoverBlockKind, InlayHint,
|
||||
InlayHintLabel, InlayHintLabelPart, InlayHintLabelPartTooltip, InlayHintTooltip, Location,
|
||||
LocationLink, MarkupContent, PrepareRenameResponse, ProjectTransaction, ResolveState,
|
||||
ActionVariant, CodeAction, CoreCompletion, DocumentHighlight, Hover, HoverBlock,
|
||||
HoverBlockKind, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayHintLabelPartTooltip,
|
||||
InlayHintTooltip, Location, LocationLink, MarkupContent, PrepareRenameResponse,
|
||||
ProjectTransaction, ResolveState,
|
||||
};
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use async_trait::async_trait;
|
||||
|
@ -2218,10 +2219,10 @@ impl LspCommand for GetCodeActions {
|
|||
async fn response_from_lsp(
|
||||
self,
|
||||
actions: Option<lsp::CodeActionResponse>,
|
||||
_: Entity<LspStore>,
|
||||
lsp_store: Entity<LspStore>,
|
||||
_: Entity<Buffer>,
|
||||
server_id: LanguageServerId,
|
||||
_: AsyncApp,
|
||||
cx: AsyncApp,
|
||||
) -> Result<Vec<CodeAction>> {
|
||||
let requested_kinds_set = if let Some(kinds) = self.kinds {
|
||||
Some(kinds.into_iter().collect::<HashSet<_>>())
|
||||
|
@ -2229,18 +2230,47 @@ impl LspCommand for GetCodeActions {
|
|||
None
|
||||
};
|
||||
|
||||
let language_server = cx.update(|cx| {
|
||||
lsp_store
|
||||
.read(cx)
|
||||
.language_server_for_id(server_id)
|
||||
.with_context(|| {
|
||||
format!("Missing the language server that just returned a response {server_id}")
|
||||
})
|
||||
})??;
|
||||
|
||||
let server_capabilities = language_server.capabilities();
|
||||
let available_commands = server_capabilities
|
||||
.execute_command_provider
|
||||
.as_ref()
|
||||
.map(|options| options.commands.as_slice())
|
||||
.unwrap_or_default();
|
||||
Ok(actions
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.filter_map(|entry| {
|
||||
let lsp::CodeActionOrCommand::CodeAction(lsp_action) = entry else {
|
||||
return None;
|
||||
let lsp_action = match entry {
|
||||
lsp::CodeActionOrCommand::CodeAction(lsp_action) => {
|
||||
if let Some(command) = lsp_action.command.as_ref() {
|
||||
if !available_commands.contains(&command.command) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
ActionVariant::Action(Box::new(lsp_action))
|
||||
}
|
||||
lsp::CodeActionOrCommand::Command(command) => {
|
||||
if available_commands.contains(&command.command) {
|
||||
ActionVariant::Command(command)
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some((requested_kinds, kind)) =
|
||||
requested_kinds_set.as_ref().zip(lsp_action.kind.as_ref())
|
||||
requested_kinds_set.as_ref().zip(lsp_action.action_kind())
|
||||
{
|
||||
if !requested_kinds.contains(kind) {
|
||||
if !requested_kinds.contains(&kind) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue