aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/caps.rs108
1 files changed, 72 insertions, 36 deletions
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 37d695448..34fefe034 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -7,16 +7,18 @@ use lsp_types::{
7 DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, HoverProviderCapability, 7 DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, HoverProviderCapability,
8 ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions, 8 ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
9 SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend, 9 SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
10 SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, 10 SemanticTokensOptions, SemanticTokensServerCapabilities, ServerCapabilities,
11 TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability, 11 SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
12 WorkDoneProgressOptions, 12 TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions,
13}; 13};
14use serde_json::json; 14use serde_json::{json, Value};
15 15
16use crate::semantic_tokens; 16use crate::semantic_tokens;
17 17
18pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities { 18pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
19 let code_action_provider = code_action_capabilities(client_caps); 19 let code_action_provider = code_action_capabilities(client_caps);
20 let semantic_tokens_provider = semantic_tokens_capabilities(client_caps);
21 let experimental = experimental_capabilities(client_caps);
20 22
21 ServerCapabilities { 23 ServerCapabilities {
22 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { 24 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
@@ -69,29 +71,58 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
69 execute_command_provider: None, 71 execute_command_provider: None,
70 workspace: None, 72 workspace: None,
71 call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), 73 call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
72 semantic_tokens_provider: Some( 74 semantic_tokens_provider,
73 SemanticTokensOptions { 75 experimental,
74 legend: SemanticTokensLegend { 76 }
75 token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(), 77}
76 token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
77 },
78 78
79 document_provider: Some(SemanticTokensDocumentProvider::Bool(true)), 79fn experimental_capabilities(client_caps: &ClientCapabilities) -> Option<Value> {
80 range_provider: Some(true), 80 client_caps.experimental.as_ref().and_then(|it| {
81 work_done_progress_options: Default::default(), 81 it.as_object().map(|map| {
82 let mut obj = json!({});
83 let result = obj.as_object_mut().unwrap();
84
85 if map.contains_key("joinLines") {
86 result.insert("joinLines".into(), true.into());
87 }
88
89 if map.contains_key("ssr") {
90 result.insert("ssr".into(), true.into());
91 }
92
93 if map.contains_key("onEnter") {
94 result.insert("onEnter".into(), true.into());
82 } 95 }
83 .into(), 96
84 ), 97 if map.contains_key("parentModule") {
85 experimental: Some(json!({ 98 result.insert("parentModule".into(), true.into());
86 "joinLines": true, 99 }
87 "ssr": true, 100
88 "onEnter": true, 101 if map.contains_key("runnables") {
89 "parentModule": true, 102 result.insert("runnables".into(), json!({ "kinds": [ "cargo" ] }));
90 "runnables": { 103 }
91 "kinds": [ "cargo" ], 104
105 obj
106 })
107 })
108}
109
110fn semantic_tokens_capabilities(
111 client_caps: &ClientCapabilities,
112) -> Option<SemanticTokensServerCapabilities> {
113 client_caps.text_document.as_ref().and_then(|it| it.semantic_tokens.as_ref()).map(|_|
114 // client supports semanticTokens
115 SemanticTokensOptions {
116 legend: SemanticTokensLegend {
117 token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(),
118 token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
92 }, 119 },
93 })), 120
94 } 121 document_provider: Some(SemanticTokensDocumentProvider::Bool(true)),
122 range_provider: Some(true),
123 work_done_progress_options: Default::default(),
124 }
125 .into())
95} 126}
96 127
97fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability { 128fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
@@ -100,19 +131,24 @@ fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProvi
100 .as_ref() 131 .as_ref()
101 .and_then(|it| it.code_action.as_ref()) 132 .and_then(|it| it.code_action.as_ref())
102 .and_then(|it| it.code_action_literal_support.as_ref()) 133 .and_then(|it| it.code_action_literal_support.as_ref())
103 .map_or(CodeActionProviderCapability::Simple(true), |_| { 134 .map_or(CodeActionProviderCapability::Simple(true), |caps| {
135 let mut action_kinds = vec![
136 CodeActionKind::EMPTY,
137 CodeActionKind::QUICKFIX,
138 CodeActionKind::REFACTOR,
139 CodeActionKind::REFACTOR_EXTRACT,
140 CodeActionKind::REFACTOR_INLINE,
141 CodeActionKind::REFACTOR_REWRITE,
142 ];
143
144 // Not all clients can fall back gracefully for unknown values.
145 // Microsoft.VisualStudio.LanguageServer.Protocol.CodeActionKind does not support CodeActionKind::EMPTY
146 // So have to filter out.
147 action_kinds
148 .retain(|it| caps.code_action_kind.value_set.contains(&it.as_str().to_owned()));
149
104 CodeActionProviderCapability::Options(CodeActionOptions { 150 CodeActionProviderCapability::Options(CodeActionOptions {
105 // Advertise support for all built-in CodeActionKinds. 151 code_action_kinds: Some(action_kinds),
106 // Ideally we would base this off of the client capabilities
107 // but the client is supposed to fall back gracefully for unknown values.
108 code_action_kinds: Some(vec![
109 CodeActionKind::EMPTY,
110 CodeActionKind::QUICKFIX,
111 CodeActionKind::REFACTOR,
112 CodeActionKind::REFACTOR_EXTRACT,
113 CodeActionKind::REFACTOR_INLINE,
114 CodeActionKind::REFACTOR_REWRITE,
115 ]),
116 work_done_progress_options: Default::default(), 152 work_done_progress_options: Default::default(),
117 }) 153 })
118 }) 154 })