mattmc3 / antidote

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

Conditionally include a plugin #162

Closed farzadmf closed 10 months ago

farzadmf commented 10 months ago

Hi, I like the idea of antidote having its own file for plugins, but I have a use case which I'm not sure how to achieve using the "static" file.

Let's say I want to check if a variable is set, and only if that's the case, include a plugin in the list.

My original use case is for powerlevel10k; I'm using different themes on my different computers, and the issue I get is that if I include powerlevel10k in the file, it's loaded automatically, overwriting things.

So, I want to load powerlevel10k based on a variable I set in my config

mattmc3 commented 10 months ago

There's an annotation called conditional that lets you achieve something like this. I use it for loading macOS only plugins like so:

# .zshrc
# define a function
is-macos() {
  [[ $OSTYPE == darwin* ]]
}

# now load antidote
source /path/to/antidote.zsh
antidote load

And then in your .zsh_plugins.txt

# .zsh_plugins.txt
sorin-ionescu/prezto path:modules/osx conditional:is-macos

So, let's apply this to your situation. Perhaps you are setting the ZSH_THEME variable to whatever prompt you want. You could do something like:

# .zshrc
# define a function
prompt-is-p10k() {
  [[ $ZSH_THEME == 'p10k' ]]
}
# now load antidote
source /path/to/antidote.zsh
antidote load
# .zsh_plugins.txt
romkatv/powerlevel10k conditional:prompt-is-p10k

However, might I suggest a better alternative. Why don't you use Zsh's built in prompt mechanism? Pull themes into your fpath with the kind:fpath annotation. Then, you don't need to set variables - just call prompt powerlevel10k in your .zshrc.

# .zshrc
# load antidote plugins
source /path/to/antidote.zsh
antidote load

# now set your prompt - you can wrap in an `if` statement too if you want
autoload -Uz promptint && promptinit
prompt powerlevel10k
# .zsh_plugins.txt
# kind:fpath will make any prompt you want available to Zsh's built-in prompt system
# as long as that prompt plugin defines a prompt_THEME_setup function
sindresorhus/pure kind:fpath
romkatv/powerlevel10k kind:fpath

Hope this helps. Ping me again if not.

farzadmf commented 10 months ago

Thank you @mattmc3 for the super quick and comprehensive reply.

Now that I have you here, maybe I can mention the root issue that caused me to start playing around with my config:

I really LOVE antidote, and I find it much faster than the other plugin managers I've tried (honestly, not sure why it doesn't have as much stars as some other popular ones).

Everything was working fine, but recently I noticed that my prompt is actually "tricking" me when using antidote.

I do a lot of stuff in the background when I open a new shell (some hooks running, some commands checking things etc.), but what I mean by "tricking me" is this:

antidote brings me to the prompt, but it's basically blocked when I start typing for, say, 200-300ms and then it reflects what I typed.

I tried experimenting with zplug, and, as I mentioned before, it is slower than antidote, but at least when I see my prompt (which of course takes longer to appear), I can immediately start typing and I see the characters I'm typing.

I think this started happening maybe in the last few weeks, or at least it was barely noticable before.

As I mentioned, I'm doing a bunch of things, so I'm OK with my prompt appearing with a delay, but the fact that it's "fake" is what is driving me crazy.

I'm hoping that you could tell me what I can try with this information to fix the issue (because having a reproducible config is honestly out of the question :slightly_frowning_face: because of the million things I'm doing in a million different files, a bunch of them being company-related things that can't be shared)

mattmc3 commented 10 months ago

I really LOVE antidote, and I find it much faster than the other plugin managers I've tried (honestly, not sure why it doesn't have as much stars as some other popular ones).

Thanks! I suspect most people have long had their preferred plugin manager - antidote is much later to the game and built off the wonderful work Carlos put into antibody.

antidote brings me to the prompt, but it's basically blocked when I start typing for, say, 200-300ms and then it reflects what I typed.

I suspect you are using PowerLevel10k's instaprompt? That's the feature that shows you a quick version of your prompt, but then loads the rest of your config in the background. Do you get the same behavior if you switch to a different prompt (like sindresorhus/pure)? PowerLevel10k is a great prompt - but I suspect this is unrelated to antidote and more to do with the plugins you're loading.

If you are willing to post your config or point me to it, that might help. If not, that's okay - you can also debug Zsh yourself by adding this like to the top of your .zshrc: zmodload zsh/zprof and then running zprof when your prompt is fully loaded. You should see profile metrics that will tell you what's slowing things down. Note that if you use antidote load it might look like antidote-load is the culprit, but that will only be because it is loading all your plugins. If you dig one level deeper, you can see which actual plugins are causing the slowdown.

farzadmf commented 10 months ago

Unfortunately, this is happening with starship, so it has nothing to do with p10k.

I tried to see if I can see something with zprof, but I'll try again.

Can you think of any reason why the same list of plugins in zplug would yield my prompt ready to type immediately but having the blocking behavior I mentioned in antidote?

mattmc3 commented 10 months ago

No, I cannot. That's really weird. I use starship myself and have had great luck with it and have never seen that behavior.

farzadmf commented 10 months ago

Can you think of any change made recently (in the past month maybe) that might affect this?

Right now, I'm playing with my plugins.txt for antidote, and as I disable the plugins I have there, that delay seems to be decreasing, so I guess that means that it has something to do with those?

Literally dumping my file here, just in case it might be of help:

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/azure          kind:defer
https://github.com/ohmyzsh/ohmyzsh path:plugins/docker         kind:defer
https://github.com/ohmyzsh/ohmyzsh path:plugins/docker-compose kind:defer
https://github.com/ohmyzsh/ohmyzsh path:plugins/fancy-ctrl-z   kind:defer
https://github.com/ohmyzsh/ohmyzsh path:plugins/git            kind:defer
# https://github.com/ohmyzsh/ohmyzsh path:plugins/terraform      kind:defer
https://github.com/ohmyzsh/ohmyzsh path:plugins/git-auto-fetch kind:defer

# For some reason, this just randomly puts the region in the prompt!!!
# https://github.com/ohmyzsh/ohmyzsh path:plugins/aws kind:defer

https://github.com/romkatv/powerlevel10k kind:fpath

https://github.com/ael-code/zsh-colored-man-pages
https://github.com/Aloxaf/fzf-tab
https://github.com/ChrisPenner/copy-pasta
https://github.com/djui/alias-tips
https://github.com/jeffreytse/zsh-vi-mode
https://github.com/marlonrichert/zsh-edit
https://github.com/mtxr/zsh-change-case
https://github.com/zsh-users/zsh-autosuggestions

https://github.com/hlissner/zsh-autopair                      kind:defer
https://github.com/zdharma-continuum/fast-syntax-highlighting kind:defer

# Disable; contributes to prompt delay!
# https://github.com/bilelmoussaoui/flatpak-zsh-completion      kind:defer

# vim: ft=zsh
farzadmf commented 10 months ago

As I continue playing, starship seems to be the culprit. As I said, I run a lot of things, so I expect things to be a bit slow, but it seems like antidote is not "waiting" for things and showing me the prompt, but starship needs more time, so the prompt is blocked (seems like zplug is actually waiting for that "more time")

Sorry, I know you're like "what a stupid thing to say", but I'm trying to be like a good patient mentioning all the symptoms, hoping that something is found

mattmc3 commented 10 months ago

Oh, I see where the issue is. You are using kind:defer on nearly everything. Roman has been pretty clear that while zsh-defer may work well for some plugins, it can also cause some very hard to track down problems. See https://github.com/romkatv/zsh-defer#caveats. Roman has gone so far as to say he doesn't recommend using it at all and recommends PowerLevel10k with instaprompt. But I have found that, when used sparingly, zsh-defer can be useful.

I would recommend pulling the kind:defer annotations off and adding back only if you have a plugin that's slow and might benefit from it, and only one at a time so as to verify the rest of your config works.

farzadmf commented 10 months ago

OMG!, THANK YOU @mattmc3, I still have a tiny delay for the prompt, but it's barely noticable (at least for my use case, it's fine) :rocket:


However, I have a new problem :stuck_out_tongue_closed_eyes: ; I tried "un-deferring" everything, and I saw these errors:

zsh-syntax-highlighting: unhandled ZLE widget 'reverse-yank-pop'

cp: cannot create regular file ‘/home/farzadmf/.zplug/repos/robbyrussell/oh-my-zsh/cache//completions/_docker’: No such file or directory

First error

This seems to be the reason for the first unhandled ... one:

+_zsh_highlight_bind_widgets:54> [[ reverse-yank-pop == zle-* ]]
+_zsh_highlight_bind_widgets:59> print -r -- 'zsh-syntax-highlighting: unhandled ZLE widget '\''reverse-yank-pop'\'

zsh-syntax-highlighting: unhandled ZLE widget 'reverse-yank-pop'

If I https://github.com/zdharma-continuum/fast-syntax-highlighting kind:defer, the first error (unhandled ...) seems to be gone, but I think the error shouldn't happen with defer, right?


Second error

Tried zsh -x, and I see this line seems to be causing the cannot create ... error:

/local/home/farzadmf/.cache/antidote/https-COLON--SLASH--SLASH-github.com-SLASH-ohmyzsh-SLASH-ohmyzsh/plugins/docker/docker.plugin.zsh:58> cp /local/home/farzadmf/.cache/antidote/https-COLON--SLASH--SLASH-github.com-SLASH-ohmyzsh-SLASH-ohmyzsh/plugins/docker/completions/_docker /home/farzadmf/.zplug/repos/robbyrussell/oh-my-zsh/cache//completions/_docker

cp: cannot create regular file ‘/home/farzadmf/.zplug/repos/robbyrussell/oh-my-zsh/cache//completions/_docker’: No such file or directory

Seems like antidote is trying to copy something to ~/.zplug directory?? :thinking: It's most probably me messing things up, but I've no idea what!

And docker completion fails with (when I press TAB):

(eval):1: _docker: function definition file not found
mattmc3 commented 10 months ago

For the first error, the path being referenced is .zplug, so there's something residual from when you used that plugin manager. I use zdharma-continuum/fast-syntax-highlighting kind:defer in my own config with great success, so if that's working for you go for it.

You might also want to start fresh - it looks like there's a lot of residual cruft. Check that your antidote home is storing the repos where you really want them. Removing your static plugins file and running rm -rf -- $(antidote home) to start fresh might also help you troubleshoot.

farzadmf commented 10 months ago

I do have the plugin (fast-syntax-highlighting) and it's kind:defer. In my effort to "un-defer" everything, I wanted to also remove defer from it, but I guess I can't

Regarding the docker completion issue, I looked around and saw that they're relying on ZSH_CACHE_DIR to be set (and also OMZ seems to set ZSH as well), so I ended up setting it (ZSH_CACHE_DIR I mean) to a directory I'm using (and add the completions sub-directory to fpath), and it seems to be working fine