Skip to content

Make rendering of fix diffs more concise - #26161

Merged
AlexWaygood merged 5 commits into
mainfrom
alex/subdiagnostic-context-lines
Jun 22, 2026
Merged

Make rendering of fix diffs more concise#26161
AlexWaygood merged 5 commits into
mainfrom
alex/subdiagnostic-context-lines

Conversation

@AlexWaygood

@AlexWaygood AlexWaygood commented Jun 19, 2026

Copy link
Copy Markdown
Member

Summary

On main:

Screenshot image

with this PR:

Screenshot image

This makes our rendering of fix diffs more similar to how we render annotations. It's also more similar to rustc fix suggestions:

Screenshot image

The functional changes in this PR are in ruff_db. Everything else is snapshot changes.

Test Plan

I added a test

@AlexWaygood
AlexWaygood requested a review from a team as a code owner June 19, 2026 19:03
@AlexWaygood AlexWaygood added ty Multi-file analysis & type inference diagnostics Related to reporting of diagnostics. labels Jun 19, 2026
@astral-sh-bot
astral-sh-bot Bot requested a review from MichaReiser June 19, 2026 19:04
@astral-sh-bot

astral-sh-bot Bot commented Jun 19, 2026

Copy link
Copy Markdown

Memory usage report

Summary

Project Old New Diff Outcome
flake8 30.82MB 30.82MB -
prefect 518.54MB 518.54MB -0.00% (24.00B) ⬇️
trio 77.56MB 77.55MB -0.01% (6.14kB) ⬇️
sphinx 193.95MB 193.94MB -0.01% (16.53kB) ⬇️

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
parsed_module 19.36MB 19.36MB -0.00% (24.00B) ⬇️

trio

Name Old New Diff Outcome
parsed_module 15.04MB 15.04MB -0.04% (6.14kB) ⬇️

sphinx

Name Old New Diff Outcome
parsed_module 18.37MB 18.36MB -0.09% (16.53kB) ⬇️

@astral-sh-bot

astral-sh-bot Bot commented Jun 19, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

No diagnostic changes detected ✅

Flaky changes detected. This PR summary excludes flaky changes; see the HTML report for details.

Full report with detailed diff (timing results)

@AlexWaygood
AlexWaygood marked this pull request as draft June 19, 2026 19:09
@astral-sh-bot

astral-sh-bot Bot commented Jun 19, 2026

Copy link
Copy Markdown

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@AlexWaygood
AlexWaygood force-pushed the alex/subdiagnostic-context-lines branch from 317ed58 to 42ee9cf Compare June 19, 2026 19:40
@AlexWaygood
AlexWaygood marked this pull request as ready for review June 19, 2026 20:04
@AlexWaygood
AlexWaygood requested review from a team as code owners June 19, 2026 20:04
@MichaReiser

Copy link
Copy Markdown
Member

Reducing the context size makes sense to me, but I'm not sure if 0 is ideal. Let's say you have something like this

if a in (
	"a",
	"b",
	"a",
	"c"
): ...

Ruff flags the duplicate "a" in the set. I think the diagnostic itself is understandable (or at least, could be made that way) by highlighting both occurrences of "a" (it might still be somewhat difficult with context window 0, but at least you have the line numbers).

But the fix with a context window now shows you one line that deletes "a". You won't be able to tell whether it deletes the first or second "a" without cross referencing with the diagnostic code frame. That's why I'm leaning towards retaining at least 1 line of context.

It might also be helpful to make the same change in Ruff and publish the snapshot diff somewhere. Ruff's coverage is much better.

unformatted: File would be reformatted
--> input.py:1:1
|
-

@MichaReiser MichaReiser Jun 20, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E.g. this diff is not very useful anymore. We could as well omit it

|
help: Remove unused import: `os`
|
- import os # F401

@MichaReiser MichaReiser Jun 20, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, why are we omitting line numbers now? Oh, is it because the diff shows the line numbers after applying the fix. Hmm, this is somewhat surprising to me (@ntBre). Without line numbers, the diff doesn't feel very useful to me anymore

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which line number would we display here? I believe we went with the new line number to avoid both the old approach of showing both (e.g. 1 2 |) and to avoid confusing situations like:

1 - import os
1 | x = y

I'd have to look at the code again, but from what I remember I think it might be tricky to detect that we're in this situation (no relevant context and only a deletion).

@AlexWaygood

Copy link
Copy Markdown
Member Author

It might also be helpful to make the same change in Ruff and publish the snapshot diff somewhere. Ruff's coverage is much better.

It results in a huuuuge diff on this PR, so I got scared and backed out that change 😆 but this makes sense

@AlexWaygood

Copy link
Copy Markdown
Member Author

(And yep, I'll bump the context window to 1)

@AlexWaygood
AlexWaygood marked this pull request as draft June 20, 2026 12:08
@AlexWaygood
AlexWaygood force-pushed the alex/subdiagnostic-context-lines branch 3 times, most recently from 5929e7c to 0e4ed0c Compare June 20, 2026 12:20
@AlexWaygood
AlexWaygood force-pushed the alex/subdiagnostic-context-lines branch from 0e4ed0c to 22df38a Compare June 20, 2026 12:22
@AlexWaygood

Copy link
Copy Markdown
Member Author

I bumped the context window to 1. I also added a mechanism similar to #24694 so that same-annotation fix diffs are merged if they are <=2 lines apart. Here's the new before/after for the diagnostic in the PR description.

Before image
On this PR image

@AlexWaygood
AlexWaygood marked this pull request as ready for review June 20, 2026 18:41
@astral-sh-bot
astral-sh-bot Bot requested a review from ntBre June 20, 2026 18:41
@AlexWaygood
AlexWaygood requested review from MichaReiser and removed request for ntBre June 20, 2026 18:41

@MichaReiser MichaReiser left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the context of 1. I haven't looked through the entire diff, but I noticed a few extra empty lines that aren't clear to me where they come from

- print( 'hello' )
5 + print("hello")
6 | ```
|

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we now retaining more lines here

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a 1-row gutter around fix-diff hunks. This is similar to what we do for our diagnostic annotations, and was again inspired by what rustc does for its fix diffs. Here's what rustc does:

rustc diff suggestion image

It allows the fix diff to "breathe" a little bit by adding a little bit of padding below the help message, making the rendering look less cluttered. I found the "cluttered" issue was especially a problem with a small context window. Here's an example diff rendering on this PR currently:

Current rendering with the gutter image

and I could make this change to the PR:

Patch
diff --git a/crates/ruff_db/src/diagnostic/render/full.rs b/crates/ruff_db/src/diagnostic/render/full.rs
index 1dffd0f65c..88913f675e 100644
--- a/crates/ruff_db/src/diagnostic/render/full.rs
+++ b/crates/ruff_db/src/diagnostic/render/full.rs
@@ -113,15 +113,6 @@ impl<'a> Diff<'a> {
             merge_window: config.merge_window,
         })
     }
-
-    fn write_gutter(&self, f: &mut std::fmt::Formatter, width: NonZeroUsize) -> std::fmt::Result {
-        writeln!(
-            f,
-            "{line} {separator}",
-            line = fmt_styled(Line { index: None, width }, self.stylesheet.line_no),
-            separator = fmt_styled("|", self.stylesheet.line_no),
-        )
-    }
 }

 impl std::fmt::Display for Diff<'_> {
@@ -211,8 +202,6 @@ impl std::fmt::Display for Diff<'_> {
                 writeln!(f, "{:>1$} cell {cell}", ":::", digit_with.get() + 3)?;
             }

-            self.write_gutter(f, digit_with)?;
-
             for (idx, group) in grouped_ops.iter().enumerate() {
                 if idx > 0 {
                     writeln!(f, "{:-^1$}", "-", 80)?;
@@ -273,8 +262,6 @@ impl std::fmt::Display for Diff<'_> {
                     }
                 }
             }
-
-            self.write_gutter(f, digit_with)?;
         }

         match self.fix.applicability() {

which would make the same diagnostic look like this, which I find to still be an improvement over main, but looks a bit cluttered to my eyes:

Rendering without the gutter image

Comment thread crates/ruff/tests/cli/lint.rs
Comment thread crates/ruff_db/src/diagnostic/render/full.rs Outdated
@AlexWaygood AlexWaygood changed the title [ty] Make rendering of fix diffs more concise Make rendering of fix diffs more concise Jun 22, 2026
@AlexWaygood
AlexWaygood enabled auto-merge (squash) June 22, 2026 16:53
@AlexWaygood
AlexWaygood merged commit 8c03352 into main Jun 22, 2026
58 of 59 checks passed
@AlexWaygood
AlexWaygood deleted the alex/subdiagnostic-context-lines branch June 22, 2026 16:53
PeterJCLaw added a commit to PeterJCLaw/ruff that referenced this pull request Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

diagnostics Related to reporting of diagnostics. ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants