1 //! Advertises the capabilities of the LSP Server.
3 CallHierarchyServerCapability, ClientCapabilities, CodeActionKind, CodeActionOptions,
4 CodeActionProviderCapability, CodeLensOptions, CompletionOptions, DeclarationCapability,
5 DocumentOnTypeFormattingOptions, FileOperationFilter, FileOperationPattern,
6 FileOperationPatternKind, FileOperationRegistrationOptions, FoldingRangeProviderCapability,
7 HoverProviderCapability, ImplementationProviderCapability, OneOf, RenameOptions, SaveOptions,
8 SelectionRangeProviderCapability, SemanticTokensFullOptions, SemanticTokensLegend,
9 SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
10 TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
11 WorkDoneProgressOptions, WorkspaceFileOperationsServerCapabilities,
12 WorkspaceServerCapabilities,
16 use crate::config::{Config, RustfmtConfig};
17 use crate::semantic_tokens;
19 pub fn server_capabilities(config: &Config) -> ServerCapabilities {
21 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
22 open_close: Some(true),
23 change: Some(TextDocumentSyncKind::INCREMENTAL),
25 will_save_wait_until: None,
26 save: Some(SaveOptions::default().into()),
28 hover_provider: Some(HoverProviderCapability::Simple(true)),
29 completion_provider: Some(CompletionOptions {
30 resolve_provider: completions_resolve_provider(&config.caps),
31 trigger_characters: Some(vec![":".to_string(), ".".to_string(), "'".to_string()]),
32 all_commit_characters: None,
33 completion_item: None,
34 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
36 signature_help_provider: Some(SignatureHelpOptions {
37 trigger_characters: Some(vec!["(".to_string(), ",".to_string()]),
38 retrigger_characters: None,
39 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
41 declaration_provider: Some(DeclarationCapability::Simple(true)),
42 definition_provider: Some(OneOf::Left(true)),
43 type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
44 implementation_provider: Some(ImplementationProviderCapability::Simple(true)),
45 references_provider: Some(OneOf::Left(true)),
46 document_highlight_provider: Some(OneOf::Left(true)),
47 document_symbol_provider: Some(OneOf::Left(true)),
48 workspace_symbol_provider: Some(OneOf::Left(true)),
49 code_action_provider: Some(code_action_capabilities(&config.caps)),
50 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
51 document_formatting_provider: Some(OneOf::Left(true)),
52 document_range_formatting_provider: match config.rustfmt() {
53 RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => Some(OneOf::Left(true)),
54 _ => Some(OneOf::Left(false)),
56 document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
57 first_trigger_character: "=".to_string(),
58 more_trigger_character: Some(vec![".".to_string(), ">".to_string(), "{".to_string()]),
60 selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
61 folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
62 rename_provider: Some(OneOf::Right(RenameOptions {
63 prepare_provider: Some(true),
64 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
66 linked_editing_range_provider: None,
67 document_link_provider: None,
69 execute_command_provider: None,
70 workspace: Some(WorkspaceServerCapabilities {
71 workspace_folders: None,
72 file_operations: Some(WorkspaceFileOperationsServerCapabilities {
76 will_rename: Some(FileOperationRegistrationOptions {
79 scheme: Some(String::from("file")),
80 pattern: FileOperationPattern {
81 glob: String::from("**/*.rs"),
82 matches: Some(FileOperationPatternKind::File),
87 scheme: Some(String::from("file")),
88 pattern: FileOperationPattern {
89 glob: String::from("**"),
90 matches: Some(FileOperationPatternKind::Folder),
100 call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
101 semantic_tokens_provider: Some(
102 SemanticTokensOptions {
103 legend: SemanticTokensLegend {
104 token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(),
105 token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
108 full: Some(SemanticTokensFullOptions::Delta { delta: Some(true) }),
110 work_done_progress_options: Default::default(),
114 moniker_provider: None,
115 experimental: Some(json!({
117 "openCargoToml": true,
120 "parentModule": true,
123 "kinds": [ "cargo" ],
125 "workspaceSymbolScopeKindFiltering": true,
130 fn completions_resolve_provider(client_caps: &ClientCapabilities) -> Option<bool> {
131 if completion_item_edit_resolve(client_caps) {
134 tracing::info!("No `additionalTextEdits` completion resolve capability was found in the client capabilities, autoimport completion is disabled");
139 /// Parses client capabilities and returns all completion resolve capabilities rust-analyzer supports.
140 pub(crate) fn completion_item_edit_resolve(caps: &ClientCapabilities) -> bool {
153 .any(|cap_string| cap_string.as_str() == "additionalTextEdits"),
158 fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
162 .and_then(|it| it.code_action.as_ref())
163 .and_then(|it| it.code_action_literal_support.as_ref())
164 .map_or(CodeActionProviderCapability::Simple(true), |_| {
165 CodeActionProviderCapability::Options(CodeActionOptions {
166 // Advertise support for all built-in CodeActionKinds.
167 // Ideally we would base this off of the client capabilities
168 // but the client is supposed to fall back gracefully for unknown values.
169 code_action_kinds: Some(vec![
170 CodeActionKind::EMPTY,
171 CodeActionKind::QUICKFIX,
172 CodeActionKind::REFACTOR,
173 CodeActionKind::REFACTOR_EXTRACT,
174 CodeActionKind::REFACTOR_INLINE,
175 CodeActionKind::REFACTOR_REWRITE,
177 resolve_provider: Some(true),
178 work_done_progress_options: Default::default(),