Display case-sensitive keybindings for vim commands (#24322)

This Pull Request tackles the issue outline in #14287 by changing the
way `KeyBinding`s for vim mode are displayed in the command palette.
It's worth pointing out that this whole thing was pretty much
implemented by Conrad Irwin during a pairing session, I just tried to
clean up some other changes introduced for a different issue, while
improving some comments.

Here's a quick list of the changes introduced:

- Update `KeyBinding` with a new `vim_mode` field to determine whether
the keybinding should be displayed in vim mode.
- Update the way `KeyBinding` is rendered, so as to detect if the
keybinding is for vim mode, if it is, only display keys in uppercase if
they require the shift key.
- Introduce a new global state – `VimStyle(bool)` - use to determine
whether `vim_mode` should be enabled or disabled when creating a new
`KeyBinding` struct. This global state is automatically set by the `vim`
crate whenever vim mode is enabled or disabled.
- Since the app's context is now required when building a `KeyBinding` ,
update a lot of callers to correctly pass this context.

And before and after screenshots, for comparison:

| before | after |
|--------|-------|
| <img width="1050" alt="SCR-20250205-tyeq"
src="https://github.com/user-attachments/assets/e577206d-2a3d-4e06-a96f-a98899cc15c0"
/> | <img width="1050" alt="SCR-20250205-tylh"
src="https://github.com/user-attachments/assets/ebbf70a9-e838-4d32-aee5-0ffde94d65fb"
/> |

Closes #14287 

Release Notes:

- Fix rendering of vim commands to preserve case sensitivity

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Dino 2025-02-15 05:03:59 +00:00 committed by GitHub
parent 14289b5a6e
commit e0fc767c11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 236 additions and 165 deletions

View file

@ -1,5 +1,5 @@
use gpui::{div, Context, Element, Entity, Render, Subscription, WeakEntity, Window};
use itertools::Itertools;
use ui::text_for_keystrokes;
use workspace::{item::ItemHandle, ui::prelude::*, StatusItemView};
use crate::{Vim, VimEvent, VimGlobals};
@ -15,7 +15,7 @@ impl ModeIndicator {
/// Construct a new mode indicator in this window.
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
cx.observe_pending_input(window, |this: &mut Self, window, cx| {
this.update_pending_keys(window);
this.update_pending_keys(window, cx);
cx.notify();
})
.detach();
@ -50,13 +50,10 @@ impl ModeIndicator {
}
}
fn update_pending_keys(&mut self, window: &mut Window) {
self.pending_keys = window.pending_input_keystrokes().map(|keystrokes| {
keystrokes
.iter()
.map(|keystroke| format!("{}", keystroke))
.join(" ")
});
fn update_pending_keys(&mut self, window: &mut Window, cx: &App) {
self.pending_keys = window
.pending_input_keystrokes()
.map(|keystrokes| text_for_keystrokes(keystrokes, cx));
}
fn vim(&self) -> Option<Entity<Vim>> {

View file

@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsStore};
use std::borrow::BorrowMut;
use std::{fmt::Display, ops::Range, sync::Arc};
use ui::{Context, SharedString};
use ui::{Context, KeyBinding, SharedString};
use workspace::searchable::Direction;
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
@ -217,6 +217,7 @@ impl VimGlobals {
cx.observe_global::<SettingsStore>(move |cx| {
if Vim::enabled(cx) {
KeyBinding::set_vim_mode(cx, true);
CommandPaletteFilter::update_global(cx, |filter, _| {
filter.show_namespace(Vim::NAMESPACE);
});
@ -224,6 +225,7 @@ impl VimGlobals {
interceptor.set(Box::new(command_interceptor));
});
} else {
KeyBinding::set_vim_mode(cx, true);
*Vim::globals(cx) = VimGlobals::default();
CommandPaletteInterceptor::update_global(cx, |interceptor, _| {
interceptor.clear();