You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When running crush inside tmux (outer terminal: kitty), the terminal capability probe leaks the string Gi=31;OK into the editor input field on startup, right after the prompt icon.
So \x1b_ becomes Alt+_ (2 bytes consumed), the remaining Gi=31;OK are forwarded one character at a time as ordinary printable keys, and the trailing \x1b\ becomes Alt+.
Crush inserts the printable chars into the textarea. Since they arrive without the ESC/APC framing, ultraviolet treats them as regular keypresses and they land in the input field (Gi=31;OK).
Skip the capability probe when running inside tmux, since tmux's TTY key parser cannot forward APC/kitty-graphics responses to the pane. E.g. in shouldQueryCapabilities:
funcshouldQueryCapabilities(env uv.Environ) bool {
// tmux cannot forward APC (kitty graphics) responses from the outer// terminal; they get split into keypresses ("Gi=31;OK" in the prompt).if_, isTmux:=env.LookupEnv("TMUX"); isTmux {
returnfalse
}
...
}
Alternatively, in QueryCmd only send the kitty graphics probe when not inside tmux.
Repro
Inside tmux (outer kitty), run crush (any mode).
Observe Gi=31;OK typed into the editor input field on startup.
Note: the exact leaked string depends on the outer terminal's response payload; with kitty it is the OK response to the a=q query with transmission id 31.
Summary
When running
crushinside tmux (outer terminal: kitty), the terminal capability probe leaks the stringGi=31;OKinto the editor input field on startup, right after the prompt icon.Environment
crushv0.88.1 (also reproducible onmain)xterm-kitty)TERM_PROGRAM=tmux,TERM=xterm-256color)What I see
On startup the bottom editor line renders:
where
Yis the yolo-mode prompt icon.Gi=31;OKis typed into the textarea as if the user had pressed those keys.Root cause
Crush sends a kitty graphics probe.
QueryCmdininternal/ui/common/capabilities.gowrites:i.e.
\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\. Inside tmux this is wrapped withansi.TmuxPassthrough(DCS passthrough,allow-passthrough on).shouldQueryCapabilitiesreturns true for tmux. After PR fix(ui): prevent AAAA probe bleed in terminals without Kitty graphics support #1967 the logic is:With
TERM_PROGRAM=tmux, the middle branch is true, so the probe is sent even though tmux is not a kitty-graphics terminal.The outer terminal responds with an APC sequence. kitty answers:
tmux splits the APC response into keypresses. tmux's TTY key parser (
tty-keys.c) has no entry for\x1b_(APC). The fallback path does:So
\x1b_becomesAlt+_(2 bytes consumed), the remainingGi=31;OKare forwarded one character at a time as ordinary printable keys, and the trailing\x1b\becomesAlt+.Crush inserts the printable chars into the textarea. Since they arrive without the ESC/APC framing, ultraviolet treats them as regular keypresses and they land in the input field (
Gi=31;OK).Related
TERM_PROGRAM=tmuxstill passes, so this tmux scenario is not fixed by it either.Suggested fix
Skip the capability probe when running inside tmux, since tmux's TTY key parser cannot forward APC/kitty-graphics responses to the pane. E.g. in
shouldQueryCapabilities:Alternatively, in
QueryCmdonly send the kitty graphics probe when not inside tmux.Repro
crush(any mode).Gi=31;OKtyped into the editor input field on startup.Note: the exact leaked string depends on the outer terminal's response payload; with kitty it is the
OKresponse to thea=qquery with transmission id 31.