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
+16
-4
@@ -83,12 +83,19 @@ netssh sync. Inside tmux or zellij the panes open in the current session.`,
|
||||
}
|
||||
|
||||
func syncCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "sync",
|
||||
var pane bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "sync [--pane]",
|
||||
Short: "Toggle typing into all panes of the current tmux window or zellij tab",
|
||||
Args: cobra.NoArgs,
|
||||
Long: `Toggle broadcast in the current tmux window or zellij tab. With --pane,
|
||||
exclude the current tmux pane from broadcast, or include it again.
|
||||
|
||||
In windows opened by netssh multi, tmux also has keys for this:
|
||||
prefix S (all panes) and prefix e (this pane); see multi.sync_key and
|
||||
multi.solo_key. In zellij, use Ctrl+t then s.`,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
state, err := multiplex.ToggleSync(multiplex.System{})
|
||||
state, err := multiplex.ToggleSync(multiplex.System{}, pane)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -96,6 +103,8 @@ func syncCmd() *cobra.Command {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolVar(&pane, "pane", false, "Exclude the current tmux pane from broadcast, or include it again")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// runMulti expands selectors and opens one pane per host.
|
||||
@@ -147,7 +156,10 @@ func runMulti(cfg *config.Config, selectors []string, f multiFlags) error {
|
||||
if err := os.MkdirAll(layoutDir, 0o700); err != nil {
|
||||
return err
|
||||
}
|
||||
syncKey, soloKey := cfg.Multi.Keys()
|
||||
return multiplex.Open(kind, panes, multiplex.Options{
|
||||
SyncKey: syncKey,
|
||||
SoloKey: soloKey,
|
||||
Label: multiLabel(selectors),
|
||||
Sync: f.sync,
|
||||
PerWindow: cfg.Multi.PanesPerWindowOrDefault(),
|
||||
|
||||
Reference in new issue
Block a user