title: How to properly call compinit (and bashcompinit) in zsh
body: <p>The whole issue is discussed <a href="https://github.com/DannyBen/alf/issues/39" rel="nofollow noreferrer">here</a> and <a href="https://github.com/nvm-sh/nvm/issues/2489" rel="nofollow noreferrer">here</a>. Since no one involved in those discussions was 100% sure about the issue, I'm asking for help here. (For the sake of completeness, I'll start from the beginning.)</p>
  <p>Let's say we have two scripts (sourced in <code>~/.zshrc</code>) that set up some completion logic for ZSH. Now based on what I learned, at some point in the script you need to call <code>compinit</code> and <code>bashcompinit</code> like this (copied from NVM completion script)</p>
  <pre class="lang-sh prettyprint-override"><code>if [[ -n ${ZSH_VERSION-} ]]; then
    autoload -U +X compinit &amp;&amp; if [[ ${ZSH_DISABLE_COMPFIX-} = true ]]; then
      compinit -u
    else
      compinit
    fi
    autoload -U +X bashcompinit &amp;&amp; bashcompinit
  fi
  </code></pre>
  <p>Apparently, according to ZSH manual, <code>bashcompinit</code> must be called after <code>compinit</code>, (not sure if it's relevant). Now the problem is, the moment the second script calls <code>compinit</code>, the logic coming from the first script is gone (i.e. no completion from the first script is available). A simple snippet to reproduce this is (copied from <a href="https://github.com/DannyBen/alf/issues/39" rel="nofollow noreferrer">here</a>):</p>
  <pre class="lang-sh prettyprint-override"><code>complete -W &quot;hello world&quot; one
  one &lt;tab&gt;   # to see autocomplete working
  compinit 
  one &lt;tab&gt;   # to see autocomplete NOT working
  </code></pre>
  <p>Someone proposed (<a href="https://github.com/DannyBen/alf/issues/39" rel="nofollow noreferrer">here</a>) something like below to solve the issue (by checking if <code>compinit</code> is already called before calling it):</p>
  <pre class="lang-sh prettyprint-override"><code>if [[ -n ${ZSH_VERSION-} ]]; then
    if ! command -v compinit &gt; /dev/null; then
      autoload -U +X compinit &amp;&amp; if [[ ${ZSH_DISABLE_COMPFIX-} = true ]]; then
        compinit -u
      else
        compinit
      fi
    fi
    autoload -U +X bashcompinit &amp;&amp; bashcompinit
  fi
  </code></pre>
  <p>Another idea could be to call <code>compinit</code> and <code>bashcompinit</code> not in the custom completion script, but in <code>~/.zshrc</code> (which hurts the automated installation process for tools like NVM).</p>
  <p>I'd like to know what is the correct way to set up completion in general (or specifically with respect to calling <code>compinit</code>).</p>
  <p>Thanks.</p>