mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 08:02:24 +00:00
fix(keymap): make the three panel actions bindable, and stop dropping typos in silence
ShowRightPanelInfo, ShowRightPanelChanges and ShowRightPanelFiles have a make_binding arm and are dispatched like any other action — but they had no slot in default_bindings, which is the only list set_binding writes into. So `"ShowRightPanelInfo": "ctrl-1"` in a hand-edited config.json went into a branch that did nothing, and the Keybindings page, which reads that same list, never showed them at all. They now have empty default slots, so they appear under View and can be bound like anything else. A binding naming an action that does not exist — a typo, or a name from an older build — now says so in the log instead of vanishing. every_dispatchable_action_has_a_slot_to_bind_it_in keeps the two lists from drifting apart again.
This commit is contained in:
+46
-2
@@ -315,6 +315,13 @@ pub(crate) fn default_bindings() -> Vec<(&'static str, &'static str)> {
|
||||
("ToggleSftp", ""),
|
||||
("ShowSshForwards", ""),
|
||||
("ToggleCodePanel", "secondary-shift-e"),
|
||||
// Implemented, dispatchable, and until now unbindable: `set_binding`
|
||||
// only fills slots that exist here, so `"ShowRightPanelInfo": "ctrl-1"`
|
||||
// in config.json was dropped without a word, and the Keybindings page —
|
||||
// which reads this list — never showed them at all.
|
||||
("ShowRightPanelInfo", ""),
|
||||
("ShowRightPanelChanges", ""),
|
||||
("ShowRightPanelFiles", ""),
|
||||
("EditorSave", "secondary-s"),
|
||||
("OpenSshProfiles", ""),
|
||||
("RestartSshSession", "secondary-shift-r"),
|
||||
@@ -493,6 +500,18 @@ fn authored_entry(action: &str) -> Option<(CommandGroup, String)> {
|
||||
t(L10nKey::AppMenuRightPanel).to_string(),
|
||||
),
|
||||
"ToggleCodePanel" => (CommandGroup::View, t(L10nKey::AppMenuCodePanel).to_string()),
|
||||
"ShowRightPanelInfo" => (
|
||||
CommandGroup::View,
|
||||
t(L10nKey::CmdRightPanelInfo).to_string(),
|
||||
),
|
||||
"ShowRightPanelChanges" => (
|
||||
CommandGroup::View,
|
||||
t(L10nKey::CmdRightPanelChanges).to_string(),
|
||||
),
|
||||
"ShowRightPanelFiles" => (
|
||||
CommandGroup::View,
|
||||
t(L10nKey::CmdRightPanelFiles).to_string(),
|
||||
),
|
||||
"FindInTerminal" => (
|
||||
CommandGroup::Terminal,
|
||||
t(L10nKey::CmdFindInTerminal).to_string(),
|
||||
@@ -620,8 +639,11 @@ pub(crate) fn effective_bindings(cx: &App) -> Vec<(String, String)> {
|
||||
}
|
||||
|
||||
fn set_binding(effective: &mut [(String, String)], action: &str, key: String) {
|
||||
if let Some(slot) = effective.iter_mut().find(|(a, _)| a == action) {
|
||||
slot.1 = key;
|
||||
match effective.iter_mut().find(|(a, _)| a == action) {
|
||||
Some(slot) => slot.1 = key,
|
||||
// A hand-edited config.json with a typo used to vanish into this
|
||||
// branch. The Keybindings page lists every name that works.
|
||||
None => log::warn!("keybinding for unknown action {action:?} ignored"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -912,6 +934,28 @@ fn make_binding(action: &str, keystroke: &str) -> Option<KeyBinding> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn every_dispatchable_action_has_a_slot_to_bind_it_in() {
|
||||
// `make_binding` is what turns an action name into a real binding, and
|
||||
// `default_bindings` is the only list `set_binding` will write into. An
|
||||
// action in the first but not the second cannot be bound at all — not
|
||||
// from config.json, which drops it silently, and not from the
|
||||
// Keybindings page, which reads the second.
|
||||
let bindable: std::collections::HashSet<&str> =
|
||||
default_bindings().into_iter().map(|(a, _)| a).collect();
|
||||
for action in [
|
||||
"ShowRightPanelInfo",
|
||||
"ShowRightPanelChanges",
|
||||
"ShowRightPanelFiles",
|
||||
] {
|
||||
assert!(bindable.contains(action), "{action} has nowhere to bind to");
|
||||
assert!(
|
||||
make_binding(action, "ctrl-1").is_some(),
|
||||
"{action} has a slot but nothing to dispatch"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_action_has_an_authored_name() {
|
||||
crate::ui::i18n::set_locale("en");
|
||||
|
||||
Reference in New Issue
Block a user