diff options
author | sigmaSd | 2023-07-21 19:50:08 +0000 |
---|---|---|
committer | GitHub | 2023-07-21 19:50:08 +0000 |
commit | 8977123f25baba838d2d16f8a40e78563c4ebf4a (patch) | |
tree | 8f8b7187e817ca7175d194249cd77dd88ec7684e | |
parent | d52b790379ffc5646409a9972e0a4e70bcc8a981 (diff) |
feat: resolve code action (#7677)
-rw-r--r-- | helix-lsp/src/client.rs | 29 | ||||
-rw-r--r-- | helix-term/src/commands/lsp.rs | 15 |
2 files changed, 41 insertions, 3 deletions
diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index a3711317..92ab03db 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -7,8 +7,9 @@ use crate::{ use helix_core::{find_workspace, path, syntax::LanguageServerFeature, ChangeSet, Rope}; use helix_loader::{self, VERSION_AND_GIT_HASH}; use lsp::{ - notification::DidChangeWorkspaceFolders, DidChangeWorkspaceFoldersParams, OneOf, - PositionEncodingKind, WorkspaceFolder, WorkspaceFoldersChangeEvent, + notification::DidChangeWorkspaceFolders, CodeActionCapabilityResolveSupport, + DidChangeWorkspaceFoldersParams, OneOf, PositionEncodingKind, WorkspaceFolder, + WorkspaceFoldersChangeEvent, }; use lsp_types as lsp; use parking_lot::Mutex; @@ -609,6 +610,12 @@ impl Client { .collect(), }, }), + is_preferred_support: Some(true), + disabled_support: Some(true), + data_support: Some(true), + resolve_support: Some(CodeActionCapabilityResolveSupport { + properties: vec!["edit".to_owned(), "command".to_owned()], + }), ..Default::default() }), publish_diagnostics: Some(lsp::PublishDiagnosticsClientCapabilities { @@ -954,6 +961,24 @@ impl Client { Some(self.call::<lsp::request::ResolveCompletionItem>(completion_item)) } + pub fn resolve_code_action( + &self, + code_action: lsp::CodeAction, + ) -> Option<impl Future<Output = Result<Value>>> { + let capabilities = self.capabilities.get().unwrap(); + + // Return early if the server does not support resolving code action. + match capabilities.completion_provider { + Some(lsp::CompletionOptions { + resolve_provider: Some(true), + .. + }) => (), + _ => return None, + } + + Some(self.call::<lsp::request::CodeActionResolveRequest>(code_action)) + } + pub fn text_document_signature_help( &self, text_document: lsp::TextDocumentIdentifier, diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs index 145bddd0..1f592118 100644 --- a/helix-term/src/commands/lsp.rs +++ b/helix-term/src/commands/lsp.rs @@ -743,7 +743,20 @@ pub fn code_action(cx: &mut Context) { } lsp::CodeActionOrCommand::CodeAction(code_action) => { log::debug!("code action: {:?}", code_action); - if let Some(ref workspace_edit) = code_action.edit { + // we support lsp "codeAction/resolve" for `edit` and `command` fields + let mut resolved_code_action = None; + if code_action.edit.is_none() || code_action.command.is_none() { + if let Some(future) = language_server.resolve_code_action(code_action.clone()) { + if let Ok(response) = helix_lsp::block_on(future) { + if let Ok(code_action) = serde_json::from_value::<CodeAction>(response) { + resolved_code_action = Some(code_action); + } + } + } + } + let resolved_code_action = resolved_code_action.as_ref().unwrap_or(code_action); + + if let Some(ref workspace_edit) = resolved_code_action.edit { log::debug!("edit: {:?}", workspace_edit); let _ = apply_workspace_edit(editor, offset_encoding, workspace_edit); } |