feat(multi): tmux keys to toggle broadcast and exclude single panes
In windows opened by netssh multi, prefix S toggles broadcast for all panes and prefix e excludes the current pane (a pane-level synchronize-panes off, shown as [SOLO] in the border) or includes it again. netssh sync --pane does the same from a shell. S and e are unbound in a default tmux (E would be "spread evenly"). netssh writes the bindings to a small tmux config and sources it, binds a key only if the user's tmux.conf does not use it (netssh's own earlier binding is refreshed), and the bindings act only in windows marked @netssh. multi.sync_key and multi.solo_key change the keys or turn them off (none); also in the configurator. zellij syncs whole tabs only, so excluding a pane is tmux-only. testenv: the render test presses the keys through the xterm client (send-keys -K) and checks [SOLO], that broadcast skips the excluded pane, that S toggles, and that other windows are unaffected. The client gets GNU grep: BusyBox grep -oF counted only one match per line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
699b9469b6
commit
396d489187
14 files changed
+342
-31
No files matched your search
@@ -32,13 +32,34 @@ visible "tmux: borders show host and [SYNC]" tmux-1 "$p1 [SYNC]" "$p2 [SYNC]" "$
|
||||
side_by_side tmux-1 "$p1" "$p2" && ok "tmux: tiled, first two panes side by side" || bad "tmux: tiled, first two panes side by side" "$(screen_text tmux-1)"
|
||||
tmux send-keys -t netssh-pve "echo typed-once-\$(hostname)" Enter
|
||||
visible "tmux: broadcast output in every pane" tmux-2 "typed-once-fsn1-pve1" "typed-once-fsn1-pve2" "typed-once-fsn1-pve3"
|
||||
tmux set-window-option -t netssh-pve synchronize-panes off
|
||||
# Keys as typed in xterm (send-keys -K goes through the client's prefix and
|
||||
# key tables): prefix e excludes the active pane, prefix S toggles all panes.
|
||||
client=$(tmux list-clients -t netssh-pve -F '#{client_name}' | head -1)
|
||||
press() { tmux send-keys -K -c "$client" C-b "$1"; sleep 0.5; }
|
||||
panes=($(tmux list-panes -t netssh-pve -F '#{pane_id}'))
|
||||
tmux select-pane -t "${panes[2]}"
|
||||
press e
|
||||
visible "tmux: prefix e marks the pane [SOLO]" tmux-solo "$p3 [SOLO]" "$p1 [SYNC]" "$p2 [SYNC]"
|
||||
tmux send-keys -t "${panes[2]}" "echo solo-only" Enter
|
||||
tmux send-keys -t "${panes[0]}" "echo two-panes" Enter
|
||||
sleep 1
|
||||
shot tmux-solo-2
|
||||
[ "$(screen_count tmux-solo-2 "solo-only")" = 2 ] && ok "tmux: the excluded pane types alone" || bad "tmux: the excluded pane types alone" "$(screen_text tmux-solo-2)"
|
||||
[ "$(screen_count tmux-solo-2 "two-panes")" = 4 ] && ok "tmux: broadcast skips the excluded pane" || bad "tmux: broadcast skips the excluded pane" "$(screen_text tmux-solo-2)"
|
||||
press e
|
||||
visible "tmux: prefix e again includes it" tmux-solo-3 "$p3 [SYNC]"
|
||||
|
||||
press S
|
||||
sync_is() { [ "$(tmux show-window-options -t netssh-pve -v synchronize-panes 2>/dev/null)" = "$1" ]; }
|
||||
wait_for 5 sync_is off && ok "tmux: prefix S turns broadcast off" || bad "tmux: prefix S turns broadcast off" "$(tmux show-window-options -t netssh-pve)"
|
||||
tmux send-keys -t netssh-pve "echo just-this-pane" Enter
|
||||
sleep 1
|
||||
shot tmux-3
|
||||
[ "$(screen_count tmux-3 "just-this-pane")" = 2 ] && ok "tmux: without broadcast only one pane gets input" || bad "tmux: without broadcast only one pane gets input" "$(screen_text tmux-3)"
|
||||
shows_sync() { screen_shows tmux-3 "[SYNC]"; }
|
||||
shows_sync && bad "tmux: [SYNC] disappears when broadcast is off" "$(screen_text tmux-3)" || ok "tmux: [SYNC] disappears when broadcast is off"
|
||||
press S
|
||||
wait_for 5 sync_is on && ok "tmux: prefix S turns it on again" || bad "tmux: prefix S turns it on again" "$(tmux show-window-options -t netssh-pve)"
|
||||
tmux kill-server
|
||||
|
||||
# --- more hosts than panes_per_window: further windows ---
|
||||
@@ -64,6 +85,12 @@ zellij kill-all-sessions --yes >/dev/null 2>&1
|
||||
# --- TUI: mark hosts, open them together ---
|
||||
term tmux new-session -s tui netssh
|
||||
visible "TUI: search screen" tui-1 "Search hostname"
|
||||
# The netssh keys do nothing outside netssh multi windows.
|
||||
tmux source-file "$XDG_CACHE_HOME/netssh/netssh-multi.tmux.conf"
|
||||
client=$(tmux list-clients -t tui -F '#{client_name}' | head -1)
|
||||
tmux send-keys -K -c "$client" C-b S
|
||||
sleep 0.5
|
||||
[ "$(tmux show-window-options -t tui -v synchronize-panes 2>/dev/null)" != on ] && ok "tmux: prefix S leaves other windows alone" || bad "tmux: prefix S leaves other windows alone" "synchronize-panes turned on in a non-netssh window"
|
||||
tmux send-keys -t tui "pve"
|
||||
visible "TUI: results listed" tui-2 "$p1" "$p2" "$p3"
|
||||
tmux send-keys -t tui C-a
|
||||
|
||||
@@ -124,10 +124,10 @@ screen_text() {
|
||||
for i in "${!OCR_VARIANTS[@]}"; do ocr_variant "$1" "$i"; done
|
||||
}
|
||||
|
||||
# ocr_norm maps characters OCR confuses in DejaVu Sans Mono (1/l/I/|, C/( , 0/O)
|
||||
# to one form; expected text gets the same mapping, so comparisons stay strict
|
||||
# about everything else.
|
||||
ocr_norm() { tr 'lI|(O' '111C0'; }
|
||||
# ocr_norm maps characters OCR confuses in DejaVu Sans Mono (1/l/I/|, C/( , 0/O,
|
||||
# typographic dashes for "-") to one form; expected text gets the same mapping,
|
||||
# so comparisons stay strict about everything else.
|
||||
ocr_norm() { sed 's/[‐‑‒–—―−]/-/g' | tr 'lI|(O' '111C0'; }
|
||||
|
||||
# screen_shows NAME TEXT... — take a screenshot and check that OCR finds every TEXT.
|
||||
screen_shows() {
|
||||
|
||||
Reference in new issue
Block a user