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

@ -511,7 +511,7 @@ impl PickerDelegate for TasksModalDelegate {
.child(
left_button
.map(|(label, action)| {
let keybind = KeyBinding::for_action(&*action, window);
let keybind = KeyBinding::for_action(&*action, window, cx);
Button::new("edit-current-task", label)
.label_size(LabelSize::Small)
@ -530,7 +530,7 @@ impl PickerDelegate for TasksModalDelegate {
secondary: current_modifiers.secondary(),
}
.boxed_clone();
this.children(KeyBinding::for_action(&*action, window).map(|keybind| {
this.children(KeyBinding::for_action(&*action, window, cx).map(|keybind| {
let spawn_oneshot_label = if current_modifiers.secondary() {
"Spawn Oneshot Without History"
} else {
@ -545,26 +545,28 @@ impl PickerDelegate for TasksModalDelegate {
})
}))
} else if current_modifiers.secondary() {
this.children(KeyBinding::for_action(&menu::SecondaryConfirm, window).map(
|keybind| {
let label = if is_recent_selected {
"Rerun Without History"
} else {
"Spawn Without History"
};
Button::new("spawn", label)
.label_size(LabelSize::Small)
.key_binding(keybind)
.on_click(move |_, window, cx| {
window.dispatch_action(
menu::SecondaryConfirm.boxed_clone(),
cx,
)
})
},
))
this.children(
KeyBinding::for_action(&menu::SecondaryConfirm, window, cx).map(
|keybind| {
let label = if is_recent_selected {
"Rerun Without History"
} else {
"Spawn Without History"
};
Button::new("spawn", label)
.label_size(LabelSize::Small)
.key_binding(keybind)
.on_click(move |_, window, cx| {
window.dispatch_action(
menu::SecondaryConfirm.boxed_clone(),
cx,
)
})
},
),
)
} else {
this.children(KeyBinding::for_action(&menu::Confirm, window).map(
this.children(KeyBinding::for_action(&menu::Confirm, window, cx).map(
|keybind| {
let run_entry_label =
if is_recent_selected { "Rerun" } else { "Spawn" };