#!/bin/bash # Only the plugins are updated; the kickstart.nvim config itself is the user's to edit. LAZY_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/nvim/lazy" PLUGIN_BACKUPS="${XDG_STATE_HOME:-$HOME/.local/state}/coredesktop/nvim-plugins" is_installed() { command -v nvim &>/dev/null && [ -d "$LAZY_DIR/lazy.nvim" ] } # lazy.nvim won't update a plugin whose tracked files differ from its checkout # (it checks with `git ls-files -d -m`). An interrupted update can leave a # plugin like that, along with leftovers git won't overwrite, such as new files # and half-cloned submodules (LuaSnip, 2026-10-20). Move such a plugin out of # the way, so `Lazy! sync` installs it afresh; any edits made to it are in the # copy. So is a plugin an earlier version of this step only stashed. set_aside_broken_plugins() { local dir name dest for dir in "$LAZY_DIR"/*/; do dir="${dir%/}" [ -d "$dir/.git" ] || continue if [ -z "$(git -C "$dir" ls-files -d -m 2> /dev/null)" ] \ && ! git -C "$dir" stash list 2> /dev/null | grep -q "Stashed by CoreDesktop's update"; then continue fi name="$(basename "$dir")" dest="$PLUGIN_BACKUPS/$name-$(date +%Y-%m-%d-%H%M%S)" mkdir -p "$PLUGIN_BACKUPS" && mv "$dir" "$dest" \ && echo " $name's files didn't match its version, so it will be installed again. The old copy is in $dest" done } run_update() { echo "Updating Neovim plugins..." set_aside_broken_plugins nvim --headless "+Lazy! sync" +qa }