159 lines
6.6 KiB
Rust
Raw Normal View History

2019-12-21 15:27:38 -05:00
//! Advertizes the capabilities of the LSP Server.
2020-05-03 20:56:36 +03:00
use std::env;
use ide::CompletionResolveCapability;
2019-01-14 13:55:56 +03:00
use lsp_types::{
CallHierarchyServerCapability, ClientCapabilities, CodeActionKind, CodeActionOptions,
CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
2020-07-15 18:17:46 -04:00
DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, HoverProviderCapability,
2020-09-23 15:41:55 -04:00
ImplementationProviderCapability, OneOf, RenameOptions, SaveOptions,
SelectionRangeProviderCapability, SemanticTokensFullOptions, SemanticTokensLegend,
SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
WorkDoneProgressOptions,
2018-08-10 21:13:39 +03:00
};
use rustc_hash::FxHashSet;
2020-05-21 19:50:23 +02:00
use serde_json::json;
use crate::semantic_tokens;
2018-08-10 15:07:43 +03:00
pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
2018-08-13 02:38:34 +03:00
ServerCapabilities {
2019-02-08 14:49:43 +03:00
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
open_close: Some(true),
2020-05-04 19:54:23 +03:00
change: Some(if env::var("RA_NO_INCREMENTAL_SYNC").is_ok() {
2020-05-03 20:56:36 +03:00
TextDocumentSyncKind::Full
2020-05-04 19:54:23 +03:00
} else {
TextDocumentSyncKind::Incremental
2020-05-03 20:56:36 +03:00
}),
2019-02-08 14:49:43 +03:00
will_save: None,
will_save_wait_until: None,
2020-07-12 12:28:00 -04:00
save: Some(SaveOptions::default().into()),
2019-02-08 14:49:43 +03:00
})),
2020-07-15 18:17:46 -04:00
hover_provider: Some(HoverProviderCapability::Simple(true)),
2018-08-26 12:51:45 +03:00
completion_provider: Some(CompletionOptions {
2020-11-28 16:26:30 +02:00
resolve_provider: Some(true),
2018-12-25 15:20:37 +01:00
trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
2018-08-26 12:51:45 +03:00
}),
signature_help_provider: Some(SignatureHelpOptions {
2019-12-12 07:55:05 -05:00
trigger_characters: Some(vec!["(".to_string(), ",".to_string()]),
retrigger_characters: None,
work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
}),
declaration_provider: None,
2020-09-23 15:41:55 -04:00
definition_provider: Some(OneOf::Left(true)),
2019-04-23 14:11:27 -04:00
type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
implementation_provider: Some(ImplementationProviderCapability::Simple(true)),
2020-09-23 15:41:55 -04:00
references_provider: Some(OneOf::Left(true)),
document_highlight_provider: Some(OneOf::Left(true)),
document_symbol_provider: Some(OneOf::Left(true)),
workspace_symbol_provider: Some(OneOf::Left(true)),
code_action_provider: Some(code_action_capabilities(client_caps)),
code_lens_provider: Some(CodeLensOptions {
resolve_provider: resolve_provider(client_caps),
}),
2020-09-23 15:41:55 -04:00
document_formatting_provider: Some(OneOf::Left(true)),
2018-08-13 02:38:34 +03:00
document_range_formatting_provider: None,
2018-08-28 11:12:42 +03:00
document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
first_trigger_character: "=".to_string(),
2019-10-25 12:16:56 +03:00
more_trigger_character: Some(vec![".".to_string(), ">".to_string()]),
2018-08-28 11:12:42 +03:00
}),
2019-12-20 18:57:31 -05:00
selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
2019-12-23 09:33:49 -05:00
semantic_highlighting: None,
2018-09-23 11:10:57 -04:00
folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
2020-09-23 15:41:55 -04:00
rename_provider: Some(OneOf::Right(RenameOptions {
2018-10-31 23:41:43 +03:00
prepare_provider: Some(true),
work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
2018-10-18 17:56:22 -04:00
})),
on_type_rename_provider: None,
2019-09-03 10:50:39 -04:00
document_link_provider: None,
2018-08-13 02:38:34 +03:00
color_provider: None,
execute_command_provider: None,
2018-09-23 11:10:57 -04:00
workspace: None,
call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
2020-02-25 08:38:50 -05:00
semantic_tokens_provider: Some(
SemanticTokensOptions {
legend: SemanticTokensLegend {
2020-03-02 14:05:44 -05:00
token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(),
token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
},
full: Some(SemanticTokensFullOptions::Delta { delta: Some(true) }),
range: Some(true),
2020-02-25 08:38:50 -05:00
work_done_progress_options: Default::default(),
}
.into(),
),
2020-05-21 19:50:23 +02:00
experimental: Some(json!({
"joinLines": true,
2020-05-22 00:28:49 +02:00
"ssr": true,
2020-05-25 14:12:53 +02:00
"onEnter": true,
"parentModule": true,
2020-06-02 17:34:18 +02:00
"runnables": {
"kinds": [ "cargo" ],
},
2020-05-21 19:50:23 +02:00
})),
2018-08-13 02:38:34 +03:00
}
}
fn resolve_provider(client_caps: &ClientCapabilities) -> Option<bool> {
if enabled_resolve_capabilities(client_caps)?.is_empty() {
None
} else {
Some(true)
}
}
/// Parses client capabilities and returns all that rust-analyzer supports.
pub fn enabled_resolve_capabilities(
caps: &ClientCapabilities,
) -> Option<FxHashSet<CompletionResolveCapability>> {
Some(
caps.text_document
.as_ref()?
.completion
.as_ref()?
.completion_item
.as_ref()?
.resolve_support
.as_ref()?
.properties
.iter()
.filter_map(|cap_string| {
Some(match cap_string.as_str() {
"additionalTextEdits" => CompletionResolveCapability::AdditionalTextEdits,
"detail" => CompletionResolveCapability::Detail,
"documentation" => CompletionResolveCapability::Documentation,
_unsupported => return None,
})
})
.collect(),
)
}
fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
client_caps
.text_document
.as_ref()
.and_then(|it| it.code_action.as_ref())
.and_then(|it| it.code_action_literal_support.as_ref())
.map_or(CodeActionProviderCapability::Simple(true), |_| {
CodeActionProviderCapability::Options(CodeActionOptions {
// Advertise support for all built-in CodeActionKinds.
// Ideally we would base this off of the client capabilities
// but the client is supposed to fall back gracefully for unknown values.
code_action_kinds: Some(vec![
CodeActionKind::EMPTY,
CodeActionKind::QUICKFIX,
CodeActionKind::REFACTOR,
CodeActionKind::REFACTOR_EXTRACT,
CodeActionKind::REFACTOR_INLINE,
CodeActionKind::REFACTOR_REWRITE,
]),
resolve_provider: Some(true),
work_done_progress_options: Default::default(),
})
})
}