use par_term_config::Config;
pub fn binding_for(config: &Config, action: &str) -> Option<String> {
config
.keybindings
.iter()
.find(|binding| binding.action == action)
.map(|binding| display_chord(&binding.key))
}
pub fn with_binding(config: &Config, label: &str, action: &str) -> String {
match binding_for(config, action) {
Some(chord) => format!("{label} ({chord})"),
None => label.to_string(),
}
}
fn display_chord(key: &str) -> String {
key.split('+')
.map(|part| match part {
"CmdOrCtrl" => primary_modifier_name(),
other => other,
})
.collect::<Vec<_>>()
.join("+")
}
pub fn primary_modifier_name() -> &'static str {
if cfg!(target_os = "macos") {
"Cmd"
} else {
"Ctrl"
}
}
#[cfg(test)]
mod tests {
use super::*;
use par_term_config::KeyBinding;
#[test]
fn text_follows_a_rebinding() {
let config = Config {
keybindings: vec![KeyBinding {
key: "Ctrl+Alt+Q".to_string(),
action: "ssh_quick_connect".to_string(),
}],
..Config::default()
};
let text = with_binding(&config, "SSH Quick Connect", "ssh_quick_connect");
assert!(text.starts_with("SSH Quick Connect ("), "{text}");
assert!(text.contains('Q'), "{text}");
}
#[test]
fn unbound_action_shows_no_chord() {
let config = Config {
keybindings: Vec::new(),
..Config::default()
};
assert_eq!(with_binding(&config, "Search", "toggle_search"), "Search");
}
}