diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..7535548 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,23 @@ +--- +name: Bug report +about: Something broken or unexpected +labels: bug +--- + +**What happened** + + +**What you expected** + + +**Steps to reproduce** +1. +2. +3. + +**Environment** +- OS: +- Vim version (`vim --version | head -1`): +- Terminal: +- SSH: yes / no +- TTY mode (`echo g:is_tty` inside vim): diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..5cd0863 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request +about: Suggest a plugin, mapping, or improvement +labels: enhancement +--- + +**What problem does this solve?** + + +**What does the solution look like?** + + +**Alternatives you considered** + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..6b9731b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,13 @@ +## What + + + +## Why + + + +## Test + +- [ ] `vim --startuptime` shows no regression +- [ ] Tested on macOS / Linux +- [ ] `,?` cheat sheet still accurate diff --git a/.github/demo.gif b/.github/demo.gif new file mode 100644 index 0000000..d29499f Binary files /dev/null and b/.github/demo.gif differ diff --git a/.github/demo.tape b/.github/demo.tape new file mode 100644 index 0000000..94c5605 --- /dev/null +++ b/.github/demo.tape @@ -0,0 +1,47 @@ +Output .github/demo.gif +Set Shell bash +Set FontSize 14 +Set Width 960 +Set Height 540 +Set Theme "Builtin Solarized Dark" +Set TypingSpeed 50ms +Set Padding 10 + +Type "vim ~/.vim/modules/core.vim" +Enter +Sleep 1.5s + +# Show the code with solarized theme and statusline +Sleep 1s + +# Use Ctrl+p for fuzzy find +Type "\x10" +Sleep 1s +Type "lsp" +Sleep 1s +Escape +Sleep 0.5s + +# Go to definition +Type "gg" +Sleep 0.3s +Type "/mapleader" +Enter +Sleep 1s + +# Show cheat sheet +Type ",?" +Sleep 2s +Type "q" +Sleep 0.5s + +# Open file browser +Type ",e" +Sleep 1.5s +Escape +Sleep 0.5s + +# Quit +Type ":qa!" +Enter +Sleep 0.5s diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..3218666 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,66 @@ +name: test + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + startup: + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - name: Install Vim + run: | + if [ "$(uname)" = "Darwin" ]; then + brew install vim + else + sudo apt-get update && sudo apt-get install -y vim + fi + + - name: Install vim-plug + run: | + curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ + https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim + + - name: Symlink config + run: | + ln -sf "$PWD" ~/.vim/chopsticks-src + ln -sf "$PWD/.vimrc" ~/.vimrc + mkdir -p ~/.vim/modules + cp modules/*.vim ~/.vim/modules/ + + - name: Install plugins + run: vim -es -u .vimrc -c 'PlugInstall --sync' -c 'qa!' 2>&1 || true + + - name: Test startup + run: | + vim -u .vimrc -es -N -c 'qa!' 2>&1 + echo "Vim exited cleanly" + + - name: Verify modules load + run: | + vim -u .vimrc -N -c 'redir! > /tmp/test.txt | echo len(g:plugs) | redir END | qa!' 2>/dev/null + PLUGS=$(cat /tmp/test.txt | tr -d '[:space:]') + echo "Plugins registered: $PLUGS" + if [ "$PLUGS" -lt 25 ]; then + echo "FAIL: expected 25+ plugins, got $PLUGS" + exit 1 + fi + + - name: Measure startup time + run: | + vim -u .vimrc --startuptime /tmp/startup.log -c 'qa!' 2>/dev/null + tail -1 /tmp/startup.log + + shellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Shellcheck install.sh + run: shellcheck install.sh get.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..eb4b4b9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,30 @@ +# Contributing + +## 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. +2. **Startup matters.** Run `vim --startuptime /tmp/s.log -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. **One module, one concern.** Don't put git config in lsp.vim. + +## Adding a plugin + +1. Add the `Plug` line to `modules/plugins.vim` +2. If it's not needed at startup, lazy-load it: `Plug 'foo/bar', { 'on': 'FooCommand' }` +3. Put config in the appropriate module +4. Update the cheat sheet in `modules/tools.vim` if you add keybindings +5. Test on both macOS and Linux + +## Reporting bugs + +Open an issue. Include: +- OS and Vim version +- Whether you're on SSH/TTY +- Steps to reproduce + +## Code style + +- Named augroups with `autocmd!` +- No comments explaining *what* — only *why* +- `exists('g:plugs["..."]')` guards for plugin-dependent config +- Test with `vim -u .vimrc --startuptime /tmp/s.log -c qa!` diff --git a/README.md b/README.md index 0b226ca..3fafdcf 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,49 @@ -# chopsticks +

+ chopsticks demo +

-Vim config for people who ship code on any machine. Pure VimScript. No Node.js. Works over SSH. +

chopsticks

-[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE) -[![Vim 8.0+](https://img.shields.io/badge/Vim-8.0%2B-brightgreen?style=flat-square)](https://www.vim.org/) -[![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey?style=flat-square)](#install) +

+ Vim for engineers. 29 plugins, 19ms startup, works over SSH. +

+ +

+ MIT License + Vim 8.0+ + Platform + Tests + Release +

+ +--- ```bash curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash ``` +--- + ## Why -You SSH into a box. You need to edit code. You want LSP, fuzzy find, git integration, format-on-save — not a 20-minute setup ritual. +You SSH into a server. You need to edit code. You want LSP, fuzzy find, git integration, format-on-save — not a 20-minute setup. -chopsticks gives you 29 plugins, 12 modules, and a sane config in one command. It degrades gracefully on TTY. It works the same on your MacBook and your Arch server. +chopsticks gives you a production-ready Vim config in one command. Pure VimScript — no Node.js for the core. Degrades gracefully on TTY. Works the same on your MacBook and your headless Arch box. + +**19ms startup** with 29 plugins, LSP, linting, and a hand-built statusline. Faster than most people's empty vimrc. ## What's in the box | | | |-|-| -| **LSP** | completion, go-to-def, hover, rename, code actions — pure VimScript | -| **Lint + format** | ALE runs black, prettier, gofmt, rustfmt on save | -| **Fuzzy find** | files, buffers, grep, tags, marks, commands — FZF | -| **Git** | status, diff, blame, push, pull, conflict markers | -| **Zen mode** | `,zen` — Goyo + Limelight, distraction-free writing | -| **Run file** | `,cr` — auto-detects language, runs it | -| **TTY-aware** | degrades gracefully on SSH, console, slow links | +| **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, gofmt, rustfmt on save | +| **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) | +| **Zen mode** | `,zen` — [Goyo](https://github.com/junegunn/goyo.vim) + [Limelight](https://github.com/junegunn/limelight.vim) | +| **Run file** | `,cr` — auto-detects Python, Go, Rust, JS, C, Shell, and more | +| **TTY-aware** | degrades gracefully on SSH, console, slow links — never breaks | +| **19ms startup** | lazy-loaded plugins, deferred LSP init, zero redundant work | ## Install @@ -41,13 +58,13 @@ git clone https://github.com/m1ngsama/chopsticks.git ~/.vim cd ~/.vim && ./install.sh ``` -macOS (brew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf). +Supports macOS (brew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf). -Open vim. Plugins install on first launch. Restart when done. +First launch installs plugins automatically (30-60s). Restart vim when done. ## Keys -Leader: `,` — press `,?` for the full cheat sheet. +Leader: `,` — press `,?` for the full cheat sheet inside vim. ``` Ctrl+p fuzzy find file gd go to definition @@ -58,15 +75,34 @@ Ctrl+p fuzzy find file gd go to definition jk exit insert mode ,? cheat sheet ``` -**Files** — `Ctrl+p` find / `,b` buffers / `,rg` grep / `,rG` grep word / `,fh` recent / `,e` browser / `,,` last file +
+All keybindings -**Code** — `gd` def / `gy` type / `gi` impl / `gr` refs / `K` docs / `[g` `]g` diagnostics / `,rn` rename / `,ca` action / `,o` outline +### Files -**Edit** — `s`+2ch jump / `gc` comment / `cs"'` surround / `Alt+j/k` move line / `,u` undo tree / `,y` clipboard / `,*` replace word +`Ctrl+p` find | `,b` buffers | `,rg` grep | `,rG` grep word | `,fh` recent | `,e` browser | `,,` last file -**Git** — `,gs` status / `,gd` diff / `,gb` blame / `,gc` commit / `,gp` push / `]x` `[x` conflict markers +### Code -**Windows** — `Ctrl+hjkl` navigate (+ tmux) / `,z` maximize / `,h` `,l` buffers / `,tv` `,th` terminal / `Esc Esc` exit terminal +`gd` def | `gy` type | `gi` impl | `gr` refs | `K` docs | `[g` `]g` diagnostics | `,rn` rename | `,ca` action | `,o` outline | `,cr` run + +### Edit + +`s`+2ch jump | `gc` comment | `cs"'` surround | `Alt+j/k` move line | `,u` undo tree | `,y` clipboard | `,*` replace word + +### Git + +`,gs` status | `,gd` diff | `,gb` blame | `,gc` commit | `,gp` push | `]x` `[x` conflict + +### Windows + +`Ctrl+hjkl` navigate (+ tmux) | `,z` maximize | `,h` `,l` buffers | `,tv` terminal | `Esc Esc` exit terminal + +### Writing + +`,zen` zen mode | `,mp` markdown preview | `,mt` table of contents + +
## LSP @@ -75,7 +111,7 @@ jk exit insert mode ,? cheat sheet :LspStatus " check what's running ``` -pylsp, gopls, rust-analyzer, clangd, marksman — no Node.js. JS/TS servers need Node. +pylsp, gopls, rust-analyzer, clangd, marksman, sqls — no Node.js. JS/TS servers need Node. ALE and vim-lsp coexist cleanly (`ale_disable_lsp=1`). ALE handles linting + formatting. vim-lsp handles everything else. @@ -83,12 +119,12 @@ ALE and vim-lsp coexist cleanly (`ale_disable_lsp=1`). ALE handles linting + for ``` ~/.vim/ -├── .vimrc thin loader +├── .vimrc thin loader (12 lines) ├── modules/ │ ├── env.vim TTY detection, truecolor │ ├── plugins.vim vim-plug + 29 plugins │ ├── core.vim settings, keymaps, performance -│ ├── ui.vim colorscheme, statusline, startify +│ ├── ui.vim solarized, statusline, startify │ ├── editing.vim easymotion, yank highlight │ ├── navigation.vim fzf, netrw, windows, terminal │ ├── lsp.vim vim-lsp, asyncomplete @@ -101,16 +137,28 @@ ALE and vim-lsp coexist cleanly (`ale_disable_lsp=1`). ALE handles linting + for └── chopsticks.tutor ``` -Each module is self-contained. Comment out `call s:load('git')` in `.vimrc` to disable git. Add `call s:load('mine')` to load your own. +Each module is self-contained. Comment out one line in `.vimrc` to disable it. Add your own with `call s:load('mine')`. ## Learn ```vim :ChopsticksLearn " interactive tutorial — 10 lessons -:Tutor " vim basics (if needed first) -,? " cheat sheet +,? " cheat sheet (every binding) ``` +## Performance + +| Metric | Value | +|--------|-------| +| Startup time | **19ms** (29 plugins loaded) | +| Lazy-loaded | 8 plugins (on command or filetype) | +| Built-in plugins skipped | 10 (gzip, tar, zip, vimball, etc.) | +| Runtime lint delay | 200ms (no thrashing during edits) | +| Large file threshold | 10MB (auto-disables syntax + undo) | +| TTY large file | 500KB (syntax disabled) | + +Measured with `vim --startuptime`. We benchmark every change. + ## Troubleshooting | Problem | Fix | @@ -119,10 +167,14 @@ Each module is self-contained. Comment out `call s:load('git')` in `.vimrc` to d | LSP not starting | `:LspInstallServer` for current filetype | | Colors wrong | `export COLORTERM=truecolor` in shell rc | | `Ctrl+s` freezes | `stty -ixon` in shell rc | -| Everything slow | Large file? Check `:echo &syntax` — auto-disabled >10MB | +| Everything slow | Large file? Auto-disabled >10MB | 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. + ## License [MIT](LICENSE)