From 973f437dbdc2ff7effa3e2717dba82aa1e65a07a Mon Sep 17 00:00:00 2001 From: froppa <5844892+froppa@users.noreply.github.com> Date: Tue, 6 Oct 2026 18:47:50 +0200 Subject: [PATCH] ghostty: keep Hyper chords off the menu bar so herdr gets them Ghostty shows the last binding for an action as its menu shortcut, so New Tab, Split Right and Close carried the Hyper chords. macOS fires a menu shortcut before any key table, so the herdr table never saw them. performable: bindings never become menu shortcuts (Binding.zig reverse map), which leaves the menus on the Command defaults. --- home/dot_config/ghostty/config | 66 +++++++++++++++++----------------- test.sh | 5 +-- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/home/dot_config/ghostty/config b/home/dot_config/ghostty/config index 82f37bd..a36f000 100644 --- a/home/dot_config/ghostty/config +++ b/home/dot_config/ghostty/config @@ -116,38 +116,40 @@ shell-integration-features = cursor,title,ssh-env,path # Same chords as Herdr's [keys], so muscle memory carries over. # While Herdr runs, the `herdr` key table below hands them to it. - -keybind = ctrl+alt+super+i=new_split:right -keybind = ctrl+alt+super+slash=new_split:down -keybind = ctrl+alt+super+z=toggle_split_zoom -keybind = ctrl+alt+super+x=close_surface -keybind = ctrl+alt+super+equal=equalize_splits - -keybind = ctrl+alt+super+arrow_left=goto_split:left -keybind = ctrl+alt+super+arrow_down=goto_split:down -keybind = ctrl+alt+super+arrow_up=goto_split:up -keybind = ctrl+alt+super+arrow_right=goto_split:right - -keybind = ctrl+alt+super+shift+arrow_left=resize_split:left,10 -keybind = ctrl+alt+super+shift+arrow_down=resize_split:down,10 -keybind = ctrl+alt+super+shift+arrow_up=resize_split:up,10 -keybind = ctrl+alt+super+shift+arrow_right=resize_split:right,10 - -keybind = ctrl+alt+super+c=new_tab -keybind = ctrl+alt+super+p=previous_tab -keybind = ctrl+alt+super+n=next_tab -keybind = ctrl+alt+super+comma=prompt_tab_title -keybind = ctrl+alt+super+shift+comma=move_tab:-1 -keybind = ctrl+alt+super+shift+period=move_tab:1 -keybind = ctrl+alt+super+digit_1=goto_tab:1 -keybind = ctrl+alt+super+digit_2=goto_tab:2 -keybind = ctrl+alt+super+digit_3=goto_tab:3 -keybind = ctrl+alt+super+digit_4=goto_tab:4 -keybind = ctrl+alt+super+digit_5=goto_tab:5 -keybind = ctrl+alt+super+digit_6=goto_tab:6 -keybind = ctrl+alt+super+digit_7=goto_tab:7 -keybind = ctrl+alt+super+digit_8=goto_tab:8 -keybind = ctrl+alt+super+digit_9=goto_tab:9 +# performable: keeps them off the menu bar; a menu shortcut fires before +# any key table, so the table could never hand it to Herdr. + +keybind = performable:ctrl+alt+super+i=new_split:right +keybind = performable:ctrl+alt+super+slash=new_split:down +keybind = performable:ctrl+alt+super+z=toggle_split_zoom +keybind = performable:ctrl+alt+super+x=close_surface +keybind = performable:ctrl+alt+super+equal=equalize_splits + +keybind = performable:ctrl+alt+super+arrow_left=goto_split:left +keybind = performable:ctrl+alt+super+arrow_down=goto_split:down +keybind = performable:ctrl+alt+super+arrow_up=goto_split:up +keybind = performable:ctrl+alt+super+arrow_right=goto_split:right + +keybind = performable:ctrl+alt+super+shift+arrow_left=resize_split:left,10 +keybind = performable:ctrl+alt+super+shift+arrow_down=resize_split:down,10 +keybind = performable:ctrl+alt+super+shift+arrow_up=resize_split:up,10 +keybind = performable:ctrl+alt+super+shift+arrow_right=resize_split:right,10 + +keybind = performable:ctrl+alt+super+c=new_tab +keybind = performable:ctrl+alt+super+p=previous_tab +keybind = performable:ctrl+alt+super+n=next_tab +keybind = performable:ctrl+alt+super+comma=prompt_tab_title +keybind = performable:ctrl+alt+super+shift+comma=move_tab:-1 +keybind = performable:ctrl+alt+super+shift+period=move_tab:1 +keybind = performable:ctrl+alt+super+digit_1=goto_tab:1 +keybind = performable:ctrl+alt+super+digit_2=goto_tab:2 +keybind = performable:ctrl+alt+super+digit_3=goto_tab:3 +keybind = performable:ctrl+alt+super+digit_4=goto_tab:4 +keybind = performable:ctrl+alt+super+digit_5=goto_tab:5 +keybind = performable:ctrl+alt+super+digit_6=goto_tab:6 +keybind = performable:ctrl+alt+super+digit_7=goto_tab:7 +keybind = performable:ctrl+alt+super+digit_8=goto_tab:8 +keybind = performable:ctrl+alt+super+digit_9=goto_tab:9 # Herdr-only chords: swallowed outside Herdr instead of reaching zsh # as escape/control sequences. diff --git a/test.sh b/test.sh index f7390f0..e7cc4ba 100755 --- a/test.sh +++ b/test.sh @@ -112,9 +112,10 @@ grep -Fq 'herdr machine add evo-dev' home/.chezmoiscripts/run_after_60-add-herdr grep -Fq '{{ if and (eq .chezmoi.os "darwin") .personal -}}' home/.chezmoiscripts/run_after_60-add-herdr-evo-dev.sh.tmpl || fail "only the personal Mac may attach evo-dev" grep -Fq 'command = /bin/zsh' home/dot_config/ghostty/config || fail "Ghostty must launch zsh; herdr is started on demand" grep -Fq 'config-file = ?config.local' home/dot_config/ghostty/config || fail "Ghostty must load the optional machine-local override last" -! grep -qE '^keybind = ctrl\+alt\+super\+[^=]+=text:' home/dot_config/ghostty/config || fail "Hyper chords must reach herdr, not be rewritten into tmux prefix bytes" +! grep -qE '^keybind = (performable:)?ctrl\+alt\+super\+[^=]+=text:' home/dot_config/ghostty/config || fail "Hyper chords must reach herdr, not be rewritten into tmux prefix bytes" +! grep -qE '^keybind = ctrl\+alt\+super\+[^=]+=[^i]' home/dot_config/ghostty/config || fail "Hyper actions must be performable: a menu shortcut fires before the herdr key table" grep -q 'activate_key_table:herdr' home/dot_zshrc || fail "the herdr wrapper must hand Ghostty's Hyper chords to herdr" -[[ "$(grep -oE '^keybind = ctrl\+alt\+super\+[^=]+' home/dot_config/ghostty/config | sed 's/^keybind = //' | grep -v '+equal$')" == "$(grep -E '^keybind = herdr/.+=unbind$' home/dot_config/ghostty/config | sed 's/^keybind = herdr\///; s/=unbind$//')" ]] || fail "the herdr key table must unbind every Hyper chord Ghostty binds" +[[ "$(grep -oE '^keybind = (performable:)?ctrl\+alt\+super\+[^=]+' home/dot_config/ghostty/config | sed -E 's/^keybind = (performable:)?//' | grep -v '+equal$')" == "$(grep -E '^keybind = herdr/.+=unbind$' home/dot_config/ghostty/config | sed 's/^keybind = herdr\///; s/=unbind$//')" ]] || fail "the herdr key table must unbind every Hyper chord Ghostty binds" [[ ! -e home/dot_config/ghostty/herdr.ghostty ]] || fail "herdr is the default; the herdr.ghostty overlay is gone" grep -Fq "bind -n M-C-a if -F '#{@ssht}' 'send-keys M-C-a' 'switch-client -T prefix'" home/dot_config/tmux/tmux.conf || fail "Hyper chords must drive the remote tmux in an ssht pane" grep -Fq 'tmux*:RGB:extkeys' home/dot_config/tmux/tmux.conf || fail "a remote tmux nested by ssht must get extended keys for Claude Code's Shift-Enter"