Skip to content

Commit 29c3421

Browse files
committed
Don't return any TextEdit if formatting is unchanged
I found that `textDocument/formatting` was always returning a full `TextEdit` replacement, even when there are no changes, which caused Vim (w/ vim-lsp) to always indicate a modified buffer after formatting. We can easily compare whether there were changes and return `null` if not, so the client knows there's nothing to do.
1 parent b14bf68 commit 29c3421

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

crates/rust-analyzer/src/handlers.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -748,10 +748,15 @@ pub(crate) fn handle_formatting(
748748
}
749749
}
750750

751-
Ok(Some(vec![lsp_types::TextEdit {
752-
range: Range::new(Position::new(0, 0), end_position),
753-
new_text: captured_stdout,
754-
}]))
751+
if *file == captured_stdout {
752+
// The document is already formatted correctly -- no edits needed.
753+
Ok(None)
754+
} else {
755+
Ok(Some(vec![lsp_types::TextEdit {
756+
range: Range::new(Position::new(0, 0), end_position),
757+
new_text: captured_stdout,
758+
}]))
759+
}
755760
}
756761

757762
fn handle_fixes(

crates/rust-analyzer/tests/rust-analyzer/main.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,42 @@ pub use std::collections::HashMap;
259259
);
260260
}
261261

262+
#[test]
263+
fn test_format_document_unchanged() {
264+
if skip_slow_tests() {
265+
return;
266+
}
267+
268+
let server = project(
269+
r#"
270+
//- /Cargo.toml
271+
[package]
272+
name = "foo"
273+
version = "0.0.0"
274+
275+
//- /src/lib.rs
276+
fn main() {}
277+
"#,
278+
)
279+
.wait_until_workspace_is_loaded();
280+
281+
server.request::<Formatting>(
282+
DocumentFormattingParams {
283+
text_document: server.doc_id("src/lib.rs"),
284+
options: FormattingOptions {
285+
tab_size: 4,
286+
insert_spaces: false,
287+
insert_final_newline: None,
288+
trim_final_newlines: None,
289+
trim_trailing_whitespace: None,
290+
properties: HashMap::new(),
291+
},
292+
work_done_progress_params: WorkDoneProgressParams::default(),
293+
},
294+
json!(null),
295+
);
296+
}
297+
262298
#[test]
263299
fn test_missing_module_code_action() {
264300
if skip_slow_tests() {

0 commit comments

Comments
 (0)