diff options
-rw-r--r-- | crates/rust-analyzer/src/caps.rs | 108 |
1 files changed, 36 insertions, 72 deletions
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index 34fefe034..37d695448 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs | |||
@@ -7,18 +7,16 @@ 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, SemanticTokensServerCapabilities, ServerCapabilities, | 10 | SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, |
11 | SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, | 11 | TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability, |
12 | TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions, | 12 | WorkDoneProgressOptions, |
13 | }; | 13 | }; |
14 | use serde_json::{json, Value}; | 14 | use serde_json::json; |
15 | 15 | ||
16 | use crate::semantic_tokens; | 16 | use crate::semantic_tokens; |
17 | 17 | ||
18 | pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities { | 18 | pub 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); | ||
22 | 20 | ||
23 | ServerCapabilities { | 21 | ServerCapabilities { |
24 | text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { | 22 | text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { |
@@ -71,58 +69,29 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti | |||
71 | execute_command_provider: None, | 69 | execute_command_provider: None, |
72 | workspace: None, | 70 | workspace: None, |
73 | call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), | 71 | call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), |
74 | semantic_tokens_provider, | 72 | semantic_tokens_provider: Some( |
75 | experimental, | 73 | SemanticTokensOptions { |
76 | } | 74 | legend: SemanticTokensLegend { |
77 | } | 75 | token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(), |
78 | 76 | token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(), | |
79 | fn experimental_capabilities(client_caps: &ClientCapabilities) -> Option<Value> { | 77 | }, |
80 | client_caps.experimental.as_ref().and_then(|it| { | ||
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()); | ||
95 | } | ||
96 | |||
97 | if map.contains_key("parentModule") { | ||
98 | result.insert("parentModule".into(), true.into()); | ||
99 | } | ||
100 | 78 | ||
101 | if map.contains_key("runnables") { | 79 | document_provider: Some(SemanticTokensDocumentProvider::Bool(true)), |
102 | result.insert("runnables".into(), json!({ "kinds": [ "cargo" ] })); | 80 | range_provider: Some(true), |
81 | work_done_progress_options: Default::default(), | ||
103 | } | 82 | } |
104 | 83 | .into(), | |
105 | obj | 84 | ), |
106 | }) | 85 | experimental: Some(json!({ |
107 | }) | 86 | "joinLines": true, |
108 | } | 87 | "ssr": true, |
109 | 88 | "onEnter": true, | |
110 | fn semantic_tokens_capabilities( | 89 | "parentModule": true, |
111 | client_caps: &ClientCapabilities, | 90 | "runnables": { |
112 | ) -> Option<SemanticTokensServerCapabilities> { | 91 | "kinds": [ "cargo" ], |
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(), | ||
119 | }, | 92 | }, |
120 | 93 | })), | |
121 | document_provider: Some(SemanticTokensDocumentProvider::Bool(true)), | 94 | } |
122 | range_provider: Some(true), | ||
123 | work_done_progress_options: Default::default(), | ||
124 | } | ||
125 | .into()) | ||
126 | } | 95 | } |
127 | 96 | ||
128 | fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability { | 97 | fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability { |
@@ -131,24 +100,19 @@ fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProvi | |||
131 | .as_ref() | 100 | .as_ref() |
132 | .and_then(|it| it.code_action.as_ref()) | 101 | .and_then(|it| it.code_action.as_ref()) |
133 | .and_then(|it| it.code_action_literal_support.as_ref()) | 102 | .and_then(|it| it.code_action_literal_support.as_ref()) |
134 | .map_or(CodeActionProviderCapability::Simple(true), |caps| { | 103 | .map_or(CodeActionProviderCapability::Simple(true), |_| { |
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 | |||
150 | CodeActionProviderCapability::Options(CodeActionOptions { | 104 | CodeActionProviderCapability::Options(CodeActionOptions { |
151 | code_action_kinds: Some(action_kinds), | 105 | // Advertise support for all built-in CodeActionKinds. |
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 | ]), | ||
152 | work_done_progress_options: Default::default(), | 116 | work_done_progress_options: Default::default(), |
153 | }) | 117 | }) |
154 | }) | 118 | }) |