aboutsummaryrefslogtreecommitdiff
path: root/helix-lsp
diff options
context:
space:
mode:
authorPhilipp Mildenberger2023-03-20 16:44:04 +0000
committerPhilipp Mildenberger2023-05-18 19:58:17 +0000
commitff262084271492bba239dbc2e5788be3c4d5a4e5 (patch)
tree0c668cc05e1757377fa3cd418921c9ee575da350 /helix-lsp
parent9d089c27c77cb2797a0495b46477dfe348d09a91 (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.rs99
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;
}