mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 02:29:33 +01:00
fix(tmux): bind nested prefix before unbind so an empty table cannot abort the chain
A user tmux config that leaves the prefix table empty makes unbind-key -a -T prefix fail and drop later commands in the \; chain, including send-prefix and remain-on-exit failed. Bind C-q send-prefix, clear the table, then bind it again. Also accept macOS ttys in the TUI switch-guard test without reading /proc, and describe the client_pid hook escape as defensive on tmux 3.4. Co-authored-by: DDT <1786035110@qq.com>
This commit is contained in:
10 files changed
+106
-28
No files matched your search
+7
-4
@@ -1230,7 +1230,8 @@ export function remoteTmuxLocation(remote: SessionRemote, sessionId: string): {
|
||||
* 'tmux -L codeman-remote new-session -A -s codeman-ssh-<id> -c <path> "cd <path> && exec <cli>" \
|
||||
* \; set -t codeman-ssh-<id> status off \; set -t codeman-ssh-<id> mouse off \
|
||||
* \; set -t codeman-ssh-<id> prefix C-q \; set -s escape-time 0 \; \
|
||||
* unbind-key -a -T prefix \; bind-key -T prefix C-q send-prefix'
|
||||
* bind-key -T prefix C-q send-prefix \; unbind-key -a -T prefix \; \
|
||||
* bind-key -T prefix C-q send-prefix'
|
||||
*
|
||||
* COD-107 — the connection options (`-p`, `-i`, `-J`, SOCKS `-o ProxyCommand`,
|
||||
* arbitrary `-o`) come from the shared `buildSshConnectionArgs(remote)`, so the
|
||||
@@ -1356,9 +1357,11 @@ export function buildRemoteLaunchCommand(options: {
|
||||
// The prefix TABLE is server-global (unlike `prefix C-q`, which is per
|
||||
// session). This socket is dedicated to Codeman's owned sessions, so the
|
||||
// same reduction as the local socket applies: Ctrl+Q then )/(/s/w/L must
|
||||
// not switch-client / choose-tree onto a sibling. BEFORE remain-on-exit,
|
||||
// which stays last because an old remote tmux rejects `failed` and aborts
|
||||
// the rest of the chain.
|
||||
// not switch-client / choose-tree onto a sibling. Bind, then unbind-all,
|
||||
// then bind again: a user config that left the prefix table empty makes
|
||||
// `unbind-key -a -T prefix` fail and abort the rest of this chain.
|
||||
// BEFORE remain-on-exit, which stays last because an old remote tmux
|
||||
// rejects `failed` and aborts the rest of the chain.
|
||||
...nestedPrefixTableResetCommands(),
|
||||
// #210: keep a CRASHED pane so the failure is still on screen. Without this,
|
||||
// tmux destroys the pane -> window -> session (and, being the only session,
|
||||
|
||||
@@ -63,11 +63,21 @@ export const NESTED_TMUX_PREFIX = 'C-q';
|
||||
* Joined with `\;` onto the `new-session` that creates the server
|
||||
* (`buildRemoteLaunchCommand`, `buildDockerLaunchCommand`). No `tmux` binary
|
||||
* and no `-g`: the table is server-global, which is what we want on these
|
||||
* dedicated sockets and nowhere else. Put them BEFORE `remain-on-exit failed`
|
||||
* so a remote tmux that rejects `failed` does not drop the reduction.
|
||||
* dedicated sockets and nowhere else.
|
||||
*
|
||||
* Those servers load the user's tmux config (no `-f /dev/null`). A config that
|
||||
* leaves the prefix table empty makes `unbind-key -a -T prefix` fail with
|
||||
* "table prefix doesn't exist", and tmux then drops every later command in the
|
||||
* `\;` chain, including the bind and `remain-on-exit failed` (#210). The same
|
||||
* empty table is what #669 handled on the local socket. Binding `send-prefix`
|
||||
* first creates the table so the unbind can run; the unbind clears stock
|
||||
* bindings (and that first bind); the second bind puts `send-prefix` back.
|
||||
* Put them BEFORE `remain-on-exit failed` so a remote tmux that rejects
|
||||
* `failed` does not drop the reduction.
|
||||
*/
|
||||
export function nestedPrefixTableResetCommands(): readonly [string, string] {
|
||||
return ['unbind-key -a -T prefix', `bind-key -T prefix ${NESTED_TMUX_PREFIX} send-prefix`];
|
||||
export function nestedPrefixTableResetCommands(): readonly [string, string, string] {
|
||||
const sendPrefix = `bind-key -T prefix ${NESTED_TMUX_PREFIX} send-prefix`;
|
||||
return [sendPrefix, 'unbind-key -a -T prefix', sendPrefix];
|
||||
}
|
||||
|
||||
/** One `list-keys -T prefix` line: key and command. */
|
||||
|
||||
@@ -491,9 +491,11 @@ export function tuiSwitchGuard(tty: string): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* `set-hook` command for `TUI_SWITCH_ATTACH_HOOK`. `\#{client_pid}` is deferred
|
||||
* so tmux expands it when the hook fires, not when the hook is stored (a bare
|
||||
* `#{client_pid}` is expanded at `set-hook` time, in no client, and stored empty).
|
||||
* `set-hook` command for `TUI_SWITCH_ATTACH_HOOK`. `\#{client_pid}` is
|
||||
* defensive. On tmux 3.4 both this form and a bare `#{client_pid}` are stored
|
||||
* verbatim and both record the attaching client's pid. The escape stays so a
|
||||
* tmux that expands formats while the hook is stored (no client exists yet)
|
||||
* cannot save an empty pid.
|
||||
*/
|
||||
export function tuiSwitchAttachHook(tty: string): string {
|
||||
return (
|
||||
|
||||
Reference in new issue
Block a user