vim: Prevent flickering during movement actions (#52270)

## Context

Closes #52202

Some actions we're unnecessarily delayed during execution by a
yield_now().await call, causing flickering while moving around.

Video Before:


https://github.com/user-attachments/assets/f9922915-8bc7-4e9e-8ce9-18a1e898b69e

Video After:


https://github.com/user-attachments/assets/a46a6338-3fef-4784-8fd7-ecec07a28cf6



## How to Review

when we call the yield in workspace.rs

## 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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- vim: fixed screen flickering during motions.

Co-authored-by: Cameron Mcloughlin <cameron.studdstreet@gmail.com>
This commit is contained in:
Finn EitreimandCameron Mcloughlin authored and GitHub committed 2026-04-20 19:57:19 +01:00
1 parent 8d49ee3a7c
commit ef9d8dd88f
1 file changed
+20 -17
+20 -17
View File
@@ -3364,24 +3364,27 @@ impl Workspace {
};
keystroke
};
cx.update(|window, cx| {
let focused = window.focused(cx);
window.dispatch_keystroke(keystroke.clone(), cx);
if window.focused(cx) != focused {
// dispatch_keystroke may cause the focus to change.
// draw's side effect is to schedule the FocusChanged events in the current flush effect cycle
// And we need that to happen before the next keystroke to keep vim mode happy...
// (Note that the tests always do this implicitly, so you must manually test with something like:
// "bindings": { "g z": ["workspace::SendKeystrokes", ": j <enter> u"]}
// )
window.draw(cx).clear();
}
})
.ok();
let focus_changed = cx
.update(|window, cx| {
let focused = window.focused(cx);
window.dispatch_keystroke(keystroke.clone(), cx);
if window.focused(cx) != focused {
// dispatch_keystroke may cause the focus to change.
// draw's side effect is to schedule the FocusChanged events in the current flush effect cycle
// And we need that to happen before the next keystroke to keep vim mode happy...
// (Note that the tests always do this implicitly, so you must manually test with something like:
// "bindings": { "g z": ["workspace::SendKeystrokes", ": j <enter> u"]}
// )
window.draw(cx).clear();
return true;
}
false
})
.unwrap_or(false);
// Yield between synthetic keystrokes so deferred focus and
// other effects can settle before dispatching the next key.
yield_now().await;
if focus_changed {
yield_now().await;
}
}
*keystrokes.borrow_mut() = Default::default();