Skip to content

Commit 6bf4fc2

Browse files
committed
LSP: Two stage initialization
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.
1 parent 5c1c23e commit 6bf4fc2

File tree

3 files changed

+57
-26
lines changed

3 files changed

+57
-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: None,
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: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,47 @@ use std::env;
44
use crate::semantic_tokens;
55

66
use lsp_types::{
7-
CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability,
8-
CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions,
9-
FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions,
10-
RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability,
11-
SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions,
12-
ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
13-
TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions,
7+
CallHierarchyServerCapability, ClientCapabilities, CodeActionOptions,
8+
CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
9+
DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
10+
ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
11+
SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
12+
SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
13+
TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
14+
WorkDoneProgressOptions,
1415
};
1516

16-
pub fn server_capabilities() -> ServerCapabilities {
17+
pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
18+
let mut code_action_provider = CodeActionProviderCapability::Simple(true);
19+
20+
match client_caps.text_document.as_ref() {
21+
Some(it) => {
22+
match it.code_action.as_ref().and_then(|c| c.code_action_literal_support.as_ref()) {
23+
Some(_literal_support) => {
24+
code_action_provider =
25+
CodeActionProviderCapability::Options(CodeActionOptions {
26+
// Advertise support for all built-in CodeActionKinds.
27+
// Ideally we would base this off of the client capabilities
28+
// but the client is supposed to fall back gracefully for unknown values.
29+
code_action_kinds: Some(vec![
30+
lsp_types::code_action_kind::EMPTY.to_string(),
31+
lsp_types::code_action_kind::QUICKFIX.to_string(),
32+
lsp_types::code_action_kind::REFACTOR.to_string(),
33+
lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
34+
lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
35+
lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
36+
lsp_types::code_action_kind::SOURCE.to_string(),
37+
lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
38+
]),
39+
work_done_progress_options: Default::default(),
40+
});
41+
}
42+
None => {}
43+
}
44+
}
45+
None => {}
46+
};
47+
1748
ServerCapabilities {
1849
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
1950
open_close: Some(true),
@@ -45,20 +76,7 @@ pub fn server_capabilities() -> ServerCapabilities {
4576
document_highlight_provider: Some(true),
4677
document_symbol_provider: Some(true),
4778
workspace_symbol_provider: Some(true),
48-
code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions {
49-
// Advertise support for all built-in CodeActionKinds
50-
code_action_kinds: Some(vec![
51-
lsp_types::code_action_kind::EMPTY.to_string(),
52-
lsp_types::code_action_kind::QUICKFIX.to_string(),
53-
lsp_types::code_action_kind::REFACTOR.to_string(),
54-
lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
55-
lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
56-
lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
57-
lsp_types::code_action_kind::SOURCE.to_string(),
58-
lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
59-
]),
60-
work_done_progress_options: Default::default(),
61-
})),
79+
code_action_provider: Some(code_action_provider),
6280
code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
6381
document_formatting_provider: Some(true),
6482
document_range_formatting_provider: None,

0 commit comments

Comments
 (0)