mirror of
https://oauth2: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@github.com/m1ngsama/chopsticks.git
synced 2026-06-26 05:54:37 +08:00
Compare commits
5 commits
5d2eb8dde5
...
db68caee11
| Author | SHA1 | Date | |
|---|---|---|---|
| db68caee11 | |||
| d6df4fee3e | |||
| 002bc7bd3e | |||
| fc872918a1 | |||
| 8a36b41d66 |
7 changed files with 131 additions and 16 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -23,6 +23,13 @@
|
|||
|
||||
### 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)
|
||||
- `install.sh` Python tools now prefer `pipx` and `pip3 --user` over
|
||||
`pip3 install --break-system-packages`; the break-system path is gated
|
||||
behind `CHOPSTICKS_ALLOW_BREAK_SYSTEM=1` so PEP 668 distros are no
|
||||
longer silently polluted
|
||||
- `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
|
||||
|
|
@ -33,6 +40,12 @@
|
|||
|
||||
### Changed
|
||||
|
||||
- `set exrc`/`set secure` are now opt-in via `g:chopsticks_enable_exrc = 1`;
|
||||
Vim no longer sources project-local `.vimrc`/`.exrc` from the working
|
||||
directory by default
|
||||
- Normal-mode `,F` (reindent the entire file with `gg=G`) is now opt-in
|
||||
via `g:chopsticks_enable_reindent_file = 1`; visual-mode `,F` (reindent
|
||||
selection) stays as the default since it's bounded by the user's pick
|
||||
- `,?` cheat sheet is now profile-aware and hides LSP/ALE/preview/UndoTree keys
|
||||
when those features are disabled
|
||||
- Module reload/source paths now use `fnameescape()` so installs in paths with
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Rules
|
||||
|
||||
1. **No Node.js dependencies.** The LSP engine is pure VimScript. Some language servers need Node — that's fine. The config itself must not.
|
||||
1. **No Node.js in the Vim runtime.** Plugins must work with pure VimScript — no coc.nvim or other Node-backed completion engines. External CLIs (prettier, eslint, markdownlint, stylelint, tsc) installed via npm are fine; ALE shells out to them as optional system tools, not as part of the Vim runtime.
|
||||
2. **Startup matters.** Run `vim -u .vimrc -i NONE --startuptime /tmp/s.log -es -N -c qa!` before and after. If your change adds >1ms, it needs a good reason.
|
||||
3. **Works on TTY.** Test over SSH. If it breaks in a terminal without true color, fix it or gate it behind `g:is_tty`.
|
||||
4. **Native-first keymaps.** Enhance Vim's native behavior instead of replacing it. Do not override built-in motions, operators, text objects, or help-oriented keys for discoverability alone; prefer leader-prefixed or otherwise non-conflicting ergonomic mappings.
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ let g:chopsticks_enable_sudo_save_bang = 1 " optional: :w!! sudo save
|
|||
let g:chopsticks_enable_completion_keymaps = 1 " optional: Tab/Enter completion
|
||||
let g:chopsticks_enable_auto_pairs = 1 " optional: automatic pair insertion
|
||||
let g:chopsticks_enable_terminal_keymaps = 1 " optional: terminal Esc/Ctrl navigation
|
||||
let g:chopsticks_enable_exrc = 1 " optional: source project-local .vimrc/.exrc from CWD
|
||||
let g:chopsticks_enable_reindent_file = 1 " optional: ,F reindents the entire file
|
||||
```
|
||||
|
||||
`minimal` avoids LSP, ALE, completion plugins, extra language syntax plugins,
|
||||
|
|
@ -123,7 +125,7 @@ Esc exit insert mode ,? cheat sheet
|
|||
|
||||
### Edit
|
||||
|
||||
`,S`+2ch jump | `gc` comment | `cs"'` surround | `Alt+j/k` move line | `,u` undo tree | `,y` clipboard | `,*` replace word | `,F` re-indent | `,W` strip whitespace | `[<Space>` `]<Space>` blank lines
|
||||
`,S`+2ch jump | `gc` comment | `cs"'` surround | `Alt+j/k` move line | `,u` undo tree | `,y` clipboard | `,*` replace word | `,F` re-indent (v) | `,W` strip whitespace | `[<Space>` `]<Space>` blank lines
|
||||
|
||||
### Git
|
||||
|
||||
|
|
@ -230,7 +232,7 @@ More in the [wiki](https://github.com/m1ngsama/chopsticks/wiki).
|
|||
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md). The two rules that matter: no Node.js dependencies, and don't regress startup time.
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md). The two rules that matter: no Node.js in the Vim runtime, and don't regress startup time.
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
95
install.sh
95
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."
|
||||
|
|
@ -966,19 +1015,45 @@ elif [[ $_I_PYTHON -lt 0 ]] || ! _selected "$_I_PYTHON"; then
|
|||
skip "Python tool suite (skipped by user)"
|
||||
SKIPPED+=("black" "isort" "flake8" "pylint" "yamllint" "sqlfluff")
|
||||
else
|
||||
# Prefer pipx (isolated per-tool venvs, the recommended path on PEP 668
|
||||
# distros like Debian 12+/Ubuntu 23.04+). Bootstrap pipx via the system
|
||||
# package manager if missing. Only fall back to --break-system-packages
|
||||
# if the user explicitly opts in.
|
||||
if ! command -v pipx >/dev/null 2>&1; then
|
||||
if pkg_install pipx pipx python-pipx pipx 2>/dev/null; then
|
||||
ok "pipx (recommended Python CLI installer)"
|
||||
else
|
||||
warn "pipx not available — falling back to pip3 --user"
|
||||
fi
|
||||
fi
|
||||
|
||||
case ":$PATH:" in
|
||||
*":$HOME/.local/bin:"*) ;;
|
||||
*) warn "\$HOME/.local/bin is not on PATH — pipx/pip --user tools will not be found"
|
||||
info "Add to your shell rc: export PATH=\"\$HOME/.local/bin:\$PATH\"" ;;
|
||||
esac
|
||||
|
||||
pip_install() {
|
||||
local pkg="$1" check="${2:-$1}"
|
||||
if command -v "$check" >/dev/null 2>&1; then
|
||||
ok "$pkg (already installed)"; return
|
||||
fi
|
||||
if pip3 install --quiet "$pkg" 2>/dev/null; then
|
||||
ok "$pkg"; INSTALLED+=("$pkg")
|
||||
elif pip3 install --quiet --break-system-packages "$pkg" 2>/dev/null; then
|
||||
warn "$pkg installed with --break-system-packages (consider using a virtualenv)"
|
||||
ok "$pkg"; INSTALLED+=("$pkg")
|
||||
else
|
||||
fail "$pkg"; FAILED+=("$pkg")
|
||||
if command -v pipx >/dev/null 2>&1 && pipx install --quiet "$pkg" 2>/dev/null; then
|
||||
ok "$pkg (via pipx)"; INSTALLED+=("$pkg")
|
||||
return
|
||||
fi
|
||||
if pip3 install --quiet --user "$pkg" 2>/dev/null; then
|
||||
ok "$pkg (via pip --user)"; INSTALLED+=("$pkg")
|
||||
return
|
||||
fi
|
||||
if [[ "${CHOPSTICKS_ALLOW_BREAK_SYSTEM:-0}" == "1" ]] && \
|
||||
pip3 install --quiet --break-system-packages "$pkg" 2>/dev/null; then
|
||||
warn "$pkg installed with --break-system-packages (CHOPSTICKS_ALLOW_BREAK_SYSTEM=1)"
|
||||
INSTALLED+=("$pkg")
|
||||
return
|
||||
fi
|
||||
fail "$pkg — install pipx, or set CHOPSTICKS_ALLOW_BREAK_SYSTEM=1 to bypass PEP 668"
|
||||
FAILED+=("$pkg")
|
||||
}
|
||||
pip_install black
|
||||
pip_install isort
|
||||
|
|
|
|||
|
|
@ -183,8 +183,10 @@ endif
|
|||
|
||||
" ── Project-Local Config ────────────────────────────────────────────────────
|
||||
|
||||
if get(g:, 'chopsticks_enable_exrc', 0)
|
||||
set exrc
|
||||
set secure
|
||||
endif
|
||||
set sessionoptions=blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal
|
||||
|
||||
if has("patch-8.1.0360")
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ endfunction
|
|||
|
||||
" ── Utilities ──────────────────────────────────────────────────────────────
|
||||
|
||||
if get(g:, 'chopsticks_enable_reindent_file', 0)
|
||||
nnoremap <leader>F gg=G``
|
||||
endif
|
||||
vnoremap <leader>F =
|
||||
nnoremap <leader>wa :wa<CR>
|
||||
|
||||
|
|
|
|||
|
|
@ -236,6 +236,27 @@ check_vim() {
|
|||
-c 'if has("terminal") && (maparg("<Esc><Esc>", "t") !~# "<C-\\\\><C-N>" || maparg("<C-h>", "t") !~# "<C-W>h" || maparg("<C-j>", "t") !~# "<C-W>j" || maparg("<C-k>", "t") !~# "<C-W>k" || maparg("<C-l>", "t") !~# "<C-W>l") | cquit | endif' \
|
||||
-c 'qa!' 2>&1
|
||||
|
||||
XDG_CONFIG_HOME="$EMPTY_XDG" vim -u .vimrc -i NONE -es -N \
|
||||
-c 'if &exrc || &secure | cquit | endif' \
|
||||
-c 'qa!' 2>&1
|
||||
|
||||
XDG_CONFIG_HOME="$EMPTY_XDG" vim -u NONE -i NONE -es -N \
|
||||
-c 'let g:chopsticks_enable_exrc = 1' \
|
||||
-c 'source .vimrc' \
|
||||
-c 'if !&exrc || !&secure | cquit | endif' \
|
||||
-c 'qa!' 2>&1
|
||||
|
||||
XDG_CONFIG_HOME="$EMPTY_XDG" vim -u .vimrc -i NONE -es -N \
|
||||
-c 'if maparg(",F", "n") !=# "" | cquit | endif' \
|
||||
-c 'if maparg(",F", "v") !~# "=" | cquit | endif' \
|
||||
-c 'qa!' 2>&1
|
||||
|
||||
XDG_CONFIG_HOME="$EMPTY_XDG" vim -u NONE -i NONE -es -N \
|
||||
-c 'let g:chopsticks_enable_reindent_file = 1' \
|
||||
-c 'source .vimrc' \
|
||||
-c 'if maparg(",F", "n") !~# "gg=G" | cquit | endif' \
|
||||
-c 'qa!' 2>&1
|
||||
|
||||
XDG_CONFIG_HOME="$EMPTY_XDG" vim -u .vimrc -i NONE -es -N \
|
||||
-c 'silent! delcommand LspStatus' \
|
||||
-c 'silent! delcommand LspInstallServer' \
|
||||
|
|
|
|||
Loading…
Reference in a new issue