Commit Graph

1 Commits

Author SHA1 Message Date
Daniel Portales a98dd4abcf Fix region_highlight entries leaking across accept/edit cycles
Before this change, the highlight module tracked only the most recent
plugin-owned entry in a scalar (_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT) and
relied on a parameter-expansion subtraction to remove it:

    region_highlight=("${(@)region_highlight:#$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT}")

That has two failure modes:

1. The tracked string is expanded as a zsh glob pattern. If the user's
   ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE contains characters like `#`
   (e.g. `fg=#RRGGBB`), the entry is never removed and orphans
   accumulate in region_highlight across redraws. See #789.

2. Only one entry can be tracked at a time. When apply is called
   repeatedly without a successful reset (which happens under fast edits
   and widget-wrapping interactions), every apply overwrites the tracked
   reference and previous entries are orphaned.

Both manifest as stale suggestion colors bleeding onto accepted text,
typically in combination with zsh-syntax-highlighting (whose entries
interleave with ours in region_highlight).

Changes:

* Track every plugin-owned entry in an array
  (_ZSH_AUTOSUGGEST_OWNED_HIGHLIGHTS).

* On zsh 5.9+, tag each entry with `memo=zsh-autosuggestions` and on
  reset strip by memo in a single pass — robust regardless of how other
  plugins manipulate region_highlight. This matches the mechanism
  zsh-syntax-highlighting has used since 0.8.0.

* On zsh < 5.9, remove owned entries by literal string comparison
  (loop, not pattern expansion) to avoid the `#`-as-glob issue.

* _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT is retained and kept in sync for
  backwards compatibility with any external consumer.

Adds spec/highlight_spec.rb covering:
  - round-trip with a hex-colored style (regression for #789)
  - reset does not touch foreign region_highlight entries
  - accumulated orphans from repeated apply calls are all cleaned up

Supersedes #790 (which used `shift -p region_highlight` — incorrect
when another plugin has appended the most-recent entry).

Fixes #789, #698.
2026-04-20 07:52:36 -06:00