1 //! Advertises the capabilities of the LSP Server.
2 use ide_db
::line_index
::WideEncoding
;
4 CallHierarchyServerCapability
, ClientCapabilities
, CodeActionKind
, CodeActionOptions
,
5 CodeActionProviderCapability
, CodeLensOptions
, CompletionOptions
,
6 CompletionOptionsCompletionItem
, DeclarationCapability
, DocumentOnTypeFormattingOptions
,
7 FileOperationFilter
, FileOperationPattern
, FileOperationPatternKind
,
8 FileOperationRegistrationOptions
, FoldingRangeProviderCapability
, HoverProviderCapability
,
9 ImplementationProviderCapability
, InlayHintOptions
, InlayHintServerCapabilities
, OneOf
,
10 PositionEncodingKind
, RenameOptions
, SaveOptions
, SelectionRangeProviderCapability
,
11 SemanticTokensFullOptions
, SemanticTokensLegend
, SemanticTokensOptions
, ServerCapabilities
,
12 SignatureHelpOptions
, TextDocumentSyncCapability
, TextDocumentSyncKind
,
13 TextDocumentSyncOptions
, TypeDefinitionProviderCapability
, WorkDoneProgressOptions
,
14 WorkspaceFileOperationsServerCapabilities
, WorkspaceFoldersServerCapabilities
,
15 WorkspaceServerCapabilities
,
19 use crate::config
::{Config, RustfmtConfig}
;
20 use crate::line_index
::PositionEncoding
;
21 use crate::lsp_ext
::negotiated_encoding
;
22 use crate::semantic_tokens
;
24 pub fn server_capabilities(config
: &Config
) -> ServerCapabilities
{
26 position_encoding
: match negotiated_encoding(config
.caps()) {
27 PositionEncoding
::Utf8
=> Some(PositionEncodingKind
::UTF8
),
28 PositionEncoding
::Wide(wide
) => match wide
{
29 WideEncoding
::Utf16
=> Some(PositionEncodingKind
::UTF16
),
30 WideEncoding
::Utf32
=> Some(PositionEncodingKind
::UTF32
),
34 text_document_sync
: Some(TextDocumentSyncCapability
::Options(TextDocumentSyncOptions
{
35 open_close
: Some(true),
36 change
: Some(TextDocumentSyncKind
::INCREMENTAL
),
38 will_save_wait_until
: None
,
39 save
: Some(SaveOptions
::default().into()),
41 hover_provider
: Some(HoverProviderCapability
::Simple(true)),
42 completion_provider
: Some(CompletionOptions
{
43 resolve_provider
: completions_resolve_provider(config
.caps()),
44 trigger_characters
: Some(vec
![
50 all_commit_characters
: None
,
51 completion_item
: completion_item(config
),
52 work_done_progress_options
: WorkDoneProgressOptions { work_done_progress: None }
,
54 signature_help_provider
: Some(SignatureHelpOptions
{
55 trigger_characters
: Some(vec
!["(".to_string(), ",".to_string(), "<".to_string()]),
56 retrigger_characters
: None
,
57 work_done_progress_options
: WorkDoneProgressOptions { work_done_progress: None }
,
59 declaration_provider
: Some(DeclarationCapability
::Simple(true)),
60 definition_provider
: Some(OneOf
::Left(true)),
61 type_definition_provider
: Some(TypeDefinitionProviderCapability
::Simple(true)),
62 implementation_provider
: Some(ImplementationProviderCapability
::Simple(true)),
63 references_provider
: Some(OneOf
::Left(true)),
64 document_highlight_provider
: Some(OneOf
::Left(true)),
65 document_symbol_provider
: Some(OneOf
::Left(true)),
66 workspace_symbol_provider
: Some(OneOf
::Left(true)),
67 code_action_provider
: Some(code_action_capabilities(config
.caps())),
68 code_lens_provider
: Some(CodeLensOptions { resolve_provider: Some(true) }
),
69 document_formatting_provider
: Some(OneOf
::Left(true)),
70 document_range_formatting_provider
: match config
.rustfmt() {
71 RustfmtConfig
::Rustfmt { enable_range_formatting: true, .. }
=> Some(OneOf
::Left(true)),
72 _
=> Some(OneOf
::Left(false)),
74 document_on_type_formatting_provider
: Some(DocumentOnTypeFormattingOptions
{
75 first_trigger_character
: "=".to_string(),
76 more_trigger_character
: Some(more_trigger_character(config
)),
78 selection_range_provider
: Some(SelectionRangeProviderCapability
::Simple(true)),
79 folding_range_provider
: Some(FoldingRangeProviderCapability
::Simple(true)),
80 rename_provider
: Some(OneOf
::Right(RenameOptions
{
81 prepare_provider
: Some(true),
82 work_done_progress_options
: WorkDoneProgressOptions { work_done_progress: None }
,
84 linked_editing_range_provider
: None
,
85 document_link_provider
: None
,
87 execute_command_provider
: None
,
88 workspace
: Some(WorkspaceServerCapabilities
{
89 workspace_folders
: Some(WorkspaceFoldersServerCapabilities
{
90 supported
: Some(true),
91 change_notifications
: Some(OneOf
::Left(true)),
93 file_operations
: Some(WorkspaceFileOperationsServerCapabilities
{
97 will_rename
: Some(FileOperationRegistrationOptions
{
100 scheme
: Some(String
::from("file")),
101 pattern
: FileOperationPattern
{
102 glob
: String
::from("**/*.rs"),
103 matches
: Some(FileOperationPatternKind
::File
),
107 FileOperationFilter
{
108 scheme
: Some(String
::from("file")),
109 pattern
: FileOperationPattern
{
110 glob
: String
::from("**"),
111 matches
: Some(FileOperationPatternKind
::Folder
),
121 call_hierarchy_provider
: Some(CallHierarchyServerCapability
::Simple(true)),
122 semantic_tokens_provider
: Some(
123 SemanticTokensOptions
{
124 legend
: SemanticTokensLegend
{
125 token_types
: semantic_tokens
::SUPPORTED_TYPES
.to_vec(),
126 token_modifiers
: semantic_tokens
::SUPPORTED_MODIFIERS
.to_vec(),
129 full
: Some(SemanticTokensFullOptions
::Delta { delta: Some(true) }
),
131 work_done_progress_options
: Default
::default(),
135 moniker_provider
: None
,
136 inlay_hint_provider
: Some(OneOf
::Right(InlayHintServerCapabilities
::Options(
138 work_done_progress_options
: Default
::default(),
139 resolve_provider
: Some(true),
142 inline_value_provider
: None
,
143 experimental
: Some(json
!({
144 "externalDocs": true,
147 "matchingBrace": true,
150 "openCargoToml": true,
151 "parentModule": true,
153 "kinds": [ "cargo" ],
156 "workspaceSymbolScopeKindFiltering": true,
161 fn completions_resolve_provider(client_caps
: &ClientCapabilities
) -> Option
<bool
> {
162 if completion_item_edit_resolve(client_caps
) {
165 tracing
::info
!("No `additionalTextEdits` completion resolve capability was found in the client capabilities, autoimport completion is disabled");
170 /// Parses client capabilities and returns all completion resolve capabilities rust-analyzer supports.
171 pub(crate) fn completion_item_edit_resolve(caps
: &ClientCapabilities
) -> bool
{
184 .any(|cap_string
| cap_string
.as_str() == "additionalTextEdits"),
189 fn completion_item(config
: &Config
) -> Option
<CompletionOptionsCompletionItem
> {
190 Some(CompletionOptionsCompletionItem
{
191 label_details_support
: Some(config
.completion_label_details_support()),
195 fn code_action_capabilities(client_caps
: &ClientCapabilities
) -> CodeActionProviderCapability
{
199 .and_then(|it
| it
.code_action
.as_ref())
200 .and_then(|it
| it
.code_action_literal_support
.as_ref())
201 .map_or(CodeActionProviderCapability
::Simple(true), |_
| {
202 CodeActionProviderCapability
::Options(CodeActionOptions
{
203 // Advertise support for all built-in CodeActionKinds.
204 // Ideally we would base this off of the client capabilities
205 // but the client is supposed to fall back gracefully for unknown values.
206 code_action_kinds
: Some(vec
![
207 CodeActionKind
::EMPTY
,
208 CodeActionKind
::QUICKFIX
,
209 CodeActionKind
::REFACTOR
,
210 CodeActionKind
::REFACTOR_EXTRACT
,
211 CodeActionKind
::REFACTOR_INLINE
,
212 CodeActionKind
::REFACTOR_REWRITE
,
214 resolve_provider
: Some(true),
215 work_done_progress_options
: Default
::default(),
220 fn more_trigger_character(config
: &Config
) -> Vec
<String
> {
221 let mut res
= vec
![".".to_string(), ">".to_string(), "{".to_string()];
222 if config
.snippet_cap() {
223 res
.push("<".to_string());