getantidote / zdotdir

A full-featured sample Zsh config driven by antidote
MIT License
103 stars 38 forks source link

compinit/completions for omz plugins #6

Closed vanhecke closed 2 months ago

vanhecke commented 9 months ago

I believe completions are loaded a bit differently with OMZ and other frameworks.

When adding the following plugin: ohmyzsh/ohmyzsh path:plugins/macos

I receive the following error:

/Users/jvanhecke/Library/Caches/antidote/https-COLON--SLASH--SLASH-github.com-SLASH-ohmyzsh-SLASH-ohmyzsh/plugins/macos/macos.plugin.zsh:232: command not found: compdef
/Users/jvanhecke/Library/Caches/antidote/https-COLON--SLASH--SLASH-github.com-SLASH-ohmyzsh-SLASH-ohmyzsh/plugins/macos/macos.plugin.zsh:264: command not found: compdef
/Users/jvanhecke/Library/Caches/antidote/https-COLON--SLASH--SLASH-github.com-SLASH-ohmyzsh-SLASH-ohmyzsh/plugins/macos/music:170: command not found: compdef

This also happens with other omz plugins such as git,rails, rake, chruby but also lib/directories.

I know load these plugins after loading the belak/zsh-utils path:completion but I'm not sure if this is correct.

mattmc3 commented 8 months ago

Completions are complicated. Let's talk compinit... compinit works by finding _completion files in your fpath. That means fpath has to be fully populated prior to calling compinit. If you use oh-my-zsh, if populates fpath and runs compinit prior to loading plugins. This is only problematic if you expect to be able to add to fpath later. Conversely, if you wait to run compinit until the end of your config, then functions like compdef aren't available earlier in your config, and oh-my-zsh uses compdef in plugins like the ones you name: git, rails, etc.

TLDR; I just released a big update to my completions plugin in Zephyr that addresses all of this. If you are using antidote, just load this plugin first:

# .zsh_plugins.txt
mattmc3/zephyr path:plugins/completion
matru commented 2 months ago

@mattmc3 Zephyr pulls completions from zsh-users/zsh-completions, but the one in zephyr's repo is pretty outdated by now.

In .zsh_plugins.txt you mention the following:

### Completions
#
# You may want to add some additional completions to Zsh. Completions look in your fpath
# for completion functions, which are functions named with a leading underscore
# (eg: _git). You need to add all supplemental completions to your fpath prior to
# running `compinit` to use completions functionality properly. You will want to find
# a completion plugin that runs `compinit` for you, or you can run it yourself in
# your .zshrc after antidote loads like this:
#
#   autoload -Uz compinit && compinit
#
###

# With antidote, using Zephyr's completion plugin is recommended. This plugin is meant
# to be run near the TOP of your .zsh_plugins.txt file.
mattmc3/zephyr path:plugins/completion

# zsh-users/zsh-completions is a popular plugin for adding supplemental completions.
# We combine the `path:` and `kind:fpath` annotations here:
# zsh-users/zsh-completions path:src kind:fpath

# Most other compinit plugins should be near the END of .zsh_plugins.txt so that $fpath
# has been fully populated. One such plugin is zsh-utils and its completion subplugin.
# belak/zsh-utils path:completion

If using antidote, why is it preferred to use zephyr's? Can I use only zsh-users/zsh-completions instead? Can I also use the zsh-utils one together with either?

Also would there be any issues if using these too: https://github.com/Aloxaf/fzf-tab, https://github.com/lincheney/fzf-tab-completion and https://github.com/marlonrichert/zsh-autocomplete. Perhaps you could let me know what combination would work best

mattmc3 commented 2 months ago

If using antidote, why is it preferred to use zephyr's?

It's not. You can use any completion plugin you want, or none at all. Can you tell me where you found that reference to Zephyr in a .zsh_plugins.txt? I thought I had removed all references to Zephyr in this repo.

Can I use only zsh-users/zsh-completions instead?

I know this can be crazy confusing, so let me state this as clearly as I know how. When we talk about completions, there's two different parts to it.

Also would there be any issues if using these too: https://github.com/Aloxaf/fzf-tab, https://github.com/lincheney/fzf-tab-completion and https://github.com/marlonrichert/zsh-autocomplete. Perhaps you could let me know what combination would work best

antidote is plugin agnostic. Use whatever you like. My only recommendation is if you are using Oh-My-Zsh plugins or Prezto modules, you might want to consider using use-omz or use-prezto respectively, as those frameworks have some dependencies that you have to deal with yourself if you don't include those helper plugins.

matru commented 2 months ago

Can you tell me where you found that reference to Zephyr in a .zsh_plugins.txt? I thought I had removed all references to Zephyr in this repo.

I've already linked this before, but it's on Line 34:

# With antidote, using Zephyr's completion plugin is recommended. This plugin is meant
# to be run near the TOP of your .zsh_plugins.txt file.
mattmc3/zephyr path:plugins/completion

Ok, so it is indeed preferred to use both zsh-users/zsh-completions and belak/zsh-utils path:completion, in order to make sure the former even initializes, or just do it manually. As for the fzf-tab, fzf-tab-compleition and zsh-autocomplete by Marlon, I actually wanted to ask if they have any interference with the completion plugins that I've spoken above, or it has nothing to do with those?

Thanks for notifying me on use-omz. Is there anything I need to care about when using it? Btw, how does OMZ check the security of a directory, by what method? You mention it here on the use-omz readme:

Oh-My-Zsh by default checks the security of directories in fpath when running compinit.

mattmc3 commented 2 months ago

Ok, so it is indeed preferred to use both zsh-users/zsh-completions and belak/zsh-utils path:completion, in order to make sure the former even initializes, or just do it manually

Whichever way you prefer, but yes - I recommend using both. However, if you are using OMZ, and have included the getantidote/use-omz plugin, then it handles initializing your completions instead of belak/zsh-utils path:completion. You don't need both.

As for the fzf-tab, fzf-tab-compleition and zsh-autocomplete by Marlon, I actually wanted to ask if they have any interference with the completion plugins that I've spoken above, or it has nothing to do with those?

I'm familiar with Marlon's excellent Zsh plugins, but have not used any of those myself. If there's interference with using them, I recommend opening an issue with Marlon.

Thanks for notifying me on use-omz. Is there anything I need to care about when using it?

Not really. The docs are pretty clear, in my (not so) humble opinion.

Btw, how does OMZ check the security of a directory, by what method? You mention it here on the use-omz readme:

You can see OMZ's compaudit code here:

matru commented 2 months ago

One more thing @mattmc3, since you mentioned that use-omz handles completions through compinit, and I don't need to use zsh-utils path:completion at all, what happens if I want to install a plugin like: https://github.com/marlonrichert/zsh-autocomplete where he specifically mentions?

In your .zshrc file:
    Remove any calls to compinit.
    Add near the top, before any calls to compdef
mattmc3 commented 2 months ago

use-omz by default wraps compinit and compdef calls and defers them until the very end of your .zshrc, but it does it in such a way that if you (or a plugin like marlonrichert/zsh-autocomplete) decide you want to make those calls yourself, use-omz will gracefully unwrap those functions and let those calls happen whenever you do them in your config. So basically, while I cannot vouch for how other plugins behave (ie: I am not a user of zsh-autocomplete), it should work just fine and be none-the-wiser that use-omz is adding those wrappers at all.

So, in summary, If you don't include a plugin that handles compinit and forget to call compinit yourself, use-omz will helpfully ensure that call actually happens as a failsafe, and it does it in such a way as to mimic OMZ's behavior where possible. By deciding to include use-omz, the assumption is that's the behavior you want, so it's not a customizable thing. Customizing that would mean crafting your own plugin.

matru commented 2 months ago

Oh, I see. Thanks for the clear up!

matru commented 1 month ago

@mattmc3 I noticed a few things and I would still ask for your help since you're really knowledgable on it and it might help out the repo since it's a starter config.

I was adding this plugin https://github.com/Aloxaf/fzf-tab, and it mentioned the following:

  1. make sure fzf is installed

  2. fzf-tab needs to be loaded after compinit, but before plugins which will wrap widgets, such as zsh-autosuggestions or fast-syntax-highlighting

  3. Completions should be configured before compinit, as stated in the zsh-completions manual installation guide.

So this means that I can't rely on use-omz for loading compinit since it will load compinit the very last (before the deferred item), and I need to load fzf-tab after few plugins like fast-syntax-highlighting (which is deferred with antidote, and I believe it will load the last in any case, so no issues there as the position doesn't matter in the plugins txt file), but also autosuggestions, which is at the very bottom in the file, but it will still load before compinit. So what I had to do is enable and rely on belak/zsh-utils path:completion for compinit, in order to perserve required order, let me know if that's correct in the zdotdir config, here's the latest commit: https://github.com/matru/zdotdir/commit/c9f83434d76cf5006bbd4bd132e322a9937c1a45

But one more thing I am struggling with is the following, https://github.com/marlonrichert/zsh-autocomplete mentioned that I should omit compinit from my config:

In your .zshrc file:

Remove any calls to compinit.
Add near the top, before any calls to compdef:

source /path/to/zsh-autocomplete/zsh-autocomplete.plugin.zsh

I believe autocomplete loads compinit itself (https://github.com/marlonrichert/zsh-autocomplete/issues/215#issuecomment-808706856), does this mean that I should be swapping belak/zsh-utils path:completion with marlonrichert/zsh-autocomplete? For the second requirement to be before any calls of compdef, I am not sure if any of the other plugins in my last can even call compdef. But if they don't I guess near the don't top doesn't matter as long as it's loaded without any calls to compinit and before any calls to compdef?

mattmc3 commented 1 month ago

Based on what you've described, it sounds like your load order might need to look something like this:

#.zsh_plugins.txt

# Some OMZ plugins
getantidote/use-omz
ohmyzsh/ohmyzsh path:plugins/git
ohmyzsh/ohmyzsh path:plugins/magic-enter
ohmyzsh/ohmyzsh path:plugins/extract

# Plugins before compinit
zsh-users/zsh-completions

# Plugins that claim to run compinit (meaning use-omz won't)
marlonrichert/zsh-autocomplete 
# belak/zsh-utils path:completion  # No need to load this if zsh-autocomplete ran compinit

# Plugins that say to load them after compinit
Aloxaf/fzf-tab

# Other stuff that doesn't affect completions
zsh-users/zsh-autosuggestions
zdharma-continuum/fast-syntax-highlighting

This is more support than I'm likely to keep providing in the future because my knowledge of what specific plugins do is out of scope for antidote support. I would generally suggest trying out your config and seeing what works, and tweaking as necessary.

matru commented 1 month ago

@mattmc3 thanks, I totally understand it, I know I pushed with all the questions. Hopefully someone else also finds our discussion useful.