diff options
author | Philipp Mildenberger | 2023-03-20 16:44:04 +0000 |
---|---|---|
committer | Philipp Mildenberger | 2023-05-18 19:58:17 +0000 |
commit | ff262084271492bba239dbc2e5788be3c4d5a4e5 (patch) | |
tree | 0c668cc05e1757377fa3cd418921c9ee575da350 /helix-lsp | |
parent | 9d089c27c77cb2797a0495b46477dfe348d09a91 (diff) |
Filter language servers also by capabilities in `doc.language_servers_with_feature`
* Add `helix_lsp::client::Client::supports_feature(&self, LanguageServerFeature)`
* Extend `doc.language_servers_with_feature` to use this method as filter as well
* Add macro `language_server_with_feature!` to reduce boilerplate for non-mergeable language server requests (like goto-definition)
* Refactored most of the `find_map` code to use the either the macro or filter directly via `doc.language_servers_with_feature`
Diffstat (limited to 'helix-lsp')
-rw-r--r-- | helix-lsp/src/client.rs | 99 |
1 files changed, 89 insertions, 10 deletions
diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 65c6954d..b1a73247 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -4,7 +4,7 @@ use crate::{ Call, Error, OffsetEncoding, Result, }; -use helix_core::{find_workspace, path, ChangeSet, Rope}; +use helix_core::{find_workspace, path, syntax::LanguageServerFeature, ChangeSet, Rope}; use helix_loader::{self, VERSION_AND_GIT_HASH}; use lsp::{ notification::DidChangeWorkspaceFolders, DidChangeWorkspaceFoldersParams, OneOf, @@ -276,6 +276,93 @@ impl Client { .expect("language server not yet initialized!") } + #[inline] // TODO inline? + pub fn supports_feature(&self, feature: LanguageServerFeature) -> bool { + let capabilities = match self.capabilities.get() { + Some(capabilities) => capabilities, + None => return false, // not initialized, TODO unwrap/expect instead? + }; + match feature { + LanguageServerFeature::Format => matches!( + capabilities.document_formatting_provider, + Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) + ), + LanguageServerFeature::GotoDeclaration => matches!( + capabilities.declaration_provider, + Some( + lsp::DeclarationCapability::Simple(true) + | lsp::DeclarationCapability::RegistrationOptions(_) + | lsp::DeclarationCapability::Options(_), + ) + ), + LanguageServerFeature::GotoDefinition => matches!( + capabilities.definition_provider, + Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) + ), + LanguageServerFeature::GotoTypeDefinition => matches!( + capabilities.type_definition_provider, + Some( + lsp::TypeDefinitionProviderCapability::Simple(true) + | lsp::TypeDefinitionProviderCapability::Options(_), + ) + ), + LanguageServerFeature::GotoReference => matches!( + capabilities.references_provider, + Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) + ), + LanguageServerFeature::GotoImplementation => matches!( + capabilities.implementation_provider, + Some( + lsp::ImplementationProviderCapability::Simple(true) + | lsp::ImplementationProviderCapability::Options(_), + ) + ), + LanguageServerFeature::SignatureHelp => capabilities.signature_help_provider.is_some(), + LanguageServerFeature::Hover => matches!( + capabilities.hover_provider, + Some( + lsp::HoverProviderCapability::Simple(true) + | lsp::HoverProviderCapability::Options(_), + ) + ), + LanguageServerFeature::DocumentHighlight => matches!( + capabilities.document_highlight_provider, + Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) + ), + LanguageServerFeature::Completion => capabilities.completion_provider.is_some(), + LanguageServerFeature::CodeAction => matches!( + capabilities.code_action_provider, + Some( + lsp::CodeActionProviderCapability::Simple(true) + | lsp::CodeActionProviderCapability::Options(_), + ) + ), + LanguageServerFeature::WorkspaceCommand => { + capabilities.execute_command_provider.is_some() + } + LanguageServerFeature::DocumentSymbols => matches!( + capabilities.document_symbol_provider, + Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) + ), + LanguageServerFeature::WorkspaceSymbols => matches!( + capabilities.workspace_symbol_provider, + Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) + ), + LanguageServerFeature::Diagnostics => true, // there's no extra server capability + LanguageServerFeature::RenameSymbol => matches!( + capabilities.rename_provider, + Some(lsp::OneOf::Left(true)) | Some(lsp::OneOf::Right(_)) + ), + LanguageServerFeature::InlayHints => matches!( + capabilities.inlay_hint_provider, + Some( + lsp::OneOf::Left(true) + | lsp::OneOf::Right(lsp::InlayHintServerCapabilities::Options(_)) + ) + ), + } + } + pub fn offset_encoding(&self) -> OffsetEncoding { self.capabilities() .position_encoding @@ -1301,21 +1388,13 @@ impl Client { Some(self.call::<lsp::request::CodeActionRequest>(params)) } - pub fn supports_rename(&self) -> bool { - let capabilities = self.capabilities.get().unwrap(); - matches!( - capabilities.rename_provider, - Some(lsp::OneOf::Left(true) | lsp::OneOf::Right(_)) - ) - } - pub fn rename_symbol( &self, text_document: lsp::TextDocumentIdentifier, position: lsp::Position, new_name: String, ) -> Option<impl Future<Output = Result<lsp::WorkspaceEdit>>> { - if !self.supports_rename() { + if !self.supports_feature(LanguageServerFeature::RenameSymbol) { return None; } |