perl_lsp_capability_map/
lib.rs1use lsp_types::ServerCapabilities;
7use perl_lsp_feature_ids::*;
8
9pub fn feature_ids_from_caps(c: &ServerCapabilities) -> Vec<&'static str> {
11 let mut v = Vec::new();
12
13 if c.completion_provider.is_some() {
15 v.push(LSP_COMPLETION);
16 }
17 if c.hover_provider.is_some() {
18 v.push(LSP_HOVER);
19 }
20 if c.signature_help_provider.is_some() {
21 v.push(LSP_SIGNATURE_HELP);
22 }
23 if c.definition_provider.is_some() {
24 v.push(LSP_DEFINITION);
25 }
26 if c.declaration_provider.is_some() {
27 v.push(LSP_DECLARATION);
28 }
29 if c.notebook_document_sync.is_some() {
30 v.push(LSP_NOTEBOOK_DOCUMENT_SYNC);
31 }
32 if c.type_definition_provider.is_some() {
33 v.push(LSP_TYPE_DEFINITION);
34 }
35 if c.implementation_provider.is_some() {
36 v.push(LSP_IMPLEMENTATION);
37 }
38 if c.references_provider.is_some() {
39 v.push(LSP_REFERENCES);
40 }
41 if c.document_highlight_provider.is_some() {
42 v.push(LSP_DOCUMENT_HIGHLIGHT);
43 }
44 if c.document_symbol_provider.is_some() {
45 v.push(LSP_DOCUMENT_SYMBOL);
46 }
47 if c.code_action_provider.is_some() {
48 v.push(LSP_CODE_ACTION);
49 }
50 if c.code_lens_provider.is_some() {
51 v.push(LSP_CODE_LENS);
52 }
53 if c.document_link_provider.is_some() {
54 v.push(LSP_DOCUMENT_LINK);
55 }
56 if c.color_provider.is_some() {
57 v.push(LSP_DOCUMENT_COLOR);
58 }
59 if c.document_formatting_provider.is_some() {
60 v.push(LSP_FORMATTING);
61 }
62 if c.document_range_formatting_provider.is_some() {
63 v.push(LSP_RANGE_FORMATTING);
64 }
65 if c.document_on_type_formatting_provider.is_some() {
66 v.push(LSP_ON_TYPE_FORMATTING);
67 }
68 if c.rename_provider.is_some() {
69 v.push(LSP_RENAME);
70 }
71 if c.folding_range_provider.is_some() {
72 v.push(LSP_FOLDING_RANGE);
73 }
74 if c.selection_range_provider.is_some() {
75 v.push(LSP_SELECTION_RANGE);
76 }
77 if c.linked_editing_range_provider.is_some() {
78 v.push(LSP_LINKED_EDITING_RANGE);
79 }
80 if c.call_hierarchy_provider.is_some() {
81 v.push(LSP_CALL_HIERARCHY);
82 }
83 if c.semantic_tokens_provider.is_some() {
84 v.push(LSP_SEMANTIC_TOKENS);
85 }
86 if c.moniker_provider.is_some() {
87 v.push(LSP_MONIKER);
88 }
89 if c.inline_value_provider.is_some() {
91 v.push(LSP_INLINE_VALUE);
92 }
93 if c.inlay_hint_provider.is_some() {
94 v.push(LSP_INLAY_HINT);
95 }
96 if c.diagnostic_provider.is_some() {
97 v.push(LSP_PULL_DIAGNOSTICS);
98 }
99
100 if c.workspace_symbol_provider.is_some() {
102 v.push(LSP_WORKSPACE_SYMBOL);
103 }
104 if c.execute_command_provider.is_some() {
105 v.push(LSP_EXECUTE_COMMAND);
106 }
107
108 v.sort();
109 v.dedup();
110 v
111}
112
113pub fn caps_from_feature_ids(features: &[&str]) -> ServerCapabilities {
115 use lsp_types::*;
116
117 let mut caps = ServerCapabilities::default();
118
119 for &feature in features {
120 match feature {
121 LSP_COMPLETION => {
122 caps.completion_provider = Some(CompletionOptions {
123 trigger_characters: Some(vec![
124 "$".to_string(),
125 "@".to_string(),
126 "%".to_string(),
127 ">".to_string(),
128 ":".to_string(),
129 ]),
130 ..Default::default()
131 });
132 }
133 LSP_HOVER => {
134 caps.hover_provider = Some(HoverProviderCapability::Simple(true));
135 }
136 LSP_SIGNATURE_HELP => {
137 caps.signature_help_provider = Some(SignatureHelpOptions {
138 trigger_characters: Some(vec!["(".to_string(), ",".to_string()]),
139 ..Default::default()
140 });
141 }
142 LSP_DEFINITION => {
143 caps.definition_provider = Some(OneOf::Left(true));
144 }
145 LSP_DECLARATION => {
146 caps.declaration_provider = Some(DeclarationCapability::Simple(true));
147 }
148 LSP_NOTEBOOK_DOCUMENT_SYNC => {
149 caps.notebook_document_sync = Some(OneOf::Left(NotebookDocumentSyncOptions {
150 notebook_selector: vec![NotebookSelector::ByNotebook {
151 notebook: Notebook::String("jupyter-notebook".to_string()),
152 cells: Some(vec![NotebookCellSelector { language: "perl".to_string() }]),
153 }],
154 save: Some(true),
155 }));
156 }
157 LSP_TYPE_DEFINITION => {
158 caps.type_definition_provider =
159 Some(TypeDefinitionProviderCapability::Simple(true));
160 }
161 LSP_IMPLEMENTATION => {
162 caps.implementation_provider = Some(ImplementationProviderCapability::Simple(true));
163 }
164 LSP_REFERENCES => {
165 caps.references_provider = Some(OneOf::Left(true));
166 }
167 LSP_DOCUMENT_SYMBOL => {
168 caps.document_symbol_provider = Some(OneOf::Left(true));
169 }
170 LSP_CODE_ACTION => {
171 caps.code_action_provider = Some(CodeActionProviderCapability::Simple(true));
172 }
173 LSP_FORMATTING => {
174 caps.document_formatting_provider = Some(OneOf::Left(true));
175 }
176 LSP_RANGE_FORMATTING => {
177 caps.document_range_formatting_provider = Some(OneOf::Left(true));
178 }
179 LSP_RENAME => {
180 caps.rename_provider = Some(OneOf::Left(true));
181 }
182 LSP_FOLDING_RANGE => {
183 caps.folding_range_provider = Some(FoldingRangeProviderCapability::Simple(true));
184 }
185 LSP_SEMANTIC_TOKENS => {
186 caps.semantic_tokens_provider =
187 Some(SemanticTokensServerCapabilities::SemanticTokensOptions(
188 SemanticTokensOptions {
189 legend: SemanticTokensLegend {
190 token_types: vec![
191 SemanticTokenType::NAMESPACE,
192 SemanticTokenType::TYPE,
193 SemanticTokenType::CLASS,
194 SemanticTokenType::ENUM,
195 SemanticTokenType::INTERFACE,
196 SemanticTokenType::STRUCT,
197 SemanticTokenType::TYPE_PARAMETER,
198 SemanticTokenType::PARAMETER,
199 SemanticTokenType::VARIABLE,
200 SemanticTokenType::PROPERTY,
201 SemanticTokenType::ENUM_MEMBER,
202 SemanticTokenType::EVENT,
203 SemanticTokenType::FUNCTION,
204 SemanticTokenType::METHOD,
205 SemanticTokenType::MACRO,
206 SemanticTokenType::KEYWORD,
207 SemanticTokenType::MODIFIER,
208 SemanticTokenType::COMMENT,
209 SemanticTokenType::STRING,
210 SemanticTokenType::NUMBER,
211 SemanticTokenType::REGEXP,
212 SemanticTokenType::OPERATOR,
213 ],
214 token_modifiers: vec![
215 SemanticTokenModifier::DECLARATION,
216 SemanticTokenModifier::DEFINITION,
217 SemanticTokenModifier::READONLY,
218 SemanticTokenModifier::STATIC,
219 SemanticTokenModifier::DEPRECATED,
220 SemanticTokenModifier::ABSTRACT,
221 SemanticTokenModifier::ASYNC,
222 SemanticTokenModifier::MODIFICATION,
223 SemanticTokenModifier::DOCUMENTATION,
224 SemanticTokenModifier::DEFAULT_LIBRARY,
225 ],
226 },
227 full: Some(SemanticTokensFullOptions::Bool(true)),
228 range: Some(true),
229 ..Default::default()
230 },
231 ));
232 }
233 LSP_DOCUMENT_HIGHLIGHT => {
234 caps.document_highlight_provider = Some(OneOf::Left(true));
235 }
236 LSP_CODE_LENS => {
237 caps.code_lens_provider = Some(CodeLensOptions { resolve_provider: Some(true) });
238 }
239 LSP_DOCUMENT_LINK => {
240 caps.document_link_provider = Some(DocumentLinkOptions {
241 resolve_provider: Some(true),
242 work_done_progress_options: WorkDoneProgressOptions::default(),
243 });
244 }
245 LSP_DOCUMENT_COLOR | LSP_COLOR => {
246 caps.color_provider = Some(ColorProviderCapability::Simple(true));
247 }
248 LSP_ON_TYPE_FORMATTING => {
249 caps.document_on_type_formatting_provider = Some(DocumentOnTypeFormattingOptions {
250 first_trigger_character: ";".to_string(),
251 more_trigger_character: Some(vec!["}".to_string()]),
252 });
253 }
254 LSP_SELECTION_RANGE => {
255 caps.selection_range_provider =
256 Some(SelectionRangeProviderCapability::Simple(true));
257 }
258 LSP_LINKED_EDITING_RANGE => {
259 caps.linked_editing_range_provider =
260 Some(LinkedEditingRangeServerCapabilities::Simple(true));
261 }
262 LSP_CALL_HIERARCHY => {
263 caps.call_hierarchy_provider = Some(CallHierarchyServerCapability::Simple(true));
264 }
265 LSP_MONIKER => {
266 caps.moniker_provider =
267 Some(OneOf::Right(MonikerServerCapabilities::Options(MonikerOptions {
268 work_done_progress_options: WorkDoneProgressOptions::default(),
269 })));
270 }
271 LSP_INLINE_VALUE => {
272 caps.inline_value_provider = Some(OneOf::Right(
273 InlineValueServerCapabilities::Options(InlineValueOptions::default()),
274 ));
275 }
276 LSP_INLAY_HINT => {
277 caps.inlay_hint_provider =
278 Some(OneOf::Right(InlayHintServerCapabilities::Options(InlayHintOptions {
279 resolve_provider: Some(true),
280 ..Default::default()
281 })));
282 }
283 LSP_PULL_DIAGNOSTICS => {
284 caps.diagnostic_provider =
285 Some(DiagnosticServerCapabilities::Options(DiagnosticOptions {
286 identifier: Some("perl-lsp".to_string()),
287 inter_file_dependencies: true,
288 workspace_diagnostics: true,
289 ..Default::default()
290 }));
291 }
292 LSP_WORKSPACE_SYMBOL => {
293 caps.workspace_symbol_provider = Some(OneOf::Left(true));
294 }
295 LSP_EXECUTE_COMMAND => {
296 caps.execute_command_provider = Some(ExecuteCommandOptions {
297 commands: vec!["perl.runCritic".to_string()],
298 ..Default::default()
299 });
300 }
301 _ => {
302 }
304 }
305 }
306
307 caps
308}
309
310#[cfg(test)]
311mod tests {
312 use lsp_types::{ColorProviderCapability, ServerCapabilities};
313
314 use super::{LSP_COLOR, LSP_DOCUMENT_COLOR, caps_from_feature_ids, feature_ids_from_caps};
315
316 #[test]
317 fn feature_ids_from_caps_reports_catalog_color_id() {
318 let caps = ServerCapabilities {
319 color_provider: Some(ColorProviderCapability::Simple(true)),
320 ..Default::default()
321 };
322
323 assert_eq!(feature_ids_from_caps(&caps), vec![LSP_DOCUMENT_COLOR]);
324 }
325
326 #[test]
327 fn caps_from_feature_ids_accepts_legacy_color_alias() {
328 let caps = caps_from_feature_ids(&[LSP_COLOR]);
329 assert!(caps.color_provider.is_some());
330 }
331
332 #[test]
333 fn caps_from_feature_ids_accepts_canonical_color_id() {
334 let caps = caps_from_feature_ids(&[LSP_DOCUMENT_COLOR]);
335 assert!(caps.color_provider.is_some());
336 }
337}