Skip to content

editor: Defer rendering the git blame popover until after the markdown is parsed#52231

Merged
SomeoneToIgnore merged 1 commit intozed-industries:mainfrom
timvermeulen:fix-blame-popover-glitch
Apr 16, 2026
Merged

editor: Defer rendering the git blame popover until after the markdown is parsed#52231
SomeoneToIgnore merged 1 commit intozed-industries:mainfrom
timvermeulen:fix-blame-popover-glitch

Conversation

@timvermeulen
Copy link
Copy Markdown
Contributor

Fixes this single-frame glitch that sometimes occurs when the git blame popover is rendered before the markdown has been parsed.

Screen.Recording.2026-03-23.at.17.28.37.mov

Self-Review Checklist

  • I've reviewed my own diff for quality, security, and reliability
  • Unsafe blocks (if any) have justifying comments
  • The content is consistent with the UI/UX checklist
  • Tests cover the new/changed behavior
  • Performance impact has been considered and is acceptable

Release Notes:

  • Fixed a visual glitch where the git blame popover could briefly appear empty while its markdown content was being parsed
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Mar 23, 2026
@github-actions github-actions Bot added the community champion Issues filed by our amazing community champions! 🫶 label Mar 23, 2026
@zed-codeowner-coordinator zed-codeowner-coordinator Bot requested review from a team, as-cii and dinocosta and removed request for a team March 23, 2026 17:08
@maxdeviant maxdeviant changed the title editor: Defer rendering the git blame popover until after the markdow… Mar 23, 2026
@timvermeulen timvermeulen force-pushed the fix-blame-popover-glitch branch from 896450e to e8a1c89 Compare March 26, 2026 19:16
@zelenenka zelenenka assigned SomeoneToIgnore and unassigned as-cii Apr 15, 2026
Copy link
Copy Markdown
Contributor

@SomeoneToIgnore SomeoneToIgnore left a comment

Choose a reason for hiding this comment

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

Thank you for the idea.

Roughly estimating, we have 63 occurrences of Entity<Markdown>, which means we have to fix them all?

Would it make more sense to show an empty div() in the markdown's rendering if it's not parsed yet instead?

@timvermeulen
Copy link
Copy Markdown
Contributor Author

Would it make more sense to show an empty div() in the markdown's rendering if it's not parsed yet instead?

It seems to me that this is already effectively what's happening, with the popover only very briefly fitting above the blame annotation while it doesn't yet contain the markdown, but it needing too much vertical space and therefore being rendered below the blame annotation once the markdown has been parsed.

Roughly estimating, we have 63 occurrences of Entity<Markdown>, which means we have to fix them all?

Yeah, fair, maybe there are other places where we might want to do something similar. Though I think this one is particularly noticeable because of the aforementioned way the position of the blame popover is determined. It's not super obvious tot me that not rendering the thing that contains markdown before the markdown has been parsed is the right behavior in every place that markdown is being rendered?

@SomeoneToIgnore
Copy link
Copy Markdown
Contributor

SomeoneToIgnore commented Apr 16, 2026

Thank you, watching frame-by-frame, I think indeed we show the div there already:

before after

My main concern is how ad-hoc this change is, as we sure someone could do better?

Even in this example, what does it show for the footer?
Nothing for me, at least, despite scrolling all the way down:

image

which means that we're not done for this very example still?

If you insist you can do nothing on top of it, I can merge it, as it's better than before, of course...

@timvermeulen
Copy link
Copy Markdown
Contributor Author

Thank you, watching frame-by-frame, I think indeed we show the div there already:

Yep, apologies, the PR description was a bit light on details, it could have been clearer.

My main concern is how ad-hoc this change is, as we sure someone could do better?

There seems to be some precedence for it here:

let Some((false, markdown)) = self.get_or_create_markdown(
mat.candidate_id,
Some(source),
true,
&completions,
cx,
) else {
return None;
};

Where get_or_create_markdown returns markdown.is_parsing() for the first tuple element (in one of the code paths, at least). Agreed on it being ad-hoc though, it's just currently the only hook that the Markdown type has to determine whether rendering it will render the actual markdown or the initial ParsedMarkdown::default().

I think I currently tend towards fixing this in the way that I did in this PR using Markdown::is_parsing because it's the only place where I've noticed this async markdown parsing to be this noticeable visually (specifically due to how the blame popover is positioned based on essentially the size of the rendered markdown). If the fact that Markdown silently renders as ParsedMarkdown::default() before the markdown has been parsed became a footgun that caused similar glitches in other places, then I'd definitely be inclined to look for a more general solution.

Still I'm totally happy to iterate on this, if this feels too hacky 🙂 I'm not entirely sure right now what a more robust solution would look like, though.

Even in this example, what does it show for the footer?
Nothing for me, at least, despite scrolling all the way down:

Oh interesting! This looks like a completely separate bug, that the blame popover falls off the bottom of the window if the popover is too tall, instead of shrinking. I can also reproduce this in the regular Zed.

@SomeoneToIgnore
Copy link
Copy Markdown
Contributor

I am sure that completion-related popovers that render completion items' details and docs, and signature help popovers are sure affected by this design, e.g. the latter used to flicker with empty elements when invoked rapidly.

The general way to see it fixed is the type system?
Somewhere, there's an impl Render for T being called, and we should have methods to return Option of such item possible to render only when it's ready.

I agree that's a rather complex task though, and a "completely separate bug" is actually another way to make this PR to look complete?
Its original intent, the way I understand it, is to make the git blame popover look nice when hovered, and we're somewhere halfway there too.

@timvermeulen
Copy link
Copy Markdown
Contributor Author

I am sure that completion-related popovers that render completion items' details and docs, and signature help popovers are sure affected by this design, e.g. the latter used to flicker with empty elements when invoked rapidly.

Yeah fair, other places are definitely affected. Indeed when I add an artificial delay to the markdown parsing future, it shows that something similar happens when hovering over a symbol in the editor:

Screen.Recording.2026-04-16.at.15.12.23.mov

It's just less jarring because this one is actually empty, whereas a blame popover without markdown still contains a lot of other info 😄

The general way to see it fixed is the type system?
Somewhere, there's an impl Render for T being called, and we should have methods to return Option of such item possible to render only when it's ready.

Right. And then you'd probably also need a way to handle the case where a child element is not yet ready, either by propagating this state of not-readiness or by e.g. rendering a fallback when you don't want to propagate this, like a Suspense boundary in React. I'll look into how invasive of a change something like this would be.

I agree that's a rather complex task though, and a "completely separate bug" is actually another way to make this PR to look complete?

I'd prefer keeping that separate from this PR because (as I understand it) it has nothing to do with the markdown rendering, and I'll first need to investigate which other UI elements might have the same behavior of being positioned partially outside the window.

Copy link
Copy Markdown
Contributor

@SomeoneToIgnore SomeoneToIgnore left a comment

Choose a reason for hiding this comment

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

Great, looks like we're on the same page, thank you for looking at this.

Let's have the biggest offender fixed this way then, and see if any follow-up PRs can handle the issue structurally.

@SomeoneToIgnore SomeoneToIgnore enabled auto-merge (squash) April 16, 2026 14:01
@SomeoneToIgnore SomeoneToIgnore force-pushed the fix-blame-popover-glitch branch from e8a1c89 to 9340e03 Compare April 16, 2026 14:06
@SomeoneToIgnore SomeoneToIgnore merged commit 7d365ef into zed-industries:main Apr 16, 2026
31 checks passed
@timvermeulen timvermeulen deleted the fix-blame-popover-glitch branch April 17, 2026 13:42
G36maid pushed a commit to G36maid/zed that referenced this pull request Apr 29, 2026
…n is parsed (zed-industries#52231)

Fixes this single-frame glitch that sometimes occurs when the git blame
popover is rendered before the markdown has been parsed.


https://github.com/user-attachments/assets/d5a322c3-e46f-4597-a10f-a676da57daa7

## Self-Review Checklist

<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed a visual glitch where the git blame popover could briefly appear
empty while its markdown content was being parsed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement community champion Issues filed by our amazing community champions! 🫶

4 participants