Last active
March 13, 2023 11:35
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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