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:
parent
64b8749eb3
commit
d60cdbf74e
@ -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,
|
||||
|
@ -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(),
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user