fix: correct non-TTY vim-plug install; add real plugin count check

- _vim_run non-TTY branch: remove </dev/null (caused "Error reading
  input, exiting" before downloads finished → 0 plugins installed) and
  >/dev/null (broke async job callbacks → partial install of ~13/26).
  Now only redirects stderr; stdin inherits from caller so vim's event
  loop runs to completion.
- Add post-install verification: count ~/.vim/plugged entries and die
  if empty, replacing the unconditional "ok Plugins installed" that
  masked failures silently.
- .vimrc, install.sh, QUICKSTART.md, README.md: carry forward the full
  v1.2 rewrite (checkbox module selection, solarized palette, LSP
  stack) that accumulated in the previous session.

Tested: macOS (27 plugins, exit 0) and Arch Linux SSH (26 plugins,
exit 0). shellcheck: zero warnings.
This commit is contained in:
m1ngsama 2026-04-10 18:43:52 +08:00
parent 716e7e5808
commit 0b3f631e98
4 changed files with 1363 additions and 1887 deletions

1591
.vimrc

File diff suppressed because it is too large Load diff

View file

@ -1,63 +1,47 @@
# Quick Start
Five minutes from zero to a working Vim engineering environment.
> **New to Vim?** Read Step 0 first — it takes 2 minutes and prevents the most
> common beginner frustration. Already know how Vim modes work? [Skip to Step 1](#step-1-install).
Five minutes from zero to a working Vim environment.
---
## Step 0: Vim Basics
## Step 0: Vim Basics (2 minutes)
> **When confused, press `Esc` until things feel normal again — then keep reading.**
> **When confused, press `Esc` until things feel normal again.**
Vim is **modal**: the keyboard behaves differently depending on which mode you are in.
Most people get stuck because they try to type text while in Normal mode.
Vim is **modal** — the keyboard behaves differently depending on which mode you are in.
### The Three Modes
| Mode | Purpose | Enter | Leave |
|------|---------|-------|-------|
| **Normal** | Navigate and run commands | default on startup | — |
| **Insert** | Type text | `i` before / `a` after / `o` new line | `Esc` or `jk` |
| **Visual** | Select text | `v` char / `V` line | `Esc` |
| Mode | Purpose | How to enter | How to leave |
|------|---------|--------------|--------------|
| **Normal** | Navigate and run commands | Startup default | — (you're already here) |
| **Insert** | Type text | `i` before cursor, `a` after, `o` new line below | `Esc` or `jk` |
| **Visual** | Select text | `v` char-by-char, `V` whole lines | `Esc` |
### 4 Survival Commands
Learn these before anything else. They will get you out of every stuck situation.
### 4 commands that get you out of any jam
| Command | Action |
|---------|--------|
| `Esc` or `jk` | Exit insert/visual mode — return to Normal |
| `:q!` then `Enter` | Force quit without saving (emergency exit) |
| `Esc` or `jk` | Exit insert / visual mode → Normal |
| `:q!` then `Enter` | Force quit without saving |
| `,x` | Save and quit |
| `,w` or `Ctrl+s` | Save the file |
| `,w` or `Ctrl+s` | Save |
Once in Normal mode, press `,?` to open a cheat sheet covering everything else.
Once in Normal mode, press `,?` to open the cheat sheet.
---
## Step 1: Install
**One command — works on macOS and Linux:**
```bash
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
```
This clones the repo to `~/.vim` and runs the full installer. Interactive prompts
let you choose which optional tools to install (ripgrep, Node.js, Python tools, etc.).
The installer automatically handles missing dependencies — it will offer to install
`git`, Homebrew (macOS), or Node.js via nvm if they are not found.
**Traditional install:**
Traditional:
```bash
git clone https://github.com/m1ngsama/chopsticks.git ~/.vim
cd ~/.vim && ./install.sh
```
**Non-interactive (CI / server / scripting):**
Non-interactive / CI:
```bash
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --yes
```
@ -67,37 +51,14 @@ curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | b
## Step 2: Open Vim
```bash
vim
```
The startup screen (vim-startify) shows recent files and sessions.
Press `Ctrl+p` to find a file, or just type a path.
To open a project:
```bash
vim . # NERDTree on left, Startify on right
vim myfile # opens file directly
vim # startup dashboard (recent files + sessions)
vim . # startup dashboard, current directory listed
vim myfile # edit a specific file
```
---
## Step 3: Set Up LSP (pick your path)
### Path A: With Node.js (CoC — full LSP)
```bash
node --version # must be >= 14.14
```
Inside Vim, install language servers for your stack:
```vim
:CocInstall coc-pyright coc-tsserver coc-go coc-rust-analyzer
```
Or let `install.sh` do it — it asks during setup.
### Path B: Without Node.js (vim-lsp — no dependencies)
## Step 3: Set Up LSP
Open a source file, then run:
@ -105,26 +66,39 @@ Open a source file, then run:
:LspInstallServer
```
This auto-detects and installs the correct language server for the current filetype.
This auto-detects the filetype and installs the correct language server.
No Node.js required — vim-lsp runs on pure VimScript.
Check status:
```vim
:LspStatus
```
**Markdown LSP** (`marksman`) needs a standalone binary:
```bash
brew install marksman # macOS
sudo pacman -S marksman # Arch
# install.sh handles this automatically
```
---
## The 12 Keys That Matter
## The Keys That Matter
```
, (pause 500ms) Show all keybindings (which-key)
,? Open cheat sheet inside Vim
Esc / jk Exit insert mode → Normal (memorize this)
Ctrl+s Save (works in normal and insert mode)
Ctrl+p Fuzzy find file
Ctrl+n Toggle file tree
gd Go to definition
K Show documentation
[g / ]g Prev / next LSP diagnostic
,rn Rename symbol
,rG Search word under cursor (ripgrep)
,gs Git status
,w / ,x Save / Save+quit
,? Open cheat sheet (all bindings in one place)
Esc / jk Exit insert mode → Normal
Ctrl+s Save
Ctrl+p Fuzzy find file
,e File browser (netrw)
gd Go to definition
K Show documentation
[g / ]g Prev / next LSP diagnostic
,rn Rename symbol
,rG Search word under cursor (ripgrep)
,gs Git status
,mp Markdown live preview in browser
,w / ,x Save / Save+quit
```
---
@ -138,8 +112,8 @@ K Show documentation
| `gd` | Go to definition |
| `gy` | Go to type definition |
| `gi` | Go to implementation |
| `gr` | List all references |
| `K` | Show docs for symbol under cursor |
| `gr` | List references |
| `K` | Docs for symbol under cursor |
| `Ctrl+o` | Jump back |
| `Ctrl+i` | Jump forward |
@ -152,23 +126,35 @@ K Show documentation
| `gc` | Toggle comment (visual mode too) |
| `cs"'` | Change surrounding `"` to `'` |
| `ds(` | Delete surrounding `(` |
| `s`+2ch | EasyMotion: jump anywhere |
| `s` + 2 chars | EasyMotion: jump anywhere |
### Manage Errors
| Key | Action |
|-----|--------|
| `]g` | Jump to next diagnostic |
| `]g` | Jump to next LSP diagnostic |
| `[g` | Jump to previous diagnostic |
| `K` | Read the error message |
| `,ca` | Apply code action / auto-fix |
### Markdown
| Key | Action |
|-----|--------|
| `,mp` | Open live preview in browser |
| `,mt` | Table of contents |
| `zr` / `zm` | Unfold / fold all headings |
Formatting in the buffer is live: `**bold**` renders as bold,
headings hide their `#` markers. Raw syntax reappears when
the cursor enters that line.
### Git Workflow
```
,gs git status (stage with 's', commit with 'cc')
,gd diff current file
,gb blame current file
,gb blame
,gc commit
,gp push
,gl pull
@ -176,97 +162,36 @@ K Show documentation
---
## Language Workflows
### Python
```bash
# tools installed by install.sh; or manually:
pip install black flake8 pylint isort
```
Auto-formats with `black` + `isort` on save. Lint errors show as `X`/`!` in the sign column.
### JavaScript / TypeScript
```bash
npm install -g prettier eslint typescript
```
Auto-formats with `prettier` on save.
### Go
```bash
# tools installed by install.sh; or manually:
go install golang.org/x/tools/gopls@latest
go install golang.org/x/tools/cmd/goimports@latest
go install honnef.co/go/tools/cmd/staticcheck@latest
```
`gofmt` + `goimports` run on save automatically.
### Markdown
Install `marksman` for LSP support (completions, link checking):
```bash
brew install marksman # macOS
sudo pacman -S marksman # Arch
# or: ./install.sh (handles it automatically)
```
---
## Customize
Edit config live:
```vim
,ev " opens ~/.vimrc in Vim
,sv " reloads config without restarting
```
Per-project settings: create `.vimrc` in your project root.
```vim
" project/.vimrc
set shiftwidth=2
let g:ale_python_black_options = '--line-length=100'
```
Change color scheme in `~/.vimrc`:
```vim
colorscheme dracula " or: gruvbox, solarized, onedark
```
---
## Quick Reference Card
```
BASICS (learn these first)
BASICS
Esc / jk Exit insert mode → Normal
Ctrl+s Save (normal + insert mode)
:q! + Enter Emergency quit without saving
Ctrl+s Save
:q! + Enter Emergency quit
,? Open cheat sheet
FILES
Ctrl+n File tree toggle
Ctrl+p Fuzzy find file (git-aware)
,e File browser (netrw)
,b Search open buffers
,rg Search file contents (ripgrep)
,rG Ripgrep word under cursor
,w Save | ,q Quit | ,x Save+quit
,w Save | ,q Quit | ,x Save+quit
,wa Save all buffers
,, Switch to last file
CODE
gd Go to definition
K Show documentation
[g / ]g Prev/next LSP diagnostic
[e / ]e Prev/next ALE error
,rn Rename symbol
,ca Code action / auto-fix
,f Format selection | ,F Format whole file
gd Definition | gy Type def | gi Impl | gr References
K Show documentation
[g / ]g Prev / next LSP diagnostic
[e / ]e Prev / next ALE error
,rn Rename symbol
,ca Code action
,f Format buffer / selection
MARKDOWN
,mp Live preview | ,mt Table of contents
GIT
,gs Status | ,gd Diff | ,gb Blame
@ -275,19 +200,14 @@ GIT
WINDOWS / PANES
Ctrl+h/j/k/l Move between Vim windows or tmux panes
,h / ,l Prev / next buffer
,tv Open terminal (vertical)
,th Open terminal (horizontal)
Esc Exit terminal mode
,u Undo tree | ,tt Tag browser
,tv / ,th Terminal (vertical / horizontal)
Esc Esc Exit terminal mode
,u Undo tree
SEARCH & REPLACE
/text Search forward | ?text backward
// Search for visually selected text
,* Replace word under cursor (file-wide)
CLIPBOARD
,y / ,Y Yank / yank line to system clipboard
,p / ,P Paste from system clipboard (after / before)
SEARCH
/text Forward | ?text Backward | n next | N prev
// Search visually selected text
,* Replace word under cursor (file-wide)
```
---

566
README.md
View file

@ -1,7 +1,7 @@
# chopsticks
> A batteries-included Vim configuration for full-stack engineering.
> Tiered LSP · 14 languages · TTY-aware · Zero icon fonts · One-command install.
> Flowing vim for any machine — SSH servers included.
> Solarized · vim-lsp (no Node.js) · Markdown-first · One-command install.
[![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/)
@ -9,18 +9,11 @@
[![Release](https://img.shields.io/github/v/release/m1ngsama/chopsticks?style=flat-square&label=release&color=orange)](https://github.com/m1ngsama/chopsticks/releases)
[![Last Commit](https://img.shields.io/github/last-commit/m1ngsama/chopsticks?style=flat-square)](https://github.com/m1ngsama/chopsticks/commits/main)
[![Stars](https://img.shields.io/github/stars/m1ngsama/chopsticks?style=flat-square)](https://github.com/m1ngsama/chopsticks/stargazers)
[![Issues](https://img.shields.io/github/issues/m1ngsama/chopsticks?style=flat-square)](https://github.com/m1ngsama/chopsticks/issues)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen?style=flat-square)](https://github.com/m1ngsama/chopsticks/pulls)
[![Plugins](https://img.shields.io/badge/plugins-30%2B-blueviolet?style=flat-square)](#plugins)
[![Languages](https://img.shields.io/badge/languages-14-informational?style=flat-square)](#language-support)
```bash
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
```
> **New to Vim?** Read [Step 0 in QUICKSTART.md](QUICKSTART.md#step-0-vim-basics) first —
> a 2-minute intro to modes and the 4 commands that get you out of any jam.
---
## Contents
@ -28,14 +21,13 @@ curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | b
- [Design Principles](#design-principles)
- [Requirements](#requirements)
- [Installation](#installation)
- [LSP: Tiered Backend](#lsp-tiered-backend)
- [LSP](#lsp)
- [Key Mappings](#key-mappings)
- [Markdown](#markdown)
- [Features](#features)
- [Language Support](#language-support)
- [Plugins](#plugins)
- [Customization](#customization)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
---
@ -43,51 +35,44 @@ curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | b
| Principle | What it means |
|-----------|--------------|
| **KISS** | No icon fonts, no Nerd Font glyphs — plain ASCII everywhere |
| **Tiered LSP** | CoC (full) when Node.js is available; vim-lsp (pure VimScript) otherwise |
| **TTY-aware** | Automatically detects SSH/console environments and degrades gracefully |
| **Engineering-first** | Git workflow, persistent sessions, project-local config, large-file safety |
| **Batteries included** | `install.sh` handles vim-plug, plugins, system tools, and language servers |
| **Flowing writing** | Every plugin earns its place by reducing interruptions to thought |
| **No Node.js** | vim-lsp runs on pure VimScript — works on any machine, including SSH servers |
| **Solarized** | One palette, everywhere — vim statusline matches tmux bar exactly |
| **TTY-aware** | SSH and console environments degrade gracefully without breaking |
| **KISS** | No icon fonts, no Nerd Font glyphs — plain ASCII throughout |
---
## Requirements
| Tool | Minimum | Role |
|------|---------|------|
| Vim | **8.0+** | Required — `install.sh` installs it if missing |
| git | any | Required — `install.sh` installs it if missing |
| curl | any | Required — `install.sh` installs it if missing |
| Node.js | 14.14+ | Optional — enables CoC LSP; `install.sh` offers nvm install |
| ripgrep | any | Optional — enables `,rg` / `,rG` project search |
| fzf | any | Optional — enables `Ctrl+p` fuzzy finder |
| ctags | any | Optional — enables `,tt` tag browser |
| tmux | 1.8+ | Optional — enables seamless pane navigation |
| Tool | Role |
|------|------|
| Vim 8.0+ | Required — `install.sh` installs it if missing |
| git | Required |
| curl | Required |
| ripgrep | Recommended — enables `,rg` project search |
| fzf | Recommended — enables `Ctrl+p` fuzzy finder |
| Node.js | Optional — enables npm formatters (prettier, eslint) |
`install.sh` detects your environment and installs missing dependencies automatically.
On macOS it will offer to install Homebrew if not present. On any platform it will
offer to install Node.js via nvm if missing.
`install.sh` detects your environment and installs missing dependencies.
---
## Installation
### One command (recommended)
### One command
```bash
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash
```
This bootstrap script clones the repo to `~/.vim`, then runs the full installer.
It works correctly even when piped from curl — interactive prompts use `/dev/tty`.
For non-interactive or CI environments:
Non-interactive / CI:
```bash
curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --yes
```
### Traditional (git clone)
### Git clone
```bash
git clone https://github.com/m1ngsama/chopsticks.git ~/.vim
@ -96,77 +81,57 @@ cd ~/.vim && ./install.sh
### What the installer does
1. **Preflight** — checks network, detects OS and package manager, verifies or installs `curl`, `git`, and `vim`
2. **sudo** — authenticates once upfront; gracefully skips system packages when unavailable
3. **macOS** — offers to install Homebrew if `brew` is not found
4. **Node.js** — offers to install via nvm if not found (falls back to vim-lsp if declined)
5. **Python** — offers to install Python 3 if missing; bootstraps pip3 if only python3 is present
6. **Symlinks** — backs up any existing `~/.vimrc` with a timestamp, then symlinks `~/.vimrc → ~/.vim/.vimrc`
7. **Plugins** — installs vim-plug and runs `:PlugInstall` (with a progress notice during the black-screen period)
8. **System tools** — ripgrep, fzf, ctags, shellcheck, hadolint, marksman (verified downloads)
9. **Language tools** — npm formatters, pip formatters/linters, Go tools
10. **CoC extensions** — all language servers in one step
11. **tmux** — optionally appends vim-tmux-navigator bindings to `~/.tmux.conf`
1. Detects OS and package manager
2. Verifies or installs `curl`, `git`, `vim`
3. Backs up existing `~/.vimrc`, then symlinks `~/.vimrc → ~/.vim/.vimrc`
4. Installs vim-plug and runs `:PlugInstall`
5. Offers to install system tools (ripgrep, fzf, ctags, shellcheck, hadolint, marksman)
6. Offers to install Node.js via nvm (for npm formatters — optional)
7. Offers to install npm formatters (prettier, eslint, etc.)
8. Offers to install Python formatters/linters (black, isort, flake8, etc.)
9. Offers to install Go tools (gopls, goimports, staticcheck)
10. Offers to append vim-tmux-navigator bindings to `~/.tmux.conf`
**Supported platforms:** macOS (Homebrew), Debian/Ubuntu (apt), Arch Linux (pacman), Fedora (dnf).
### Manual
```bash
git clone https://github.com/m1ngsama/chopsticks.git ~/.vim
ln -sf ~/.vim/.vimrc ~/.vimrc
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
vim +PlugInstall +qall </dev/null
```
**Supported platforms:** macOS (Homebrew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf).
---
## LSP: Tiered Backend
## LSP
Code intelligence is provided by one of two backends, chosen automatically at startup:
Code intelligence is provided by **vim-lsp** — a pure VimScript LSP client with no
Node.js dependency. It works on any machine, including servers accessed via SSH.
| Condition | Backend | Capabilities |
|-----------|---------|-------------|
| Vim 8.0.1453+ **and** Node.js 14.14+ | **CoC** | Full LSP, snippets, extension ecosystem |
| Vim 8.0+ (no Node.js) | **vim-lsp** | LSP via language server binaries, asyncomplete |
| Any Vim | **ALE** | Async linting + auto-fix (always active, both backends) |
Both CoC and vim-lsp expose the same key mappings so switching backends is transparent.
### With Node.js (CoC)
Install language server extensions from inside Vim — or let `install.sh` do it automatically:
Install a language server for the current file:
```vim
:CocInstall coc-pyright " Python
:CocInstall coc-tsserver " JavaScript / TypeScript
:CocInstall coc-go " Go
:CocInstall coc-rust-analyzer " Rust
:CocInstall coc-json coc-yaml " JSON, YAML
:CocInstall coc-html coc-css " HTML, CSS/SCSS
:CocInstall coc-sh " Shell
:CocInstall coc-sql " SQL
```
**Markdown LSP** uses `marksman` as an external binary (not a CoC extension):
```bash
brew install marksman # macOS
sudo pacman -S marksman # Arch
# or: ./install.sh handles it automatically
```
### Without Node.js (vim-lsp)
Open a source file, then run:
```vim
:LspInstallServer " detects filetype and installs the correct server
:LspInstallServer " auto-detects filetype and installs the correct server
:LspStatus " check server status
```
Supported: Python, Go, Rust, TypeScript/JavaScript, Shell, HTML, CSS/SCSS, JSON, YAML, Markdown, SQL.
Supported languages and their servers:
| Language | Server |
|----------|--------|
| Python | pylsp / pyright |
| JavaScript / TypeScript | typescript-language-server |
| Go | gopls |
| Rust | rust-analyzer |
| C / C++ | clangd |
| Shell | bash-language-server |
| HTML | vscode-html-language-server |
| CSS / SCSS | vscode-css-language-server |
| JSON | vscode-json-language-server |
| YAML | yaml-language-server |
| Markdown | marksman |
| SQL | sqls |
**Markdown LSP** requires `marksman` as a standalone binary:
```bash
brew install marksman # macOS
sudo pacman -S marksman # Arch
# or: install.sh handles it automatically
```
---
@ -174,172 +139,138 @@ Supported: Python, Go, Rust, TypeScript/JavaScript, Shell, HTML, CSS/SCSS, JSON,
**Leader key:** `,` (comma)
Press `,` and wait 500 ms to see an interactive guide to all bindings (vim-which-key).
Press `,?` to open the built-in cheat sheet at any time.
### Survival
| Key | Action |
|-----|--------|
| `jk` | Exit insert mode → Normal (ergonomic Escape) |
| `Esc` | Exit insert / visual mode (standard) |
| `Ctrl+s` | Save file (normal and insert mode) |
| `,w` | Save file |
| `,x` | Save and quit |
| `,q` | Quit |
| `,?` | Open cheat sheet |
> **`Ctrl+s` note:** some terminals freeze on `Ctrl+s` (XON/XOFF). Add `stty -ixon`
> to your `~/.bashrc` / `~/.zshrc` to disable this permanently.
Press `,?` at any time to open the built-in cheat sheet.
### Files and Buffers
| Key | Action |
|-----|--------|
| `Ctrl+p` | Fuzzy file search — git-aware (FZF) |
| `Ctrl+n` | Toggle file tree (NERDTree) |
| `,n` | Reveal current file in NERDTree |
| `,e` | Open netrw file browser |
| `,E` | Open netrw in vertical split |
| `,b` | Search open buffers (FZF) |
| `,rg` | Project-wide search (ripgrep + FZF) |
| `,rG` | Ripgrep for word under cursor (literal match) |
| `,rt` | Search tags (FZF) |
| `,gF` | Search git-tracked files (FZF) |
| `,l` | Next buffer |
| `,h` | Previous buffer |
| `,bd` | Close current buffer (preserves window layout) |
| `,rG` | Ripgrep for word under cursor |
| `,,` | Switch to last file |
| `,l` / `,h` | Next / previous buffer |
| `,bd` | Close current buffer (preserves window layout) |
### Windows, Tabs, and tmux
| Key | Action |
|-----|--------|
| `Ctrl+h/j/k/l` | Navigate between Vim splits **and** tmux panes |
| `,=` | Increase window height |
| `,-` | Decrease window height |
| `,+` | Increase window width |
| `,_` | Decrease window width |
| `,tn` | New tab |
| `,tc` | Close tab |
| `,tl` | Toggle to last tab |
| `,tv` | Open terminal (vertical split) |
| `,th` | Open terminal (horizontal split) |
| `Esc Esc` | Exit terminal mode |
### Code Intelligence (CoC / vim-lsp)
### Code Intelligence (vim-lsp)
| Key | Action |
|-----|--------|
| `gd` | Go to definition |
| `gy` | Go to type definition |
| `gi` | Go to implementation |
| `gr` | Show all references |
| `gr` | Show references |
| `K` | Hover documentation |
| `[g` | Previous diagnostic |
| `]g` | Next diagnostic |
| `[g` / `]g` | Previous / next LSP diagnostic |
| `[e` / `]e` | Previous / next ALE error |
| `,rn` | Rename symbol |
| `,f` | Format selection |
| `,F` | Format whole file |
| `,ca` | Code action (cursor position) |
| `,f` | Format buffer / selection |
| `,ca` | Code action |
| `,o` | File outline (symbols) |
| `,ws` | Workspace symbols |
| `,cD` | Diagnostics list |
| `,qf` | Quick-fix current line (CoC) |
| `Tab` | Next completion item |
| `Shift+Tab` | Previous completion item |
| `Tab` / `Shift+Tab` | Navigate completion popup |
| `Enter` | Confirm completion |
Text objects (CoC): `if`/`af` (function inner/around), `ic`/`ac` (class inner/around).
### Linting (ALE — always active)
### Markdown
| Key | Action |
|-----|--------|
| `[e` | Previous error / warning |
| `]e` | Next error / warning |
| `,aD` | Show error detail |
| `,ad` | Full diagnostics list |
Signs in the gutter: `X` = error, `!` = warning.
| `,mp` | Open live preview in browser (previm) |
| `,mt` | Table of contents |
| `zr` / `zm` | Unfold / fold all headings |
### Git (vim-fugitive)
| Key | Action |
|-----|--------|
| `,gs` | Git status (stage with `s`, commit with `cc`) |
| `,gs` | Git status |
| `,gc` | Git commit |
| `,gp` | Git push |
| `,gl` | Git pull |
| `,gd` | Git diff |
| `,gb` | Git blame |
### Search and Replace
| Key | Action |
|-----|--------|
| `n` / `N` | Next / previous match (cursor centered) |
| `//` | Search for visually selected text |
| `,*` | Search and replace word under cursor (file-wide) |
| `,rG` | Ripgrep word under cursor across project |
| `,<CR>` | Clear search highlight |
### Clipboard
| Key | Action |
|-----|--------|
| `,y` | Yank to system clipboard |
| `,Y` | Yank line to system clipboard |
| `,p` | Paste from system clipboard (after cursor) |
| `,P` | Paste from system clipboard (before cursor) |
### Editing and Navigation
### Editing
| Key | Action |
|-----|--------|
| `s` + 2 chars | EasyMotion — jump anywhere on screen |
| `gc` | Toggle comment (visual mode too) |
| `Space` | Toggle code fold |
| `Y` | Yank to end of line (consistent with `D`, `C`) |
| `Ctrl+d/u` | Half-page scroll (cursor stays centered) |
| `>` / `<` | Indent / dedent (keeps visual selection) |
| `Alt+j/k` | Move current line down / up |
| `0` | Jump to first non-blank character |
| `[q` / `]q` | Previous / next quickfix entry (vim-unimpaired) |
| `,u` | Toggle undo tree (visual branch history) |
| `,tt` | Toggle tagbar (code structure) |
| `F2` | Toggle paste mode |
| `F3` | Toggle absolute line numbers |
| `F4` | Toggle relative line numbers |
| `Y` | Yank to end of line |
| `Ctrl+d` / `Ctrl+u` | Half-page scroll, cursor centred |
| `Alt+j` / `Alt+k` | Move line down / up |
| `,u` | Undo tree (visual branch history) |
### Config and Utilities
### Survival
| Key | Action |
|-----|--------|
| `,ev` | Edit `~/.vimrc` |
| `,sv` | Reload `~/.vimrc` |
| `,wa` | Save all open buffers |
| `,wd` | Change working directory to current file's location |
| `,cp` | Copy absolute file path to clipboard |
| `,cf` | Copy filename to clipboard |
| `,qo` / `,qc` | Open / close quickfix list |
| `jk` | Exit insert mode |
| `Esc` | Exit insert / visual mode |
| `Ctrl+s` | Save |
| `,w` | Save |
| `,x` | Save and quit |
| `,q` | Quit |
| `,?` | Open cheat sheet |
### Windows, Tabs, tmux
| Key | Action |
|-----|--------|
| `Ctrl+h/j/k/l` | Navigate Vim splits **and** tmux panes |
| `,tv` / `,th` | Open terminal (vertical / horizontal split) |
| `Esc Esc` | Exit terminal mode |
| `,tn` / `,tc` | New tab / close tab |
| `,tl` | Toggle to last tab |
---
## Markdown
chopsticks treats Markdown as a first-class language.
### In-buffer rendering (concealment)
`vim-markdown` hides syntax markers and renders formatting inline:
- `**bold**` displays as bold text
- `# Heading` hides the `#` characters
- Tables align automatically
The raw syntax reappears when the cursor enters that line.
### Live browser preview (previm)
```vim
,mp " open rendered preview in browser — updates on every save
```
No Node.js required. Uses `open` (macOS) or `xdg-open` (Linux).
### Table of contents
```vim
,mt " open TOC in a quickfix window — press Enter to jump to heading
```
---
## Features
### Startup Dashboard
### Statusline
Running `vim` (no arguments) opens a full-screen Startify dashboard showing recent
files, sessions, and bookmarks. Running `vim .` opens NERDTree on the left with
the dashboard on the right.
A native, hand-written statusline using the Solarized palette:
### Keybinding Guide
```
N ~/.vimrc [+] main [vim] 42:7 68%
```
Press `,` and pause for 500 ms. A popup (vim-which-key) lists all leader bindings
organized into groups. No need to memorize everything upfront.
### Built-in Cheat Sheet
Press `,?` to open an inline reference covering modes, survival commands, search,
code intelligence, git, and clipboard — without leaving Vim.
- Mode block changes colour by mode (Normal=yellow, Insert=blue, Visual=magenta, Replace=red)
- Git branch via vim-fugitive
- Background matches tmux status bar for a seamless bottom band
### Session Management
@ -348,29 +279,23 @@ code intelligence, git, and clipboard — without leaving Vim.
:Obsess! " stop tracking
```
Sessions are stored in `~/.vim/sessions/` and automatically restored by vim-prosession
the next time you open Vim in the same directory.
Sessions auto-restore when you open Vim in the same directory.
### Project-Local Config
Drop a `.vimrc` in any project root to override settings for that project:
Drop a `.vimrc` in any project root to override settings:
```vim
" project/.vimrc
" my-project/.vimrc
set shiftwidth=2
let g:ale_python_black_options = '--line-length=100'
```
Loaded automatically via `set exrc`. Restricted to safe options via `set secure`.
### tmux Integration
`Ctrl+h/j/k/l` navigates seamlessly between Vim splits and tmux panes — no prefix
key, no mode switch.
`Ctrl+h/j/k/l` navigates seamlessly between Vim splits and tmux panes.
**Vim side:** handled by vim-tmux-navigator (installed automatically).
**tmux side:** add to `~/.tmux.conf` (or let `install.sh` append it):
Add to `~/.tmux.conf` (or let `install.sh` append it):
```tmux
is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\S+\/)?g?(view|n?vim?x?)(diff)?$'"
@ -380,123 +305,79 @@ 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'
```
Then reload: `tmux source-file ~/.tmux.conf`
### TTY / SSH Support
> **Note:** the `C-l` binding replaces the terminal's screen-clear shortcut inside
> tmux. To restore it, add `bind C-l send-keys 'C-l'` — then use `prefix + C-l`.
Detected automatically when `$TERM` is `linux` or `screen`. In TTY mode:
- True colour and cursorline disabled
- FZF preview windows disabled
- IndentLine guides disabled
- Simplified statusline (no colour)
- Syntax column limit reduced to 120 characters
### Large File Handling
Files over 10 MB automatically disable syntax highlighting, undo history, and
linting to prevent Vim from stalling.
### TTY / Console Support
Detected automatically when `$TERM` is `linux` or `screen`. In TTY mode:
- True color and cursorline disabled
- Powerline separators replaced with plain ASCII
- FZF preview windows disabled
- IndentLine guides disabled
- Syntax column limit reduced to 120 characters
- Simpler built-in status line used instead of airline
---
## Language Support
| Language | Indent | Formatter | Linter | LSP |
|----------|--------|-----------|--------|-----|
| Python | 4 sp | black, isort | flake8, pylint | coc-pyright |
| JavaScript | 2 sp | prettier | eslint | coc-tsserver |
| TypeScript | 2 sp | prettier | eslint, tsserver | coc-tsserver |
| Go | tab | gofmt, goimports | staticcheck | coc-go |
| Rust | 4 sp | rustfmt | cargo | coc-rust-analyzer |
| Shell | 2 sp | — | shellcheck | coc-sh |
| YAML | 2 sp | prettier | yamllint | coc-yaml |
| HTML | 2 sp | prettier | — | coc-html |
| CSS / SCSS | 2 sp | prettier | stylelint | coc-css |
| Less | 2 sp | prettier | — | — |
| JSON | 2 sp | prettier | — | coc-json |
| Markdown | 2 sp | prettier | markdownlint | marksman |
| SQL | 4 sp | sqlfluff | sqlfluff | — |
| Dockerfile | 2 sp | — | hadolint | — |
`install.sh` installs all formatters and linters automatically.
ALE runs them asynchronously; format-on-save is active for all supported languages.
linting to prevent stalling.
---
## Plugins
### Navigation
- **NERDTree** — file tree explorer
- **fzf + fzf.vim** — fuzzy finder for files, buffers, tags, and ripgrep
- **fzf + fzf.vim** — fuzzy finder for files, buffers, tags, ripgrep
### Git
- **vim-fugitive** — full Git integration inside Vim
- **vim-fugitive** — full Git integration
- **vim-gitgutter** — diff signs in the sign column
### LSP and Completion
- **coc.nvim** — full LSP + completion via Node.js (recommended)
- **vim-lsp** — pure VimScript LSP client (Node.js-free fallback)
- **vim-lsp-settings** — auto-configures language servers for vim-lsp
- **asyncomplete.vim** — async completion engine (vim-lsp mode)
- **vim-lsp** — pure VimScript LSP client
- **vim-lsp-settings** — auto-configures language servers
- **asyncomplete.vim** — async completion engine
- **asyncomplete-lsp.vim** — LSP completion source
### Linting
- **ALE** — asynchronous lint engine, always active regardless of LSP backend
### Linting and Formatting
- **ALE** — async linting and format-on-save
### UI
- **vim-airline** — status line and tabline
- **vim-startify** — startup dashboard with session management
- **vim-which-key** — keybinding hint popup on leader pause
- **indentLine** — indent guide lines (non-TTY only)
- **undotree** — visual undo branch history
- **tagbar** — code structure sidebar via ctags
### Markdown
- **vim-markdown** — folding, concealment, table alignment
- **previm** — live browser preview
### Language Syntax
- **vim-javascript** — enhanced JS syntax
- **yats.vim** — TypeScript syntax
- **vim-go** — Go syntax and tooling
### Editing
- **vim-surround** — change surrounding quotes, brackets, and tags
- **vim-surround** — change/delete/add surroundings
- **vim-commentary**`gc` to toggle comments
- **auto-pairs** — auto-close brackets and quotes
- **vim-easymotion** — jump anywhere on screen with 2 keystrokes (`s`)
- **vim-unimpaired** — bracket shortcut pairs (`[q`/`]q`, etc.)
- **vim-repeat** — repeat plugin maps with `.`
- **vim-unimpaired** — bracket shortcut pairs
- **targets.vim** — additional text objects
- **vim-snippets** — snippet library (used with CoC)
- **vim-tmux-navigator** — seamless `Ctrl+h/j/k/l` across Vim and tmux
- **auto-pairs** — auto-close brackets and quotes
- **vim-easymotion** — `s` + 2 chars to jump anywhere
### Language Packs
- **vim-polyglot** — syntax for 100+ languages
- **vim-go** — Go syntax and tooling (LSP handled by coc-go)
### UI
- **vim-colors-solarized** — color scheme
- **undotree** — visual undo branch history
- **vim-startify** — startup dashboard and session list
- **indentLine** — indent guides (non-TTY)
### Session
- **vim-obsession** — continuous session saving
- **vim-prosession** — project-level session management
### Color Schemes
- **gruvbox** (default), **dracula**, **solarized**, **onedark**
### Session and Navigation
- **vim-obsession** — session tracking
- **vim-tmux-navigator** — seamless Vim/tmux pane navigation
---
## Customization
### Change the color scheme
In `~/.vimrc`, find and update the `colorscheme` line:
```vim
colorscheme dracula " options: gruvbox, solarized, onedark
```
True color is enabled automatically when `$COLORTERM=truecolor`. Falls back to
256-color, then 16-color in TTY.
### Per-project overrides
Create `.vimrc` in your project root. Anything placed here overrides the global
config for that directory:
Create `.vimrc` in your project root:
```vim
" my-project/.vimrc
" project/.vimrc
set shiftwidth=2
let g:ale_python_black_options = '--line-length=120'
```
@ -512,100 +393,41 @@ Edit `~/.vimrc` directly (`,ev` opens it from inside Vim). Reload with `,sv`.
**Plugins not loading**
```vim
:PlugInstall " install any missing plugins
:PlugInstall " install missing plugins
:PlugUpdate " update all plugins
```
**CoC not working**
```bash
node --version # must be 14.14+
```
Inside Vim: `:CocInfo` for diagnostics, `:CocInstall <extension>` to add a language server.
**vim-lsp server not starting**
**LSP server not starting**
```vim
:LspInstallServer " install the correct server for the current filetype
:LspInstallServer " install server for current filetype
:LspStatus " check server status
```
**Markdown LSP not starting**
**Markdown preview not opening**
`marksman` must be installed as a standalone binary (not a CoC extension):
```bash
brew install marksman # macOS
sudo pacman -S marksman # Arch
# or: ./install.sh handles it automatically
```
`previm` uses `open` (macOS) or `xdg-open` (Linux). Make sure a browser is
set as the default handler for HTML files.
**Colors look wrong**
```bash
export TERM=xterm-256color # add to ~/.bashrc or ~/.zshrc
export TERM=xterm-256color # add to ~/.bashrc or ~/.zshrc
export COLORTERM=truecolor # for true colour
```
For true color: `export COLORTERM=truecolor`.
**ALE linters not found**
```bash
which flake8 black prettier eslint # verify tools are on PATH
which flake8 black prettier eslint # verify tools are on PATH
```
If tools were installed with `pip install --user` or `npm install -g`, make sure
the respective bin directories are on `$PATH`.
**`Ctrl+s` freezes the terminal**
Add `stty -ixon` to your `~/.bashrc`, `~/.zshrc`, or `~/.config/fish/config.fish`.
This disables XON/XOFF flow control permanently.
---
## Contributing
Bug reports and pull requests are welcome. Please follow these guidelines:
### Reporting a bug
1. Search [existing issues](https://github.com/m1ngsama/chopsticks/issues) before opening a new one.
2. Include your Vim version (`vim --version`), OS, and a minimal reproduction.
3. If the bug is plugin-specific, check whether it reproduces with a minimal config
(`vim -u NONE`) or only with chopsticks loaded.
### Proposing a change
1. Open an issue first to discuss the change, especially for non-trivial additions.
2. Keep the scope focused — one feature or fix per PR.
3. Follow existing conventions: augroups for autocmds, TTY guards for visual features,
conditional plugin loading where appropriate.
4. Update `CHANGELOG.md` with a summary of the change.
### Scope
Chopsticks is an opinionated configuration. Changes should align with the design
principles above — in particular, KISS (no icon fonts, minimal dependencies) and
TTY-compatibility. Neovim-only features and Lua configs are out of scope.
---
## Acknowledgements
Inspired by [amix/vimrc](https://github.com/amix/vimrc).
Built with [vim-plug](https://github.com/junegunn/vim-plug),
[coc.nvim](https://github.com/neoclide/coc.nvim),
[vim-lsp](https://github.com/prabirshrestha/vim-lsp),
and the broader Vim plugin community.
---
## Changelog
See [CHANGELOG.md](CHANGELOG.md).
## License
[MIT](LICENSE) © m1ng

File diff suppressed because it is too large Load diff