mattmc3 / antidote

https://getantidote.github.io - the cure to slow zsh plugin management
MIT License
859 stars 21 forks source link

Can't seem to make completion work (taking oh-my-zsh docker plugins for example) #127

Closed farzadmf closed 10 months ago

farzadmf commented 1 year ago

Hi, I'm not sure what I'm missing, but auto completion doesn't seem to work for me.

This is my config:

https://github.com/zsh-users/zsh-completions
https://github.com/belak/zsh-utils path:completion

https://github.com/ohmyzsh/ohmyzsh path:lib
https://github.com/ohmyzsh/ohmyzsh path:plugins/docker kind:defer
https://github.com/ohmyzsh/ohmyzsh path:plugins/docker kind:fpath
https://github.com/ohmyzsh/ohmyzsh path:plugins/terraform kind:defer
https://github.com/ohmyzsh/ohmyzsh path:plugins/terraform kind:fpath

https://github.com/jeffreytse/zsh-vi-mode

And I'm trying to make docker and terraform completions work.

If I run compinit manually in a shell, they work in that shell. From the docs, it seems that adding those completion plugins at the top should work, but I don't know what I'm missing.

I tried having them as kind:defer only (only 1 line instead of the 2 lines I have), but that doesn't work either


It might have something to do with zsh-vi-mode's "after init" commands, and I am using a zvm_after_init() function to run "extra commands", so I might need to do something similar for those plugins as well (however, I tried disabling zsh-vi-mode, but I still don't have the completion)

Can you please let me know if this issue can be solved? I really want to switch to antidote, but these are preventing me from doing that 🙁

mattmc3 commented 1 year ago

I've found that you cannot defer completions, unfortunately. That's not an antidote limitation, but a limitation of zsh-defer.

Completions plugins like belak/zsh-utils path:completion call Zsh's compinit, which means everything has to be in fpath before that call in order to get completions. Try this config:

# ${ZDOTDIR:-$HOME}/.zsh_plugins.txt

# OMZ
ohmyzsh/ohmyzsh path:lib
ohmyzsh/ohmyzsh path:plugins/docker     # if you want the completions but not the aliases, add kind:fpath
ohmyzsh/ohmyzsh path:plugins/terraform  # if you want the completions but not the aliases, add kind:fpath
jeffreytse/zsh-vi-mode

# Now, run your completions at the end
belak/zsh-utils path:completion
farzadmf commented 1 year ago

Thank you @mattmc3 for the quick answer.

Unfortunately, that doesn't seem to work for me either. If I move the completion plugin(s) to the end, I get this error:

....cache/antidote/https-COLON--SLASH--SLASH-github.com-SLASH-ohmyzsh-SLASH-ohmyzsh/lib/directories.zsh:34: command not found: compdef

The only way I can make it work is if I put compinit inside my zvm_after_init() function, but I think that would mean a performance hit for every new shell

mattmc3 commented 1 year ago

Got it. Taking a fresh look at the OMZ source, it appears that plugins are added to fpath as a whole separate step before being loaded. So what if you did your config like this:

# ${ZDOTDIR:-$HOME}/.zsh_plugins.txt

# Add OMZ completions plugins to `fpath`
ohmyzsh/ohmyzsh path:plugins/docker kind:fpath
ohmyzsh/ohmyzsh path:plugins/terraform kind:fpath

# do normal plugins
jeffreytse/zsh-vi-mode

# Now, run your completions before OMZ's lib is loaded
belak/zsh-utils path:completion

# OMZ
ohmyzsh/ohmyzsh path:lib
ohmyzsh/ohmyzsh path:plugins/docker
ohmyzsh/ohmyzsh path:plugins/terraform

Or, you might also consider whether you need OMZ's whole lib directory. At this point, we aren't really discussing a bug in antidote, but rather OMZ's dependency rat's nest.

farzadmf commented 1 year ago

Still not working 🙁

At this point, we aren't really discussing a bug in antidote, but rather OMZ's dependency rat's nest.

Totally agree. TBH, I don't care about OMZ (or any other framework for that matter 😛); I just want my completion to be there 😆

Or, you might also consider whether you need OMZ's whole lib directory.

It has some nice aliases for path navigation that I use regularly, but even if I disable it (comment it out), nothing changes, and I don't have auto complete


A couple of questions for you:

Is only one of these enough? Or should I have both?

chiragbhatia94 commented 1 year ago

Hi Team, I am also unable to get auto complete to work with ohmyzsh plugins like asdf, docker etc. Kindly suggest.

farzadmf commented 1 year ago

For me, the "manual" way mentioned in the docs seems to do the trick (it seems?)

I have both plugins mentioned for completion:

zsh-users/zsh-completions
belak/zsh-utils path:completion

Along with the code snippet mentioned in there, and it seems to do the trick maybe?

FWIW, I'm not quite confident as this doesn't seem to be the recommended way, so I'm pretty sure something should be missing here!

mattmc3 commented 1 year ago

The zsh-users/zsh-completions plugin adds additional Zsh completion definitions for ~150 different commands. But, it doesn't run compinit, which is what tells Zsh you're done building your fpath and ready to initialize your completions. That's why you also need a plugin like belak/zsh-utils path:completion or mattmc3/zephyr path:completion. There's also a third completion concern, which is what zstyles do you want to set to display those completions. Zephyr's completion plugin is designed for all 3, and is patterned after Prezto. I know - clear as mud, right?

AlexAxthelm commented 11 months ago

Hey all, I found a solution that is working for me:

in my plugins file, I needed to explicitly call out the completions subdirectory for my fpath (I'm avoiding the aliases), and make sure it was followed by one of the compinit-calling plugins:

ohmyzsh/ohmyzsh path:plugins/docker/completions kind:fpath
# ...
# later on
belak/zsh-utils path:completion

then, since zsh-utils caches the completions, I needed to remove the compdump file so that it would run compinit again (for me that was at ~/.cache/zsh/compdump).

One other note, from the OMZ Docker readme, if you're using the -it flag to open an interactive session (like I was), then the completions won't come through by default, since OMZ doesn't deal with flag stacking, but this can be voercome with zstyles.

farzadmf commented 10 months ago

Thank you @AlexAxthelm for the reply. I was forced to use another plugin manager for the computer I had this issue with, but I'll try to give this a try if I get the chance.

I'm also curious about what you said:

OMZ doesn't deal with flag stacking, but this can be voercome with zstyles.

How can this be done? I had to force myself to always type -i -t because of this; is there a solution?

AlexAxthelm commented 10 months ago

@farzadmf in the OMZ Docker readme, they include this snippet that allows for -it rather than -i -t

zstyle ':completion:*:*:docker:*' option-stacking yes
zstyle ':completion:*:*:docker-*:*' option-stacking yes

But this doesn't give you the completion for the flags, it just lets you still have completion for container names after passing -it

farzadmf commented 10 months ago

Thank you @AlexAxthelm for the link (and the snippet). Seems like the side effect mentioned there isn't worth its convenience (it's not super hard to type -i -t anyway :laughing: )

mattmc3 commented 10 months ago

See:

mattmc3 commented 2 months ago

As of June 2024, the recommended way of handling OMZ is now to include the new getantidote/use-omz plugin at the TOP of your .zsh_plugins.txt file. It handles all OMZ dependency resolution, setting OMZ variables, and deferred completion initialization for OMZ users. No more compdef errors, and no more need to use a separate completion plugin!

farzadmf commented 2 months ago

@mattmc3 thank you for the update. As I mentioned a couple of comments above, I've been using the "manual" way mentioned in the docs, and it has been working fine.

I gave this new way a shot, and I think my shell startup became slower, so I went back to the "manual" way.

Does it make sense for the startup to become slower?

My work Mac is a f...ing Intel machine, and each new shell takes at least 3s (yes, 3 seconds if it's fast!), and sometimes goes to 6s!!!

I do a bunch of things on startup, and I'm OK with the delay, which on a "normal" Linux machine is around 200ms to 400ms, but the Mac is too terrible for me to tolerate another added delay

mattmc3 commented 2 months ago

@farzadmf - Here are some profiling tips that might help.

Add this snippet to the very top of your ~/.zshrc temporarily: zmodload zsh/zprof. Next, start a new Zsh shell and run zprof. What do you see? Ignore the percentages - just look at the timings. You'll always have a few things that stubbornly take longer than you'd like. For me it's always compinit and promptint.

Here's my top 10 for comparison:

Note: I'm on an M3 MacBook so don't expect to hit my actual timings, but just generally what's comparatively slower for you. Also, if you happen to see "antidote-load" at the top of the list, that's because of how you loaded antidote. It's what's sourcing all your plugins, so ignore its timing and look for the actual plugins to see what's really running slow.

num  calls                time                       self            name
-----------------------------------------------------------------------------------
 1)    1           9.80     9.80   25.41%      9.80     9.80   25.41%  compinit
 2)    3           7.53     2.51   19.51%      7.53     2.51   19.51%  promptinit
 3)    1           6.90     6.90   17.89%      6.18     6.18   16.02%  _zsh_highlight_load_highlighters
 4)    1           3.71     3.71    9.62%      3.53     3.53    9.15%  (anon) [/Users/matt/.cache/repos/romkatv/powerlevel10k/powerlevel10k.zsh-theme:50]
 5)    1           7.66     7.66   19.86%      2.06     2.06    5.35%  prompt_p10k_setup
 6)    1           1.74     1.74    4.52%      1.74     1.74    4.52%  colors
 7)    1           5.05     5.05   13.08%      1.34     1.34    3.47%  prompt_powerlevel10k_setup
 8)    2           1.26     0.63    3.27%      1.26     0.63    3.27%  cached-eval
 9)    1           1.24     1.24    3.21%      1.23     1.23    3.19%  _zsh_highlight__function_callable_p
10)   13           1.09     0.08    2.82%      1.09     0.08    2.82%  add-zsh-hook

I also pretty regularly run romkatv/zsh-bench and get pretty good results:

% zsh-bench
==> benchmarking login shell of user matt ...
creates_tty=0
has_compsys=1
has_syntax_highlighting=1
has_autosuggestions=1
has_git_prompt=1
first_prompt_lag_ms=16.270
first_command_lag_ms=136.003
command_lag_ms=48.736
input_lag_ms=10.972
exit_time_ms=70.642

You might also check to see what Zsh version you're running:

$ echo $ZSH_VERSION
5.9

And finally, have a look at romkatv/powerlevel10k and its instant-prompt feature. That instant prompt will smooth over a lot of config sins, especially on older hardware.

Best of luck!

farzadmf commented 2 months ago

@mattmc3 thank you so much for all the tips, and sorry for the delayed reply.

I'll definitely look into all those things.

that's because of how you loaded antidote

Does this mean that there's a better way for me to load antidote if this happens?

It's what's sourcing all your plugins, so ignore its timing

A bit confused here; if it's taking long to source all plugins, can it be ignored? 🤔 Isn't it contributing to the total time?

have a look at romkatv/powerlevel10k and its instant-prompt feature

I might have this (not sure TBH). I'm saying that because I see the prompt appear in my startup folder, which is a git repo. Seems like it takes some time to fully load the prompt since the branch information part is "grey" and then gets some "color", but during this transition, the prompt is unusable for me (so it appearing is a bit of a false impression that the prompt loaded).

As I said, this may be another messed up thing in my computer, delaying thing and may have nothing to do with the instant-prompt feature.

mattmc3 commented 2 months ago

Does this mean that there's a better way for me to load antidote if this happens?

No. The recommended way to load antidote is absolutely to use antidote load, however there is a different way to load it if you really want to avoid any calls to antidote whatsoever unless absolutely necessary. Depending on which way you choose, you'll see different output in zprof. My call out was merely that somethings you see in zprof are rollups of the underlying work, so antidote-load will look like it takes the longest, but really it's the summation of all your plugin timings, and if you load it a different way your config will still take just as long, you just won't see all that grouped together under one heading.

I might have this (not sure TBH).

You are only using instant prompt if .zsh_plugins.txt contains romkatv/powelevel10k and the first few lines in your .zshrc is this:

if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

Based on the behavior you describe, I don't think you are. I suspect you have $ZSH_THEME set to an Oh-My-Zsh theme. Switching to powerlevel10k might be the quickest possible way for you to see a big speed improvement without a lot of additional detective work. Its claim to fame is its the fastest Zsh prompt available.

Feel free to post your zprof results here though, and I can try to help more. Without seeing what you're seeing though, this is the best I can offer.