Skip to content

Commit 5aa3a4c

Browse files
bors[bot]kjeremy
andauthored
Merge #4516
4516: LSP: Two stage initialization r=kjeremy a=kjeremy Fills in server information. Derives CodeAction capabilities from the client. If code action literals are unsupported we fall back to the "simple support" which just sends back commands (this is already supported in our config). The difference being that we did not adjust our server capabilities so that if the client was checking for `CodeActionProvider: "true"` in the response that would have failed. Part of #144 Fixes #4130 (the specific case called out in that issue) Co-authored-by: kjeremy <[email protected]>
2 parents 90332ca + acc5e8d commit 5aa3a4c

File tree

3 files changed

+55
-26
lines changed

3 files changed

+55
-26
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/rust-analyzer/src/bin/main.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,25 @@ fn run_server() -> Result<()> {
7474
log::info!("lifecycle: server started");
7575

7676
let (connection, io_threads) = Connection::stdio();
77-
let server_capabilities = serde_json::to_value(rust_analyzer::server_capabilities()).unwrap();
7877

79-
let initialize_params = connection.initialize(server_capabilities)?;
78+
let (initialize_id, initialize_params) = connection.initialize_start()?;
8079
let initialize_params =
8180
from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
8281

82+
let server_capabilities = rust_analyzer::server_capabilities(&initialize_params.capabilities);
83+
84+
let initialize_result = lsp_types::InitializeResult {
85+
capabilities: server_capabilities,
86+
server_info: Some(lsp_types::ServerInfo {
87+
name: String::from("rust-analyzer"),
88+
version: Some(String::from(env!("REV"))),
89+
}),
90+
};
91+
92+
let initialize_result = serde_json::to_value(initialize_result).unwrap();
93+
94+
connection.initialize_finish(initialize_id, initialize_result)?;
95+
8396
if let Some(client_info) = initialize_params.client_info {
8497
log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
8598
}

crates/rust-analyzer/src/caps.rs

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@
22
use std::env;
33

44
use lsp_types::{
5-
CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability,
6-
CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions,
7-
FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions,
8-
RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability,
9-
SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions,
10-
ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
11-
TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions,
5+
CallHierarchyServerCapability, ClientCapabilities, CodeActionOptions,
6+
CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
7+
DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
8+
ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
9+
SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
10+
SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
11+
TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
12+
WorkDoneProgressOptions,
1213
};
1314
use serde_json::json;
1415

1516
use crate::semantic_tokens;
1617

17-
pub fn server_capabilities() -> ServerCapabilities {
18+
pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
19+
let code_action_provider = code_action_capabilities(client_caps);
20+
1821
ServerCapabilities {
1922
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
2023
open_close: Some(true),
@@ -46,20 +49,7 @@ pub fn server_capabilities() -> ServerCapabilities {
4649
document_highlight_provider: Some(true),
4750
document_symbol_provider: Some(true),
4851
workspace_symbol_provider: Some(true),
49-
code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions {
50-
// Advertise support for all built-in CodeActionKinds
51-
code_action_kinds: Some(vec![
52-
lsp_types::code_action_kind::EMPTY.to_string(),
53-
lsp_types::code_action_kind::QUICKFIX.to_string(),
54-
lsp_types::code_action_kind::REFACTOR.to_string(),
55-
lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
56-
lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
57-
lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
58-
lsp_types::code_action_kind::SOURCE.to_string(),
59-
lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
60-
]),
61-
work_done_progress_options: Default::default(),
62-
})),
52+
code_action_provider: Some(code_action_provider),
6353
code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
6454
document_formatting_provider: Some(true),
6555
document_range_formatting_provider: None,
@@ -98,3 +88,29 @@ pub fn server_capabilities() -> ServerCapabilities {
9888
})),
9989
}
10090
}
91+
92+
fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
93+
client_caps
94+
.text_document
95+
.as_ref()
96+
.and_then(|it| it.code_action.as_ref())
97+
.and_then(|it| it.code_action_literal_support.as_ref())
98+
.map_or(CodeActionProviderCapability::Simple(true), |_| {
99+
CodeActionProviderCapability::Options(CodeActionOptions {
100+
// Advertise support for all built-in CodeActionKinds.
101+
// Ideally we would base this off of the client capabilities
102+
// but the client is supposed to fall back gracefully for unknown values.
103+
code_action_kinds: Some(vec![
104+
lsp_types::code_action_kind::EMPTY.to_string(),
105+
lsp_types::code_action_kind::QUICKFIX.to_string(),
106+
lsp_types::code_action_kind::REFACTOR.to_string(),
107+
lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
108+
lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
109+
lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
110+
lsp_types::code_action_kind::SOURCE.to_string(),
111+
lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
112+
]),
113+
work_done_progress_options: Default::default(),
114+
})
115+
})
116+
}

0 commit comments

Comments
 (0)