Skip to content

Instantly share code, notes, and snippets.

@bokwoon95
Last active March 13, 2023 11:35
Show Gist options
  • Save bokwoon95/172ecc04039afdbe94256789467afbc7 to your computer and use it in GitHub Desktop.
Save bokwoon95/172ecc04039afdbe94256789467afbc7 to your computer and use it in GitHub Desktop.
bash script to automatically download and update vim plugins (lightweight alternative to a plugin manager using native vim 8 packages)
#!/bin/bash
# == USAGE ==
# Put Github URLs inside a file called `plugins.start.txt` inside your vim
# directory (either `$HOME/.vim/plugins.start.txt` or
# `$HOME/.config/nvim/plugins.start.txt`). Then, run this script which will
# clone or update the plugins accordingly.
#
# == EXAMPLE ==
# $ cat "$HOME/.config/nvim/plugins.start.txt"
# https://github.com/tpope/vim-commentary
# https://github.com/tpope/vim-eunuch
# https://github.com/andymass/vim-matchup
# https://github.com/romainl/vim-qlist
# https://github.com/tpope/vim-repeat
# https://github.com/mhinz/vim-signify
# https://github.com/tpope/vim-sleuth
# https://github.com/tpope/vim-surround
# https://github.com/moll/vim-bbye
# https://github.com/nvim-lua/plenary.nvim
# https://github.com/nvim-telescope/telescope.nvim
# https://github.com/lambdalisue/fern.vim
# https://github.com/neovim/nvim-lspconfig
# https://github.com/tpope/vim-unimpaired
#
# == NOTES ==
# 1) To update optional plugins, put the URLs in `plugins.opt.txt` instead.
# 2) Empty lines or lines starting with '#' are ignored (useful for comments).
# 3) You can change the pack/* name by changing the first part of the filename
# e.g. plugins in `foo.start.txt` will be downloaded to `pack/foo/start/`,
# plugins in `foo.opt.txt` will be downloaded to `pack/foo/opt/`.
# update_plugins takes in a directory path and updates a bunch of plugins in it
# according to vim 8 native package loading rules.
update_plugins() {
# update_plugin takes in a URL and git clones or git pulls it in the current
# directory.
update_plugin() {
URL="$(echo "$1" | xargs)" # trim space
case $URL in
'#'*) return ;; # ignore comments
'') return ;; # ignore empty lines
esac
dir="$(basename "$URL")"
if [ ! -d "$dir" ]; then
git clone --depth 1 "$1"
return $?
fi
if ! pushd "$dir"; then
return $? # failed to enter $dir
fi
if ! git pull --depth 1 --ff-only; then
# git pull --ff-only failed, fallback to forcibly overwriting local copy
git fetch --all --depth 1 && git reset --hard "origin/$(git branch | grep '*' | cut -d' ' -f2)"
fi
popd 2>/dev/null 1>&2
}
export -f update_plugin
ROOT_DIR="$1" # $ROOT_DIR is either $HOME/.vim or $HOME/.config/nvim
if [ ! -d "$ROOT_DIR" ]; then
return
fi
for filepath in $(find "$ROOT_DIR" -type f -name '*.start.txt' -o -name '*.opt.txt'); do
# e.g.
# filepath: $HOME/.vim/plugins.start.txt
# filename: plugins.start
# dirname : plugins
# dirtype : start
# dir : $HOME/.vim/pack/plugins/start
filename="$(basename "${filepath%.txt}")"
dirname="${filename%.*}"
if [ ! "$dirname" ]; then
continue
fi
dirtype="${filename##*.}"
dir="$ROOT_DIR/pack/$dirname/$dirtype"
mkdir -p "$dir"
pushd "$dir"
# update each plugin in parallel with xargs
cat "$filepath" | xargs -I{} -P10 sh -c 'update_plugin {}'
popd 2>/dev/null 1>&2
done
case $ROOT_DIR in
*nvim*) command -v nvim >/dev/null 1>&2 && nvim --headless -c 'helptags ALL' -c 'q!' >/dev/null 1>&2 ;;
*.vim*) command -v vim >/dev/null 1>&2 && vim -c 'helptags ALL' -c 'q!' >/dev/null 1>&2 ;;
esac
}
VIM_ROOT="$HOME/.vim"
NVIM_ROOT="${XDG_CONFIG_HOME:-$HOME/.config}/nvim"
SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$PWD}")" 2>/dev/null 1>&2 && pwd)"
has_prefix() { case $1 in "$2"*) true;; *) false;; esac }
if has_prefix "$PWD" "$VIM_ROOT"; then update_plugins "$VIM_ROOT" # are we in $VIM_ROOT?
elif has_prefix "$PWD" "$NVIM_ROOT"; then update_plugins "$NVIM_ROOT" # are we in $NVIM_ROOT?
elif has_prefix "$SCRIPT_DIR" "$VIM_ROOT"; then update_plugins "$VIM_ROOT" # is script in $VIM_ROOT?
elif has_prefix "$SCRIPT_DIR" "$NVIM_ROOT"; then update_plugins "$NVIM_ROOT" # is script is $NVIM_ROOT?
else
update_plugins "$VIM_ROOT"
update_plugins "$NVIM_ROOT"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment