fix: disambiguate shifted punctuation keybinds

refs #2674
This commit is contained in:
akbash-bot
2026-08-11 17:13:04 +00:00
parent 06ca0baa12
commit 98a939e84c
3 changed files with 36 additions and 2 deletions
+1
View File
@@ -19,6 +19,7 @@
- Experimental pane graphics now support bounded named layers, acknowledged full-RGBA primary-layer direct file frames on audited local terminals, owned BGRA fallback, exact pixel mouse input, and placement-only resize replay.
### Fixed
- Prefix keybindings now disambiguate layout-aware shifted punctuation, so a shifted `\` no longer triggers `prefix+|` on keyboard layouts where the same key produces both characters. (#2674)
- OpenCode panes now track the root conversation selected in their own TUI for native restore without adopting activity from attached clients. (#2450)
- Server stop requests now bypass pane and API traffic, preventing busy sessions from blocking shutdown or admitting a client while shutdown is pending. (#2612)
- Fish `Ctrl+Alt` keybindings now work in panes after legacy Alt-prefixed control bytes are decoded with both modifiers. (#2514)
+33
View File
@@ -2815,6 +2815,39 @@ resize_pane_left = "prefix+shift+left"
assert_eq!(action, Some(NavigateAction::LastPane));
}
#[test]
fn shifted_backslash_layout_prefers_horizontal_split_binding() {
let config: Config = toml::from_str(
r#"
[keys]
split_vertical = "prefix+|"
split_horizontal = 'prefix+\'
"#,
)
.unwrap();
let mut state = state_with_workspaces(&["test"]);
state.keybinds = config.keybinds();
let key = crate::input::parse_terminal_key_sequence("\x1b[124:92;2:1u").unwrap();
assert_eq!(key.code, KeyCode::Char('|'));
assert_eq!(key.modifiers, KeyModifiers::SHIFT);
assert_eq!(key.shifted_codepoint, Some('\\' as u32));
assert!(state.keybinds.split_horizontal.matches_prefix_key(&key));
assert!(!state.keybinds.split_vertical.matches_prefix_key(&key));
assert_eq!(
action_for_key(&state, key, BindingDispatch::Prefix),
Some(NavigateAction::SplitHorizontal)
);
assert_eq!(
action_for_key(
&state,
TerminalKey::new(KeyCode::Char('|'), KeyModifiers::empty()),
BindingDispatch::Prefix,
),
Some(NavigateAction::SplitVertical)
);
}
#[test]
fn prefix_tab_override_can_map_to_last_pane() {
let config: Config = toml::from_str(
+2 -2
View File
@@ -1437,8 +1437,8 @@ fn shifted_char_matches_expected(
let KeyCode::Char(expected) = expected_code else {
return false;
};
if shifted_codepoint.and_then(char::from_u32) == Some(expected) {
return true;
if let Some(shifted) = shifted_codepoint.and_then(char::from_u32) {
return shifted == expected;
}
matches!(actual_code, KeyCode::Char(actual) if actual == expected && is_shifted_punctuation(expected))
}