]> git.lizzy.rs Git - rust.git/blob - crates/rust-analyzer/src/caps.rs
Latest LSP 3.16 protocol
[rust.git] / crates / rust-analyzer / src / caps.rs
1 //! Advertizes the capabilities of the LSP Server.
2 use std::env;
3
4 use lsp_types::{
5     CallHierarchyServerCapability, ClientCapabilities, CodeActionKind, CodeActionOptions,
6     CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
7     DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, HoverProviderCapability,
8     ImplementationProviderCapability, OneOf, RenameOptions, SaveOptions,
9     SelectionRangeProviderCapability, SemanticTokensFullOptions, SemanticTokensLegend,
10     SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
11     TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
12     WorkDoneProgressOptions,
13 };
14 use serde_json::json;
15
16 use crate::semantic_tokens;
17
18 pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
19     ServerCapabilities {
20         text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
21             open_close: Some(true),
22             change: Some(if env::var("RA_NO_INCREMENTAL_SYNC").is_ok() {
23                 TextDocumentSyncKind::Full
24             } else {
25                 TextDocumentSyncKind::Incremental
26             }),
27             will_save: None,
28             will_save_wait_until: None,
29             save: Some(SaveOptions::default().into()),
30         })),
31         hover_provider: Some(HoverProviderCapability::Simple(true)),
32         completion_provider: Some(CompletionOptions {
33             resolve_provider: None,
34             trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
35             work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
36         }),
37         signature_help_provider: Some(SignatureHelpOptions {
38             trigger_characters: Some(vec!["(".to_string(), ",".to_string()]),
39             retrigger_characters: None,
40             work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
41         }),
42         declaration_provider: None,
43         definition_provider: Some(OneOf::Left(true)),
44         type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
45         implementation_provider: Some(ImplementationProviderCapability::Simple(true)),
46         references_provider: Some(OneOf::Left(true)),
47         document_highlight_provider: Some(OneOf::Left(true)),
48         document_symbol_provider: Some(OneOf::Left(true)),
49         workspace_symbol_provider: Some(OneOf::Left(true)),
50         code_action_provider: Some(code_action_capabilities(client_caps)),
51         code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
52         document_formatting_provider: Some(OneOf::Left(true)),
53         document_range_formatting_provider: None,
54         document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
55             first_trigger_character: "=".to_string(),
56             more_trigger_character: Some(vec![".".to_string(), ">".to_string()]),
57         }),
58         selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
59         semantic_highlighting: None,
60         folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
61         rename_provider: Some(OneOf::Right(RenameOptions {
62             prepare_provider: Some(true),
63             work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
64         })),
65         on_type_rename_provider: None,
66         document_link_provider: None,
67         color_provider: None,
68         execute_command_provider: None,
69         workspace: None,
70         call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
71         semantic_tokens_provider: Some(
72             SemanticTokensOptions {
73                 legend: SemanticTokensLegend {
74                     token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(),
75                     token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
76                 },
77
78                 full: Some(SemanticTokensFullOptions::Delta { delta: Some(true) }),
79                 range: Some(true),
80                 work_done_progress_options: Default::default(),
81             }
82             .into(),
83         ),
84         experimental: Some(json!({
85             "joinLines": true,
86             "ssr": true,
87             "onEnter": true,
88             "parentModule": true,
89             "runnables": {
90                 "kinds": [ "cargo" ],
91             },
92         })),
93     }
94 }
95
96 fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
97     client_caps
98         .text_document
99         .as_ref()
100         .and_then(|it| it.code_action.as_ref())
101         .and_then(|it| it.code_action_literal_support.as_ref())
102         .map_or(CodeActionProviderCapability::Simple(true), |_| {
103             CodeActionProviderCapability::Options(CodeActionOptions {
104                 // Advertise support for all built-in CodeActionKinds.
105                 // Ideally we would base this off of the client capabilities
106                 // but the client is supposed to fall back gracefully for unknown values.
107                 code_action_kinds: Some(vec![
108                     CodeActionKind::EMPTY,
109                     CodeActionKind::QUICKFIX,
110                     CodeActionKind::REFACTOR,
111                     CodeActionKind::REFACTOR_EXTRACT,
112                     CodeActionKind::REFACTOR_INLINE,
113                     CodeActionKind::REFACTOR_REWRITE,
114                 ]),
115                 resolve_provider: Some(true),
116                 work_done_progress_options: Default::default(),
117             })
118         })
119 }