mattmc3/antidote

Using Antidote to install fzf

Closed this issue · 5 comments

I'm looking to migrate away from oh-my-zsh and Antidote seems like what I'm looking for. I'm struggling a bit getting fzf to install, and I think it's due to fzf requiring execution of an install script. While I could probably just manually install it, my goal is to make setting up my zsh environment on a new machine as one-step as possible, and update everything just by doing antidote update.

FZF's official git-style install instructions state to run this:

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

I'm trying to coax Antidote to manage those steps. In .zsh_plugins.txt, I have this line: junegunn/fzf

When I start up my zsh shell, Antidote spits out this error:

/home/myusername/.zsh_plugins.zsh:source:3: no such file or directory: /home/myusername/.cache/antidote/https-COLON--SLASH--SLASH-github.com-SLASH-junegunn-SLASH-fzf/https-COLON--SLASH--SLASH-github.com-SLASH-junegunn-SLASH-fzf.plugin.zsh

Antidote's docs are a bit sparse, but I believe this is because it's defaulting to kind:zsh and it's not looking for a script called install

I found this issue #78 , which basically seems to suggest my best bet is to create my own fzf.plugin.zsh file that will effectively detect whether it's a new install (or update) and conditionally run fzf's install command. Unfortunately, I can't seem to find any documentation on .plugin.zsh files besides "they exist." So I'm not sure how I would detect that Antidote was trying to update fzf, etc., to make sure I only call install when needed.

Is there a cleaner way? Thank you!

Similar issue with zoxide, which, like fzf, has a binary that needs to be installed.

Their installation steps (if you aren't using a package manager) state

# install binary
curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | bash
# add this to ~/.zshrc
eval "$(zoxide init zsh)"

Happily, Zoxide at least provides a zoxide.plugin.zsh, but that unfortunately doesn't handle the binary installation.

Is there a tidy way to make Antidote manage the entire lifecycle of plugins like these?

The solution currently has been, as you said, to create your own fzf.plugin.zsh file to do what you want.

BUT...

This is a really timely question since I just added support for the "pre:" and "post:" annotations in the new 1.8.x branch (not released yet, but probably soon in 1.8.2). The idea being that for utilities like this, you could simply have a function that runs prior to ('pre'), or after ('post') antidote loads a plugin. So, for zoxide, your config might look like:

#.zshrc
check_zoxide_exists() {
  # change brew to whatever your preferred OS package manager is
  (( $+commands[zoxide] )) || brew install zoxide
}

# do antidote things
source /path/to/antidote
antidote load

# rest of your .zshrc
...etc

And then in ~/.zsh_plugins.txt:

#.zsh_plugins.txt
ajeetdsouza/zoxide pre:check_zoxide_exists

fzf is a bit more difficult because its installer fights like hell to add config to your .zshrc instead of simply giving you a fzf.plugin.zsh file to load as you please, so anything you do with antidote is probably fighting against that. Meaning, you can clone fzf, but loading it like other plugins might mean you load it multiple times unless you remove the cruft the installer puts in your .zshrc.

Here's an antidote strategy for fzf

#.zshrc
run_fzf_postinstaller() {
  if [[ ! -f "${XDG_CONFIG_HOME:=$HOME/.config}"/fzf/fzf.zsh ]]; then
    $(antidote path junegunn/fzf)/install --xdg --all
  fi
}

# do antidote things
source /path/to/antidote
antidote load

# rest of your .zshrc
...etc
#.zsh_plugins.txt
junegunn/fzf kind:clone post:run_fzf_postinstaller
# Uncomment this if you remove the fzf init from your .zshrc
# $XDG_CONFIG_HOME/fzf

Hm, I tried checking out the dev branch and following your antidote strategy for fzf. The antidote install --help shows --post as an option, but while it is cloning fzf, it doesn't seem to be executing the post step.

I typed run_fzf_postinstaller in my shell, and it recognized the function. And it's declared above antidote load in my zshrc.

Any ideas? Is there a log somewhere, perhaps?

I've been able to install fzf without issues using the following.

In my .zshrc

# Define config folder
export ZDOTDIR=~/.config/zsh

# Download plugin manager if we don't have it
if ! [[ -e $ZDOTDIR/antidote ]]
then
    git clone --depth=1 https://github.com/mattmc3/antidote.git ${ZDOTDIR:-~}/antidote
fi

# Make plugin folder names pretty
zstyle ':antidote:bundle' use-friendly-names 'yes'

# Source and load plugins found in ${ZDOTDIR}/.zsh_plugins.txt
source ${ZDOTDIR:-~}/antidote/antidote.zsh

# Install fzf binary if not found
if ! [[ -e "$(antidote home)/junegunn/fzf/bin/fzf" ]]
then
  antidote load
  "$(antidote home)/junegunn/fzf/install" --bin
fi

# Load the plugins
antidote load

# Restore FZF Key bindings
zvm_after_init() {
  source "$(antidote home)/junegunn/fzf/shell/completion.zsh"
  source "$(antidote home)/junegunn/fzf/shell/key-bindings.zsh"
}

In my .zsh_plugins.txt

# Clone fzf repo
# Binary is installed in ~/.zshrc
junegunn/fzf kind:clone
# Add completion scripts and fzf binary to PATH
junegunn/fzf path:shell kind:zsh
junegunn/fzf path:bin kind:path

This installs the FZF binary as well as the shell completion scripts so hopefully it works for you!

Thanks @parispjones. I think as far as antidote is concerned, it appears things are working as designed. Given that there are solutions that work for fzf, I don't think there's reason to keep this issue open, but if something is broken with antidote or there's a simple feature that works for multiple tools like this (not just fzf specific), we can reopen.