From 9cfec7d0d80bfa6b12866d7a5d463829fe4f69f8 Mon Sep 17 00:00:00 2001 From: m1ngsama Date: Sat, 16 May 2026 22:38:51 +0800 Subject: [PATCH] Make PlugClean interactive in install.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously install.sh ran `_vim_run 'PlugClean!'` unconditionally before PlugInstall. PlugClean with bang removes any directory under ~/.vim/plugged not declared in the active profile's g:plugs, without confirmation — silently nuking plugins a user has manually cloned to try out, plus leftovers from older profile config (Goyo, Limelight, etc.). Replace with a `list_extra_plugins` helper that runs a Vim subprocess with all opt-in flags forced on and `$TMUX = '1'`, so the declared set covers every plugin any chopsticks profile/flag combination could register. Conditional plugins (vim-tmux-navigator, auto-pairs) are therefore never flagged as extras. When extras are detected: - interactive: list them, ask before running PlugClean! - --yes: leave in place, instruct the user to run :PlugClean manually - otherwise (no extras): skip PlugClean entirely (saves an 80ms Vim launch on the common case) Closes #64 --- CHANGELOG.md | 3 +++ install.sh | 55 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dafc435..7a885aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ ### Fixed +- `install.sh` no longer silently `PlugClean!`s user-added plugins from + `~/.vim/plugged`; it now lists undeclared plugin directories first and + asks before removing them (`--yes` skips the removal entirely) - `g:loaded_logipat` typo → `g:loaded_logiPat` — logiPat was loading fully (0.478ms wasted) - `get.sh` now refuses to update an existing `~/.vim` git repo unless its origin is chopsticks diff --git a/install.sh b/install.sh index e5362fb..9a749e9 100755 --- a/install.sh +++ b/install.sh @@ -656,10 +656,59 @@ VIMEOF fi } -if [[ -d "$HOME/.vim/plugged" ]] && [[ -n "$(find "$HOME/.vim/plugged" -mindepth 1 -maxdepth 1 2>/dev/null)" ]]; then - warn "PlugClean: removing plugins not listed in .vimrc from ~/.vim/plugged" +# Echoes one name per line for each directory under ~/.vim/plugged that no +# chopsticks profile/flag combination would declare. The detection script +# bypasses local config and forces every opt-in on, so a plugin that's only +# loaded inside tmux or behind a flag does NOT show up as "extra". Empty +# output means PlugClean would be a no-op for the user's tree. +list_extra_plugins() { + local declared_file="$_TMPDIR/declared-plugins.txt" + local declare_script="$_TMPDIR/declared-plugins.vim" + local plugged="$HOME/.vim/plugged" + [[ -d "$plugged" ]] || return 0 + + cat > "$declare_script" <<'VIMEOF' +let g:chopsticks_local_config = '/dev/null' +let $TMUX = '1' +let g:chopsticks_profile = 'full' +let g:chopsticks_enable_auto_pairs = 1 +let g:chopsticks_enable_terminal_keymaps = 1 +execute 'source ' . fnameescape($CHOPSTICKS_VIMRC) +if !exists('g:plugs') + cquit +endif +call writefile(sort(keys(g:plugs)), $CHOPSTICKS_DECLARED_PLUGINS) +qa! +VIMEOF + CHOPSTICKS_VIMRC="$SCRIPT_DIR/.vimrc" \ + CHOPSTICKS_DECLARED_PLUGINS="$declared_file" \ + "$VIM_BIN" -u NONE -i NONE -es -N -S "$declare_script" >/dev/null 2>&1 || return 1 + [[ -e "$declared_file" ]] || return 0 + + local plugin name + while IFS= read -r plugin; do + [[ -d "$plugin" ]] || continue + name="$(basename "$plugin")" + if ! grep -Fxq "$name" "$declared_file"; then + printf '%s\n' "$name" + fi + done < <(find "$plugged" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort) +} + +extras="$(list_extra_plugins || true)" +if [[ -n "$extras" ]]; then + warn "Plugins under ~/.vim/plugged that the active profile does not declare:" + while IFS= read -r ex; do + [[ -n "$ex" ]] && echo " - $ex" + done <<< "$extras" + if [[ $AUTO_YES -eq 1 ]]; then + info "Leaving them in place (--yes mode). Run :PlugClean inside Vim to remove." + elif ask "Remove these directories with PlugClean!?"; then + _vim_run 'PlugClean!' || true # plug.vim may exit non-zero after removal; harmless + else + info "Leaving them in place. Run :PlugClean inside Vim if you change your mind." + fi fi -_vim_run 'PlugClean!' || true # remove plugins no longer in vimrc; ignore exit code (none expected) _vim_run 'PlugInstall --sync' || true # fzf post-install hook may exit non-zero; harmless verify_plugins || die "Plugin installation failed — retry with a stable network connection."