mirror of
https://oauth2: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@github.com/m1ngsama/chopsticks.git
synced 2026-05-10 19:10:59 +08:00
Compare commits
5 commits
cddb5fa725
...
ddb4c691b9
| Author | SHA1 | Date | |
|---|---|---|---|
| ddb4c691b9 | |||
| d253583d0b | |||
| 7ff5326932 | |||
| a9e16d22d3 | |||
| db9b96f577 |
18 changed files with 875 additions and 154 deletions
132
.github/workflows/test.yml
vendored
132
.github/workflows/test.yml
vendored
|
|
@ -36,16 +36,33 @@ jobs:
|
||||||
cp modules/*.vim ~/.vim/modules/
|
cp modules/*.vim ~/.vim/modules/
|
||||||
|
|
||||||
- name: Install plugins
|
- name: Install plugins
|
||||||
run: vim -es -u .vimrc -c 'PlugInstall --sync' -c 'qa!' 2>&1 || true
|
run: |
|
||||||
|
set +e
|
||||||
|
vim -i NONE -es -u .vimrc -N -c 'PlugInstall --sync' -c 'qa!' 2>&1
|
||||||
|
plug_status=$?
|
||||||
|
set -e
|
||||||
|
if [ "$plug_status" -ne 0 ]; then
|
||||||
|
echo "PlugInstall exited with $plug_status; validating plugin directories"
|
||||||
|
fi
|
||||||
|
for plugin in fzf fzf.vim vim-fugitive vim-gitgutter ale vim-lsp vim-lsp-settings asyncomplete.vim asyncomplete-lsp.vim vim-markdown; do
|
||||||
|
test -d "$HOME/.vim/plugged/$plugin" || {
|
||||||
|
echo "FAIL: missing plugin $plugin"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
done
|
||||||
|
|
||||||
- name: Test startup
|
- name: Test startup
|
||||||
run: |
|
run: |
|
||||||
vim -u .vimrc -es -N -c 'qa!' 2>&1
|
vim -u .vimrc -i NONE -es -N -c 'qa!' 2>&1
|
||||||
echo "Vim exited cleanly"
|
echo "Vim exited cleanly"
|
||||||
|
|
||||||
- name: Verify modules load
|
- name: Verify modules load
|
||||||
run: |
|
run: |
|
||||||
vim -u .vimrc -N -c 'redir! > /tmp/test.txt | echo len(g:plugs) | redir END | qa!' 2>/dev/null
|
vim -u .vimrc -i NONE -es -N \
|
||||||
|
-c 'redir! > /tmp/test.txt' \
|
||||||
|
-c 'silent echo len(g:plugs)' \
|
||||||
|
-c 'redir END' \
|
||||||
|
-c 'qa!' 2>/dev/null
|
||||||
PLUGS=$(cat /tmp/test.txt | tr -d '[:space:]')
|
PLUGS=$(cat /tmp/test.txt | tr -d '[:space:]')
|
||||||
echo "Plugins registered: $PLUGS"
|
echo "Plugins registered: $PLUGS"
|
||||||
if [ "$PLUGS" -lt 20 ]; then
|
if [ "$PLUGS" -lt 20 ]; then
|
||||||
|
|
@ -53,10 +70,93 @@ jobs:
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
- name: Verify path-safe module loading
|
||||||
|
run: |
|
||||||
|
mkdir -p "/tmp/chopsticks path/modules"
|
||||||
|
cp .vimrc "/tmp/chopsticks path/.vimrc"
|
||||||
|
cp modules/*.vim "/tmp/chopsticks path/modules/"
|
||||||
|
vim -u "/tmp/chopsticks path/.vimrc" -i NONE -es -N -c 'qa!' 2>&1
|
||||||
|
|
||||||
|
- name: Verify minimal profile
|
||||||
|
run: |
|
||||||
|
vim -u NONE -i NONE -es -N \
|
||||||
|
-c 'let g:chopsticks_profile = "minimal"' \
|
||||||
|
-c 'source .vimrc' \
|
||||||
|
-c 'if has_key(g:plugs, "ale") || has_key(g:plugs, "vim-lsp") || has_key(g:plugs, "vim-lsp-settings") || has_key(g:plugs, "asyncomplete.vim") | cquit | endif' \
|
||||||
|
-c 'qa!' 2>&1
|
||||||
|
|
||||||
|
- name: Verify local config hook
|
||||||
|
run: |
|
||||||
|
mkdir -p /tmp/chopsticks-ci
|
||||||
|
printf "%s\n" "let g:chopsticks_profile = 'minimal'" > /tmp/chopsticks-ci/local.vim
|
||||||
|
vim -u NONE -i NONE -es -N \
|
||||||
|
-c 'let g:chopsticks_local_config = "/tmp/chopsticks-ci/local.vim"' \
|
||||||
|
-c 'source .vimrc' \
|
||||||
|
-c 'if g:chopsticks_profile !=# "minimal" || has_key(g:plugs, "ale") || has_key(g:plugs, "vim-lsp") | cquit | endif' \
|
||||||
|
-c 'qa!' 2>&1
|
||||||
|
|
||||||
|
- name: Verify XDG local config hook
|
||||||
|
run: |
|
||||||
|
mkdir -p /tmp/chopsticks-xdg
|
||||||
|
printf "%s\n" "let g:chopsticks_profile = 'minimal'" > /tmp/chopsticks-xdg/chopsticks.vim
|
||||||
|
XDG_CONFIG_HOME=/tmp/chopsticks-xdg vim -u NONE -i NONE -es -N \
|
||||||
|
-c 'source .vimrc' \
|
||||||
|
-c 'if g:chopsticks_profile !=# "minimal" || has_key(g:plugs, "ale") || has_key(g:plugs, "vim-lsp") | cquit | endif' \
|
||||||
|
-c 'qa!' 2>&1
|
||||||
|
|
||||||
|
- name: Verify profile-aware cheat sheet
|
||||||
|
run: |
|
||||||
|
vim -u NONE -i NONE -es -N \
|
||||||
|
-c 'let g:chopsticks_profile = "minimal"' \
|
||||||
|
-c 'source .vimrc' \
|
||||||
|
-c 'normal ,?' \
|
||||||
|
-c 'redir! > /tmp/chopsticks-cheat.txt' \
|
||||||
|
-c 'silent %print' \
|
||||||
|
-c 'redir END' \
|
||||||
|
-c 'qa!' 2>&1
|
||||||
|
if grep -Eq 'definition|LspInstallServer|ALE errors|undo tree|markdown preview' /tmp/chopsticks-cheat.txt; then
|
||||||
|
cat /tmp/chopsticks-cheat.txt
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
grep -q ',cr run file' /tmp/chopsticks-cheat.txt
|
||||||
|
|
||||||
|
- name: Verify Markdown quiet defaults
|
||||||
|
run: |
|
||||||
|
vim -u .vimrc -i NONE -es -N README.md \
|
||||||
|
-c 'set filetype=markdown' \
|
||||||
|
-c 'if &l:spell || &l:conceallevel != 0 || &l:signcolumn !=# "no" || exists("g:lsp_settings_filetype_markdown") | cquit | endif' \
|
||||||
|
-c 'qa!' 2>&1
|
||||||
|
|
||||||
|
- name: Verify ergonomic defaults
|
||||||
|
run: |
|
||||||
|
vim -u .vimrc -i NONE -es -N \
|
||||||
|
-c 'if maparg("s", "n") !=# "" | cquit | endif' \
|
||||||
|
-c 'if maparg(",w", "n") =~# "!" | cquit | endif' \
|
||||||
|
-c 'if !&swapfile || !&writebackup || &directory !~# "\.vim/.swap" | cquit | endif' \
|
||||||
|
-c 'qa!' 2>&1
|
||||||
|
|
||||||
|
- name: Verify local ALE override
|
||||||
|
run: |
|
||||||
|
vim -u NONE -i NONE -es -N \
|
||||||
|
-c 'let g:ale_fix_on_save = 0' \
|
||||||
|
-c 'source .vimrc' \
|
||||||
|
-c 'if g:ale_fix_on_save != 0 | cquit | endif' \
|
||||||
|
-c 'qa!' 2>&1
|
||||||
|
|
||||||
|
- name: Verify large file protection
|
||||||
|
run: |
|
||||||
|
truncate -s 11000000 /tmp/chopsticks-large.py
|
||||||
|
vim -u .vimrc -i NONE -es -N /tmp/chopsticks-large.py \
|
||||||
|
-c 'set filetype=python' \
|
||||||
|
-c 'if &l:syntax !=# "" || &l:undolevels != -1 || &l:swapfile || get(b:, "ale_enabled", 1) != 0 | cquit | endif' \
|
||||||
|
-c 'qa!' 2>&1
|
||||||
|
|
||||||
- name: Measure startup time
|
- name: Measure startup time
|
||||||
run: |
|
run: |
|
||||||
vim -u .vimrc --startuptime /tmp/startup.log -c 'qa!' 2>/dev/null
|
vim -u .vimrc -i NONE --startuptime /tmp/startup.log -es -N -c 'qa!' 2>/dev/null
|
||||||
tail -1 /tmp/startup.log
|
tail -1 /tmp/startup.log
|
||||||
|
STARTUP_MS=$(tail -1 /tmp/startup.log | awk '{print $1}')
|
||||||
|
awk -v ms="$STARTUP_MS" 'BEGIN { if (ms > 150) exit 1 }'
|
||||||
|
|
||||||
shellcheck:
|
shellcheck:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
@ -64,3 +164,27 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Shellcheck install.sh
|
- name: Shellcheck install.sh
|
||||||
run: shellcheck install.sh get.sh
|
run: shellcheck install.sh get.sh
|
||||||
|
- name: Verify installer profile-only modes
|
||||||
|
run: |
|
||||||
|
XDG_CONFIG_HOME=/tmp/chopsticks-dry ./install.sh --dry-run --profile=full \
|
||||||
|
| tee /tmp/chopsticks-dry-run.txt
|
||||||
|
grep -q 'Profile: full' /tmp/chopsticks-dry-run.txt
|
||||||
|
test ! -e /tmp/chopsticks-dry/chopsticks.vim
|
||||||
|
|
||||||
|
XDG_CONFIG_HOME=/tmp/chopsticks-config ./install.sh --configure-only --profile=minimal
|
||||||
|
grep -q "let g:chopsticks_profile = 'minimal'" /tmp/chopsticks-config/chopsticks.vim
|
||||||
|
|
||||||
|
XDG_CONFIG_HOME=/tmp/chopsticks-config ./install.sh --configure-only --profile=full
|
||||||
|
grep -q "let g:chopsticks_profile = 'full'" /tmp/chopsticks-config/chopsticks.vim
|
||||||
|
|
||||||
|
XDG_CONFIG_HOME=/tmp/chopsticks-default ./install.sh --configure-only --yes
|
||||||
|
grep -q "let g:chopsticks_profile = 'engineer'" /tmp/chopsticks-default/chopsticks.vim
|
||||||
|
|
||||||
|
docs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install markdownlint
|
||||||
|
run: npm install -g markdownlint-cli
|
||||||
|
- name: Lint Markdown
|
||||||
|
run: markdownlint README.md QUICKSTART.md CONTRIBUTING.md CHANGELOG.md
|
||||||
|
|
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -2,3 +2,7 @@
|
||||||
*.swo
|
*.swo
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Session.vim
|
Session.vim
|
||||||
|
autoload/
|
||||||
|
plugged/
|
||||||
|
.swap/
|
||||||
|
.undo/
|
||||||
|
|
|
||||||
13
.markdownlint.json
Normal file
13
.markdownlint.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"MD013": false,
|
||||||
|
"MD022": false,
|
||||||
|
"MD024": {
|
||||||
|
"siblings_only": true
|
||||||
|
},
|
||||||
|
"MD032": false,
|
||||||
|
"MD033": false,
|
||||||
|
"MD040": false,
|
||||||
|
"MD041": false,
|
||||||
|
"MD060": false
|
||||||
|
}
|
||||||
14
.vimrc
14
.vimrc
|
|
@ -1,10 +1,18 @@
|
||||||
|
let g:chopsticks_dir = fnamemodify(resolve(expand('<sfile>')), ':h')
|
||||||
|
let s:xdg_config_home = !empty($XDG_CONFIG_HOME) && $XDG_CONFIG_HOME =~# '^/'
|
||||||
|
\ ? $XDG_CONFIG_HOME
|
||||||
|
\ : '~/.config'
|
||||||
|
let s:local_config = expand(get(g:, 'chopsticks_local_config',
|
||||||
|
\ s:xdg_config_home . '/chopsticks.vim'))
|
||||||
|
if filereadable(s:local_config)
|
||||||
|
execute 'source ' . fnameescape(s:local_config)
|
||||||
|
endif
|
||||||
|
|
||||||
if exists('g:chopsticks_loaded') | finish | endif
|
if exists('g:chopsticks_loaded') | finish | endif
|
||||||
let g:chopsticks_loaded = 1
|
let g:chopsticks_loaded = 1
|
||||||
|
|
||||||
let g:chopsticks_dir = fnamemodify(resolve(expand('<sfile>')), ':h')
|
|
||||||
|
|
||||||
function! s:load(mod) abort
|
function! s:load(mod) abort
|
||||||
execute 'source ' . g:chopsticks_dir . '/modules/' . a:mod . '.vim'
|
execute 'source ' . fnameescape(g:chopsticks_dir . '/modules/' . a:mod . '.vim')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call s:load('env')
|
call s:load('env')
|
||||||
|
|
|
||||||
52
CHANGELOG.md
52
CHANGELOG.md
|
|
@ -3,15 +3,56 @@
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- `~/.config/chopsticks.vim` local pre-load config for profile and user choices
|
||||||
|
- `g:chopsticks_enable_markdown_preview` to control Previm independently
|
||||||
|
- `g:chopsticks_profile` with `minimal`, `engineer`, and `full` profiles
|
||||||
|
- `.markdownlint.json` aligned with the project's README/changelog style
|
||||||
- `:ChopsticksStatus` diagnostic command — checks system tools, LSP servers, linters, formatters
|
- `:ChopsticksStatus` diagnostic command — checks system tools, LSP servers, linters, formatters
|
||||||
- `,af` toggle format-on-save (ALE `fix_on_save`)
|
- `,af` toggle format-on-save (ALE `fix_on_save`)
|
||||||
- `,gL` git log graph (last 20 commits)
|
- `,gL` git log graph (last 20 commits)
|
||||||
- `,gC` FZF git commits search, `,gB` buffer commits
|
- `,gC` FZF git commits search, `,gB` buffer commits
|
||||||
|
- Interactive installer profile selection for `minimal`, `engineer`, and `full`
|
||||||
|
- `install.sh --profile=minimal|engineer|full` for scripted profile selection
|
||||||
|
- `install.sh --dry-run` to show the resolved profile/config path without writes
|
||||||
|
- `install.sh --configure-only` to update local profile config without reinstalling
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- `g:loaded_logipat` typo → `g:loaded_logiPat` — logiPat was loading fully (0.478ms wasted)
|
- `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
|
||||||
|
- Large file protection now stays active after filetype and syntax autocommands
|
||||||
|
- `g:ale_fix_on_save = 0` in local config is now respected
|
||||||
|
- Local config now respects absolute `XDG_CONFIG_HOME` instead of hardcoding
|
||||||
|
`~/.config`
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- `,?` 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
|
||||||
|
spaces are handled correctly
|
||||||
|
- CI now verifies path-safe module loading, the local config hook, and
|
||||||
|
minimal-profile cheat sheet output
|
||||||
|
- Markdown now opens in quiet writing mode by default: no real-time markdownlint,
|
||||||
|
no Marksman LSP, no spell noise, no conceal, no sign column, and no realtime preview
|
||||||
|
- Native `s` is no longer shadowed by EasyMotion; use `,S` for the two-character jump
|
||||||
|
- `,w` now uses a normal `:write` instead of forced `:write!`
|
||||||
|
- Swap files are enabled again and stored under `~/.vim/.swap` for crash recovery
|
||||||
|
- Installer defaults are slimmer: only core search tools stay selected by default;
|
||||||
|
language and lint suites are opt-in
|
||||||
|
- `:ChopsticksStatus` now respects disabled LSP/lint profiles instead of reporting
|
||||||
|
intentionally disabled tools as missing
|
||||||
|
- `,sv` now clears the load guard before sourcing `$MYVIMRC`
|
||||||
|
- CI now verifies key plugin directories, Markdown quiet defaults, markdownlint,
|
||||||
|
and an explicit startup-time threshold
|
||||||
|
- Installer plugin validation now checks every plugin required by the active profile
|
||||||
|
- The optional tool menu now hides LSP/lint suites in `minimal` and selects
|
||||||
|
Marksman by default in `full`
|
||||||
|
- tmux integration is written as a managed block so future installer runs can
|
||||||
|
update it without appending duplicate bindings
|
||||||
|
- Installer cleanup now restores the cursor after interrupted checkbox menus
|
||||||
- Skip 2 more built-in plugins: openPlugin, manpager (10 → 12 total)
|
- Skip 2 more built-in plugins: openPlugin, manpager (10 → 12 total)
|
||||||
- Remove deprecated `set ttyfast` (no-op since Vim 8)
|
- Remove deprecated `set ttyfast` (no-op since Vim 8)
|
||||||
- Add `grepprg=rg --vimgrep` — `:grep` now uses ripgrep + quickfix
|
- Add `grepprg=rg --vimgrep` — `:grep` now uses ripgrep + quickfix
|
||||||
|
|
@ -23,17 +64,20 @@
|
||||||
## 2.1.0 — 2025-04-22
|
## 2.1.0 — 2025-04-22
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Cheat sheet (`,?`) — vertical sidebar, one key per line, section headers
|
- Cheat sheet (`,?`) — vertical sidebar, one key per line, section headers
|
||||||
- Previm markdown preview restored (lazy-loaded, `,mp`)
|
- Previm markdown preview restored (lazy-loaded, `,mp`)
|
||||||
- `:LspInstallServer` added to cheat sheet
|
- `:LspInstallServer` added to cheat sheet
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Plugin count: 25 (restored previm, dropped 5 bloat plugins)
|
- Plugin count: 25 (restored previm, dropped 5 bloat plugins)
|
||||||
- QUICKSTART updated — removed stale references, improved first-launch guidance
|
- QUICKSTART updated — removed stale references, improved first-launch guidance
|
||||||
|
|
||||||
## 2.0.0 — 2025-04-21
|
## 2.0.0 — 2025-04-21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Sidebar toggle (`,e` / `,E`) — left-side netrw with `topleft vertical`, winfixwidth, proper toggle
|
- Sidebar toggle (`,e` / `,E`) — left-side netrw with `topleft vertical`, winfixwidth, proper toggle
|
||||||
- Enriched statusline — SLMode, SLGit, SLAle, SLFlags
|
- Enriched statusline — SLMode, SLGit, SLAle, SLFlags
|
||||||
- Toggle feedback — F2/F3/F4/F6/`,ss` echo current state
|
- Toggle feedback — F2/F3/F4/F6/`,ss` echo current state
|
||||||
|
|
@ -41,6 +85,7 @@
|
||||||
- Interactive tutorial (`:ChopsticksLearn` — removed in later release)
|
- Interactive tutorial (`:ChopsticksLearn` — removed in later release)
|
||||||
|
|
||||||
### Removed (Unix minimalism refactor)
|
### Removed (Unix minimalism refactor)
|
||||||
|
|
||||||
- **565 lines** of dead code and bloat
|
- **565 lines** of dead code and bloat
|
||||||
- 5 plugins: Goyo, Limelight, vim-obsession, indentLine, vim-unimpaired
|
- 5 plugins: Goyo, Limelight, vim-obsession, indentLine, vim-unimpaired
|
||||||
- `modules/writing.vim` — folded into `languages.vim`
|
- `modules/writing.vim` — folded into `languages.vim`
|
||||||
|
|
@ -50,6 +95,7 @@
|
||||||
- TTY welcome message, `,so`, `,ms`, `,sh` mappings
|
- TTY welcome message, `,so`, `,ms`, `,sh` mappings
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- CI plugin threshold lowered to 20
|
- CI plugin threshold lowered to 20
|
||||||
- README: hero layout with demo GIF, badges, architecture diagram
|
- README: hero layout with demo GIF, badges, architecture diagram
|
||||||
- vim-markdown settings absorbed from writing.vim into languages.vim
|
- vim-markdown settings absorbed from writing.vim into languages.vim
|
||||||
|
|
@ -57,6 +103,7 @@
|
||||||
## 1.3.0 — 2025-04-20
|
## 1.3.0 — 2025-04-20
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Startup: 39ms → 19ms (51% faster)
|
- Startup: 39ms → 19ms (51% faster)
|
||||||
- Dropped vim-unimpaired for performance
|
- Dropped vim-unimpaired for performance
|
||||||
- Runtime tuning across modules
|
- Runtime tuning across modules
|
||||||
|
|
@ -64,16 +111,19 @@
|
||||||
## 1.2.0 — 2025-04-19
|
## 1.2.0 — 2025-04-19
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Hero README with demo GIF, CI badges
|
- Hero README with demo GIF, CI badges
|
||||||
- GitHub Actions CI (startup test on macOS + Ubuntu, shellcheck)
|
- GitHub Actions CI (startup test on macOS + Ubuntu, shellcheck)
|
||||||
- Issue/PR templates
|
- Issue/PR templates
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Documentation rewrite — clean, short, for engineers
|
- Documentation rewrite — clean, short, for engineers
|
||||||
|
|
||||||
## 1.1.0 — 2025-04-18
|
## 1.1.0 — 2025-04-18
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- 12-module architecture (env → plugins → core → ui → editing → navigation → lsp → lint → git → writing → languages → tools)
|
- 12-module architecture (env → plugins → core → ui → editing → navigation → lsp → lint → git → writing → languages → tools)
|
||||||
- Zen mode (Goyo + Limelight)
|
- Zen mode (Goyo + Limelight)
|
||||||
- Run file (`,cr`) with auto filetype detection
|
- Run file (`,cr`) with auto filetype detection
|
||||||
|
|
@ -82,12 +132,14 @@
|
||||||
- Robust installer (`get.sh`) with preflight checks
|
- Robust installer (`get.sh`) with preflight checks
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- `.vimrc` split into 12 self-contained modules
|
- `.vimrc` split into 12 self-contained modules
|
||||||
- Comprehensive bug audit (14 fixes)
|
- Comprehensive bug audit (14 fixes)
|
||||||
|
|
||||||
## 1.0.0 — 2025-04-16
|
## 1.0.0 — 2025-04-16
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Initial Vim configuration — migrated from Neovim
|
- Initial Vim configuration — migrated from Neovim
|
||||||
- vim-plug plugin manager
|
- vim-plug plugin manager
|
||||||
- vim-lsp + asyncomplete (pure VimScript LSP)
|
- vim-lsp + asyncomplete (pure VimScript LSP)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
## Rules
|
## 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 dependencies.** The LSP engine is pure VimScript. Some language servers need Node — that's fine. The config itself must not.
|
||||||
2. **Startup matters.** Run `vim --startuptime /tmp/s.log -c qa!` before and after. If your change adds >1ms, it needs a good reason.
|
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`.
|
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. **One module, one concern.** Don't put git config in lsp.vim.
|
4. **One module, one concern.** Don't put git config in lsp.vim.
|
||||||
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
## Reporting bugs
|
## Reporting bugs
|
||||||
|
|
||||||
Open an issue. Include:
|
Open an issue. Include:
|
||||||
|
|
||||||
- OS and Vim version
|
- OS and Vim version
|
||||||
- Whether you're on SSH/TTY
|
- Whether you're on SSH/TTY
|
||||||
- Steps to reproduce
|
- Steps to reproduce
|
||||||
|
|
@ -25,6 +26,6 @@ Open an issue. Include:
|
||||||
## Code style
|
## Code style
|
||||||
|
|
||||||
- Named augroups with `autocmd!`
|
- Named augroups with `autocmd!`
|
||||||
- No comments explaining *what* — only *why*
|
- No comments explaining _what_ — only _why_
|
||||||
- `exists('g:plugs["..."]')` guards for plugin-dependent config
|
- `exists('g:plugs["..."]')` guards for plugin-dependent config
|
||||||
- Test with `vim -u .vimrc --startuptime /tmp/s.log -c qa!`
|
- Test with `vim -u .vimrc -i NONE --startuptime /tmp/s.log -es -N -c qa!`
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,27 @@ Five minutes from zero to a working Vim setup.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --profile=minimal
|
||||||
```
|
```
|
||||||
|
|
||||||
Open vim. First launch auto-installs plugins — **wait 30-60s, don't close vim**. Restart when done.
|
Open vim. First launch auto-installs plugins — **wait 30-60s, don't close vim**. Restart when done.
|
||||||
|
|
||||||
|
Default profile is `engineer`. Interactive installs ask for a profile first;
|
||||||
|
`--profile=minimal`, `--profile=engineer`, or `--profile=full` selects it
|
||||||
|
without prompting. You can later put `let g:chopsticks_profile = 'minimal'` in
|
||||||
|
`${XDG_CONFIG_HOME:-~/.config}/chopsticks.vim` for a smaller core-only setup,
|
||||||
|
or use `full` for the heavier Markdown/LSP feedback.
|
||||||
|
|
||||||
|
To switch later without reinstalling anything:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/.vim && ./install.sh --configure-only --profile=full
|
||||||
|
```
|
||||||
|
|
||||||
## Modes
|
## Modes
|
||||||
|
|
||||||
| Mode | Enter | Leave |
|
| Mode | Enter | Leave |
|
||||||
|------|-------|-------|
|
| ------ | --------------- | ------------- |
|
||||||
| Normal | startup default | — |
|
| Normal | startup default | — |
|
||||||
| Insert | `i` / `a` / `o` | `Esc` or `jk` |
|
| Insert | `i` / `a` / `o` | `Esc` or `jk` |
|
||||||
| Visual | `v` / `V` | `Esc` |
|
| Visual | `v` / `V` | `Esc` |
|
||||||
|
|
@ -67,7 +80,7 @@ Tab / S-Tab cycle completions
|
||||||
## Edit
|
## Edit
|
||||||
|
|
||||||
```
|
```
|
||||||
s + 2 chars EasyMotion jump
|
,S + 2 chars EasyMotion jump
|
||||||
gc toggle comment
|
gc toggle comment
|
||||||
cs"' change surrounding " to '
|
cs"' change surrounding " to '
|
||||||
Alt+j / Alt+k move line
|
Alt+j / Alt+k move line
|
||||||
|
|
@ -91,10 +104,16 @@ Ctrl+h/j/k/l splits + tmux panes
|
||||||
,mt table of contents
|
,mt table of contents
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Markdown is quiet by default: no real-time lint, no spell noise, no concealed
|
||||||
|
syntax. Enable the heavier Markdown tools only when you want them.
|
||||||
|
|
||||||
## Health check
|
## Health check
|
||||||
|
|
||||||
```
|
```
|
||||||
:ChopsticksStatus see what's installed and what's missing
|
:ChopsticksStatus see what's installed and what's missing
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The `,?` cheat sheet follows your active profile, so `minimal` users only see
|
||||||
|
keys for features that are actually loaded.
|
||||||
|
|
||||||
See [README](README.md) for the full reference. See the [wiki](https://github.com/m1ngsama/chopsticks/wiki) for deep dives.
|
See [README](README.md) for the full reference. See the [wiki](https://github.com/m1ngsama/chopsticks/wiki) for deep dives.
|
||||||
|
|
|
||||||
66
README.md
66
README.md
|
|
@ -35,13 +35,13 @@ chopsticks gives you a production-ready Vim config in one command. Pure VimScrip
|
||||||
## What's in the box
|
## What's in the box
|
||||||
|
|
||||||
| Feature | Description |
|
| Feature | Description |
|
||||||
|---------|-------------|
|
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| **LSP** | completion, go-to-def, hover, rename, code actions — pure VimScript ([vim-lsp](https://github.com/prabirshrestha/vim-lsp)) |
|
| **LSP** | completion, go-to-def, hover, rename, code actions — pure VimScript ([vim-lsp](https://github.com/prabirshrestha/vim-lsp)) |
|
||||||
| **Lint + format** | [ALE](https://github.com/dense-analysis/ale) runs black, prettier, goimports, rustfmt on save |
|
| **Lint + format** | [ALE](https://github.com/dense-analysis/ale) runs black, prettier, goimports, rustfmt on save |
|
||||||
| **Fuzzy find** | files, buffers, grep, tags, marks, commands — [FZF](https://github.com/junegunn/fzf.vim) |
|
| **Fuzzy find** | files, buffers, grep, tags, marks, commands — [FZF](https://github.com/junegunn/fzf.vim) |
|
||||||
| **Git** | status, diff, blame, push, pull, conflict markers — [fugitive](https://github.com/tpope/vim-fugitive) + [gitgutter](https://github.com/airblade/vim-gitgutter) |
|
| **Git** | status, diff, blame, push, pull, conflict markers — [fugitive](https://github.com/tpope/vim-fugitive) + [gitgutter](https://github.com/airblade/vim-gitgutter) |
|
||||||
| **Run file** | `,cr` — auto-detects Python, Go, Rust, JS, C, Shell, and more |
|
| **Run file** | `,cr` — auto-detects Python, Go, Rust, JS, C, Shell, and more |
|
||||||
| **Markdown** | live preview in browser (`,mp`), table of contents (`,mt`) |
|
| **Markdown** | quiet writing defaults, browser preview (`,mp`), table of contents (`,mt`) |
|
||||||
| **Diagnostics** | `:ChopsticksStatus` — see what's installed, what's missing, how to fix it |
|
| **Diagnostics** | `:ChopsticksStatus` — see what's installed, what's missing, how to fix it |
|
||||||
| **TTY-aware** | degrades gracefully on SSH, console, slow links — never breaks |
|
| **TTY-aware** | degrades gracefully on SSH, console, slow links — never breaks |
|
||||||
|
|
||||||
|
|
@ -49,18 +49,44 @@ chopsticks gives you a production-ready Vim config in one command. Pure VimScrip
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --profile=minimal
|
||||||
```
|
```
|
||||||
|
|
||||||
Or manually:
|
Or manually:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/m1ngsama/chopsticks.git ~/.vim
|
git clone https://github.com/m1ngsama/chopsticks.git ~/.vim
|
||||||
cd ~/.vim && ./install.sh
|
cd ~/.vim && ./install.sh --profile=engineer
|
||||||
```
|
```
|
||||||
|
|
||||||
Supports macOS (brew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf).
|
Supports macOS (brew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf).
|
||||||
|
|
||||||
First launch installs plugins automatically (30-60s). Restart vim when done.
|
First launch installs plugins automatically (30-60s). Restart vim when done.
|
||||||
|
Use `./install.sh --dry-run --profile=full` to inspect the resolved profile and
|
||||||
|
config path without changing files. Use `./install.sh --configure-only
|
||||||
|
--profile=minimal` to switch profiles without reinstalling plugins or tools.
|
||||||
|
|
||||||
|
## Profiles
|
||||||
|
|
||||||
|
Default profile: `engineer`. Interactive installs ask for this profile before
|
||||||
|
plugins are installed; `--profile=minimal`, `--profile=engineer`, or
|
||||||
|
`--profile=full` selects it without prompting. `--yes` keeps the existing local
|
||||||
|
profile or uses `engineer`.
|
||||||
|
|
||||||
|
```vim
|
||||||
|
" Put this in ${XDG_CONFIG_HOME:-~/.config}/chopsticks.vim.
|
||||||
|
let g:chopsticks_profile = 'minimal' " core navigation/editing/git/markdown
|
||||||
|
let g:chopsticks_profile = 'engineer' " default: LSP, ALE, syntax extras
|
||||||
|
let g:chopsticks_profile = 'full' " engineer + heavier Markdown feedback
|
||||||
|
```
|
||||||
|
|
||||||
|
`minimal` avoids LSP, ALE, completion plugins, extra language syntax plugins,
|
||||||
|
Startify, UndoTree, and browser Markdown preview. `full` keeps those and opts
|
||||||
|
into Markdown lint, format, spell, conceal, Marksman, and LSP virtual text.
|
||||||
|
|
||||||
|
Project updates leave `~/.config/chopsticks.vim` alone, so put local choices
|
||||||
|
there instead of editing the managed `.vimrc`. The `,?` cheat sheet follows the
|
||||||
|
active profile and only shows keys for enabled features.
|
||||||
|
|
||||||
## Keys
|
## Keys
|
||||||
|
|
||||||
|
|
@ -88,7 +114,7 @@ jk exit insert mode ,? cheat sheet
|
||||||
|
|
||||||
### Edit
|
### 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 | `,W` strip whitespace | `[<Space>` `]<Space>` blank lines
|
||||||
|
|
||||||
### Git
|
### Git
|
||||||
|
|
||||||
|
|
@ -120,10 +146,36 @@ jk exit insert mode ,? cheat sheet
|
||||||
:ChopsticksStatus " see all tools + LSP + linters at a glance
|
:ChopsticksStatus " see all tools + LSP + linters at a glance
|
||||||
```
|
```
|
||||||
|
|
||||||
pylsp, gopls, rust-analyzer, clangd, marksman, sqls — no Node.js. JS/TS servers need Node.
|
pylsp, gopls, rust-analyzer, clangd, sqls — no Node.js. JS/TS servers need Node.
|
||||||
|
Markdown LSP (`marksman`) is opt-in so prose buffers stay quiet by default.
|
||||||
|
|
||||||
ALE and vim-lsp coexist cleanly (`ale_disable_lsp=1`). ALE handles linting + formatting. vim-lsp handles everything else.
|
ALE and vim-lsp coexist cleanly (`ale_disable_lsp=1`). ALE handles linting + formatting. vim-lsp handles everything else.
|
||||||
|
|
||||||
|
## Markdown
|
||||||
|
|
||||||
|
Markdown opens in writing mode: wrapped text, no spell noise, no concealed
|
||||||
|
syntax, no sign column, no real-time markdownlint, and no Marksman diagnostics.
|
||||||
|
The explicit commands still work:
|
||||||
|
|
||||||
|
```vim
|
||||||
|
,mp " preview in browser
|
||||||
|
,mt " table of contents
|
||||||
|
```
|
||||||
|
|
||||||
|
Opt into heavier Markdown tooling from your own vimrc before loading
|
||||||
|
chopsticks:
|
||||||
|
|
||||||
|
```vim
|
||||||
|
let g:chopsticks_markdown_lint = 1
|
||||||
|
let g:chopsticks_markdown_format_on_save = 1
|
||||||
|
let g:chopsticks_markdown_lsp = 1
|
||||||
|
let g:chopsticks_markdown_spell = 1
|
||||||
|
let g:chopsticks_markdown_conceal = 1
|
||||||
|
let g:previm_enable_realtime = 1
|
||||||
|
```
|
||||||
|
|
||||||
|
For Markdown LSP, install or select `marksman` first.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -148,7 +200,7 @@ Each module is self-contained. Comment out one line in `.vimrc` to disable it. A
|
||||||
## Performance
|
## Performance
|
||||||
|
|
||||||
| Metric | Value |
|
| Metric | Value |
|
||||||
|--------|-------|
|
| ------------------------ | ------------------------------------------- |
|
||||||
| Lazy-loaded | 7 plugins (on command or filetype) |
|
| Lazy-loaded | 7 plugins (on command or filetype) |
|
||||||
| Built-in plugins skipped | 12 (gzip, tar, zip, vimball, logiPat, etc.) |
|
| Built-in plugins skipped | 12 (gzip, tar, zip, vimball, logiPat, etc.) |
|
||||||
| Large file threshold | 10MB (auto-disables syntax + undo) |
|
| Large file threshold | 10MB (auto-disables syntax + undo) |
|
||||||
|
|
@ -157,7 +209,7 @@ Each module is self-contained. Comment out one line in `.vimrc` to disable it. A
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
| Problem | Fix |
|
| Problem | Fix |
|
||||||
|---------|-----|
|
| ------------------- | --------------------------------------------- |
|
||||||
| Plugins not loading | `:PlugInstall` then `:PlugUpdate` |
|
| Plugins not loading | `:PlugInstall` then `:PlugUpdate` |
|
||||||
| LSP not starting | `:LspInstallServer` for current filetype |
|
| LSP not starting | `:LspInstallServer` for current filetype |
|
||||||
| Colors wrong | `export COLORTERM=truecolor` in shell rc |
|
| Colors wrong | `export COLORTERM=truecolor` in shell rc |
|
||||||
|
|
|
||||||
29
get.sh
29
get.sh
|
|
@ -20,6 +20,24 @@ warn() { echo -e "${YELLOW}[!]${NC} $1"; }
|
||||||
die() { echo -e "${RED}[FATAL]${NC} $1" >&2; exit 1; }
|
die() { echo -e "${RED}[FATAL]${NC} $1" >&2; exit 1; }
|
||||||
step() { echo -e "\n${BOLD}==> $1${NC}"; }
|
step() { echo -e "\n${BOLD}==> $1${NC}"; }
|
||||||
|
|
||||||
|
repo_origin() {
|
||||||
|
git -C "$DEST" config --get remote.origin.url 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
is_chopsticks_repo() {
|
||||||
|
local origin="$1"
|
||||||
|
origin="${origin%/}"
|
||||||
|
origin="${origin%.git}"
|
||||||
|
case "$origin" in
|
||||||
|
https://github.com/m1ngsama/chopsticks|\
|
||||||
|
git@github.com:m1ngsama/chopsticks|\
|
||||||
|
ssh://git@github.com/m1ngsama/chopsticks)
|
||||||
|
return 0 ;;
|
||||||
|
*)
|
||||||
|
return 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
echo -e "${BOLD}chopsticks — One-command installer${NC}"
|
echo -e "${BOLD}chopsticks — One-command installer${NC}"
|
||||||
echo "----------------------------------"
|
echo "----------------------------------"
|
||||||
echo " Repo: $REPO"
|
echo " Repo: $REPO"
|
||||||
|
|
@ -43,6 +61,17 @@ ok "git $(git --version | awk '{print $3}')"
|
||||||
step "Setting up $DEST"
|
step "Setting up $DEST"
|
||||||
|
|
||||||
if [[ -d "$DEST/.git" ]]; then
|
if [[ -d "$DEST/.git" ]]; then
|
||||||
|
ORIGIN="$(repo_origin)"
|
||||||
|
if ! is_chopsticks_repo "$ORIGIN"; then
|
||||||
|
die "$DEST is a git repo, but it does not look like chopsticks.
|
||||||
|
origin: ${ORIGIN:-none}
|
||||||
|
Back it up first: mv ~/.vim ~/.vim.bak
|
||||||
|
Then re-run: curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash"
|
||||||
|
fi
|
||||||
|
[[ -f "$DEST/install.sh" && -f "$DEST/.vimrc" ]] || \
|
||||||
|
die "$DEST looks incomplete. Expected install.sh and .vimrc.
|
||||||
|
Back it up first: mv ~/.vim ~/.vim.bak
|
||||||
|
Then re-run: curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash"
|
||||||
warn "$DEST already exists — pulling latest changes"
|
warn "$DEST already exists — pulling latest changes"
|
||||||
git -C "$DEST" pull --ff-only origin main 2>/dev/null || \
|
git -C "$DEST" pull --ff-only origin main 2>/dev/null || \
|
||||||
warn "Could not pull latest — using existing version (run: git -C ~/.vim pull)"
|
warn "Could not pull latest — using existing version (run: git -C ~/.vim pull)"
|
||||||
|
|
|
||||||
305
install.sh
305
install.sh
|
|
@ -1,28 +1,53 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# install.sh - chopsticks vim configuration installer
|
# install.sh - chopsticks vim configuration installer
|
||||||
# Usage: cd /path/to/chopsticks && ./install.sh [--yes] [--help]
|
# Usage: cd /path/to/chopsticks && ./install.sh [--yes] [--profile=engineer] [--help]
|
||||||
#
|
#
|
||||||
# --yes non-interactive: install all optional components automatically
|
# --yes non-interactive: use default profile/component selections
|
||||||
|
# --profile=PROFILE choose minimal, engineer, or full without prompting
|
||||||
|
# --configure-only update local chopsticks profile config and exit
|
||||||
|
# --dry-run show resolved profile/config path without writing files
|
||||||
# --help show this help and exit
|
# --help show this help and exit
|
||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
AUTO_YES=0
|
AUTO_YES=0
|
||||||
|
REQUESTED_PROFILE=""
|
||||||
|
CONFIGURE_ONLY=0
|
||||||
|
DRY_RUN=0
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
case "$arg" in
|
case "$arg" in
|
||||||
--yes) AUTO_YES=1 ;;
|
--yes) AUTO_YES=1 ;;
|
||||||
|
--profile=*) REQUESTED_PROFILE="${arg#*=}" ;;
|
||||||
|
--profile)
|
||||||
|
echo "Use --profile=minimal, --profile=engineer, or --profile=full" >&2
|
||||||
|
exit 1 ;;
|
||||||
|
--configure-only) CONFIGURE_ONLY=1 ;;
|
||||||
|
--dry-run) DRY_RUN=1 ;;
|
||||||
--help|-h)
|
--help|-h)
|
||||||
echo "Usage: ./install.sh [OPTIONS]"
|
echo "Usage: ./install.sh [OPTIONS]"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " --yes Non-interactive mode: select all defaults automatically"
|
echo " --yes Non-interactive mode: use default profile/component selections"
|
||||||
|
echo " --profile=PROFILE"
|
||||||
|
echo " Select minimal, engineer, or full without prompting"
|
||||||
|
echo " --configure-only"
|
||||||
|
echo " Update local profile config and exit; no plugins or tools installed"
|
||||||
|
echo " --dry-run"
|
||||||
|
echo " Show resolved profile/config path without writing files"
|
||||||
echo " --help Show this help and exit"
|
echo " --help Show this help and exit"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Supported platforms: macOS (brew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf)"
|
echo "Supported platforms: macOS (brew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf)"
|
||||||
exit 0 ;;
|
exit 0 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
case "$REQUESTED_PROFILE" in
|
||||||
|
""|minimal|engineer|full) ;;
|
||||||
|
*)
|
||||||
|
echo "Invalid profile: $REQUESTED_PROFILE" >&2
|
||||||
|
echo "Use: minimal, engineer, or full" >&2
|
||||||
|
exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
# ── Colours (respect NO_COLOR and non-TTY) ───────────────────────────────────
|
# ── Colours (respect NO_COLOR and non-TTY) ───────────────────────────────────
|
||||||
if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then
|
if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then
|
||||||
|
|
@ -51,6 +76,13 @@ info() { echo " $1"; }
|
||||||
INSTALLED=()
|
INSTALLED=()
|
||||||
SKIPPED=()
|
SKIPPED=()
|
||||||
FAILED=()
|
FAILED=()
|
||||||
|
if [[ -n "${XDG_CONFIG_HOME:-}" && "$XDG_CONFIG_HOME" == /* ]]; then
|
||||||
|
CONFIG_HOME="$XDG_CONFIG_HOME"
|
||||||
|
else
|
||||||
|
CONFIG_HOME="$HOME/.config"
|
||||||
|
fi
|
||||||
|
LOCAL_CONFIG="$CONFIG_HOME/chopsticks.vim"
|
||||||
|
CONFIG_PROFILE="${REQUESTED_PROFILE:-engineer}"
|
||||||
|
|
||||||
# Ask yes/no; reads from /dev/tty so it works under: curl | bash
|
# Ask yes/no; reads from /dev/tty so it works under: curl | bash
|
||||||
ask() {
|
ask() {
|
||||||
|
|
@ -66,16 +98,160 @@ ask() {
|
||||||
[[ "$reply" =~ ^[Yy]$ ]]
|
[[ "$reply" =~ ^[Yy]$ ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── Error trap ────────────────────────────────────────────────────────────────
|
profile_from_config() {
|
||||||
|
[[ -f "$LOCAL_CONFIG" ]] || return 0
|
||||||
|
sed -nE "s/^[[:space:]]*let[[:space:]]+g:chopsticks_profile[[:space:]]*=[[:space:]]*['\"](minimal|engineer|full)['\"].*/\1/p" \
|
||||||
|
"$LOCAL_CONFIG" | tail -n1
|
||||||
|
}
|
||||||
|
|
||||||
|
choose_profile() {
|
||||||
|
local default="${1:-engineer}" reply
|
||||||
|
while true; do
|
||||||
|
echo "Choose Vim profile:"
|
||||||
|
echo " 1) minimal core navigation/editing/git/markdown; no LSP/ALE/completion extras"
|
||||||
|
echo " 2) engineer default; LSP, ALE, completion, syntax extras"
|
||||||
|
echo " 3) full engineer plus heavier Markdown lint/spell/conceal/LSP feedback"
|
||||||
|
if [[ -t 0 ]]; then
|
||||||
|
read -r -p "Profile [$default]: " reply
|
||||||
|
elif { true </dev/tty; } 2>/dev/null; then
|
||||||
|
read -r -p "Profile [$default]: " reply </dev/tty
|
||||||
|
else
|
||||||
|
CONFIG_PROFILE="$default"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
reply="${reply:-$default}"
|
||||||
|
case "$reply" in
|
||||||
|
1|minimal) CONFIG_PROFILE="minimal"; return ;;
|
||||||
|
2|engineer) CONFIG_PROFILE="engineer"; return ;;
|
||||||
|
3|full) CONFIG_PROFILE="full"; return ;;
|
||||||
|
*) warn "Choose 1, 2, 3, minimal, engineer, or full." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
write_profile_config() {
|
||||||
|
local profile="$1" config_dir tmp
|
||||||
|
config_dir="$(dirname "$LOCAL_CONFIG")"
|
||||||
|
mkdir -p "$config_dir"
|
||||||
|
|
||||||
|
if [[ -f "$LOCAL_CONFIG" ]] && \
|
||||||
|
grep -Eq '^[[:space:]]*let[[:space:]]+g:chopsticks_profile[[:space:]]*=' "$LOCAL_CONFIG"; then
|
||||||
|
tmp="$_TMPDIR/chopsticks-local-config"
|
||||||
|
awk -v profile="$profile" '
|
||||||
|
/^[[:space:]]*let[[:space:]]+g:chopsticks_profile[[:space:]]*=/ && !done {
|
||||||
|
printf "let g:chopsticks_profile = \047%s\047\n", profile
|
||||||
|
done = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
' "$LOCAL_CONFIG" > "$tmp"
|
||||||
|
mv "$tmp" "$LOCAL_CONFIG"
|
||||||
|
else
|
||||||
|
[[ -s "$LOCAL_CONFIG" ]] && printf '\n' >> "$LOCAL_CONFIG"
|
||||||
|
{
|
||||||
|
echo '" chopsticks local preferences'
|
||||||
|
echo "let g:chopsticks_profile = '$profile'"
|
||||||
|
} >> "$LOCAL_CONFIG"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_profile() {
|
||||||
|
local existing
|
||||||
|
existing="$(profile_from_config)"
|
||||||
|
|
||||||
|
step "Configuring Vim profile"
|
||||||
|
if [[ $DRY_RUN -eq 1 ]]; then
|
||||||
|
if [[ -n "$REQUESTED_PROFILE" ]]; then
|
||||||
|
CONFIG_PROFILE="$REQUESTED_PROFILE"
|
||||||
|
elif [[ -n "$existing" ]]; then
|
||||||
|
CONFIG_PROFILE="$existing"
|
||||||
|
else
|
||||||
|
CONFIG_PROFILE="engineer"
|
||||||
|
fi
|
||||||
|
info "Dry run: no files will be changed"
|
||||||
|
info "Profile: $CONFIG_PROFILE"
|
||||||
|
info "Local config: $LOCAL_CONFIG"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$REQUESTED_PROFILE" ]]; then
|
||||||
|
CONFIG_PROFILE="$REQUESTED_PROFILE"
|
||||||
|
write_profile_config "$CONFIG_PROFILE"
|
||||||
|
ok "Profile saved: $CONFIG_PROFILE ($LOCAL_CONFIG)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$existing" ]]; then
|
||||||
|
CONFIG_PROFILE="$existing"
|
||||||
|
ok "Profile: $CONFIG_PROFILE ($LOCAL_CONFIG)"
|
||||||
|
if [[ $AUTO_YES -eq 1 ]] || ! { true </dev/tty; } 2>/dev/null; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if ask "Change profile now?"; then
|
||||||
|
choose_profile "$existing"
|
||||||
|
if [[ "$CONFIG_PROFILE" != "$existing" ]]; then
|
||||||
|
write_profile_config "$CONFIG_PROFILE"
|
||||||
|
ok "Profile saved: $CONFIG_PROFILE ($LOCAL_CONFIG)"
|
||||||
|
else
|
||||||
|
skip "profile unchanged"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ $AUTO_YES -eq 1 ]] || ! { true </dev/tty; } 2>/dev/null; then
|
||||||
|
CONFIG_PROFILE="engineer"
|
||||||
|
if [[ $CONFIGURE_ONLY -eq 1 ]]; then
|
||||||
|
write_profile_config "$CONFIG_PROFILE"
|
||||||
|
ok "Profile saved: $CONFIG_PROFILE ($LOCAL_CONFIG)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
info "Profile: engineer (default; create $LOCAL_CONFIG to change later)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
choose_profile engineer
|
||||||
|
if [[ "$CONFIG_PROFILE" == "engineer" && $CONFIGURE_ONLY -eq 0 ]]; then
|
||||||
|
info "Profile: engineer (default; no local override written)"
|
||||||
|
else
|
||||||
|
write_profile_config "$CONFIG_PROFILE"
|
||||||
|
ok "Profile saved: $CONFIG_PROFILE ($LOCAL_CONFIG)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Error trap / cleanup ──────────────────────────────────────────────────────
|
||||||
on_error() {
|
on_error() {
|
||||||
echo -e "\n${RED}[FATAL]${NC} Command '${BASH_COMMAND}' failed at line ${BASH_LINENO[0]}." >&2
|
echo -e "\n${RED}[FATAL]${NC} Command '${BASH_COMMAND}' failed at line ${BASH_LINENO[0]}." >&2
|
||||||
echo " To get a full debug log:" >&2
|
echo " To get a full debug log:" >&2
|
||||||
echo " ./install.sh 2>&1 | tee /tmp/chopsticks-install.log" >&2
|
echo " ./install.sh 2>&1 | tee /tmp/chopsticks-install.log" >&2
|
||||||
echo " Report issues: https://github.com/m1ngsama/chopsticks/issues" >&2
|
echo " Report issues: https://github.com/m1ngsama/chopsticks/issues" >&2
|
||||||
}
|
}
|
||||||
|
cleanup() {
|
||||||
|
if [[ ${_MENU_CURSOR_HIDDEN:-0} -eq 1 ]]; then
|
||||||
|
tput cnorm 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
[[ -n "${_TMPDIR:-}" ]] && rm -rf "$_TMPDIR" 2>/dev/null
|
||||||
|
}
|
||||||
|
on_interrupt() {
|
||||||
|
echo "" >&2
|
||||||
|
die "Interrupted."
|
||||||
|
}
|
||||||
trap on_error ERR
|
trap on_error ERR
|
||||||
_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/chopsticks-XXXXXX")
|
_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/chopsticks-XXXXXX")
|
||||||
trap 'rm -rf "$_TMPDIR" 2>/dev/null' EXIT
|
trap cleanup EXIT
|
||||||
|
trap on_interrupt INT TERM
|
||||||
|
|
||||||
|
if [[ $DRY_RUN -eq 1 || $CONFIGURE_ONLY -eq 1 ]]; then
|
||||||
|
echo -e "${BOLD}chopsticks — Vim Configuration Installer${NC}"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
configure_profile
|
||||||
|
if [[ $DRY_RUN -eq 1 ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}Configuration complete.${NC}"
|
||||||
|
echo " Profile: $CONFIG_PROFILE"
|
||||||
|
echo " Local config: $LOCAL_CONFIG"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
# ── Safe download helper ──────────────────────────────────────────────────────
|
# ── Safe download helper ──────────────────────────────────────────────────────
|
||||||
safe_download() {
|
safe_download() {
|
||||||
|
|
@ -183,7 +359,9 @@ _menu_checkbox() {
|
||||||
local _lines=$(( 3 + 2 * _MENU_N ))
|
local _lines=$(( 3 + 2 * _MENU_N ))
|
||||||
local _key _esc _i
|
local _key _esc _i
|
||||||
|
|
||||||
tput civis 2>/dev/null # hide cursor
|
if tput civis 2>/dev/null; then
|
||||||
|
_MENU_CURSOR_HIDDEN=1
|
||||||
|
fi
|
||||||
local _first=1
|
local _first=1
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
|
|
@ -211,7 +389,10 @@ _menu_checkbox() {
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
tput cnorm 2>/dev/null # restore cursor
|
if [[ ${_MENU_CURSOR_HIDDEN:-0} -eq 1 ]]; then
|
||||||
|
tput cnorm 2>/dev/null || true
|
||||||
|
_MENU_CURSOR_HIDDEN=0
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
MENU_SEL=("${_MENU_SELS[@]}")
|
MENU_SEL=("${_MENU_SELS[@]}")
|
||||||
}
|
}
|
||||||
|
|
@ -381,6 +562,8 @@ fi
|
||||||
|
|
||||||
mkdir -p "$HOME/.vim"
|
mkdir -p "$HOME/.vim"
|
||||||
|
|
||||||
|
configure_profile
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# 3. vim-plug + Plugins
|
# 3. vim-plug + Plugins
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
@ -423,12 +606,51 @@ _vim_run() {
|
||||||
vim --not-a-term "$@" 2>/dev/null
|
vim --not-a-term "$@" 2>/dev/null
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verify_plugins() {
|
||||||
|
local required_file="$_TMPDIR/required-plugins.txt"
|
||||||
|
local verify_script="$_TMPDIR/required-plugins.vim"
|
||||||
|
local missing=() dir
|
||||||
|
|
||||||
|
cat > "$verify_script" <<'VIMEOF'
|
||||||
|
if !exists('g:plugs')
|
||||||
|
cquit
|
||||||
|
endif
|
||||||
|
let s:dirs = []
|
||||||
|
for s:plug in values(g:plugs)
|
||||||
|
let s:dir = get(s:plug, 'dir', '')
|
||||||
|
if !empty(s:dir)
|
||||||
|
call add(s:dirs, fnamemodify(s:dir, ':p'))
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
call writefile(s:dirs, $CHOPSTICKS_REQUIRED_PLUGINS)
|
||||||
|
qa!
|
||||||
|
VIMEOF
|
||||||
|
|
||||||
|
CHOPSTICKS_REQUIRED_PLUGINS="$required_file" \
|
||||||
|
vim -u "$SCRIPT_DIR/.vimrc" -i NONE -es -N -S "$verify_script" >/dev/null 2>&1 || return 1
|
||||||
|
|
||||||
|
[[ -s "$required_file" ]] || return 1
|
||||||
|
while IFS= read -r dir; do
|
||||||
|
[[ -z "$dir" ]] && continue
|
||||||
|
[[ -d "$dir" ]] || missing+=("$dir")
|
||||||
|
done < "$required_file"
|
||||||
|
|
||||||
|
if [[ ${#missing[@]} -gt 0 ]]; then
|
||||||
|
fail "Plugin installation incomplete — missing:"
|
||||||
|
for dir in "${missing[@]}"; do echo " ! $dir"; done
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
if [[ -d "$HOME/.vim/plugged" ]] && [[ -n "$(find "$HOME/.vim/plugged" -mindepth 1 -maxdepth 1 2>/dev/null)" ]]; then
|
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"
|
warn "PlugClean: removing plugins not listed in .vimrc from ~/.vim/plugged"
|
||||||
fi
|
fi
|
||||||
_vim_run +'PlugClean!' +qall || true # remove plugins no longer in vimrc; ignore exit code (none expected)
|
_vim_run +'PlugClean!' +qall || true # remove plugins no longer in vimrc; ignore exit code (none expected)
|
||||||
_vim_run +'PlugInstall --sync' +qall || true # fzf post-install hook may exit non-zero; harmless
|
_vim_run +'PlugInstall --sync' +qall || true # fzf post-install hook may exit non-zero; harmless
|
||||||
|
|
||||||
|
verify_plugins || die "Plugin installation failed — retry with a stable network connection."
|
||||||
|
|
||||||
_plug_count=$(find "$HOME/.vim/plugged" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
|
_plug_count=$(find "$HOME/.vim/plugged" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
|
||||||
if [[ $_plug_count -eq 0 ]]; then
|
if [[ $_plug_count -eq 0 ]]; then
|
||||||
die "Plugin installation failed — ~/.vim/plugged is empty. Check network and retry."
|
die "Plugin installation failed — ~/.vim/plugged is empty. Check network and retry."
|
||||||
|
|
@ -440,9 +662,14 @@ ok "Plugins installed ($_plug_count)"
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
step "Select optional components"
|
step "Select optional components"
|
||||||
|
info "Vim profile: $CONFIG_PROFILE"
|
||||||
|
|
||||||
_ITEMS=()
|
_ITEMS=()
|
||||||
_idx=0
|
_idx=0
|
||||||
|
_PROFILE_TOOLING=1
|
||||||
|
[[ $CONFIG_PROFILE == "minimal" ]] && _PROFILE_TOOLING=0
|
||||||
|
_MARKSMAN_DEFAULT=0
|
||||||
|
[[ $CONFIG_PROFILE == "full" ]] && _MARKSMAN_DEFAULT=1
|
||||||
|
|
||||||
# Index map (-1 = not in menu / unavailable)
|
# Index map (-1 = not in menu / unavailable)
|
||||||
_I_RIPGREP=-1; _I_FZF=-1; _I_CTAGS=-1; _I_SHELLCHECK=-1
|
_I_RIPGREP=-1; _I_FZF=-1; _I_CTAGS=-1; _I_SHELLCHECK=-1
|
||||||
|
|
@ -467,42 +694,46 @@ if [[ $HAS_PKG_MGR -eq 1 ]]; then
|
||||||
: $(( _idx++ ))
|
: $(( _idx++ ))
|
||||||
|
|
||||||
_I_CTAGS=$_idx
|
_I_CTAGS=$_idx
|
||||||
_ITEMS+=("universal-ctags|code symbol index (backing engine for ,rt tag jumps)|1")
|
_ITEMS+=("universal-ctags|Optional symbol index for ,rt tag jumps|0")
|
||||||
: $(( _idx++ ))
|
: $(( _idx++ ))
|
||||||
|
|
||||||
|
if [[ $_PROFILE_TOOLING -eq 1 ]]; then
|
||||||
_I_SHELLCHECK=$_idx
|
_I_SHELLCHECK=$_idx
|
||||||
_ITEMS+=("shellcheck|shell script static analysis (ALE integration, on-save)|1")
|
_ITEMS+=("shellcheck|Optional shell script static analysis via ALE|0")
|
||||||
: $(( _idx++ ))
|
: $(( _idx++ ))
|
||||||
|
|
||||||
_I_HADOLINT=$_idx
|
_I_HADOLINT=$_idx
|
||||||
_ITEMS+=("hadolint|Dockerfile linting (ALE integration, on-save)|1")
|
_ITEMS+=("hadolint|Optional Dockerfile linting via ALE|0")
|
||||||
: $(( _idx++ ))
|
: $(( _idx++ ))
|
||||||
|
|
||||||
_I_MARKSMAN=$_idx
|
_I_MARKSMAN=$_idx
|
||||||
_ITEMS+=("marksman|Markdown LSP — completion · go-to-definition · live diagnostics|1")
|
_ITEMS+=("marksman|Markdown LSP for full profile or explicit Markdown LSP|$_MARKSMAN_DEFAULT")
|
||||||
: $(( _idx++ ))
|
: $(( _idx++ ))
|
||||||
|
else
|
||||||
|
skip "lint/LSP system tools hidden by minimal profile"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
warn "No package manager available — system tools skipped"
|
warn "No package manager available — system tools skipped"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── npm tools ────────────────────────────────────────────────────────────────
|
# ── npm tools ────────────────────────────────────────────────────────────────
|
||||||
if [[ $HAS_NODE -eq 1 ]]; then
|
if [[ $HAS_NODE -eq 1 && $_PROFILE_TOOLING -eq 1 ]]; then
|
||||||
_I_NPM=$_idx
|
_I_NPM=$_idx
|
||||||
_ITEMS+=("npm formatter suite|prettier / eslint / markdownlint / stylelint / tsc — ALE fix-on-save|1")
|
_ITEMS+=("npm formatter suite|Optional prettier / eslint / markdownlint / stylelint / tsc|0")
|
||||||
: $(( _idx++ ))
|
: $(( _idx++ ))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Python tools ─────────────────────────────────────────────────────────────
|
# ── Python tools ─────────────────────────────────────────────────────────────
|
||||||
if [[ $HAS_PIP -eq 1 ]]; then
|
if [[ $HAS_PIP -eq 1 && $_PROFILE_TOOLING -eq 1 ]]; then
|
||||||
_I_PYTHON=$_idx
|
_I_PYTHON=$_idx
|
||||||
_ITEMS+=("Python tool suite|black / isort / flake8 / pylint / yamllint / sqlfluff — ALE fix-on-save|1")
|
_ITEMS+=("Python tool suite|Optional black / isort / flake8 / pylint / yamllint / sqlfluff|0")
|
||||||
: $(( _idx++ ))
|
: $(( _idx++ ))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Go tools ─────────────────────────────────────────────────────────────────
|
# ── Go tools ─────────────────────────────────────────────────────────────────
|
||||||
if [[ $HAS_GO -eq 1 ]]; then
|
if [[ $HAS_GO -eq 1 && $_PROFILE_TOOLING -eq 1 ]]; then
|
||||||
_I_GO=$_idx
|
_I_GO=$_idx
|
||||||
_ITEMS+=("Go tool suite|gopls (LSP) / goimports / staticcheck — completion · format · analysis|1")
|
_ITEMS+=("Go tool suite|Optional gopls / goimports / staticcheck|0")
|
||||||
: $(( _idx++ ))
|
: $(( _idx++ ))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -510,7 +741,7 @@ fi
|
||||||
if command -v tmux >/dev/null 2>&1; then
|
if command -v tmux >/dev/null 2>&1; then
|
||||||
if ! grep -q 'vim-tmux-navigator' "$HOME/.tmux.conf" 2>/dev/null; then
|
if ! grep -q 'vim-tmux-navigator' "$HOME/.tmux.conf" 2>/dev/null; then
|
||||||
_I_TMUX=$_idx
|
_I_TMUX=$_idx
|
||||||
_ITEMS+=("tmux integration|seamless Ctrl+h/j/k/l navigation between vim and tmux panes|1")
|
_ITEMS+=("tmux integration|Optional Ctrl+h/j/k/l navigation between vim and tmux panes|0")
|
||||||
: $(( _idx++ ))
|
: $(( _idx++ ))
|
||||||
else
|
else
|
||||||
ok "tmux integration (vim-tmux-navigator already configured)"
|
ok "tmux integration (vim-tmux-navigator already configured)"
|
||||||
|
|
@ -680,6 +911,9 @@ step "npm tools (formatters + linters)"
|
||||||
if [[ $HAS_NODE -eq 0 ]]; then
|
if [[ $HAS_NODE -eq 0 ]]; then
|
||||||
skip "npm tools (Node.js not installed)"
|
skip "npm tools (Node.js not installed)"
|
||||||
SKIPPED+=("prettier" "markdownlint-cli" "stylelint" "eslint" "typescript")
|
SKIPPED+=("prettier" "markdownlint-cli" "stylelint" "eslint" "typescript")
|
||||||
|
elif [[ $_PROFILE_TOOLING -eq 0 ]]; then
|
||||||
|
skip "npm tools (minimal profile)"
|
||||||
|
SKIPPED+=("prettier" "markdownlint-cli" "stylelint" "eslint" "typescript")
|
||||||
elif [[ $_I_NPM -lt 0 ]] || ! _selected "$_I_NPM"; then
|
elif [[ $_I_NPM -lt 0 ]] || ! _selected "$_I_NPM"; then
|
||||||
skip "npm formatter suite (skipped by user)"
|
skip "npm formatter suite (skipped by user)"
|
||||||
SKIPPED+=("prettier" "markdownlint-cli" "stylelint" "eslint" "typescript")
|
SKIPPED+=("prettier" "markdownlint-cli" "stylelint" "eslint" "typescript")
|
||||||
|
|
@ -712,6 +946,9 @@ step "Python tools (formatters + linters)"
|
||||||
if [[ $HAS_PIP -eq 0 ]]; then
|
if [[ $HAS_PIP -eq 0 ]]; then
|
||||||
skip "Python tools (pip3 not installed)"
|
skip "Python tools (pip3 not installed)"
|
||||||
SKIPPED+=("black" "isort" "flake8" "pylint" "yamllint" "sqlfluff")
|
SKIPPED+=("black" "isort" "flake8" "pylint" "yamllint" "sqlfluff")
|
||||||
|
elif [[ $_PROFILE_TOOLING -eq 0 ]]; then
|
||||||
|
skip "Python tools (minimal profile)"
|
||||||
|
SKIPPED+=("black" "isort" "flake8" "pylint" "yamllint" "sqlfluff")
|
||||||
elif [[ $_I_PYTHON -lt 0 ]] || ! _selected "$_I_PYTHON"; then
|
elif [[ $_I_PYTHON -lt 0 ]] || ! _selected "$_I_PYTHON"; then
|
||||||
skip "Python tool suite (skipped by user)"
|
skip "Python tool suite (skipped by user)"
|
||||||
SKIPPED+=("black" "isort" "flake8" "pylint" "yamllint" "sqlfluff")
|
SKIPPED+=("black" "isort" "flake8" "pylint" "yamllint" "sqlfluff")
|
||||||
|
|
@ -747,6 +984,9 @@ step "Go tools"
|
||||||
if [[ $HAS_GO -eq 0 ]]; then
|
if [[ $HAS_GO -eq 0 ]]; then
|
||||||
skip "Go tools (go not installed — see https://go.dev/dl/)"
|
skip "Go tools (go not installed — see https://go.dev/dl/)"
|
||||||
SKIPPED+=("gopls" "goimports" "staticcheck")
|
SKIPPED+=("gopls" "goimports" "staticcheck")
|
||||||
|
elif [[ $_PROFILE_TOOLING -eq 0 ]]; then
|
||||||
|
skip "Go tools (minimal profile)"
|
||||||
|
SKIPPED+=("gopls" "goimports" "staticcheck")
|
||||||
elif [[ $_I_GO -lt 0 ]] || ! _selected "$_I_GO"; then
|
elif [[ $_I_GO -lt 0 ]] || ! _selected "$_I_GO"; then
|
||||||
skip "Go tool suite (skipped by user)"
|
skip "Go tool suite (skipped by user)"
|
||||||
SKIPPED+=("gopls" "goimports" "staticcheck")
|
SKIPPED+=("gopls" "goimports" "staticcheck")
|
||||||
|
|
@ -789,14 +1029,26 @@ elif ! _selected "$_I_TMUX"; then
|
||||||
SKIPPED+=("tmux-navigator-config")
|
SKIPPED+=("tmux-navigator-config")
|
||||||
else
|
else
|
||||||
TMUX_CONF="$HOME/.tmux.conf"
|
TMUX_CONF="$HOME/.tmux.conf"
|
||||||
cat >> "$TMUX_CONF" << 'TMUXEOF'
|
TMUX_BEGIN="# >>> chopsticks vim-tmux-navigator >>>"
|
||||||
|
TMUX_END="# <<< chopsticks vim-tmux-navigator <<<"
|
||||||
|
if [[ -f "$TMUX_CONF" ]] && grep -Fq "$TMUX_BEGIN" "$TMUX_CONF"; then
|
||||||
|
tmp="$_TMPDIR/tmux.conf"
|
||||||
|
awk -v begin="$TMUX_BEGIN" -v end="$TMUX_END" '
|
||||||
|
$0 == begin { skip = 1; next }
|
||||||
|
$0 == end { skip = 0; next }
|
||||||
|
!skip { print }
|
||||||
|
' "$TMUX_CONF" > "$tmp"
|
||||||
|
mv "$tmp" "$TMUX_CONF"
|
||||||
|
fi
|
||||||
|
cat >> "$TMUX_CONF" << TMUXEOF
|
||||||
|
|
||||||
# vim-tmux-navigator: seamless Ctrl+h/j/k/l navigation between vim and tmux
|
$TMUX_BEGIN
|
||||||
is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\S+\/)?g?(view|n?vim?x?)(diff)?$'"
|
is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\S+\/)?g?(view|n?vim?x?)(diff)?$'"
|
||||||
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
|
bind-key -n 'C-h' if-shell "\$is_vim" 'send-keys C-h' 'select-pane -L'
|
||||||
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
|
bind-key -n 'C-j' if-shell "\$is_vim" 'send-keys C-j' 'select-pane -D'
|
||||||
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
|
bind-key -n 'C-k' if-shell "\$is_vim" 'send-keys C-k' 'select-pane -U'
|
||||||
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
|
bind-key -n 'C-l' if-shell "\$is_vim" 'send-keys C-l' 'select-pane -R'
|
||||||
|
$TMUX_END
|
||||||
TMUXEOF
|
TMUXEOF
|
||||||
ok "vim-tmux-navigator bindings appended to ~/.tmux.conf"
|
ok "vim-tmux-navigator bindings appended to ~/.tmux.conf"
|
||||||
warn "Reload tmux config now: tmux source-file ~/.tmux.conf"
|
warn "Reload tmux config now: tmux source-file ~/.tmux.conf"
|
||||||
|
|
@ -828,6 +1080,11 @@ echo -e "${BOLD}=======================================${NC}"
|
||||||
echo -e "${GREEN}Installation complete.${NC}"
|
echo -e "${GREEN}Installation complete.${NC}"
|
||||||
echo -e "${BOLD}=======================================${NC}"
|
echo -e "${BOLD}=======================================${NC}"
|
||||||
|
|
||||||
|
echo -e "\n${BOLD}Profile:${NC} $CONFIG_PROFILE"
|
||||||
|
if [[ -f "$LOCAL_CONFIG" ]]; then
|
||||||
|
echo " Local config: $LOCAL_CONFIG"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ${#INSTALLED[@]} -gt 0 ]]; then
|
if [[ ${#INSTALLED[@]} -gt 0 ]]; then
|
||||||
echo -e "\n${GREEN}Installed:${NC}"
|
echo -e "\n${GREEN}Installed:${NC}"
|
||||||
for t in "${INSTALLED[@]}"; do echo " + $t"; done
|
for t in "${INSTALLED[@]}"; do echo " + $t"; done
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,14 @@ endif
|
||||||
|
|
||||||
set display+=lastline
|
set display+=lastline
|
||||||
set ffs=unix,dos,mac
|
set ffs=unix,dos,mac
|
||||||
set nowb
|
set writebackup
|
||||||
set noswapfile
|
|
||||||
|
if has('unix')
|
||||||
|
let s:swap_dir = expand(get(g:, 'chopsticks_swap_dir', '~/.vim/.swap'))
|
||||||
|
let &directory = s:swap_dir . '//,/tmp//'
|
||||||
|
silent! call mkdir(s:swap_dir, 'p', 0700)
|
||||||
|
endif
|
||||||
|
set swapfile
|
||||||
|
|
||||||
if has('persistent_undo')
|
if has('persistent_undo')
|
||||||
set undofile
|
set undofile
|
||||||
|
|
@ -89,7 +95,7 @@ let mapleader = ","
|
||||||
|
|
||||||
" ── Basic Keymaps ───────────────────────────────────────────────────────────
|
" ── Basic Keymaps ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
nnoremap <leader>w :w!<cr>
|
nnoremap <leader>w :w<cr>
|
||||||
nnoremap <leader>q :q<cr>
|
nnoremap <leader>q :q<cr>
|
||||||
nnoremap <leader>x :x<cr>
|
nnoremap <leader>x :x<cr>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ let g:EasyMotion_do_mapping = 0
|
||||||
let g:EasyMotion_smartcase = 1
|
let g:EasyMotion_smartcase = 1
|
||||||
|
|
||||||
if exists('g:plugs["vim-easymotion"]')
|
if exists('g:plugs["vim-easymotion"]')
|
||||||
nmap s <Plug>(easymotion-overwin-f2)
|
nmap <Leader>S <Plug>(easymotion-overwin-f2)
|
||||||
nmap <Leader>j <Plug>(easymotion-j)
|
nmap <Leader>j <Plug>(easymotion-j)
|
||||||
nmap <Leader>k <Plug>(easymotion-k)
|
nmap <Leader>k <Plug>(easymotion-k)
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,38 @@ let g:is_tty = empty($TERM) || $TERM ==# 'dumb' || $TERM =~# 'linux'
|
||||||
\ || $TERM =~# 'screen' || &term =~# 'builtin'
|
\ || $TERM =~# 'screen' || &term =~# 'builtin'
|
||||||
let g:has_true_color = ($COLORTERM ==# 'truecolor' || $COLORTERM ==# '24bit')
|
let g:has_true_color = ($COLORTERM ==# 'truecolor' || $COLORTERM ==# '24bit')
|
||||||
|
|
||||||
|
let g:chopsticks_profile = get(g:, 'chopsticks_profile', 'engineer')
|
||||||
|
if index(['minimal', 'engineer', 'full'], g:chopsticks_profile) < 0
|
||||||
|
let g:chopsticks_profile = 'engineer'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:profile_full = g:chopsticks_profile ==# 'full'
|
||||||
|
let s:profile_minimal = g:chopsticks_profile ==# 'minimal'
|
||||||
|
|
||||||
|
let g:chopsticks_enable_lsp = get(g:, 'chopsticks_enable_lsp',
|
||||||
|
\ !s:profile_minimal)
|
||||||
|
let g:chopsticks_enable_lint = get(g:, 'chopsticks_enable_lint',
|
||||||
|
\ !s:profile_minimal)
|
||||||
|
let g:chopsticks_enable_extra_languages = get(g:,
|
||||||
|
\ 'chopsticks_enable_extra_languages', !s:profile_minimal)
|
||||||
|
let g:chopsticks_enable_ui_extras = get(g:, 'chopsticks_enable_ui_extras',
|
||||||
|
\ !s:profile_minimal)
|
||||||
|
let g:chopsticks_enable_markdown_preview = get(g:,
|
||||||
|
\ 'chopsticks_enable_markdown_preview', !s:profile_minimal)
|
||||||
|
|
||||||
|
let g:chopsticks_markdown_lint = get(g:, 'chopsticks_markdown_lint',
|
||||||
|
\ s:profile_full)
|
||||||
|
let g:chopsticks_markdown_format_on_save = get(g:,
|
||||||
|
\ 'chopsticks_markdown_format_on_save', s:profile_full)
|
||||||
|
let g:chopsticks_markdown_lsp = get(g:, 'chopsticks_markdown_lsp',
|
||||||
|
\ s:profile_full)
|
||||||
|
let g:chopsticks_markdown_spell = get(g:, 'chopsticks_markdown_spell',
|
||||||
|
\ s:profile_full)
|
||||||
|
let g:chopsticks_markdown_conceal = get(g:, 'chopsticks_markdown_conceal',
|
||||||
|
\ s:profile_full)
|
||||||
|
let g:chopsticks_lsp_virtual_text = get(g:, 'chopsticks_lsp_virtual_text',
|
||||||
|
\ s:profile_full && !g:is_tty)
|
||||||
|
|
||||||
" Skip built-in plugins we never use
|
" Skip built-in plugins we never use
|
||||||
let g:loaded_2html_plugin = 1
|
let g:loaded_2html_plugin = 1
|
||||||
let g:loaded_getscriptPlugin = 1
|
let g:loaded_getscriptPlugin = 1
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
" ── vim-markdown ───────────────────────────────────────────────────────────
|
" ── vim-markdown ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
let g:vim_markdown_conceal = 1
|
let g:vim_markdown_conceal = get(g:, 'vim_markdown_conceal',
|
||||||
|
\ g:chopsticks_markdown_conceal)
|
||||||
let g:vim_markdown_conceal_code_blocks = 0
|
let g:vim_markdown_conceal_code_blocks = 0
|
||||||
let g:vim_markdown_folding_disabled = 0
|
let g:vim_markdown_folding_disabled = get(g:, 'vim_markdown_folding_disabled', 1)
|
||||||
let g:vim_markdown_folding_level = 2
|
let g:vim_markdown_folding_level = 2
|
||||||
let g:vim_markdown_frontmatter = 1
|
let g:vim_markdown_frontmatter = 1
|
||||||
let g:vim_markdown_toml_frontmatter = 1
|
let g:vim_markdown_toml_frontmatter = 1
|
||||||
|
|
@ -22,7 +23,7 @@ if has('macunix')
|
||||||
elseif executable('xdg-open')
|
elseif executable('xdg-open')
|
||||||
let g:previm_open_cmd = 'xdg-open'
|
let g:previm_open_cmd = 'xdg-open'
|
||||||
endif
|
endif
|
||||||
let g:previm_enable_realtime = 1
|
let g:previm_enable_realtime = get(g:, 'previm_enable_realtime', 0)
|
||||||
if exists('g:plugs["previm"]')
|
if exists('g:plugs["previm"]')
|
||||||
nnoremap <leader>mp :PrevimOpen<CR>
|
nnoremap <leader>mp :PrevimOpen<CR>
|
||||||
endif
|
endif
|
||||||
|
|
@ -40,6 +41,22 @@ let g:go_highlight_function_calls = 1
|
||||||
|
|
||||||
" ── Filetype Detection ──────────────────────────────────────────────────────
|
" ── Filetype Detection ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function! s:MarkdownDefaults() abort
|
||||||
|
setlocal wrap linebreak textwidth=0 colorcolumn=0 signcolumn=no
|
||||||
|
let &l:conceallevel = get(g:, 'chopsticks_markdown_conceal', 0) ? 2 : 0
|
||||||
|
|
||||||
|
if get(g:, 'chopsticks_markdown_spell', 0)
|
||||||
|
setlocal spell
|
||||||
|
else
|
||||||
|
setlocal nospell
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !get(g:, 'chopsticks_markdown_lint', 0)
|
||||||
|
\ && !get(g:, 'chopsticks_markdown_format_on_save', 0)
|
||||||
|
let b:ale_enabled = 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
augroup ChopstickFiletype
|
augroup ChopstickFiletype
|
||||||
autocmd!
|
autocmd!
|
||||||
|
|
||||||
|
|
@ -60,8 +77,7 @@ augroup ChopstickFiletype
|
||||||
\ setlocal expandtab shiftwidth=2 tabstop=2
|
\ setlocal expandtab shiftwidth=2 tabstop=2
|
||||||
autocmd FileType yaml
|
autocmd FileType yaml
|
||||||
\ setlocal expandtab shiftwidth=2 tabstop=2
|
\ setlocal expandtab shiftwidth=2 tabstop=2
|
||||||
autocmd FileType markdown
|
autocmd FileType markdown call s:MarkdownDefaults()
|
||||||
\ setlocal wrap linebreak spell textwidth=0 conceallevel=2
|
|
||||||
autocmd FileType sh
|
autocmd FileType sh
|
||||||
\ setlocal expandtab shiftwidth=2 tabstop=2 textwidth=80
|
\ setlocal expandtab shiftwidth=2 tabstop=2 textwidth=80
|
||||||
autocmd FileType make
|
autocmd FileType make
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
" lint.vim — ALE async linting and format-on-save
|
" lint.vim — ALE async linting and format-on-save
|
||||||
|
|
||||||
|
if !g:chopsticks_enable_lint
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
let g:ale_disable_lsp = 1
|
let g:ale_disable_lsp = 1
|
||||||
|
|
||||||
let g:ale_linters = {
|
let s:ale_linters = {
|
||||||
\ 'python': ['flake8', 'pylint'],
|
\ 'python': ['flake8', 'pylint'],
|
||||||
\ 'javascript': ['eslint'],
|
\ 'javascript': ['eslint'],
|
||||||
\ 'typescript': ['eslint'],
|
\ 'typescript': ['eslint'],
|
||||||
|
|
@ -14,11 +18,16 @@ let g:ale_linters = {
|
||||||
\ 'dockerfile': ['hadolint'],
|
\ 'dockerfile': ['hadolint'],
|
||||||
\ 'css': ['stylelint'],
|
\ 'css': ['stylelint'],
|
||||||
\ 'scss': ['stylelint'],
|
\ 'scss': ['stylelint'],
|
||||||
\ 'markdown': ['markdownlint'],
|
|
||||||
\ 'sql': ['sqlfluff'],
|
\ 'sql': ['sqlfluff'],
|
||||||
\}
|
\}
|
||||||
|
|
||||||
let g:ale_fixers = {
|
if g:chopsticks_markdown_lint
|
||||||
|
let s:ale_linters.markdown = ['markdownlint']
|
||||||
|
endif
|
||||||
|
|
||||||
|
let g:ale_linters = s:ale_linters
|
||||||
|
|
||||||
|
let s:ale_fixers = {
|
||||||
\ '*': ['remove_trailing_lines', 'trim_whitespace'],
|
\ '*': ['remove_trailing_lines', 'trim_whitespace'],
|
||||||
\ 'python': ['black', 'isort'],
|
\ 'python': ['black', 'isort'],
|
||||||
\ 'javascript': ['prettier', 'eslint'],
|
\ 'javascript': ['prettier', 'eslint'],
|
||||||
|
|
@ -32,11 +41,16 @@ let g:ale_fixers = {
|
||||||
\ 'css': ['prettier'],
|
\ 'css': ['prettier'],
|
||||||
\ 'scss': ['prettier'],
|
\ 'scss': ['prettier'],
|
||||||
\ 'less': ['prettier'],
|
\ 'less': ['prettier'],
|
||||||
\ 'markdown': ['prettier'],
|
|
||||||
\ 'sql': ['sqlfluff'],
|
\ 'sql': ['sqlfluff'],
|
||||||
\}
|
\}
|
||||||
|
|
||||||
let g:ale_fix_on_save = 1
|
if g:chopsticks_markdown_format_on_save
|
||||||
|
let s:ale_fixers.markdown = ['prettier']
|
||||||
|
endif
|
||||||
|
|
||||||
|
let g:ale_fixers = s:ale_fixers
|
||||||
|
|
||||||
|
let g:ale_fix_on_save = get(g:, 'ale_fix_on_save', 1)
|
||||||
let g:ale_python_isort_options = '--profile black'
|
let g:ale_python_isort_options = '--profile black'
|
||||||
let g:ale_sign_error = 'X'
|
let g:ale_sign_error = 'X'
|
||||||
let g:ale_sign_warning = '!'
|
let g:ale_sign_warning = '!'
|
||||||
|
|
@ -45,6 +59,7 @@ let g:ale_lint_on_insert_leave = 1
|
||||||
let g:ale_lint_on_enter = 1
|
let g:ale_lint_on_enter = 1
|
||||||
let g:ale_lint_delay = 200
|
let g:ale_lint_delay = 200
|
||||||
let g:ale_echo_delay = 100
|
let g:ale_echo_delay = 100
|
||||||
|
let g:ale_virtualtext_cursor = get(g:, 'ale_virtualtext_cursor', 'disabled')
|
||||||
|
|
||||||
if exists('g:plugs["ale"]')
|
if exists('g:plugs["ale"]')
|
||||||
nnoremap <silent> [e :ALEPrevious<cr>
|
nnoremap <silent> [e :ALEPrevious<cr>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
" lsp.vim — vim-lsp settings, asyncomplete, LSP buffer keymaps
|
" lsp.vim — vim-lsp settings, asyncomplete, LSP buffer keymaps
|
||||||
|
|
||||||
|
if !g:chopsticks_enable_lsp
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
let g:lsp_settings_lazyload = 1
|
let g:lsp_settings_lazyload = 1
|
||||||
|
|
||||||
let g:lsp_settings_filetype_python = ['pylsp']
|
let g:lsp_settings_filetype_python = ['pylsp']
|
||||||
|
|
@ -14,10 +18,13 @@ let g:lsp_settings_filetype_css = ['vscode-css-language-server']
|
||||||
let g:lsp_settings_filetype_scss = ['vscode-css-language-server']
|
let g:lsp_settings_filetype_scss = ['vscode-css-language-server']
|
||||||
let g:lsp_settings_filetype_json = ['vscode-json-language-server']
|
let g:lsp_settings_filetype_json = ['vscode-json-language-server']
|
||||||
let g:lsp_settings_filetype_yaml = ['yaml-language-server']
|
let g:lsp_settings_filetype_yaml = ['yaml-language-server']
|
||||||
let g:lsp_settings_filetype_markdown = ['marksman']
|
|
||||||
let g:lsp_settings_filetype_sql = ['sqls']
|
let g:lsp_settings_filetype_sql = ['sqls']
|
||||||
|
|
||||||
let g:lsp_diagnostics_virtual_text_enabled = !g:is_tty
|
if g:chopsticks_markdown_lsp
|
||||||
|
let g:lsp_settings_filetype_markdown = ['marksman']
|
||||||
|
endif
|
||||||
|
|
||||||
|
let g:lsp_diagnostics_virtual_text_enabled = g:chopsticks_lsp_virtual_text
|
||||||
let g:lsp_diagnostics_virtual_text_delay = 200
|
let g:lsp_diagnostics_virtual_text_delay = 200
|
||||||
let g:lsp_diagnostics_highlights_enabled = !g:is_tty
|
let g:lsp_diagnostics_highlights_enabled = !g:is_tty
|
||||||
let g:lsp_document_highlight_enabled = !g:is_tty
|
let g:lsp_document_highlight_enabled = !g:is_tty
|
||||||
|
|
@ -52,7 +59,7 @@ inoremap <expr> <CR> pumvisible() ? asyncomplete#close_popup() : "\<CR>"
|
||||||
|
|
||||||
function! s:on_lsp_buffer_enabled() abort
|
function! s:on_lsp_buffer_enabled() abort
|
||||||
setlocal omnifunc=lsp#complete
|
setlocal omnifunc=lsp#complete
|
||||||
if !g:is_tty
|
if !g:is_tty && &filetype !=# 'markdown'
|
||||||
setlocal signcolumn=yes
|
setlocal signcolumn=yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,25 +29,35 @@ Plug 'wellle/targets.vim'
|
||||||
Plug 'jiangmiao/auto-pairs'
|
Plug 'jiangmiao/auto-pairs'
|
||||||
Plug 'easymotion/vim-easymotion', { 'on': '<Plug>(easymotion' }
|
Plug 'easymotion/vim-easymotion', { 'on': '<Plug>(easymotion' }
|
||||||
|
|
||||||
" ── Linting & Formatting ────────────────────────────────────────────────────
|
if g:chopsticks_enable_lint
|
||||||
|
" ── Linting & Formatting ────────────────────────────────────────────────
|
||||||
Plug 'dense-analysis/ale'
|
Plug 'dense-analysis/ale'
|
||||||
|
endif
|
||||||
|
|
||||||
" ── LSP + Completion ─────────────────────────────────────────────────────────
|
if g:chopsticks_enable_lsp
|
||||||
|
" ── LSP + Completion ─────────────────────────────────────────────────────
|
||||||
Plug 'prabirshrestha/vim-lsp'
|
Plug 'prabirshrestha/vim-lsp'
|
||||||
Plug 'mattn/vim-lsp-settings'
|
Plug 'mattn/vim-lsp-settings'
|
||||||
Plug 'prabirshrestha/asyncomplete.vim'
|
Plug 'prabirshrestha/asyncomplete.vim'
|
||||||
Plug 'prabirshrestha/asyncomplete-lsp.vim'
|
Plug 'prabirshrestha/asyncomplete-lsp.vim'
|
||||||
|
endif
|
||||||
|
|
||||||
" ── Language Syntax ──────────────────────────────────────────────────────────
|
" ── Language Syntax ──────────────────────────────────────────────────────────
|
||||||
|
Plug 'preservim/vim-markdown', { 'for': 'markdown' }
|
||||||
|
if g:chopsticks_enable_markdown_preview
|
||||||
|
Plug 'previm/previm', { 'on': 'PrevimOpen' }
|
||||||
|
endif
|
||||||
|
if g:chopsticks_enable_extra_languages
|
||||||
Plug 'pangloss/vim-javascript', { 'for': ['javascript', 'javascript.jsx'] }
|
Plug 'pangloss/vim-javascript', { 'for': ['javascript', 'javascript.jsx'] }
|
||||||
Plug 'HerringtonDarkholme/yats.vim', { 'for': ['typescript', 'typescript.tsx'] }
|
Plug 'HerringtonDarkholme/yats.vim', { 'for': ['typescript', 'typescript.tsx'] }
|
||||||
Plug 'preservim/vim-markdown', { 'for': 'markdown' }
|
|
||||||
Plug 'previm/previm', { 'on': 'PrevimOpen' }
|
|
||||||
Plug 'fatih/vim-go', { 'for': 'go' }
|
Plug 'fatih/vim-go', { 'for': 'go' }
|
||||||
|
endif
|
||||||
|
|
||||||
" ── UI ───────────────────────────────────────────────────────────────────────
|
" ── UI ───────────────────────────────────────────────────────────────────────
|
||||||
|
if g:chopsticks_enable_ui_extras
|
||||||
Plug 'mbbill/undotree', { 'on': 'UndotreeToggle' }
|
Plug 'mbbill/undotree', { 'on': 'UndotreeToggle' }
|
||||||
Plug 'mhinz/vim-startify'
|
Plug 'mhinz/vim-startify'
|
||||||
|
endif
|
||||||
Plug 'lifepillar/vim-solarized8'
|
Plug 'lifepillar/vim-solarized8'
|
||||||
if !empty($TMUX)
|
if !empty($TMUX)
|
||||||
Plug 'christoomey/vim-tmux-navigator'
|
Plug 'christoomey/vim-tmux-navigator'
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ nnoremap <leader>W :%s/\s\+$//<CR>:let @/=''<CR>
|
||||||
vnoremap <leader>W :s/\s\+$//<CR>:let @/=''<CR>gv
|
vnoremap <leader>W :s/\s\+$//<CR>:let @/=''<CR>gv
|
||||||
|
|
||||||
nnoremap <leader>ev :edit $MYVIMRC<CR>
|
nnoremap <leader>ev :edit $MYVIMRC<CR>
|
||||||
nnoremap <leader>sv :source $MYVIMRC<CR>:echo "vimrc reloaded"<CR>
|
nnoremap <leader>sv :unlet! g:chopsticks_loaded<CR>:execute 'source ' . fnameescape($MYVIMRC)<CR>:echo "vimrc reloaded"<CR>
|
||||||
|
|
||||||
nnoremap <leader>* :%s/\<<C-r><C-w>\>//g<Left><Left>
|
nnoremap <leader>* :%s/\<<C-r><C-w>\>//g<Left><Left>
|
||||||
vnoremap <leader>* :s///g<Left><Left><Left>
|
vnoremap <leader>* :s///g<Left><Left><Left>
|
||||||
|
|
@ -64,21 +64,41 @@ augroup END
|
||||||
|
|
||||||
" ── Large File Handling ──────────────────────────────────────────────────────
|
" ── Large File Handling ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
let g:LargeFile = 1024 * 1024 * 10
|
let g:LargeFile = get(g:, 'LargeFile', 1024 * 1024 * 10)
|
||||||
let s:tty_large = g:is_tty ? 512000 : g:LargeFile
|
let s:tty_large = g:is_tty ? 512000 : g:LargeFile
|
||||||
|
|
||||||
|
function! s:ApplyLargeFileSettings() abort
|
||||||
|
if get(b:, 'chopsticks_large_file', 0)
|
||||||
|
setlocal bufhidden=unload undolevels=-1 noswapfile
|
||||||
|
let b:ale_enabled = 0
|
||||||
|
if &l:syntax !=# ''
|
||||||
|
setlocal syntax=
|
||||||
|
endif
|
||||||
|
elseif get(b:, 'chopsticks_tty_large_file', 0)
|
||||||
|
if &l:syntax !=# ''
|
||||||
|
setlocal syntax=
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:MarkLargeFile(file) abort
|
||||||
|
if empty(a:file)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:fsize = getfsize(a:file)
|
||||||
|
if l:fsize > g:LargeFile || l:fsize == -2
|
||||||
|
let b:chopsticks_large_file = 1
|
||||||
|
elseif g:is_tty && l:fsize > s:tty_large
|
||||||
|
let b:chopsticks_tty_large_file = 1
|
||||||
|
endif
|
||||||
|
call s:ApplyLargeFileSettings()
|
||||||
|
endfunction
|
||||||
|
|
||||||
augroup ChopstickLargeFile
|
augroup ChopstickLargeFile
|
||||||
autocmd!
|
autocmd!
|
||||||
autocmd BufReadPre *
|
autocmd BufReadPre * call s:MarkLargeFile(expand('<afile>'))
|
||||||
\ if !empty(expand('<afile>')) |
|
autocmd BufReadPost,FileType,Syntax * call s:ApplyLargeFileSettings()
|
||||||
\ let s:fsize = getfsize(expand('<afile>')) |
|
|
||||||
\ if s:fsize > g:LargeFile || s:fsize == -2 |
|
|
||||||
\ setlocal bufhidden=unload undolevels=-1 noswapfile syntax= |
|
|
||||||
\ let b:ale_enabled = 0 |
|
|
||||||
\ elseif g:is_tty && s:fsize > s:tty_large |
|
|
||||||
\ setlocal syntax= |
|
|
||||||
\ endif |
|
|
||||||
\ endif
|
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
" ── Run Current File (,cr) ──────────────────────────────────────────────────
|
" ── Run Current File (,cr) ──────────────────────────────────────────────────
|
||||||
|
|
@ -123,7 +143,14 @@ function! s:Check(name, cmd) abort
|
||||||
return executable(a:cmd) ? ' OK ' . a:name : ' -- ' . a:name . ' (missing: ' . a:cmd . ')'
|
return executable(a:cmd) ? ' OK ' . a:name : ' -- ' . a:name . ' (missing: ' . a:cmd . ')'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:Off(name, reason) abort
|
||||||
|
return ' off ' . a:name . ' (' . a:reason . ')'
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:LspCheck(ft, server) abort
|
function! s:LspCheck(ft, server) abort
|
||||||
|
if !get(g:, 'chopsticks_enable_lsp', 1)
|
||||||
|
return s:Off(a:ft, 'LSP disabled by profile')
|
||||||
|
endif
|
||||||
if !exists('*lsp#get_server_names')
|
if !exists('*lsp#get_server_names')
|
||||||
return ' -- ' . a:ft . ' (vim-lsp not loaded)'
|
return ' -- ' . a:ft . ' (vim-lsp not loaded)'
|
||||||
endif
|
endif
|
||||||
|
|
@ -165,6 +192,7 @@ function! s:ChopsticksStatus() abort
|
||||||
call add(l:lines, '')
|
call add(l:lines, '')
|
||||||
|
|
||||||
call add(l:lines, '── linters ──')
|
call add(l:lines, '── linters ──')
|
||||||
|
if get(g:, 'chopsticks_enable_lint', 1)
|
||||||
call add(l:lines, s:Check('flake8 (python)', 'flake8'))
|
call add(l:lines, s:Check('flake8 (python)', 'flake8'))
|
||||||
call add(l:lines, s:Check('pylint (python)', 'pylint'))
|
call add(l:lines, s:Check('pylint (python)', 'pylint'))
|
||||||
call add(l:lines, s:Check('eslint (js/ts)', 'eslint'))
|
call add(l:lines, s:Check('eslint (js/ts)', 'eslint'))
|
||||||
|
|
@ -172,16 +200,32 @@ function! s:ChopsticksStatus() abort
|
||||||
call add(l:lines, s:Check('shellcheck (sh)', 'shellcheck'))
|
call add(l:lines, s:Check('shellcheck (sh)', 'shellcheck'))
|
||||||
call add(l:lines, s:Check('yamllint (yaml)', 'yamllint'))
|
call add(l:lines, s:Check('yamllint (yaml)', 'yamllint'))
|
||||||
call add(l:lines, s:Check('hadolint (docker)', 'hadolint'))
|
call add(l:lines, s:Check('hadolint (docker)', 'hadolint'))
|
||||||
|
if get(g:, 'chopsticks_markdown_lint', 0)
|
||||||
call add(l:lines, s:Check('markdownlint (md)', 'markdownlint'))
|
call add(l:lines, s:Check('markdownlint (md)', 'markdownlint'))
|
||||||
|
else
|
||||||
|
call add(l:lines, s:Off('markdownlint (md)', 'disabled by default'))
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
call add(l:lines, s:Off('ALE linters', 'lint disabled by profile'))
|
||||||
|
endif
|
||||||
call add(l:lines, '')
|
call add(l:lines, '')
|
||||||
|
|
||||||
call add(l:lines, '── formatters ── (format-on-save is ON)')
|
call add(l:lines, '── formatters ── (format-on-save is ' . (get(g:, 'ale_fix_on_save', 0) ? 'ON' : 'OFF') . ')')
|
||||||
|
if get(g:, 'chopsticks_enable_lint', 1)
|
||||||
call add(l:lines, s:Check('black (python)', 'black'))
|
call add(l:lines, s:Check('black (python)', 'black'))
|
||||||
call add(l:lines, s:Check('isort (python)', 'isort'))
|
call add(l:lines, s:Check('isort (python)', 'isort'))
|
||||||
call add(l:lines, s:Check('prettier (js/ts/json/md)', 'prettier'))
|
call add(l:lines, s:Check('prettier (js/ts/json)', 'prettier'))
|
||||||
|
if get(g:, 'chopsticks_markdown_format_on_save', 0)
|
||||||
|
call add(l:lines, s:Check('prettier (md)', 'prettier'))
|
||||||
|
else
|
||||||
|
call add(l:lines, s:Off('prettier (md)', 'disabled by default'))
|
||||||
|
endif
|
||||||
call add(l:lines, s:Check('goimports (go)', 'goimports'))
|
call add(l:lines, s:Check('goimports (go)', 'goimports'))
|
||||||
call add(l:lines, s:Check('rustfmt (rust)', 'rustfmt'))
|
call add(l:lines, s:Check('rustfmt (rust)', 'rustfmt'))
|
||||||
call add(l:lines, s:Check('clang-format (c)', 'clang-format'))
|
call add(l:lines, s:Check('clang-format (c)', 'clang-format'))
|
||||||
|
else
|
||||||
|
call add(l:lines, s:Off('ALE formatters', 'lint disabled by profile'))
|
||||||
|
endif
|
||||||
call add(l:lines, '')
|
call add(l:lines, '')
|
||||||
|
|
||||||
let l:ok = len(filter(copy(l:lines), 'v:val =~# " OK "'))
|
let l:ok = len(filter(copy(l:lines), 'v:val =~# " OK "'))
|
||||||
|
|
@ -190,7 +234,9 @@ function! s:ChopsticksStatus() abort
|
||||||
call add(l:lines, ' ' . l:ok . ' ready, ' . l:miss . ' missing')
|
call add(l:lines, ' ' . l:ok . ' ready, ' . l:miss . ' missing')
|
||||||
call add(l:lines, '')
|
call add(l:lines, '')
|
||||||
call add(l:lines, ' Install missing tools with ./install.sh')
|
call add(l:lines, ' Install missing tools with ./install.sh')
|
||||||
|
if get(g:, 'chopsticks_enable_lsp', 1)
|
||||||
call add(l:lines, ' Install LSP servers with :LspInstallServer')
|
call add(l:lines, ' Install LSP servers with :LspInstallServer')
|
||||||
|
endif
|
||||||
|
|
||||||
let l:name = '__ChopsticksStatus__'
|
let l:name = '__ChopsticksStatus__'
|
||||||
if bufwinnr(l:name) > 0
|
if bufwinnr(l:name) > 0
|
||||||
|
|
@ -214,12 +260,13 @@ function! s:CheatSheet() abort
|
||||||
execute bufwinnr(l:name) . 'wincmd w | bd'
|
execute bufwinnr(l:name) . 'wincmd w | bd'
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
execute 'vertical botright new ' . l:name
|
|
||||||
vertical resize 42
|
let l:has_lsp = get(g:, 'chopsticks_enable_lsp', 1)
|
||||||
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile
|
let l:has_lint = get(g:, 'chopsticks_enable_lint', 1)
|
||||||
setlocal nowrap nonumber norelativenumber signcolumn=no
|
let l:has_undotree = exists('g:plugs["undotree"]')
|
||||||
setlocal winfixwidth
|
let l:has_previm = exists('g:plugs["previm"]')
|
||||||
call setline(1, [
|
|
||||||
|
let l:lines = [
|
||||||
\ ' chopsticks ,? close',
|
\ ' chopsticks ,? close',
|
||||||
\ ' ─────────────────────────────',
|
\ ' ─────────────────────────────',
|
||||||
\ '',
|
\ '',
|
||||||
|
|
@ -237,6 +284,10 @@ function! s:CheatSheet() abort
|
||||||
\ ' ,fm marks',
|
\ ' ,fm marks',
|
||||||
\ '',
|
\ '',
|
||||||
\ ' ── code ──────────────────',
|
\ ' ── code ──────────────────',
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
if l:has_lsp
|
||||||
|
call extend(l:lines, [
|
||||||
\ ' gd definition',
|
\ ' gd definition',
|
||||||
\ ' gy type definition',
|
\ ' gy type definition',
|
||||||
\ ' gi implementation',
|
\ ' gi implementation',
|
||||||
|
|
@ -246,19 +297,37 @@ function! s:CheatSheet() abort
|
||||||
\ ' ,ca code action',
|
\ ' ,ca code action',
|
||||||
\ ' ,f format',
|
\ ' ,f format',
|
||||||
\ ' ,o outline',
|
\ ' ,o outline',
|
||||||
\ ' ,cr run file',
|
|
||||||
\ ' ,mp markdown preview',
|
|
||||||
\ ' ,mt table of contents',
|
|
||||||
\ ' [g ]g LSP diagnostics',
|
\ ' [g ]g LSP diagnostics',
|
||||||
|
\ ' :LspInstallServer setup LSP',
|
||||||
|
\ ])
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(l:lines, ' ,cr run file')
|
||||||
|
if l:has_previm
|
||||||
|
call add(l:lines, ' ,mp markdown preview')
|
||||||
|
endif
|
||||||
|
call add(l:lines, ' ,mt table of contents')
|
||||||
|
|
||||||
|
if l:has_lint
|
||||||
|
call extend(l:lines, [
|
||||||
\ ' [e ]e ALE errors',
|
\ ' [e ]e ALE errors',
|
||||||
\ ' ,af format on save',
|
\ ' ,af format on save',
|
||||||
\ ' :LspInstallServer setup LSP',
|
\ ])
|
||||||
|
endif
|
||||||
|
|
||||||
|
call extend(l:lines, [
|
||||||
\ '',
|
\ '',
|
||||||
\ ' ── edit ──────────────────',
|
\ ' ── edit ──────────────────',
|
||||||
\ ' gc comment',
|
\ ' gc comment',
|
||||||
\ ' s+2ch easymotion jump',
|
\ ' ,S+2ch easymotion jump',
|
||||||
\ ' cs"'' surround',
|
\ ' cs"'' surround',
|
||||||
\ ' ,u undo tree',
|
\ ])
|
||||||
|
|
||||||
|
if l:has_undotree
|
||||||
|
call add(l:lines, ' ,u undo tree')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call extend(l:lines, [
|
||||||
\ ' ,y ,p clipboard y/p (v)',
|
\ ' ,y ,p clipboard y/p (v)',
|
||||||
\ ' Alt+j/k move line (v)',
|
\ ' Alt+j/k move line (v)',
|
||||||
\ ' ,* replace word (v)',
|
\ ' ,* replace word (v)',
|
||||||
|
|
@ -304,6 +373,13 @@ function! s:CheatSheet() abort
|
||||||
\ ' ,sv reload vimrc',
|
\ ' ,sv reload vimrc',
|
||||||
\ ' :ChopsticksStatus health',
|
\ ' :ChopsticksStatus health',
|
||||||
\ ])
|
\ ])
|
||||||
|
|
||||||
|
execute 'vertical botright new ' . l:name
|
||||||
|
vertical resize 42
|
||||||
|
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile
|
||||||
|
setlocal nowrap nonumber norelativenumber signcolumn=no
|
||||||
|
setlocal winfixwidth
|
||||||
|
call setline(1, l:lines)
|
||||||
setlocal nomodifiable readonly
|
setlocal nomodifiable readonly
|
||||||
nnoremap <buffer> <silent> q :bd<CR>
|
nnoremap <buffer> <silent> q :bd<CR>
|
||||||
nnoremap <buffer> <silent> <leader>? :bd<CR>
|
nnoremap <buffer> <silent> <leader>? :bd<CR>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue