Completions Recommendations Clarification
Closed this issue · 2 comments
I was reading through your documentation on completions and I had a few questions I hope you can clarify. You suggest the following code to utilize caching and compilation to speed up generating completions on shell startup:
# .zshrc
autoload -Uz compinit
ZSH_COMPDUMP=${ZSH_COMPDUMP:-${ZDOTDIR:-~}/.zcompdump}
# cache .zcompdump for about a day
if [[ $ZSH_COMPDUMP(#qNmh-20) ]]; then
compinit -C -d "$ZSH_COMPDUMP"
else
compinit -i -d "$ZSH_COMPDUMP"; touch "$ZSH_COMPDUMP"
fi
{
# compile .zcompdump
if [[ -s "$ZSH_COMPDUMP" && (! -s "${ZSH_COMPDUMP}.zwc" || "$ZSH_COMPDUMP" -nt "${ZSH_COMPDUMP}.zwc") ]]; then
zcompile "$ZSH_COMPDUMP"
fi
} &!
I'm trying to understand how this works. To begin with you autoload compinit, and then you bind ZSH_COMPDUMP
to the location of zcompdump
. Then you check if ZSH_COMPDUMP
has been modified within the last 20 hours. if it has, you run compinit, bypassing compaudit check, and generate the compdump. Otherwise, if it hasn't been modified within the last 20 hours you run compinit, omit insecure directories, generate the compdump, and update the file modification time to present.
Why do you bypass the compaudit check if it has been modified in the last 20 hours? I found the following information from the documentation (https://zsh.sourceforge.io/Doc/Release/Completion-System.html), "To speed up the running of compinit, it can be made to produce a dumped configuration that will be read in on future invocations; this is the default... If the number of completion files changes, compinit will recognize this and produce a new dump file." Is compaudit the mechanism by which compinit is able to recognize if the number of completion files has changed? If so, then I think this makes sense, you don't want the overhead of compaudit regenerating the cache if the completion files change within the last 20 hours.
But I am curious why this is even necessary. So long as I ensure that my completions plugin is loaded and any custom completions are sourced prior to calling compinit, shouldn't my cache persist and remain the same until a significant change? What would cause a change in the number of completion files available to compinit other than an upstream change to a completions plugin or the user explicitly adding a new completions file which is sourced in their .zshrc file? Those two things shouldn't occur that frequently.
This is a long established pattern for handling compinit, and comes from Prezto: https://github.com/sorin-ionescu/prezto/blob/e3a9583f3370e11a0da1414d3f335eac40c1e922/modules/completion/init.zsh#L49-L68
Prezto also does the .zwc compilation, it's just in the .zlogin file: https://github.com/sorin-ionescu/prezto/blob/master/runcoms/zlogin
I'm sure if you search the issue tracker on it (or I think Zim as well), you'll find some discussion of it. I'm probably not going to be your best resource to explain the whole theory, so feel free to post your question to the Prezto project if what I'm sharing here doesn't satisfy your question fully.
The basis of the trick is that it caches to skip the security check, using -C
. Per the Zsh docs:
"This security check is skipped entirely when the -C option is given, provided the dumpfile exists." In my experience, the timing of loading a new Zsh is positively impacted by skipping this check, but not significantly. So really you only do this if you're super picky about your startup time being as fast as possible (like me).
shouldn't my cache persist and remain the same until a significant change?
Insignificant changes that you might not even notice are really what you're guarding against. Any change to your fpath - a new folder, a new function, or updated function (for example: brew/apt/pacman/yum updates) could change or add completions you might want. This caching method makes sure you get a full refresh of your compinit once a day with the security check as well. If you don't notice a performance boost by doing this, then it may not be worth the caching for you.
I see, thank you for the clarification!