Summary
On Windows I tried to build a custom session switcher bound to a key: a binding spawns an external fzf picker, and after the user chooses a session the script runs switch-client -c <invoking-client> -t <chosen-session>. This cannot be made to work with multiple clients attached, because there is no way for a script spawned from a key binding to learn which client pressed the key. Two underlying problems:
#{client_name} expands to empty inside binding commands. Both new-window "... #{client_name}" and run-shell "... #{client_name}" pass an empty string to the spawned process, instead of the name of the client that pressed the key. So a spawned script can't be told the invoking client.
show -gqv @my_option does not filter to the named option — it dumps ALL options' values. So the usual workaround (set -gF @x "#{client_name}" at key-press, then read @x back in the script) is also impossible: you can't read a single user option's value.
The built-in choose-tree works perfectly (it switches the invoking client, being client-local), so the problem is specifically about exposing the invoking client to user scripts / binding commands.
Environment
- rmux 0.7.1
- Windows 11 (10.0.26200), Windows Terminal + ConPTY
- shell: PowerShell 7
- multiple clients attached (e.g. desktop + phone over SSH), each viewing a different session
Repro — issue 1 (#{client_name} empty in binding commands)
probe.ps1:
$arg = if ($args.Count -ge 1 -and $args[0]) { [string]$args[0] } else { '<EMPTY>' }
Add-Content -LiteralPath "$PSScriptRoot/probe.log" -Value ("arg=[" + $arg + "]")
bind -T prefix T run-shell -b "pwsh -NoProfile -File C:/path/probe.ps1 #{client_name}"
- Press
prefix T from a client.
- Observed:
arg=[<EMPTY>] — #{client_name} was not expanded to the invoking client. The same happens with new-window -n picker "pwsh ... #{client_name}" (the arg arrives empty).
Expected: #{client_name} expands to the name of the client that pressed the key (as in tmux), so the spawned script can target it with switch-client -c.
Repro — issue 2 (show -gqv @opt dumps all options)
set -g @cn_test HELLO123
show -gqv @cn_test → returns the values of all global options, not HELLO123.
show -gv @cn_test — same (dumps all values)
show-options -gv @cn_test — same
display-message -p "#{@cn_test}" — returns empty
- cleanup:
set -gu @cn_test
Expected: show -gv @cn_test returns just HELLO123 (the value of that one option).
Impact
Any custom interaction that must act on "the client that triggered it" — session switchers, per-client popups/menus, client-specific actions — cannot work when multiple clients are attached, because switch-client requires -c <client> under multiple clients but the invoking client can't be determined from a script. The only reliable path today is the built-in choose-tree. Exposing the invoking client (fixing issue 1) — or being able to read back a single user option that captured it (fixing issue 2) — would unblock this whole class of customization.
Note
This pattern works in tmux on Linux / WSL2: #{client_name} resolves inside binding commands, and show -gv @opt returns the single option's value, so a script-based per-client session switcher works there. Happy to provide more detail or test patches.
Summary
On Windows I tried to build a custom session switcher bound to a key: a binding spawns an external fzf picker, and after the user chooses a session the script runs
switch-client -c <invoking-client> -t <chosen-session>. This cannot be made to work with multiple clients attached, because there is no way for a script spawned from a key binding to learn which client pressed the key. Two underlying problems:#{client_name}expands to empty inside binding commands. Bothnew-window "... #{client_name}"andrun-shell "... #{client_name}"pass an empty string to the spawned process, instead of the name of the client that pressed the key. So a spawned script can't be told the invoking client.show -gqv @my_optiondoes not filter to the named option — it dumps ALL options' values. So the usual workaround (set -gF @x "#{client_name}"at key-press, then read@xback in the script) is also impossible: you can't read a single user option's value.The built-in
choose-treeworks perfectly (it switches the invoking client, being client-local), so the problem is specifically about exposing the invoking client to user scripts / binding commands.Environment
Repro — issue 1 (
#{client_name}empty in binding commands)probe.ps1:bind -T prefix T run-shell -b "pwsh -NoProfile -File C:/path/probe.ps1 #{client_name}"prefix Tfrom a client.arg=[<EMPTY>]—#{client_name}was not expanded to the invoking client. The same happens withnew-window -n picker "pwsh ... #{client_name}"(the arg arrives empty).Expected:
#{client_name}expands to the name of the client that pressed the key (as in tmux), so the spawned script can target it withswitch-client -c.Repro — issue 2 (
show -gqv @optdumps all options)set -g @cn_test HELLO123show -gqv @cn_test→ returns the values of all global options, notHELLO123.show -gv @cn_test— same (dumps all values)show-options -gv @cn_test— samedisplay-message -p "#{@cn_test}"— returns emptyset -gu @cn_testExpected:
show -gv @cn_testreturns justHELLO123(the value of that one option).Impact
Any custom interaction that must act on "the client that triggered it" — session switchers, per-client popups/menus, client-specific actions — cannot work when multiple clients are attached, because
switch-clientrequires-c <client>under multiple clients but the invoking client can't be determined from a script. The only reliable path today is the built-inchoose-tree. Exposing the invoking client (fixing issue 1) — or being able to read back a single user option that captured it (fixing issue 2) — would unblock this whole class of customization.Note
This pattern works in tmux on Linux / WSL2:
#{client_name}resolves inside binding commands, andshow -gv @optreturns the single option's value, so a script-based per-client session switcher works there. Happy to provide more detail or test patches.