fix(tmux): scrolling a pane no longer freezes typing
The wheel puts a pane into tmux's copy-mode, which took every typed key as a scrollback command and painted a yellow [0/0] box in the corner. In AgentHub's own panes (every other session on the server keeps tmux's defaults, restored verbatim): - the copy-mode position box is off (copy-mode-position-format ""); - the first keystroke after a mouse report leaves copy-mode (`copy-mode -q`, pty-attach) before it is written, once per scroll; - copy-mode keys that open a tmux prompt (g, :, /, f, digits…) leave copy-mode and reach the program; - the wheel scrolls 10 lines a notch instead of 5, and the first notch already scrolls instead of only entering copy-mode.
This commit is contained in:
@@ -183,9 +183,18 @@ describe("tmux wrapper", () => {
|
||||
calls = fake(true);
|
||||
tmux.enableMouse("agenthub-lane-1");
|
||||
assert.ok(calls.some((c) => c[0] === "set-option" && c[2] === "=agenthub-lane-1:"));
|
||||
// tmux chains the four options into two spawns; psmux above got four.
|
||||
// tmux chains the four options into two spawns, plus the copy-mode
|
||||
// position box (a newer tmux only) in its own; psmux above got five.
|
||||
const sets = calls.filter((c) => c[0] === "set-option");
|
||||
assert.equal(sets.length, 2);
|
||||
assert.equal(sets.length, 3);
|
||||
assert.deepEqual(sets[2], [
|
||||
"set-option",
|
||||
"-w",
|
||||
"-t",
|
||||
"=agenthub-lane-1:",
|
||||
"copy-mode-position-format",
|
||||
"",
|
||||
]);
|
||||
assert.deepEqual(sets[0], [
|
||||
"set-option",
|
||||
"-t",
|
||||
@@ -235,7 +244,39 @@ describe("tmux wrapper", () => {
|
||||
...["set-option", "-t", "=agenthub-lane-1:", "pane-scrollbars-style"],
|
||||
"fg=brightwhite,bg=black,width=1,pad=0",
|
||||
]);
|
||||
assert.equal(calls.length, 3);
|
||||
// No yellow `[0/0]` box in the corner while the wheel's copy-mode is on.
|
||||
assert.deepEqual(calls[3], [
|
||||
...["set-option", "-w", "-t", "=agenthub-lane-1:", "copy-mode-position-format", ""],
|
||||
]);
|
||||
// Copy-mode keys that open a prompt ("(goto line)"…) leave copy-mode and
|
||||
// reach the program in OUR sessions only; others keep tmux's default.
|
||||
assert.deepEqual(calls[4].slice(0, 9), [
|
||||
...["bind-key", "-T", "copy-mode", "g", "if-shell", "-F"],
|
||||
"#{m:agenthub-lane-*,#{session_name}}",
|
||||
"send-keys -X cancel ; send-keys -l -- 'g'",
|
||||
'command-prompt -P -p "(goto line)" { send-keys -X goto-line -- "%%" }',
|
||||
]);
|
||||
assert.ok(calls[4].includes(":"), "vi's `:` goto-line is re-bound too");
|
||||
// The wheel scrolls 10 lines a notch in OUR panes, 5 (tmux's) elsewhere.
|
||||
assert.deepEqual(calls[5].slice(0, 9), [
|
||||
...["bind-key", "-T", "root", "WheelUpPane", "if-shell", "-F"],
|
||||
"#{||:#{alternate_on},#{pane_in_mode},#{mouse_any_flag}}",
|
||||
"send-keys -M",
|
||||
'if-shell -F "#{m:agenthub-lane-*,#{session_name}}" { copy-mode -e ; send-keys -X -N 10 scroll-up } { copy-mode -e }',
|
||||
]);
|
||||
assert.ok(calls[5].includes("select-pane ; send-keys -X -N 10 scroll-down"));
|
||||
assert.ok(calls[5].includes("select-pane ; send-keys -X -N 5 scroll-down"));
|
||||
assert.equal(calls.length, 6);
|
||||
});
|
||||
|
||||
it("newSession still succeeds when tmux refuses the copy-mode bindings", () => {
|
||||
tmux.__setExecImpl((args) => {
|
||||
if (args[0] === "bind-key") throw new Error("unknown flag -F");
|
||||
return "";
|
||||
});
|
||||
assert.doesNotThrow(() =>
|
||||
tmux.newSession({ name: "agenthub-lane-1", cwd: "/tmp/repo", argv: ["claude"] })
|
||||
);
|
||||
});
|
||||
|
||||
it("newSession still succeeds on a tmux older than 3.7 (no pane-scrollbars)", () => {
|
||||
|
||||
Reference in New Issue
Block a user