mattmc3 / antidote

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

fpath order: should prepend, not append #157

Closed wookayin closed 9 months ago

wookayin commented 11 months ago

When kind:fpath is used, the bundle would currently be appended to the $fpath, but I think we should prepend to $fpath like $PATH is treated (by default). Or at least there should be some configuration option.

  if [[ "$o_kind[-1]" == fpath ]]; then
    # fpath
    script+="fpath+=( $bundle_path )"
  elif [[ "$o_kind[-1]" == path ]]; then
    # path
    script+="export PATH=\"$bundle_path:\$PATH\""
  ...

Why? For example,

# antidote plugins
zsh-users/zsh kind:fpath path:Completion/Unix/Command

results in $fpath being something like

 $HOME/.zsh/functions
 $HOME/.local/share/zsh/site-functions
 /usr/local/share/zsh/site-functions
 /opt/homebrew/share/zsh/site-functions
 /opt/homebrew/Cellar/zsh/5.9/share/zsh/functions                     # <- contains _git
+$HOME/.zsh/antidote-plugins/zsh-users/zsh/Completion/Unix/Command    # <- I want to use _git here

which is after the zsh builtin fpath. This make _completion scripts shipped with the plugin shadowed and not loadable.

The main purpose of adding a plugin as kind:fpath is to use their shell functions and completion that would override the built-ins, so I think the "prepend" behavior would make more sense than the "append" behavior.

wookayin commented 11 months ago

~A side note: Hmm, actually if that's the case antidote-plugins will take more precedence than "local" site-functions (e.g., $HOME/.local/share/zsh/site-functions).~ NVM, this is due to incorrect order of $fpath due to the use of /.zshenv.

Also many plugins are loaded in the order they were specified, e.g.

foo/A kind:fpath
foo/B kind:fpath
foo/C kind:fpath

then the resulting fpath should be in the same order..

Feel like it's tricky to have a correct $fpath order.

mattmc3 commented 11 months ago

Since antidote is based on antibody, the correct default behavior is compatibility with antibody's handling of fpath order. However, I am willing to entertain a discussion about how adding an alternative option would work.

See related issue: https://github.com/getantibody/antibody/issues/291

rteabeault commented 10 months ago

I ran into this. On the mac at least there is a default completion installed into /usr/share/zsh/5.9/functions/_gradle. When I try to install the gradle plugin from oh-my-zsh the completion does not work as this is coming later in the fpath. Not sure how to get around this currently.

wookayin commented 10 months ago

A workaround I took for my dotfiles is here,

fpath_user=(${(@)fpath:#/(opt|usr)/*zsh*})   # remove all /opt, /usr path
fpath_system=(${(@)fpath:|fpath_user})       # $fpath \setminus $fpath_user
fpath=($fpath_user $fpath_system)

But we can generalize this idea as follows:

fpath_system=($fpath)

source $ANTIDOTE_BUNDLE

fpath_user=(${(@)fpath:|fpath_system})     # $fpath \setminus $fpath_system
fpath=($fpath_user $fpath_system)
mattmc3 commented 9 months ago

With the upcoming release 1.9.4, you can add an fpath-rule annotation like so:

ohmyzsh/ohmyzsh path:plugins/gradle fpath-rule:prepend