Skip to content

fix: add terminfo capability guard to interactive.d scripts#27

Merged
alohays merged 1 commit into
mainfrom
fix/terminfo-capability-guard
Mar 23, 2026
Merged

fix: add terminfo capability guard to interactive.d scripts#27
alohays merged 1 commit into
mainfrom
fix/terminfo-capability-guard

Conversation

@alohays
Copy link
Copy Markdown
Owner

@alohays alohays commented Mar 23, 2026

Summary

  • Add dotfiles_term_capable() helper to lib.sh that validates both TERM value and actual terminfo availability via tput
  • Replace static case TERM in ''|dumb) guards in 6 interactive.d scripts with the new helper
  • Guard p10k loading in 80-prompt.sh so fallback prompt is used when terminfo is unavailable

Problem

When SSH-ing from Ghostty terminal (TERM=xterm-ghostty) to a host without the xterm-ghostty terminfo entry, ZLE plugins (p10k, autosuggestions, fast-syntax-highlighting) compute incorrect cursor positions because tput fails and $COLUMNS=0. This causes progressive character garbling (e.g., lslsls, claudeclaudecllaauudclaude).

Root Cause

The existing case TERM in ''|dumb) guards only check for empty/dumb TERM values. xterm-ghostty passes this guard (non-empty, non-dumb) but has no terminfo entry on the remote, causing all terminal capability queries to fail silently.

Fix

dotfiles_term_capable() checks both conditions:

  1. TERM is non-empty and not dumb
  2. tput cols actually succeeds (terminfo is usable)

Files Changed

  • modules/core/home/.config/dotfiles/lib.sh — new dotfiles_term_capable() helper
  • modules/prompt/home/.config/dotfiles/interactive.d/00-p10k-instant-prompt.zsh — add guard (had none)
  • modules/core/home/.config/dotfiles/interactive.d/70-zsh-plugins.sh — upgrade guard
  • modules/prompt/home/.config/dotfiles/interactive.d/80-prompt.sh — guard p10k, keep fallback
  • modules/prompt/home/.config/dotfiles/interactive.d/81-completion.zsh — upgrade guard
  • modules/prompt/home/.config/dotfiles/interactive.d/82-rich-plugins.zsh — upgrade guard
  • modules/prompt/home/.config/dotfiles/interactive.d/83-rich-fzf.sh — upgrade guard

Test plan

  • SSH into host with xterm-ghostty terminfo installed → full functionality (p10k, autosuggestions, syntax highlighting)
    • Verified: ssh mac-mini — no character garbling, p10k prompt renders correctly, autosuggestions and syntax highlighting work
    • Automated: TERM=xterm-ghostty tput cols80, infocmp xterm-ghostty → OK
  • SSH into host without terminfo → graceful fallback (simple prompt, no garbling)
    • Verified: TERM=xterm-nonexistent zsh -c 'source ~/.zshrc; dotfiles_term_capable && echo pass || echo blocked'blocked
    • Plugins correctly skipped, no ZLE cursor errors
  • Simulate: TERM=xterm-nonexistent zsh -l → plugins skipped, fallback prompt works
    • Verified: dotfiles_term_capable returns non-zero, all interactive.d guards fire, fallback prompt displayed
  • Local shell (non-SSH) → no regression, everything works as before
    • Verified: local dotfiles_term_capable → pass, all plugins load normally

🤖 Generated with Claude Code

Prevent ZLE plugin failures (double echo, cursor garbling) when
TERM is set to a value without a matching terminfo entry on the
remote host (e.g. xterm-ghostty over SSH).

Add dotfiles_term_capable() helper to lib.sh that checks both
TERM value and actual terminfo availability via tput. Replace
static TERM case guards in interactive.d scripts with this helper.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alohays alohays merged commit f07e640 into main Mar 23, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant