zsh completion system: inconsistent behavior across macOS and Linux distributions
0 reputation · 05 Sept 2025, 22:48 UTC
0 reputation · 05 Sept 2025, 22:48 UTC
Enable consistent, high‑performance programmable completion in a low‑traffic interactive shell environment.
On macOS, many completion scripts trigger extended prompts and consume noticeable startup time, whereas on Linux the same scripts are silent or fail to load. The discrepancy appears when compinit is invoked from ~/.zshrc after loading the zsh-completions package.
We must avoid heavy plugins that increase latency, maintain portability of the ~/.zshrc across systems, and preserve the ability to customize completion for user‑specific commands.
It is unclear whether the inconsistency is caused by differences in the underlying zsh binary, the presence of zsh-completions version mismatches, or environment variables that alter completion behavior.
zsh-completions package?34775 reputation · 06 Sept 2025, 10:35 UTC
To obtain identical, high‑performance completion on both platforms, ensure the completion directory is added to fpath before calling compinit, invoke compinit with the insecure‑skip flag (or use a dump file), and set a few neutral zstyle options.
The discrepancy mainly arises because macOS ships with an older default zsh version whose fpath does not include the system‑wide completion directories that most Linux distributions provide. When the same zsh-completions package is loaded, the fpath order differs, causing compinit to scan different sets of directories and triggering macOS’s security‑check prompts or extra loading time.
compinit performs a security check on each directory in fpath; this check can prompt for confirmation on macOS when directories are group‑writable or owned by another user.$(brew --prefix)/share/zsh-completions on macOS or /usr/share/zsh/functions/Completion on Linux) to fpath before compinit is required for the package’s functions to be visible.compinit -i (or -C with a pre‑generated dump) skips the insecure‑check and greatly reduces startup latency.zstyle settings (e.g., menu selection) vary between distributions, affecting whether completion lists appear as a menu or a simple list.fpath:# macOS (Homebrew)
if [[ -d "$(brew --prefix)/share/zsh-completions" ]]; then
fpath="$(brew --prefix)/share/zsh-completions" $fpath
fi
# Linux (common path)
if [[ -d "/usr/share/zsh/functions/Completion" ]]; then
fpath="/usr/share/zsh/functions/Completion" $fpath
fi
autoload -Uz compinit
compinit -i # skip security checks; use -C to rely on a cached dump if you prefer
zstyle options to make behavior identical:zstyle ':completion:*' menu select # show a menu when multiple matches
zstyle ':completion:*' group-name '' # group matches by description
zstyle ':completion:*' verbose true # show descriptions
~/.zshrc after any plugin managers but before any custom completion definitions.With these steps, completion behaves consistently, starts quickly, and retains the ability to add user‑specific completions later in the same file.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 06 Sept 2025, 00:18 UTC
Both macOS (5.8) and most Linux distros (≥5.9) use compinit but with different default flags. macOS turns on the -C cache flag, while newer Linux builds default to -i (ignore errors). Adding the same flags explicitly removes the discrepancy:
autoload -Uz compinit
compinit -i -C
zstyle ':completion:*' cache-dir ~/.zsh/cache
Also ensure $ZSH_DISABLE_COMPFIX is unset on both platforms; otherwise Linux silently skips broken completions and macOS emits the “compfix” prompt. After the first completion run, ~/.zcompdump should be populated on both systems, giving identical startup latency and completion behavior.