]> git.lizzy.rs Git - rust.git/commitdiff
Don't return any TextEdit if formatting is unchanged
authorJosh Stone <cuviper@gmail.com>
Wed, 16 Sep 2020 17:05:41 +0000 (10:05 -0700)
committerJosh Stone <cuviper@gmail.com>
Wed, 16 Sep 2020 17:05:41 +0000 (10:05 -0700)
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.

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

index 64cb4d96cbb5d3047fda15b769224cc402380920..c0943a54dc6c47ed108d251073495e88f0d36f9d 100644 (file)
@@ -748,10 +748,15 @@ pub(crate) fn handle_formatting(
         }
     }
 
-    Ok(Some(vec![lsp_types::TextEdit {
-        range: Range::new(Position::new(0, 0), end_position),
-        new_text: captured_stdout,
-    }]))
+    if *file == captured_stdout {
+        // The document is already formatted correctly -- no edits needed.
+        Ok(None)
+    } else {
+        Ok(Some(vec![lsp_types::TextEdit {
+            range: Range::new(Position::new(0, 0), end_position),
+            new_text: captured_stdout,
+        }]))
+    }
 }
 
 fn handle_fixes(
index 0880d04253f570e3253f9c62359601733e329ef9..06726f9576e5185c6a2965be8e74464c67b02f36 100644 (file)
@@ -259,6 +259,42 @@ fn main() {}
     );
 }
 
+#[test]
+fn test_format_document_unchanged() {
+    if skip_slow_tests() {
+        return;
+    }
+
+    let server = project(
+        r#"
+//- /Cargo.toml
+[package]
+name = "foo"
+version = "0.0.0"
+
+//- /src/lib.rs
+fn main() {}
+"#,
+    )
+    .wait_until_workspace_is_loaded();
+
+    server.request::<Formatting>(
+        DocumentFormattingParams {
+            text_document: server.doc_id("src/lib.rs"),
+            options: FormattingOptions {
+                tab_size: 4,
+                insert_spaces: false,
+                insert_final_newline: None,
+                trim_final_newlines: None,
+                trim_trailing_whitespace: None,
+                properties: HashMap::new(),
+            },
+            work_done_progress_params: WorkDoneProgressParams::default(),
+        },
+        json!(null),
+    );
+}
+
 #[test]
 fn test_missing_module_code_action() {
     if skip_slow_tests() {