From 5e0321793303138e16040250a065c619cd5bd125 Mon Sep 17 00:00:00 2001
From: Charlie Marsh <charlie.r.marsh@gmail.com>
Date: Thu, 9 Nov 2023 19:57:18 -0800
Subject: [PATCH] Avoid writing empty source on excluded files (#317)

Right now, if the user tries to fix or format an excluded file, we don't
write anything to `stdout`. As a result, the LSP then overwrites the
file with the empty string.

This is a compromise fix whereby we avoid writing empty fixes in the
LSP. It's a "compromise" in that it'll do the wrong thing in some cases,
e.g., if the file is _just_ `import os`, we won't remove that when the
user runs "Fix all". However, I think we already had this behavior in
the LSP in the past, and we can fix it for newer versions by changing
Ruff to output the unchanged file.

## Test Plan

Ran the debug extension.

Opened a first-party file, and ensured that formatting and linting work
as before (with the exception of the `import os` case).

Opened a third-party file, and ensured that formatting and linting had
no effect (and didn't delete the file).
---
 ruff_lsp/server.py | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/ruff_lsp/server.py b/ruff_lsp/server.py
index e1e6091..c3bbe4e 100755
--- a/ruff_lsp/server.py
+++ b/ruff_lsp/server.py
@@ -1114,7 +1114,10 @@ async def format_document(params: DocumentFormattingParams) -> list[TextEdit] |
     document = Document.from_cell_or_text_uri(params.text_document.uri)
 
     result = await _run_format_on_document(document)
-    if result is None or result.exit_code != 0:
+    if result is None or result.exit_code:
+        return None
+
+    if not result.stdout and document.source.strip():
         return None
 
     if document.kind is DocumentKind.Cell:
@@ -1145,6 +1148,9 @@ def _result_to_workspace_edit(
     if result is None:
         return None
 
+    if not result.stdout and document.source.strip():
+        return None
+
     if document.kind is DocumentKind.Text:
         edits = _fixed_source_to_edits(
             original_source=document.source, fixed_source=result.stdout.decode("utf-8")