perf: deduplicate fpath before comparing cached zcompdump metadata

The current fpath comparison uses `grep -Fx` against `$fpath` joined as
a single string. This fails whenever fpath duplicate counts drift
between sessions, which happens on any setup where `.zprofile` or
`.zshenv` modifies fpath via `brew shellenv`, `pyenv init`, `conda init`,
mise, nvm, direnv, or similar — these tools commonly re-prepend a
site-functions directory that another init file already added.

When the comparison fails, OMZ deletes the dump and runs a full
compinit rebuild on every startup, adding 500-1500 ms to shell init
despite the cache being functionally valid.

Deduplicate fpath (preserving first-occurrence order) before comparing
so sessions that differ only in duplicate counts produce identical
metadata. Order is preserved because `compinit` resolves colliding
completion files by first-occurrence in fpath, so sorting would risk
masking legitimate invalidation when two fpath orderings register
different compdef functions.

Existing dumps are invalidated once on upgrade, then work normally.

Fixes #13720
This commit is contained in:
Randy James 2026-05-01 18:20:44 -07:00
commit 477e0cc384
No known key found for this signature in database

View file

@ -110,9 +110,14 @@ if [[ -z "$ZSH_COMPDUMP" ]]; then
ZSH_COMPDUMP="${ZDOTDIR:-$HOME}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"
fi
# Construct zcompdump OMZ metadata
# Construct zcompdump OMZ metadata. fpath is deduplicated (preserving
# first-occurrence order) before comparison so that sessions which
# differ only in duplicate counts produce identical metadata. Order is
# preserved because `compinit` resolves colliding completion files by
# first-occurrence in fpath, so two fpaths with the same entries in a
# different order can legitimately produce different completions.
zcompdump_revision="#omz revision: $(builtin cd -q "$ZSH"; git rev-parse HEAD 2>/dev/null)"
zcompdump_fpath="#omz fpath: $fpath"
zcompdump_fpath="#omz fpath: ${${(@u)fpath}}"
# Delete the zcompdump file if OMZ zcompdump metadata changed
if ! command grep -q -Fx "$zcompdump_revision" "$ZSH_COMPDUMP" 2>/dev/null \