1 //! Advertises the capabilities of the LSP Server.
3 CallHierarchyServerCapability
, ClientCapabilities
, CodeActionKind
, CodeActionOptions
,
4 CodeActionProviderCapability
, CodeLensOptions
, CompletionOptions
,
5 CompletionOptionsCompletionItem
, DeclarationCapability
, DocumentOnTypeFormattingOptions
,
6 FileOperationFilter
, FileOperationPattern
, FileOperationPatternKind
,
7 FileOperationRegistrationOptions
, FoldingRangeProviderCapability
, HoverProviderCapability
,
8 ImplementationProviderCapability
, InlayHintOptions
, InlayHintServerCapabilities
, OneOf
,
9 PositionEncodingKind
, RenameOptions
, SaveOptions
, SelectionRangeProviderCapability
,
10 SemanticTokensFullOptions
, SemanticTokensLegend
, SemanticTokensOptions
, ServerCapabilities
,
11 SignatureHelpOptions
, TextDocumentSyncCapability
, TextDocumentSyncKind
,
12 TextDocumentSyncOptions
, TypeDefinitionProviderCapability
, WorkDoneProgressOptions
,
13 WorkspaceFileOperationsServerCapabilities
, WorkspaceServerCapabilities
,
17 use crate::config
::{Config, RustfmtConfig}
;
18 use crate::lsp_ext
::supports_utf8
;
19 use crate::semantic_tokens
;
21 pub fn server_capabilities(config
: &Config
) -> ServerCapabilities
{
23 position_encoding
: if supports_utf8(config
.caps()) {
24 Some(PositionEncodingKind
::UTF8
)
28 text_document_sync
: Some(TextDocumentSyncCapability
::Options(TextDocumentSyncOptions
{
29 open_close
: Some(true),
30 change
: Some(TextDocumentSyncKind
::INCREMENTAL
),
32 will_save_wait_until
: None
,
33 save
: Some(SaveOptions
::default().into()),
35 hover_provider
: Some(HoverProviderCapability
::Simple(true)),
36 completion_provider
: Some(CompletionOptions
{
37 resolve_provider
: completions_resolve_provider(config
.caps()),
38 trigger_characters
: Some(vec
![
44 all_commit_characters
: None
,
45 completion_item
: completion_item(config
),
46 work_done_progress_options
: WorkDoneProgressOptions { work_done_progress: None }
,
48 signature_help_provider
: Some(SignatureHelpOptions
{
49 trigger_characters
: Some(vec
!["(".to_string(), ",".to_string(), "<".to_string()]),
50 retrigger_characters
: None
,
51 work_done_progress_options
: WorkDoneProgressOptions { work_done_progress: None }
,
53 declaration_provider
: Some(DeclarationCapability
::Simple(true)),
54 definition_provider
: Some(OneOf
::Left(true)),
55 type_definition_provider
: Some(TypeDefinitionProviderCapability
::Simple(true)),
56 implementation_provider
: Some(ImplementationProviderCapability
::Simple(true)),
57 references_provider
: Some(OneOf
::Left(true)),
58 document_highlight_provider
: Some(OneOf
::Left(true)),
59 document_symbol_provider
: Some(OneOf
::Left(true)),
60 workspace_symbol_provider
: Some(OneOf
::Left(true)),
61 code_action_provider
: Some(code_action_capabilities(config
.caps())),
62 code_lens_provider
: Some(CodeLensOptions { resolve_provider: Some(true) }
),
63 document_formatting_provider
: Some(OneOf
::Left(true)),
64 document_range_formatting_provider
: match config
.rustfmt() {
65 RustfmtConfig
::Rustfmt { enable_range_formatting: true, .. }
=> Some(OneOf
::Left(true)),
66 _
=> Some(OneOf
::Left(false)),
68 document_on_type_formatting_provider
: Some(DocumentOnTypeFormattingOptions
{
69 first_trigger_character
: "=".to_string(),
70 more_trigger_character
: Some(more_trigger_character(config
)),
72 selection_range_provider
: Some(SelectionRangeProviderCapability
::Simple(true)),
73 folding_range_provider
: Some(FoldingRangeProviderCapability
::Simple(true)),
74 rename_provider
: Some(OneOf
::Right(RenameOptions
{
75 prepare_provider
: Some(true),
76 work_done_progress_options
: WorkDoneProgressOptions { work_done_progress: None }
,
78 linked_editing_range_provider
: None
,
79 document_link_provider
: None
,
81 execute_command_provider
: None
,
82 workspace
: Some(WorkspaceServerCapabilities
{
83 workspace_folders
: None
,
84 file_operations
: Some(WorkspaceFileOperationsServerCapabilities
{
88 will_rename
: Some(FileOperationRegistrationOptions
{
91 scheme
: Some(String
::from("file")),
92 pattern
: FileOperationPattern
{
93 glob
: String
::from("**/*.rs"),
94 matches
: Some(FileOperationPatternKind
::File
),
99 scheme
: Some(String
::from("file")),
100 pattern
: FileOperationPattern
{
101 glob
: String
::from("**"),
102 matches
: Some(FileOperationPatternKind
::Folder
),
112 call_hierarchy_provider
: Some(CallHierarchyServerCapability
::Simple(true)),
113 semantic_tokens_provider
: Some(
114 SemanticTokensOptions
{
115 legend
: SemanticTokensLegend
{
116 token_types
: semantic_tokens
::SUPPORTED_TYPES
.to_vec(),
117 token_modifiers
: semantic_tokens
::SUPPORTED_MODIFIERS
.to_vec(),
120 full
: Some(SemanticTokensFullOptions
::Delta { delta: Some(true) }
),
122 work_done_progress_options
: Default
::default(),
126 moniker_provider
: None
,
127 inlay_hint_provider
: Some(OneOf
::Right(InlayHintServerCapabilities
::Options(
129 work_done_progress_options
: Default
::default(),
130 resolve_provider
: Some(true),
133 experimental
: Some(json
!({
134 "externalDocs": true,
137 "matchingBrace": true,
140 "openCargoToml": true,
141 "parentModule": true,
143 "kinds": [ "cargo" ],
146 "workspaceSymbolScopeKindFiltering": true,
151 fn completions_resolve_provider(client_caps
: &ClientCapabilities
) -> Option
<bool
> {
152 if completion_item_edit_resolve(client_caps
) {
155 tracing
::info
!("No `additionalTextEdits` completion resolve capability was found in the client capabilities, autoimport completion is disabled");
160 /// Parses client capabilities and returns all completion resolve capabilities rust-analyzer supports.
161 pub(crate) fn completion_item_edit_resolve(caps
: &ClientCapabilities
) -> bool
{
174 .any(|cap_string
| cap_string
.as_str() == "additionalTextEdits"),
179 fn completion_item(config
: &Config
) -> Option
<CompletionOptionsCompletionItem
> {
180 Some(CompletionOptionsCompletionItem
{
181 label_details_support
: Some(config
.completion_label_details_support()),
185 fn code_action_capabilities(client_caps
: &ClientCapabilities
) -> CodeActionProviderCapability
{
189 .and_then(|it
| it
.code_action
.as_ref())
190 .and_then(|it
| it
.code_action_literal_support
.as_ref())
191 .map_or(CodeActionProviderCapability
::Simple(true), |_
| {
192 CodeActionProviderCapability
::Options(CodeActionOptions
{
193 // Advertise support for all built-in CodeActionKinds.
194 // Ideally we would base this off of the client capabilities
195 // but the client is supposed to fall back gracefully for unknown values.
196 code_action_kinds
: Some(vec
![
197 CodeActionKind
::EMPTY
,
198 CodeActionKind
::QUICKFIX
,
199 CodeActionKind
::REFACTOR
,
200 CodeActionKind
::REFACTOR_EXTRACT
,
201 CodeActionKind
::REFACTOR_INLINE
,
202 CodeActionKind
::REFACTOR_REWRITE
,
204 resolve_provider
: Some(true),
205 work_done_progress_options
: Default
::default(),
210 fn more_trigger_character(config
: &Config
) -> Vec
<String
> {
211 let mut res
= vec
![".".to_string(), ">".to_string(), "{".to_string()];
212 if config
.snippet_cap() {
213 res
.push("<".to_string());