Skip to content

feat(zsh): history expansion inlay preview#52

Open
radiosilence wants to merge 6 commits intomainfrom
worktree-agent-a80d8a88
Open

feat(zsh): history expansion inlay preview#52
radiosilence wants to merge 6 commits intomainfrom
worktree-agent-a80d8a88

Conversation

@radiosilence
Copy link
Copy Markdown
Owner

Summary

  • ZLE widget that shows a dimmed preview of what history expansion (!!, !$, !^, ^foo^bar, etc.) would expand to before pressing Enter
  • Chains via add-zle-hook-widget — doesn't clobber zsh-autosuggestions or other zle-line-pre-redraw handlers
  • Appends preview below autosuggestion ghost text: → expanded_command
  • Uses zle expand-history internally (zsh's own expansion logic, handles all edge cases)
  • Kill switch: zstyle ':hist-preview' enabled no

How it works

On each line redraw, if ! or leading ^ detected in the buffer:

  1. Saves BUFFER/CURSOR
  2. Calls zle expand-history to expand in-place
  3. If changed: captures result, restores original, shows dimmed preview via POSTDISPLAY + region_highlight
  4. If unchanged: restores and leaves POSTDISPLAY alone (autosuggestions unaffected)

Recursion guard prevents expand-history → redraw → expand-history loops.

Test plan

  • Type !! — should show dimmed preview of last command below the line
  • Type sudo !! — preview shows sudo <last_command>
  • Type !$ — preview shows last argument of previous command
  • Type ^foo^bar — preview shows last command with substitution
  • Type normal commands (no !) — no preview, autosuggestions works normally
  • zstyle ':hist-preview' enabled no — disables the widget
  • Verify no flicker or conflict with autosuggestions ghost text

🤖 Generated with Claude Code

radiosilence and others added 6 commits April 11, 2026 09:19
ZLE widget that shows dimmed preview of what history expansion chars
(!!, !$, !^, ^foo^bar) would expand to before Enter. Uses
add-zle-hook-widget to chain into zle-line-pre-redraw — appends to
POSTDISPLAY instead of clobbering it, so zsh-autosuggestions still
works. Disable via zstyle ':hist-preview' enabled no.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use absolute offsets (autosuggestions-compatible) instead of P-prefix
- Remove highlight entries by value not index (avoids shift bugs)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show expansion on the same line (→ expanded) instead of below.
Replaces autosuggestion when expansion is active — more useful context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Wider gap before arrow for readability
- Use [ ] instead of [[ ]] for buffer comparison — avoids * in
  !!:* being treated as glob pattern in the != check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace zle expand-history with manual history parsing — avoids
  triggering widget events that let autosuggestions clobber POSTDISPLAY
- Fix unicode arrow: use $'\u2192' (zsh escape) not bare \u2192
- Support: !!, !$, !^, !!:*, !!:$, !!:^, !!:0-9, ^old^new
- Sets POSTDISPLAY directly without intermediate widget calls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The pre-redraw hook fires at the wrong stage — autosuggestions
overwrites POSTDISPLAY via widget wrapping, which runs after
our hook. Fix: wrap editing widgets ourselves, chaining after
autosuggestions' wrappers so we get final say on POSTDISPLAY.

Each keystroke now: widget → autosuggestions → our preview.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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