1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-27 02:25:28 +03:00

palette: show key assignment alongside entries

For items in the main set of key assignments, show the keyboard
shortcut to the right.

Some items have multiple key assignments; we show only the first
one. We'll probably want to be a bit smarter. For instance,
both linux and windows tend to occupy the Windows/Super key
assignments, so we should probably prioritize showing the Ctrl+Shift
variants on those platforms.

refs: https://github.com/wez/wezterm/issues/3335
This commit is contained in:
Wez Furlong 2023-03-24 23:28:43 -07:00
parent 64b8749eb3
commit d60cdbf74e
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387
4 changed files with 107 additions and 39 deletions

View File

@ -316,7 +316,7 @@ impl CommandDef {
// And sweep to pick up stuff from their key assignments
let inputmap = InputMap::new(config);
for entry in inputmap.keys.default.values() {
for ((keycode, mods), entry) in inputmap.keys.default.iter() {
if result
.iter()
.position(|cmd| cmd.action == entry.action)
@ -328,7 +328,7 @@ impl CommandDef {
result.push(ExpandedCommand {
brief: cmd.brief.into(),
doc: cmd.doc.into(),
keys: vec![],
keys: vec![(*mods, keycode.clone())],
action: entry.action.clone(),
menubar: cmd.menubar,
icon: cmd.icon,

View File

@ -572,7 +572,24 @@ fn section_header(title: &str) {
println!();
}
fn human_key(key: &KeyCode) -> String {
pub fn ui_key(key: &KeyCode) -> String {
match key {
KeyCode::Char('\x1b') => "Esc".to_string(),
KeyCode::Char('\x7f') => "Esc".to_string(),
KeyCode::Char('\x08') => "Del".to_string(),
KeyCode::Char('\r') => "Enter".to_string(),
KeyCode::Char(' ') => "Space".to_string(),
KeyCode::Char('\t') => "Tab".to_string(),
KeyCode::Char(c) if c.is_ascii_control() => c.escape_debug().to_string(),
KeyCode::Char(c) => c.to_uppercase().to_string(),
KeyCode::Function(n) => format!("F{n}"),
KeyCode::Numpad(n) => format!("Numpad{n}"),
KeyCode::Physical(phys) => phys.to_string(),
_ => format!("{key:?}"),
}
}
pub fn human_key(key: &KeyCode) -> String {
match key {
KeyCode::Char('\x1b') => "Escape".to_string(),
KeyCode::Char('\x7f') => "Escape".to_string(),

View File

@ -230,28 +230,27 @@ impl CommandPalette {
None => &' ',
};
let (bg, text) = if display_idx == selected_row {
(
term_window
.config
.command_palette_fg_color
.to_linear()
.into(),
term_window
let solid_bg_color: InheritableColor = term_window
.config
.command_palette_bg_color
.to_linear()
.into(),
)
} else {
(
LinearRgba::TRANSPARENT.into(),
term_window
.into();
let solid_fg_color: InheritableColor = term_window
.config
.command_palette_fg_color
.to_linear()
.into(),
)
.into();
let (bg, text) = if display_idx == selected_row {
(solid_fg_color.clone(), solid_bg_color.clone())
} else {
(LinearRgba::TRANSPARENT.into(), solid_fg_color.clone())
};
let (label_bg, label_text) = if display_idx == selected_row {
(solid_fg_color.clone(), solid_bg_color.clone())
} else {
(solid_bg_color.clone(), solid_fg_color.clone())
};
// DRY if the brief and doc are the same
@ -263,6 +262,18 @@ impl CommandPalette {
format!("{group}{}. {}", command.brief, command.doc)
};
let key_label = if command.keys.is_empty() {
String::new()
} else {
let (mods, keycode) = &command.keys[0];
let mut mod_string = mods.to_string_with_separator("-", false, true);
if !mod_string.is_empty() {
mod_string.push_str("-");
}
let keycode = crate::inputmap::ui_key(keycode);
format!("{mod_string}{keycode}")
};
elements.push(
Element::new(
&font,
@ -270,6 +281,20 @@ impl CommandPalette {
Element::new(&font, ElementContent::Text(icon.to_string()))
.min_width(Some(Dimension::Cells(2.))),
Element::new(&font, ElementContent::Text(label)),
Element::new(&font, ElementContent::Text(key_label))
.float(Float::Right)
.padding(BoxDimension {
left: Dimension::Cells(1.25),
right: Dimension::Cells(0.5),
top: Dimension::Cells(0.),
bottom: Dimension::Cells(0.),
})
.zindex(10)
.colors(ElementColors {
border: BorderColor::default(),
bg: label_bg.clone(),
text: label_text.clone(),
}),
]),
)
.colors(ElementColors {
@ -292,7 +317,7 @@ impl CommandPalette {
let size = term_window.terminal_size;
// Avoid covering the entire width
let desired_width = (size.cols / 3).max(75).min(size.cols);
let desired_width = (size.cols / 3).max(120).min(size.cols);
// Center it
let avail_pixel_width =

View File

@ -506,32 +506,52 @@ impl Into<String> for &Modifiers {
}
}
impl ToString for Modifiers {
fn to_string(&self) -> String {
impl Modifiers {
pub fn to_string_with_separator(&self, separator: &str, want_none: bool, ui: bool) -> String {
let mut s = String::new();
if *self == Self::NONE {
if want_none && *self == Self::NONE {
s.push_str("NONE");
}
for (value, label) in [
(Self::SHIFT, "SHIFT"),
(Self::ALT, "ALT"),
(Self::CTRL, "CTRL"),
(Self::SUPER, "SUPER"),
(Self::LEFT_ALT, "LEFT_ALT"),
(Self::RIGHT_ALT, "RIGHT_ALT"),
(Self::LEADER, "LEADER"),
(Self::LEFT_CTRL, "LEFT_CTRL"),
(Self::RIGHT_CTRL, "RIGHT_CTRL"),
(Self::LEFT_SHIFT, "LEFT_SHIFT"),
(Self::RIGHT_SHIFT, "RIGHT_SHIFT"),
(Self::SHIFT, if ui { "Shift" } else { "SHIFT" }),
(
Self::ALT,
if ui && cfg!(target_os = "macos") {
"Opt"
} else if ui {
"Alt"
} else {
"ALT"
},
),
(Self::CTRL, if ui { "Ctrl" } else { "CTRL" }),
(
Self::SUPER,
if ui && cfg!(target_os = "macos") {
"Cmd"
} else if ui && cfg!(windows) {
"Win"
} else if ui {
"Super"
} else {
"SUPER"
},
),
(Self::LEFT_ALT, if ui { "LAlt" } else { "LEFT_ALT" }),
(Self::RIGHT_ALT, if ui { "RAlt" } else { "RIGHT_ALT" }),
(Self::LEADER, if ui { "Leader" } else { "LEADER" }),
(Self::LEFT_CTRL, if ui { "LCtrl" } else { "LEFT_CTRL" }),
(Self::RIGHT_CTRL, if ui { "RCtrl" } else { "RIGHT_CTRL" }),
(Self::LEFT_SHIFT, if ui { "LShift" } else { "LEFT_SHIFT" }),
(Self::RIGHT_SHIFT, if ui { "RShift" } else { "RIGHT_SHIFT" }),
(Self::ENHANCED_KEY, "ENHANCED_KEY"),
] {
if !self.contains(value) {
continue;
}
if !s.is_empty() {
s.push('|');
s.push_str(separator);
}
s.push_str(label);
}
@ -540,6 +560,12 @@ impl ToString for Modifiers {
}
}
impl ToString for Modifiers {
fn to_string(&self) -> String {
self.to_string_with_separator("|", true, false)
}
}
impl Modifiers {
/// Remove positional and other "supplemental" bits that
/// are used to carry around implementation details, but that