Skip to content

Commit 5b13c24

Browse files
bors[bot]vsrs
andauthored
Merge #5516
5516: Better LSP conformance r=matklad a=vsrs At the moment rust-analyzer does not fully conform to the LSP. This PR fixes two LSP related issues: 1) rust-analyzer sends predefined server capabilities and does not take supplied client capabilities in mind. 2) rust-analyzer uses dynamic `textDocument/didSave` registration even if the client does not support it. Co-authored-by: vsrs <[email protected]>
2 parents c3defe2 + a84dc44 commit 5b13c24

File tree

2 files changed

+43
-32
lines changed

2 files changed

+43
-32
lines changed

crates/rust-analyzer/src/config.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ pub struct ClientCapsConfig {
128128
pub hover_actions: bool,
129129
pub status_notification: bool,
130130
pub signature_help_label_offsets: bool,
131+
pub dynamic_watched_files: bool,
131132
}
132133

133134
impl Config {
@@ -290,6 +291,13 @@ impl Config {
290291
}
291292

292293
pub fn update_caps(&mut self, caps: &ClientCapabilities) {
294+
if let Some(ws_caps) = caps.workspace.as_ref() {
295+
if let Some(did_change_watched_files) = ws_caps.did_change_watched_files.as_ref() {
296+
self.client_caps.dynamic_watched_files =
297+
did_change_watched_files.dynamic_registration.unwrap_or(false);
298+
}
299+
}
300+
293301
if let Some(doc_caps) = caps.text_document.as_ref() {
294302
if let Some(value) = doc_caps.definition.as_ref().and_then(|it| it.link_support) {
295303
self.client_caps.location_link = value;

crates/rust-analyzer/src/main_loop.rs

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -106,38 +106,41 @@ impl GlobalState {
106106
);
107107
};
108108

109-
let save_registration_options = lsp_types::TextDocumentSaveRegistrationOptions {
110-
include_text: Some(false),
111-
text_document_registration_options: lsp_types::TextDocumentRegistrationOptions {
112-
document_selector: Some(vec![
113-
lsp_types::DocumentFilter {
114-
language: None,
115-
scheme: None,
116-
pattern: Some("**/*.rs".into()),
117-
},
118-
lsp_types::DocumentFilter {
119-
language: None,
120-
scheme: None,
121-
pattern: Some("**/Cargo.toml".into()),
122-
},
123-
lsp_types::DocumentFilter {
124-
language: None,
125-
scheme: None,
126-
pattern: Some("**/Cargo.lock".into()),
127-
},
128-
]),
129-
},
130-
};
131-
132-
let registration = lsp_types::Registration {
133-
id: "textDocument/didSave".to_string(),
134-
method: "textDocument/didSave".to_string(),
135-
register_options: Some(serde_json::to_value(save_registration_options).unwrap()),
136-
};
137-
self.send_request::<lsp_types::request::RegisterCapability>(
138-
lsp_types::RegistrationParams { registrations: vec![registration] },
139-
|_, _| (),
140-
);
109+
if self.config.client_caps.dynamic_watched_files {
110+
let save_registration_options = lsp_types::TextDocumentSaveRegistrationOptions {
111+
include_text: Some(false),
112+
text_document_registration_options: lsp_types::TextDocumentRegistrationOptions {
113+
document_selector: Some(vec![
114+
lsp_types::DocumentFilter {
115+
language: None,
116+
scheme: None,
117+
pattern: Some("**/*.rs".into()),
118+
},
119+
lsp_types::DocumentFilter {
120+
language: None,
121+
scheme: None,
122+
pattern: Some("**/Cargo.toml".into()),
123+
},
124+
lsp_types::DocumentFilter {
125+
language: None,
126+
scheme: None,
127+
pattern: Some("**/Cargo.lock".into()),
128+
},
129+
]),
130+
},
131+
};
132+
133+
let registration = lsp_types::Registration {
134+
id: "textDocument/didSave".to_string(),
135+
method: "textDocument/didSave".to_string(),
136+
register_options: Some(serde_json::to_value(save_registration_options).unwrap()),
137+
};
138+
139+
self.send_request::<lsp_types::request::RegisterCapability>(
140+
lsp_types::RegistrationParams { registrations: vec![registration] },
141+
|_, _| (),
142+
);
143+
}
141144

142145
self.fetch_workspaces();
143146

0 commit comments

Comments
 (0)