Fix linux zeta modifiers display (#24764)

Improves rendering of Zeta keybind shortcuts on Linux

Before:

![image](https://github.com/user-attachments/assets/9b6a61f7-dade-480f-a864-acdcede05957)

After: (with muting modifier changes merged)

![image](https://github.com/user-attachments/assets/dd616d29-ac2e-4c8b-bf9b-5d74f8e4f1c4)


Release Notes:

- N/A

---------

Co-authored-by: Michael <michael@zed.dev>
Co-authored-by: Agus <agus@zed.dev>
This commit is contained in:
Ben Kunkle 2025-02-12 16:46:42 -06:00 committed by GitHub
parent 522b8d662c
commit df8adc8b11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 89 additions and 49 deletions

View file

@ -92,7 +92,7 @@ impl RenderOnce for KeyBinding {
self.platform_style,
None,
self.size,
false,
true,
))
.map(|el| {
el.child(render_key(&keystroke, self.platform_style, None, self.size))
@ -110,7 +110,7 @@ pub fn render_key(
let key_icon = icon_for_key(keystroke, platform_style);
match key_icon {
Some(icon) => KeyIcon::new(icon, color).size(size).into_any_element(),
None => Key::new(capitalize(&keystroke.key), color)
None => Key::new(util::capitalize(&keystroke.key), color)
.size(size)
.into_any_element(),
}
@ -145,10 +145,12 @@ pub fn render_modifiers(
platform_style: PlatformStyle,
color: Option<Color>,
size: Option<AbsoluteLength>,
standalone: bool,
trailing_separator: bool,
) -> impl Iterator<Item = AnyElement> {
#[derive(Clone)]
enum KeyOrIcon {
Key(&'static str),
Plus,
Icon(IconName),
}
@ -200,23 +202,34 @@ pub fn render_modifiers(
.into_iter()
.filter(|modifier| modifier.enabled)
.collect::<Vec<_>>();
let last_ix = filtered.len().saturating_sub(1);
filtered
let platform_keys = filtered
.into_iter()
.enumerate()
.flat_map(move |(ix, modifier)| match platform_style {
PlatformStyle::Mac => vec![modifier.mac],
PlatformStyle::Linux if standalone && ix == last_ix => vec![modifier.linux],
PlatformStyle::Linux => vec![modifier.linux, KeyOrIcon::Key("+")],
PlatformStyle::Windows if standalone && ix == last_ix => {
vec![modifier.windows]
}
PlatformStyle::Windows => vec![modifier.windows, KeyOrIcon::Key("+")],
.map(move |modifier| match platform_style {
PlatformStyle::Mac => Some(modifier.mac),
PlatformStyle::Linux => Some(modifier.linux),
PlatformStyle::Windows => Some(modifier.windows),
});
let separator = match platform_style {
PlatformStyle::Mac => None,
PlatformStyle::Linux => Some(KeyOrIcon::Plus),
PlatformStyle::Windows => Some(KeyOrIcon::Plus),
};
let platform_keys = itertools::intersperse(platform_keys, separator.clone());
platform_keys
.chain(if modifiers.modified() && trailing_separator {
Some(separator)
} else {
None
})
.flatten()
.map(move |key_or_icon| match key_or_icon {
KeyOrIcon::Key(key) => Key::new(key, color).size(size).into_any_element(),
KeyOrIcon::Icon(icon) => KeyIcon::new(icon, color).size(size).into_any_element(),
KeyOrIcon::Plus => "+".into_any_element(),
})
}
@ -389,7 +402,7 @@ pub fn text_for_keystroke(keystroke: &Keystroke, platform_style: PlatformStyle)
let key = match keystroke.key.as_str() {
"pageup" => "PageUp",
"pagedown" => "PageDown",
key => &capitalize(key),
key => &util::capitalize(key),
};
text.push_str(key);
@ -397,14 +410,6 @@ pub fn text_for_keystroke(keystroke: &Keystroke, platform_style: PlatformStyle)
text
}
fn capitalize(str: &str) -> String {
let mut chars = str.chars();
match chars.next() {
None => String::new(),
Some(first_char) => first_char.to_uppercase().collect::<String>() + chars.as_str(),
}
}
#[cfg(test)]
mod tests {
use super::*;