conda-incubator / conda-zsh-completion

zsh completion for conda
Do What The F*ck You Want To Public License
364 stars 65 forks source link

Doesn't work like "similar" completion systems #38

Closed jrwrigh closed 2 years ago

jrwrigh commented 3 years ago

I tried installing the completion via antibody, which loads the plugin into $fpath fine. However, it does not work in my dotfiles due my placement of autoload -U compinit; compinit. For all of my other completion settings (including https://github.com/zsh-users/zsh-completions/), compinit must be run before they are sourced. By contrast, conda-zsh-completion requires that compinit be run after it is sourced. So my .zshrc ends up looking like:

autoload -U compinit; compinit
source /path/to/completion_settings.zsh # includes the zstyle commands for conda-zsh-completion
source /antibody/plugin/source.zsh # includes conda-zsh-completion in $fpath
compinit # only required for conda-zsh-completion

Two primary questions:

  1. Why this completion plugin is different to the others?
  2. Whether this can be changed to match the behavior?

I'm not familiar enough with zsh completions to figure out the answers to either of these unfortunately.

esc commented 2 years ago

I tried installing the completion via antibody, which loads the plugin into $fpath fine. However, it does not work in my dotfiles due my placement of autoload -U compinit; compinit. For all of my other completion settings (including https://github.com/zsh-users/zsh-completions/), compinit must be run before they are sourced. By contrast, conda-zsh-completion requires that compinit be run after it is sourced. So my .zshrc ends up looking like:

autoload -U compinit; compinit
source /path/to/completion_settings.zsh # includes the zstyle commands for conda-zsh-completion
source /antibody/plugin/source.zsh # includes conda-zsh-completion in $fpath
compinit # only required for conda-zsh-completion

Two primary questions:

  1. Why this completion plugin is different to the others?
  2. Whether this can be changed to match the behavior?

I'm not familiar enough with zsh completions to figure out the answers to either of these unfortunately.

I am not very well versed in zsh either, unfortunately, but I did ask some people "in the know" on the libera IRC chat and the response I received was:

for the compsys to notice a completer, it has to be in fpath before compinit is ran.

And:

all compinit is really doing is defining the compdef function, then search for files in fpath that begins with _ and has a magic comment #compdef so if you extend fpath after compinit is ran. nothing of interest will happen within the compsys

So, now I am very confused. Do you have any documentation on which plugins suggest to run compinit before adding to the path? I'd like to take a closer look.

jrwrigh commented 2 years ago

Do you have any documentation on which plugins suggest to run compinit before adding to the path?

Not explicitly, but I had followed this guide to get everything setup. Other than that, there are two cases that require it:

1. Plugins that call compdef

Instead of having a separate #compdef ___ file and relying on compinit to be run after adding it to $fpath, these define the completion function in their *.zsh file (which is sourced by antibody) and explicitly call compdef to set the completion up. Example of this is the OMZ tmux plugin.

2. The anomalies I don't understand (https://github.com/zsh-users/zsh-completions/)

The https://github.com/zsh-users/zsh-completions/ appears to work pretty much exactly the same as yours. However, I was also seeing behavior for the https://github.com/zsh-users/zsh-completions/ plugin where it was required to run before for the completion to work. However, once I disabled the https://github.com/Aloxaf/fzf-tab plugin, then it works either way. Which makes no sense to me.

Other interesting attempts

Based on this, I went ahead and tried to add your _conda file to the src directory of the zsh-completions to allow it to load the conda completion file. However, doing this still requires running compinit after zsh-completions is loaded. So it's definitely something to do with _conda itself. As for what, I don't know.

For reference, I was testing the other zsh-complete completion functions for cmake and dhcpcd to verify whether it was _conda or the whole of https://github.com/zsh-users/zsh-completions/ that was not loading correctly. I might check out those files to spot differences. The one for dhcpcd is very short.

jrwrigh commented 2 years ago

Regarding the 2. anomaly, I've just seen that for https://github.com/Aloxaf/fzf-tab, it states that it is required to be loaded after compinit. So since I use antibody to handle both completions and other zsh plugins, I have to run compinit before anything is loaded. This in addition to reason 1. (which I use explicitly in my custom completions file and is used by the afore mentioned tmux plugin).

esc commented 2 years ago

@jrwrigh ok, you clearly know more about zsh and completions than I do. I really haven't touched my setup for years now. If you figure out a solution, please do submit a pull-request. As for the issue. I'm not sure if it is a good idea to keep it open. It is more of a discussion than a bug to be fixed or a feature to be added?

esc commented 2 years ago

I remember that I did use zsh-completions as an inspiration so it would make sense that the conda completion is similar to those.

llua commented 2 years ago

Do you have any documentation on which plugins suggest to run compinit before adding to the path?

Not explicitly, but I had followed this guide to get everything setup. Other than that, there are two cases that require it:

1. Plugins that call compdef

Instead of having a separate #compdef ___ file and relying on compinit to be run after adding it to $fpath, these define the completion function in their *.zsh file (which is sourced by antibody) and explicitly call compdef to set the completion up. Example of this is the OMZ tmux plugin.

As inefficient and non idiomatic as foregoing autoloadable functions for a completer, your example isn't doing that. it is creating a wrapper function for tmux and associating the_tmux completer provided by zsh's source tree to the wrapper so it has the same completion as tmux.

An example of this completer working fine when it is in fpath prior to compinit running; just like any other completer. asciicast

jrwrigh commented 2 years ago

Circling back to this (after a hot minute), it turns out that my Manjaro installation automatically installs zsh-completions to /usr/share/zsh/site-functions. So the above behavior makes sense, the initial compinit run was picking up the completions /usr/share/zsh/site-functions rather than what was sourced by antibody. You must run compinit after putting functions in $fpath, but they can also be placed in path locations and be picked up there.

esc commented 2 years ago

Circling back to this (after a hot minute), it turns out that my Manjaro installation automatically installs zsh-completions to /usr/share/zsh/site-functions. So the above behavior makes sense, in that you must run compinit after putting functions in $fpath and the zsh-completions functions were already installed (not to $fpath but at a location where compinit could find it).

Thank you for circling back!