Files
dotfiles/platforms/home-manager/modules/nmasur/presets/programs/lag-triage/lag-triage.fish
T

162 lines
6.8 KiB
Fish

# Guided diagnosis for the post-TUI typing-lag problem (Ghostty + Zellij + fish).
# Run this IN THE LAGGING SHELL the moment you notice the lag, BEFORE starting
# a new shell. It captures evidence, then applies targeted resets one at a time
# so the stage that cures the lag identifies the layer holding stuck state.
# Everything is logged for filing an upstream issue.
set -l logdir ~/.local/state/lag-triage
mkdir -p $logdir
set -l logfile $logdir/(date +%Y%m%d-%H%M%S).log
function _lt --inherit-variable logfile
echo $argv | tee -a $logfile
end
function _lt_ask --inherit-variable logfile
# usage: _lt_ask VARNAME prompt... -> sets global $VARNAME (default: skip)
set -l __name $argv[1]
read -g -P "$argv[2..] " $__name
or set -g $__name skip
test -z "$$__name"; and set -g $__name skip
echo "ANSWER $__name: $$__name" >>$logfile
end
_lt "== lag-triage "(date)" =="
_lt "Log: $logfile"
_lt "Answer y / n, or press Enter to skip a question."
_lt ""
# ---- 1. Context -------------------------------------------------------------
_lt_ask ans_tui "Which TUI did you just exit (nvim/jjui/yazi/other)?"
_lt_ask ans_launch "Launched via (f)loating-pane keybind or (c)ommand typed in this shell?"
# ---- 2. Snapshot ------------------------------------------------------------
begin
echo "-- snapshot --"
fish --version
echo "fish pid: $fish_pid, started: "(ps -o lstart= -p $fish_pid 2>/dev/null)
zellij --version 2>/dev/null
echo "escape delay: '$fish_escape_delay_ms' sequence delay: '$fish_sequence_key_delay_ms'"
env | grep -iE '^(TERM|ZELLIJ|GHOSTTY|COLORTERM)' | sort
echo "-- status features --"
status features
echo "-- stty -a --"
stty -a
end >>$logfile 2>&1
_lt "Captured shell + environment snapshot."
# ---- 3. Terminal state below the shell --------------------------------------
_lt ""
_lt "Querying terminal state (takes a few seconds)..."
term-probe report 2>&1 | tee -a $logfile
_lt ""
_lt " ^ Things to look for: kitty flags with a reply > 0, modifyOtherKeys > 1,"
_lt " any mouse/alternate-screen mode SET while at a shell prompt, or a slow"
_lt " DA1 round-trip (> 100 ms means the input path itself is delayed)."
# ---- 4. Raw keystroke capture (bypasses fish entirely) ----------------------
_lt ""
_lt "Raw input capture: type ~10 characters at a steady pace, including one"
_lt "ESC press and one arrow key. This shows the exact bytes this pane delivers"
_lt "and their timing, with fish's input handling out of the picture."
term-probe keylog 2>&1 | tee -a $logfile
_lt_ask ans_keylog_instant "Did each keypress appear INSTANTLY in the capture? (y/n)"
_lt_ask ans_keylog_plain "Were plain letters single plain bytes like b'a' (not escape sequences)? (y/n)"
# ---- 5. Scope ---------------------------------------------------------------
_lt ""
_lt_ask ans_scope_pane "Optional: open a NEW zellij pane/tab and type — laggy there too? (y/n)"
_lt_ask ans_scope_window "Optional: type in a separate Ghostty window (outside this zellij session) — laggy? (y/n)"
# ---- 6. Staged resets -------------------------------------------------------
# Each stage resets one category of state a TUI could have left behind.
# The first stage that cures the lag names the culprit.
set -l fixed none
_lt ""
_lt "Now applying resets one at a time. After each, type into the test prompt"
_lt "to judge whether the lag is gone."
if test $fixed = none
_lt ""
_lt "Stage A - kitty keyboard protocol: pop stack + clear all flags"
printf '\e[<9u\e[=0;1u'
_lt_ask ans_stage_a " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_a" = y; and set fixed "A (kitty keyboard state)"
end
if test $fixed = none
_lt "Stage B - modifyOtherKeys off"
printf '\e[>4;0m'
_lt_ask ans_stage_b " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_b" = y; and set fixed "B (modifyOtherKeys)"
end
if test $fixed = none
_lt "Stage C - normal keypad + normal cursor keys"
printf '\e>\e[?1l'
_lt_ask ans_stage_c " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_c" = y; and set fixed "C (application keypad/cursor mode)"
end
if test $fixed = none
_lt "Stage D - disable mouse, focus reporting, synchronized output"
printf '\e[?1000l\e[?1001l\e[?1002l\e[?1003l\e[?1005l\e[?1006l\e[?1015l\e[?1016l\e[?1004l\e[?2026l'
_lt_ask ans_stage_d " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_d" = y; and set fixed "D (mouse/focus/sync modes)"
end
if test $fixed = none
_lt "Stage E - leave alternate screen"
printf '\e[?1049l'
_lt_ask ans_stage_e " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_e" = y; and set fixed "E (alternate screen)"
end
if test $fixed = none
_lt "Stage F - stty sane (line-discipline reset)"
stty sane
_lt_ask ans_stage_f " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_f" = y; and set fixed "F (termios/line discipline)"
end
if test $fixed = none
_lt "Stage G - DECSTR soft terminal reset"
printf '\e[!p'
_lt_ask ans_stage_g " Test typing here, then Enter — lag gone? (y/n)"
test "$ans_stage_g" = y; and set fixed "G (DECSTR-resettable mode)"
end
# ---- 7. Verdict --------------------------------------------------------------
_lt ""
_lt "== Verdict =="
if test $fixed != none
_lt "Lag cleared by stage $fixed."
_lt "That state was stuck BELOW fish — in the Zellij pane or relayed to"
_lt "Ghostty — and the TUI you exited ($ans_tui) failed to restore it, or"
_lt "Zellij failed to restore it when the pane closed."
_lt "Re-probing terminal state after the fix for comparison:"
term-probe report 2>&1 | tee -a $logfile
_lt ""
_lt "-> File this log against zellij (or ghostty, if a separate window also"
_lt " lagged). The before/after probe diff pinpoints the exact stuck mode."
else if test "$ans_keylog_instant" = y; and test "$ans_keylog_plain" = y
_lt "Raw input reaches this pane instantly as plain bytes, and no terminal"
_lt "state reset helps: the lag lives INSIDE this fish process (reader state)."
_lt "Confirm now: run 'exec fish' — if that cures it, it is fish-internal."
_lt ""
_lt "-> To catch it in the act, run your next long-lived shell as:"
_lt " FISH_DEBUG='reader,term-support' FISH_DEBUG_OUTPUT=$logdir/fish-debug.log fish"
_lt " then re-run lag-triage when it recurs and file both logs to fish-shell."
else
_lt "Keystrokes were delayed or arrived as escape sequences BEFORE fish saw"
_lt "them: the problem is in Zellij (client stdin parser / server) or Ghostty."
_lt " new pane also laggy: $ans_scope_pane (y -> session-wide, not this pane)"
_lt " separate window laggy: $ans_scope_window (y -> Ghostty itself)"
_lt "-> File this log against zellij; include the keylog byte capture."
end
_lt ""
_lt "Full log: $logfile"
functions -e _lt _lt_ask