feat: ergonomics overhaul, tmux integration, and beginner onboarding (v1.1.0)

Keybindings:
- Add jk → Esc in insert mode (ergonomic escape)
- Add Ctrl+s save in normal and insert mode
- Add // visual search (very-nomagic escaped)
- Add <leader>p/P clipboard paste
- Add <leader>rG ripgrep word under cursor (-F literal)
- Add <leader>u / <leader>tt as leader aliases for F5/F8
- Fix ALE [e/]e navigation direction (was reversed)
- Remove dead <C-h/j/k/l> maps (owned by vim-tmux-navigator)
- Remove <leader>pp (duplicate of F2, caused 500ms delay on <leader>p)

Plugins:
- Add vim-tmux-navigator for seamless Vim/tmux pane navigation
- Fix <leader>rG: pass -F so regex metacharacters don't corrupt matches
- Fix LargeFileSettings: disable ALE for files >10MB

In-Vim UX:
- Add ,? cheat sheet (read-only buffer, q to close)
- ALE lint triggers: normal/enter/insert-leave now active

install.sh:
- Add tmux.conf auto-configuration step with C-l warning
- Add post-install survival guide for first-time Vim users

Docs:
- README: full badge row (release, stars, issues, last-commit, PRs, plugins, languages)
- README: Contributing section with bug/PR guidelines
- QUICKSTART: Step 0 — Vim modes and 4 survival commands for beginners
- CHANGELOG: v1.1.0 entry
This commit is contained in:
m1ngsama 2026-04-09 12:20:10 +08:00
parent 9442aa0499
commit 23ad2e5b7a
5 changed files with 638 additions and 243 deletions

131
.vimrc
View file

@ -207,6 +207,7 @@ Plug 'dhruvasagar/vim-prosession' " Better session management
Plug 'tpope/vim-unimpaired' " Handy bracket mappings Plug 'tpope/vim-unimpaired' " Handy bracket mappings
Plug 'wellle/targets.vim' " Additional text objects Plug 'wellle/targets.vim' " Additional text objects
Plug 'honza/vim-snippets' " Snippet collection Plug 'honza/vim-snippets' " Snippet collection
Plug 'christoomey/vim-tmux-navigator' " Seamless vim/tmux pane navigation
" ===== Native LSP (vim-lsp: works without Node.js, Vim 8.0+ only) ===== " ===== Native LSP (vim-lsp: works without Node.js, Vim 8.0+ only) =====
" Used as fallback when CoC/Node.js is unavailable " Used as fallback when CoC/Node.js is unavailable
@ -323,11 +324,8 @@ nmap <leader>x :x<cr>
" Disable highlight when <leader><cr> is pressed " Disable highlight when <leader><cr> is pressed
map <silent> <leader><cr> :noh<cr> map <silent> <leader><cr> :noh<cr>
" Smart way to move between windows " Window navigation — owned by vim-tmux-navigator plugin (Ctrl+h/j/k/l works
map <C-j> <C-W>j " seamlessly across Vim splits and tmux panes; no manual maps needed here)
map <C-k> <C-W>k
map <C-h> <C-W>h
map <C-l> <C-W>l
" Close the current buffer (Bclose preserves window layout) " Close the current buffer (Bclose preserves window layout)
map <leader>bd :Bclose<cr> map <leader>bd :Bclose<cr>
@ -398,6 +396,9 @@ nnoremap Y y$
" Disable accidental Ex mode " Disable accidental Ex mode
nnoremap Q <nop> nnoremap Q <nop>
" Exit insert mode without reaching for Escape (community standard)
inoremap jk <Esc>
" Keep visual selection after indent " Keep visual selection after indent
vnoremap < <gv vnoremap < <gv
vnoremap > >gv vnoremap > >gv
@ -406,15 +407,25 @@ vnoremap > >gv
nnoremap n nzzzv nnoremap n nzzzv
nnoremap N Nzzzv nnoremap N Nzzzv
" Search for visually selected text with // (hit // in visual mode)
vnoremap // y/\V<C-r>=escape(@",'/\')<CR><CR>
" <C-s> to save in normal and insert mode
" (for terminals: add 'stty -ixon' to your shell rc to disable XON/XOFF)
nnoremap <silent> <C-s> :w<CR>
inoremap <silent> <C-s> <Esc>:w<CR>a
" Center cursor after half-page scroll " Center cursor after half-page scroll
nnoremap <C-d> <C-d>zz nnoremap <C-d> <C-d>zz
nnoremap <C-u> <C-u>zz nnoremap <C-u> <C-u>zz
" System clipboard yank (conditional: requires clipboard provider) " System clipboard yank/paste (conditional: requires clipboard provider)
if has('clipboard') if has('clipboard')
nnoremap <leader>y "+y nnoremap <leader>y "+y
vnoremap <leader>y "+y vnoremap <leader>y "+y
nnoremap <leader>Y "+Y nnoremap <leader>Y "+Y
nnoremap <leader>p "+p
nnoremap <leader>P "+P
endif endif
" Quickfix list shortcuts ([q/]q from vim-unimpaired handles navigation) " Quickfix list shortcuts ([q/]q from vim-unimpaired handles navigation)
@ -485,6 +496,7 @@ endfunction
map <C-p> :call <SID>SmartFiles()<CR> map <C-p> :call <SID>SmartFiles()<CR>
map <leader>b :Buffers<CR> map <leader>b :Buffers<CR>
map <leader>rg :Rg<CR> map <leader>rg :Rg<CR>
map <leader>rG :Rg -F <C-r><C-w><CR>
map <leader>rt :Tags<CR> map <leader>rt :Tags<CR>
map <leader>gF :GFiles<CR> map <leader>gF :GFiles<CR>
@ -583,9 +595,9 @@ let g:ale_fixers = {
let g:ale_fix_on_save = !g:use_vimlsp let g:ale_fix_on_save = !g:use_vimlsp
let g:ale_sign_error = 'X' let g:ale_sign_error = 'X'
let g:ale_sign_warning = '!' let g:ale_sign_warning = '!'
let g:ale_lint_on_text_changed = 'never' let g:ale_lint_on_text_changed = 'normal'
let g:ale_lint_on_insert_leave = 0 let g:ale_lint_on_insert_leave = 1
let g:ale_lint_on_enter = 0 let g:ale_lint_on_enter = 1
" --- vim-go: disable built-in LSP/gopls — CoC (coc-go) handles all Go intelligence --- " --- vim-go: disable built-in LSP/gopls — CoC (coc-go) handles all Go intelligence ---
" vim-go's gopls conflicts with coc-go and causes E495 errors on startup " vim-go's gopls conflicts with coc-go and causes E495 errors on startup
@ -602,16 +614,18 @@ let g:go_highlight_fields = 1
let g:go_highlight_functions = 1 let g:go_highlight_functions = 1
let g:go_highlight_function_calls = 1 let g:go_highlight_function_calls = 1
" Navigate between errors: [e/]e (unimpaired style), <leader>aD for detail " Navigate between errors: [e/]e (unimpaired convention: [ = prev, ] = next)
nmap <silent> [e :ALENext<cr> nmap <silent> [e :ALEPrevious<cr>
nmap <silent> ]e :ALEPrevious<cr> nmap <silent> ]e :ALENext<cr>
nmap <silent> <leader>aD :ALEDetail<cr> nmap <silent> <leader>aD :ALEDetail<cr>
" --- Tagbar --- " --- Tagbar ---
nmap <F8> :TagbarToggle<CR> nmap <F8> :TagbarToggle<CR>
nmap <leader>tt :TagbarToggle<CR>
" --- UndoTree --- " --- UndoTree ---
nnoremap <F5> :UndotreeToggle<CR> nnoremap <F5> :UndotreeToggle<CR>
nnoremap <leader>u :UndotreeToggle<CR>
" --- EasyMotion --- " --- EasyMotion ---
let g:EasyMotion_do_mapping = 0 " Disable default mappings let g:EasyMotion_do_mapping = 0 " Disable default mappings
@ -929,9 +943,6 @@ function! ToggleNumber()
endif endif
endfunc endfunc
" Toggle paste mode
map <leader>pp :setlocal paste!<cr>
" ============================================================================ " ============================================================================
" => Performance Optimization " => Performance Optimization
" ============================================================================ " ============================================================================
@ -1020,6 +1031,85 @@ augroup BWCCreateDir
autocmd BufWritePre * if !empty(expand('<afile>')) | call s:MkNonExDir(expand('<afile>'), +expand('<abuf>')) | endif autocmd BufWritePre * if !empty(expand('<afile>')) | call s:MkNonExDir(expand('<afile>'), +expand('<abuf>')) | endif
augroup END augroup END
" In-Vim quick reference cheat sheet — ,? opens it, q closes it
function! s:CheatSheet() abort
let l:name = '__ChopsticksCheatSheet__'
let l:winnr = bufwinnr(l:name)
if l:winnr > 0
execute l:winnr . 'wincmd w'
return
endif
execute 'botright new ' . l:name
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile
call setline(1, [
\ '=== chopsticks — Quick Reference ===',
\ '',
\ 'MODES (Vim is modal — the most important concept)',
\ ' Normal Default state. Navigate and run commands.',
\ ' Insert Type text. Enter: i/a/o Leave: Esc or jk',
\ ' Visual Select text. Enter: v/V Leave: Esc',
\ '',
\ 'SURVIVAL (learn these 4 first)',
\ ' Esc / jk Exit insert or visual mode — back to Normal',
\ ' :q! + Enter Quit without saving (emergency exit)',
\ ' ,x Save and quit',
\ ' ,w Save file | Ctrl+s Save (normal + insert)',
\ '',
\ 'NAVIGATION',
\ ' h j k l Left / Down / Up / Right',
\ ' Ctrl+p Fuzzy find file | Ctrl+n File tree',
\ ' Ctrl+o/i Jump back / forward in history',
\ ' ,, Switch to last file',
\ '',
\ 'SEARCH',
\ ' /text Search forward | n next | N prev',
\ ' // Search for visually selected text',
\ ' ,rg Search project contents (ripgrep)',
\ ' ,rG Ripgrep word under cursor',
\ ' ,* Replace word under cursor (file-wide)',
\ '',
\ 'CODE INTELLIGENCE',
\ ' gd Go to definition',
\ ' K Hover documentation',
\ ' [g / ]g Prev / next diagnostic (LSP)',
\ ' [e / ]e Prev / next ALE error',
\ ' ,ca Code action / auto-fix',
\ ' ,rn Rename symbol',
\ ' ,f Format selection | ,F Format whole file',
\ '',
\ 'EDITING',
\ ' i / a / o Insert before / after / on new line',
\ ' gc Toggle comment (works in visual too)',
\ ' u / Ctrl+r Undo / Redo',
\ ' ,p / ,P Paste from system clipboard',
\ ' ,y / ,Y Yank / line-yank to system clipboard',
\ ' s + 2 chars EasyMotion jump anywhere on screen',
\ '',
\ 'GIT',
\ ' ,gs Git status | ,gd Diff | ,gb Blame',
\ ' ,gc Commit | ,gp Push | ,gl Pull',
\ '',
\ 'WINDOWS / PANES',
\ ' Ctrl+h/j/k/l Move between Vim windows or tmux panes',
\ ' ,h / ,l Prev / next buffer',
\ ' ,tv / ,th Open terminal (vertical / horizontal)',
\ '',
\ 'TOOLS',
\ ' ,u Undo tree (visual history)',
\ ' ,tt Tagbar (code structure)',
\ ' ,o File outline (LSP symbols)',
\ '',
\ 'TIP: When confused, press Esc. Then press , and wait 500ms',
\ ' for an interactive guide to ALL keybindings.',
\ ' Re-open this sheet with ,?',
\ '',
\ '(press q to close)',
\ ])
setlocal nomodifiable readonly
nnoremap <buffer> <silent> q :bd<CR>
endfunction
nnoremap <silent> <leader>? :call <SID>CheatSheet()<CR>
" ============================================================================ " ============================================================================
" => Debugging Helpers " => Debugging Helpers
" ============================================================================ " ============================================================================
@ -1082,7 +1172,8 @@ function! LargeFileSettings()
setlocal eventignore+=FileType setlocal eventignore+=FileType
setlocal noswapfile setlocal noswapfile
setlocal syntax=OFF setlocal syntax=OFF
echo "Large file (>10MB): syntax and undo disabled for performance." let b:ale_enabled = 0
echo "Large file (>10MB): syntax, undo, and linting disabled for performance."
endfunction endfunction
" ============================================================================ " ============================================================================
@ -1148,6 +1239,10 @@ if exists('g:plugs["vim-which-key"]')
let g:which_key_map[','] = 'last-file' let g:which_key_map[','] = 'last-file'
let g:which_key_map['y'] = 'clipboard-yank' let g:which_key_map['y'] = 'clipboard-yank'
let g:which_key_map['Y'] = 'clipboard-yank-line' let g:which_key_map['Y'] = 'clipboard-yank-line'
let g:which_key_map['p'] = 'clipboard-paste-after'
let g:which_key_map['P'] = 'clipboard-paste-before'
let g:which_key_map['u'] = 'undotree-toggle'
let g:which_key_map['?'] = 'cheat-sheet'
" [a]LE lint group ([e/]e navigate; <leader>aD for detail; <leader>ad for diagnostics) " [a]LE lint group ([e/]e navigate; <leader>aD for detail; <leader>ad for diagnostics)
let g:which_key_map['a'] = { let g:which_key_map['a'] = {
@ -1200,6 +1295,7 @@ if exists('g:plugs["vim-which-key"]')
\ 'name': '+search/refactor', \ 'name': '+search/refactor',
\ 'n': 'rename', \ 'n': 'rename',
\ 'g': 'ripgrep', \ 'g': 'ripgrep',
\ 'G': 'ripgrep-word-under-cursor',
\ 't': 'tags-search', \ 't': 'tags-search',
\ } \ }
@ -1218,7 +1314,7 @@ if exists('g:plugs["vim-which-key"]')
" [t]ab / [t]erminal group " [t]ab / [t]erminal group
let g:which_key_map['t'] = { let g:which_key_map['t'] = {
\ 'name': '+tab/terminal', \ 'name': '+tab/terminal/tagbar',
\ 'n': 'new-tab', \ 'n': 'new-tab',
\ 'o': 'tab-only', \ 'o': 'tab-only',
\ 'c': 'close-tab', \ 'c': 'close-tab',
@ -1227,6 +1323,7 @@ if exists('g:plugs["vim-which-key"]')
\ 'e': 'edit-in-tab', \ 'e': 'edit-in-tab',
\ 'v': 'terminal-vertical', \ 'v': 'terminal-vertical',
\ 'h': 'terminal-horizontal', \ 'h': 'terminal-horizontal',
\ 't': 'tagbar-toggle',
\ } \ }
" [w]orkspace / [w]indow / save group (also: <leader>w = fast save) " [w]orkspace / [w]indow / save group (also: <leader>w = fast save)

View file

@ -4,6 +4,54 @@ All notable changes to chopsticks are documented here.
--- ---
## [1.1.0] - 2026-04-09
Ergonomics and automation overhaul: community-standard keybindings, seamless
tmux integration, an in-Vim cheat sheet, a beginner onboarding section, and
several correctness fixes from a systematic review.
### Added
- **`jk``Esc`** in insert mode — ergonomic escape without reaching for the key
- **`Ctrl+s` save** in normal and insert mode (add `stty -ixon` to shell rc to enable
in terminals that use XON/XOFF flow control)
- **`//` visual search** — search for visually selected text using `\V` very-nomagic escaping
- **`<leader>p` / `<leader>P`** — paste from system clipboard after/before cursor
- **`<leader>rG`** — ripgrep word under cursor with `-F` (literal, not regex)
- **`<leader>u`** — leader-key alias for UndoTree (complements `F5`)
- **`<leader>tt`** — leader-key alias for Tagbar (complements `F8`)
- **`,?` in-Vim cheat sheet** — opens a read-only buffer covering modes, survival
commands, search, code intelligence, git, and clipboard; press `q` to close
- **vim-tmux-navigator** plugin — `Ctrl+h/j/k/l` navigates seamlessly across Vim
splits and tmux panes without a prefix key
- **`install.sh` tmux step** — detects tmux and optionally appends the four
navigator `bind-key` lines to `~/.tmux.conf`; warns about `C-l`/screen-clear tradeoff
- **`install.sh` survival guide** — post-install output now shows the 4 essential
commands for first-time Vim users, plus the `stty -ixon` advisory
- **QUICKSTART.md Step 0** — new first section explaining Vim modes (Normal/Insert/Visual)
and 4 survival commands; makes the guide usable by users who have never opened Vim
- **`let b:ale_enabled = 0`** in `LargeFileSettings()` — ALE no longer spawns
linter subprocesses for files over 10 MB
### Changed
- **ALE lint triggers**`ale_lint_on_text_changed` changed from `'never'` to `'normal'`;
`ale_lint_on_insert_leave` and `ale_lint_on_enter` changed from `0` to `1` — diagnostics
now refresh on buffer enter and after edits settle in normal mode
- **`<C-h/j/k/l>` manual maps removed** — vim-tmux-navigator owns these keys at
plugin load time; the previous hand-rolled `<C-W>` maps were unreachable dead code
- **`<leader>pp` paste-mode toggle removed** — functionally identical to the existing
`F2` pastetoggle; its presence caused a 500 ms delay on every `<leader>p` paste
### Fixed
- **ALE navigation direction reversed**`[e` now correctly calls `ALEPrevious`
and `]e` calls `ALENext`, matching the vim-unimpaired `[`/`]` convention
- **`<leader>rG` regex metacharacter bug** — without `-F`, characters like `.` `*`
`(` in the cursor word were treated as regex, producing incorrect matches
---
## [1.0.0] - 2026-03-29 ## [1.0.0] - 2026-03-29
First stable release. Full-stack engineering environment out of the box — automatic First stable release. Full-stack engineering environment out of the box — automatic

View file

@ -2,6 +2,39 @@
Five minutes from zero to a working Vim engineering environment. 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).
---
## Step 0: Vim Basics
> **When confused, press `Esc` until things feel normal again — then keep reading.**
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.
### The Three Modes
| 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.
| Command | Action |
|---------|--------|
| `Esc` or `jk` | Exit insert/visual mode — return to Normal |
| `:q!` then `Enter` | Force quit without saving (emergency exit) |
| `,x` | Save and quit |
| `,w` or `Ctrl+s` | Save the file |
Once in Normal mode, press `,?` to open a cheat sheet covering everything else.
--- ---
## Step 1: Install ## Step 1: Install
@ -66,19 +99,22 @@ This auto-detects and installs the correct language server for the current filet
--- ---
## The 10 Keys That Matter ## The 12 Keys That Matter
``` ```
, (pause 500ms) Show all shortcuts , (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+p Fuzzy find file
Ctrl+n Toggle file tree Ctrl+n Toggle file tree
gd Go to definition gd Go to definition
K Show documentation K Show documentation
[g / ]g Prev / next diagnostic [g / ]g Prev / next LSP diagnostic
,rn Rename symbol ,rn Rename symbol
,rg Search project contents ,rG Search word under cursor (ripgrep)
,gs Git status ,gs Git status
,w / ,q Save / Quit ,w / ,x Save / Save+quit
``` ```
--- ---
@ -197,38 +233,51 @@ colorscheme dracula " or: gruvbox, solarized, onedark
## Quick Reference Card ## Quick Reference Card
``` ```
BASICS (learn these first)
Esc / jk Exit insert mode → Normal
Ctrl+s Save (normal + insert mode)
:q! + Enter Emergency quit without saving
,? Open cheat sheet
FILES FILES
Ctrl+n File tree toggle Ctrl+n File tree toggle
Ctrl+p Fuzzy find file (git-aware) Ctrl+p Fuzzy find file (git-aware)
,b Search open buffers ,b Search open buffers
,rg Search file contents (ripgrep) ,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 ,wa Save all buffers
,, Switch to last file
CODE CODE
gd Go to definition gd Go to definition
K Show documentation K Show documentation
[g / ]g Prev/next diagnostic [g / ]g Prev/next LSP diagnostic
[e / ]e Prev/next ALE error
,rn Rename symbol ,rn Rename symbol
,ca Code action ,ca Code action / auto-fix
,f Format selection ,f Format selection | ,F Format whole file
,F Format whole file
GIT GIT
,gs Status | ,gd Diff | ,gb Blame ,gs Status | ,gd Diff | ,gb Blame
,gc Commit | ,gp Push | ,gl Pull ,gc Commit | ,gp Push | ,gl Pull
WINDOWS WINDOWS / PANES
Ctrl+h/j/k/l Move between panes Ctrl+h/j/k/l Move between Vim windows or tmux panes
,h / ,l Prev / next buffer
,tv Open terminal (vertical) ,tv Open terminal (vertical)
,th Open terminal (horizontal) ,th Open terminal (horizontal)
Esc Exit terminal mode Esc Exit terminal mode
F5 Undo tree | F8 Tag browser ,u Undo tree | ,tt Tag browser
SEARCH SEARCH & REPLACE
/text Search forward /text Search forward | ?text backward
?text Search backward // Search for visually selected text
,* Replace word under cursor (project-wide) ,* Replace word under cursor (file-wide)
CLIPBOARD
,y / ,Y Yank / yank line to system clipboard
,p / ,P Paste from system clipboard (after / before)
``` ```
--- ---

528
README.md
View file

@ -1,41 +1,71 @@
# chopsticks — Vim Configuration # chopsticks
A native Vim configuration optimized for full-stack engineering workflows. > A batteries-included Vim configuration for full-stack engineering.
Vim 8.0+ · Tiered LSP · TTY-aware · Zero icon fonts · 14 languages. > Tiered LSP · 14 languages · TTY-aware · Zero icon fonts · One-command install.
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![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.svg)](https://www.vim.org/) [![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)](#installation)
[![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 ```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
``` ```
See [QUICKSTART.md](QUICKSTART.md) for the 5-minute guide. > **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
- [Design Principles](#design-principles)
- [Requirements](#requirements)
- [Installation](#installation)
- [LSP: Tiered Backend](#lsp-tiered-backend)
- [Key Mappings](#key-mappings)
- [Features](#features)
- [Language Support](#language-support)
- [Plugins](#plugins)
- [Customization](#customization)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
--- ---
## Design Principles ## Design Principles
- **KISS** — No icon fonts, no unicode glyphs, plain ASCII throughout | Principle | What it means |
- **Tiered LSP** — CoC (full) with vim-lsp fallback; works with or without Node.js |-----------|--------------|
- **TTY-aware** — Automatic detection and optimization for console/SSH environments | **KISS** | No icon fonts, no Nerd Font glyphs — plain ASCII everywhere |
- **Engineering-first** — Git workflow, session management, project-local config | **Tiered LSP** | CoC (full) when Node.js is available; vim-lsp (pure VimScript) otherwise |
- **Batteries included**`install.sh` handles all dependencies automatically | **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 |
--- ---
## Requirements ## Requirements
| Requirement | Minimum | Notes | | Tool | Minimum | Role |
|-------------|---------|-------| |------|---------|------|
| Vim | 8.0+ | vim9script not required | | Vim | **8.0+** | Required |
| git | any | For cloning and fugitive | | git | any | Cloning and vim-fugitive |
| curl | any | For vim-plug auto-install | | curl | any | vim-plug bootstrap |
| Node.js | 14.14+ | Optional — enables CoC LSP | | Node.js | 14.14+ | Optional — enables CoC LSP (recommended) |
| ripgrep (rg) | any | Optional — enables `:Rg` search | | ripgrep | any | Optional — enables `,rg` / `,rG` project search |
| fzf | any | Optional — enables `Ctrl+p` fuzzy search | | fzf | any | Optional — enables `Ctrl+p` fuzzy finder |
| ctags | any | Optional — enables `F8` tag browser | | ctags | any | Optional — enables `,tt` tag browser |
| tmux | 1.8+ | Optional — enables seamless pane navigation |
All optional tools are installed automatically by `install.sh` when prompted.
--- ---
@ -49,16 +79,20 @@ cd ~/.vim
./install.sh ./install.sh
``` ```
The installer: The installer handles everything in sequence:
1. Checks Vim version and detects OS / package managers
2. Backs up any existing `~/.vimrc` (timestamped) 1. Verifies Vim 8.0+ and detects OS / package manager
3. Creates symlinks: `~/.vimrc -> ~/.vim/.vimrc` and `~/.vim/coc-settings.json` 2. Backs up any existing `~/.vimrc` with a timestamp
3. Symlinks `~/.vimrc → ~/.vim/.vimrc` and `~/.vim/coc-settings.json`
4. Installs vim-plug and runs `:PlugInstall` 4. Installs vim-plug and runs `:PlugInstall`
5. Optionally installs system tools, language tools, and CoC extensions 5. Optionally installs system tools (ripgrep, fzf, ctags, shellcheck, hadolint, marksman)
6. Optionally installs language tools (npm, pip, Go)
7. Optionally installs CoC language server extensions
8. Optionally configures tmux for seamless pane navigation
Supported platforms: **macOS** (Homebrew), **Debian/Ubuntu** (apt), **Arch Linux** (pacman), **Fedora** (dnf). **Supported platforms:** macOS (Homebrew), Debian/Ubuntu (apt), Arch Linux (pacman), Fedora (dnf).
Use `--yes` for non-interactive / CI environments: Use `--yes` for non-interactive or CI environments:
```bash ```bash
./install.sh --yes ./install.sh --yes
@ -77,21 +111,21 @@ vim +PlugInstall +qall </dev/null
--- ---
## LSP: Tiered Backend System ## LSP: Tiered Backend
Code intelligence is provided by one of two backends, selected automatically: Code intelligence is provided by one of two backends, chosen automatically at startup:
| Condition | Backend | Features | | Condition | Backend | Capabilities |
|-----------|---------|----------| |-----------|---------|-------------|
| Vim 8.0.1453+ AND Node.js 14.14+ | **CoC** | Full LSP, snippets, extensions ecosystem | | 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 | | Vim 8.0+ (no Node.js) | **vim-lsp** | LSP via language server binaries, asyncomplete |
| Any Vim | **ALE** | Linting and auto-fix (always active) | | Any Vim | **ALE** | Async linting + auto-fix (always active, both backends) |
Both backends expose identical key mappings: `gd`, `K`, `[g`, `]g`, `<leader>rn`, `<leader>ca`. Both CoC and vim-lsp expose the same key mappings so switching backends is transparent.
### CoC setup (with Node.js) ### With Node.js (CoC)
Install language server extensions from inside Vim: Install language server extensions from inside Vim — or let `install.sh` do it automatically:
```vim ```vim
:CocInstall coc-pyright " Python :CocInstall coc-pyright " Python
@ -99,64 +133,86 @@ Install language server extensions from inside Vim:
:CocInstall coc-go " Go :CocInstall coc-go " Go
:CocInstall coc-rust-analyzer " Rust :CocInstall coc-rust-analyzer " Rust
:CocInstall coc-json coc-yaml " JSON, YAML :CocInstall coc-json coc-yaml " JSON, YAML
:CocInstall coc-html coc-css " HTML, CSS :CocInstall coc-html coc-css " HTML, CSS/SCSS
:CocInstall coc-sh " Shell :CocInstall coc-sh " Shell
:CocInstall coc-sql " SQL :CocInstall coc-sql " SQL
``` ```
`install.sh` installs all of the above automatically when prompted. **Markdown LSP** uses `marksman` as an external binary (not a CoC extension):
**Markdown LSP** — `marksman` is configured via `coc-settings.json` (not a CoC ```bash
extension — install `marksman` binary via `brew install marksman` or download from brew install marksman # macOS
[releases](https://github.com/artempyanykh/marksman/releases)). sudo pacman -S marksman # Arch
# or: ./install.sh handles it automatically
### vim-lsp setup (without Node.js)
Install language server binaries for your languages, then run:
```vim
:LspInstallServer " auto-installs the right server for the current filetype
``` ```
Supported languages: Python, Go, Rust, TypeScript, JavaScript, Shell, HTML, ### Without Node.js (vim-lsp)
CSS/SCSS, JSON, YAML, Markdown, SQL — via `vim-lsp-settings`.
Open a source file, then run:
```vim
:LspInstallServer " 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.
--- ---
## Key Mappings ## Key Mappings
Leader key: `,` (comma) **Leader key:** `,` (comma)
Press `,` and wait 500ms for an interactive guide to all bindings (vim-which-key). 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.
### Files and Buffers ### Files and Buffers
| Key | Action | | Key | Action |
|-----|--------| |-----|--------|
| `Ctrl+p` | Fuzzy file search — git-aware (FZF) |
| `Ctrl+n` | Toggle file tree (NERDTree) | | `Ctrl+n` | Toggle file tree (NERDTree) |
| `,n` | Reveal current file in NERDTree | | `,n` | Reveal current file in NERDTree |
| `Ctrl+p` | Fuzzy file search (FZF — git-aware) |
| `,b` | Search open buffers (FZF) | | `,b` | Search open buffers (FZF) |
| `,rg` | Project-wide search (ripgrep + FZF) | | `,rg` | Project-wide search (ripgrep + FZF) |
| `,rG` | Ripgrep for word under cursor (literal match) |
| `,rt` | Search tags (FZF) | | `,rt` | Search tags (FZF) |
| `,gF` | Search git-tracked files (FZF) | | `,gF` | Search git-tracked files (FZF) |
| `,l` | Next buffer | | `,l` | Next buffer |
| `,h` | Previous buffer | | `,h` | Previous buffer |
| `,bd` | Close current buffer | | `,bd` | Close current buffer (preserves window layout) |
| `,,` | Switch to last file | | `,,` | Switch to last file |
### Windows and Tabs ### Windows, Tabs, and tmux
| Key | Action | | Key | Action |
|-----|--------| |-----|--------|
| `Ctrl+h/j/k/l` | Navigate between windows | | `Ctrl+h/j/k/l` | Navigate between Vim splits **and** tmux panes |
| `<Leader>=` | Increase window height | | `,=` | Increase window height |
| `<Leader>-` | Decrease window height | | `,-` | Decrease window height |
| `<Leader>+` | Increase window width | | `,+` | Increase window width |
| `<Leader>_` | Decrease window width | | `,_` | Decrease window width |
| `,tn` | New tab | | `,tn` | New tab |
| `,tc` | Close tab | | `,tc` | Close tab |
| `,tl` | Toggle to last 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 (CoC / vim-lsp)
@ -165,123 +221,128 @@ Press `,` and wait 500ms for an interactive guide to all bindings (vim-which-key
| `gd` | Go to definition | | `gd` | Go to definition |
| `gy` | Go to type definition | | `gy` | Go to type definition |
| `gi` | Go to implementation | | `gi` | Go to implementation |
| `gr` | Show references | | `gr` | Show all references |
| `K` | Hover documentation | | `K` | Hover documentation |
| `[g` | Previous diagnostic | | `[g` | Previous diagnostic |
| `]g` | Next diagnostic | | `]g` | Next diagnostic |
| `,rn` | Rename symbol | | `,rn` | Rename symbol |
| `,f` | Format selection | | `,f` | Format selection |
| `,ca` | Code action (cursor) | | `,F` | Format whole file |
| `,o` | File outline | | `,ca` | Code action (cursor position) |
| `,o` | File outline (symbols) |
| `,ws` | Workspace symbols | | `,ws` | Workspace symbols |
| `,cD` | Diagnostics list | | `,cD` | Diagnostics list |
| `,cr` | Resume last CoC list |
| `,qf` | Quick-fix current line (CoC) | | `,qf` | Quick-fix current line (CoC) |
| `,cl` | Run code lens (CoC) |
| `Tab` | Next completion item | | `Tab` | Next completion item |
| `Shift+Tab` | Previous completion item | | `Shift+Tab` | Previous completion item |
| `Enter` | Confirm completion | | `Enter` | Confirm completion |
Text objects (CoC only): `if`/`af` (function), `ic`/`ac` (class) Text objects (CoC): `if`/`af` (function inner/around), `ic`/`ac` (class inner/around).
### Linting (ALE) ### Linting (ALE — always active)
| Key | Action | | Key | Action |
|-----|--------| |-----|--------|
| `[e` | Next error/warning | | `[e` | Previous error / warning |
| `]e` | Previous error/warning | | `]e` | Next error / warning |
| `,aD` | Show error details | | `,aD` | Show error detail |
| `,ad` | Full diagnostics list |
Signs: `X` = error, `!` = warning Signs in the gutter: `X` = error, `!` = warning.
### Git Workflow (fugitive) ### Git (vim-fugitive)
| Key | Action | | Key | Action |
|-----|--------| |-----|--------|
| `,gs` | Git status | | `,gs` | Git status (stage with `s`, commit with `cc`) |
| `,gc` | Git commit | | `,gc` | Git commit |
| `,gp` | Git push | | `,gp` | Git push |
| `,gl` | Git pull | | `,gl` | Git pull |
| `,gd` | Git diff | | `,gd` | Git diff |
| `,gb` | Git blame | | `,gb` | Git blame |
| `,gF` | Search git-tracked files (FZF) |
### Engineering Utilities ### 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
| Key | Action |
|-----|--------|
| `s` + 2 chars | EasyMotion — jump anywhere on screen |
| `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 |
### Config and Utilities
| Key | Action | | Key | Action |
|-----|--------| |-----|--------|
| `,ev` | Edit `~/.vimrc` | | `,ev` | Edit `~/.vimrc` |
| `,sv` | Reload `~/.vimrc` | | `,sv` | Reload `~/.vimrc` |
| `,F` | Format entire file |
| `,W` | Strip trailing whitespace |
| `,wa` | Save all open buffers | | `,wa` | Save all open buffers |
| `,wd` | Change CWD to current buffer's dir | | `,wd` | Change working directory to current file's location |
| `,cp` | Copy file path to clipboard | | `,cp` | Copy absolute file path to clipboard |
| `,cf` | Copy filename to clipboard | | `,cf` | Copy filename to clipboard |
| `,y` | Yank to system clipboard | | `,qo` / `,qc` | Open / close quickfix list |
| `,Y` | Yank line to system clipboard |
| `,*` | Search+replace word under cursor |
| `,qo` | Open quickfix list |
| `,qc` | Close quickfix list |
| `,tv` | Open terminal (vertical split) |
| `,th` | Open terminal (horizontal, 10 rows) |
| `Esc` | Exit terminal mode |
### Navigation and Editing
| Key | Action |
|-----|--------|
| `s`+2ch | EasyMotion jump to any location |
| `Space` | Toggle code fold |
| `Y` | Yank to end of line (like `D`, `C`) |
| `n` / `N` | Search next/prev (cursor centered) |
| `Ctrl+d/u` | Half-page scroll (cursor centered) |
| `>` | Indent (keeps visual selection) |
| `<` | Dedent (keeps visual selection) |
| `[q` / `]q` | Previous/next quickfix (vim-unimpaired) |
| `[e` / `]e` | Previous/next ALE error/warning |
| `F2` | Toggle paste mode |
| `F3` | Toggle line numbers |
| `F4` | Toggle relative line numbers |
| `F5` | Toggle undo history (UndoTree) |
| `F8` | Toggle code tag browser (Tagbar) |
| `0` | Jump to first non-blank character |
| `Alt+j/k` | Move line up/down |
--- ---
## Features ## Features
### Startup Screen (vim-startify) ### Startup Dashboard
Opens when Vim is launched without a file argument. Shows: Running `vim` (no arguments) opens a full-screen Startify dashboard showing recent
- Session list for current directory files, sessions, and bookmarks. Running `vim .` opens NERDTree on the left with
- Recently opened files the dashboard on the right.
- Bookmarks
Session auto-saves on quit. Auto-loads `Session.vim` if found in the current ### Keybinding Guide
directory. Auto-changes to git root on file open.
**`vim .` layout** — NERDTree on the left, Startify on the right. Press `,` and pause for 500 ms. A popup (vim-which-key) lists all leader bindings
organized into groups. No need to memorize everything upfront.
### Keybinding Guide (vim-which-key) ### Built-in Cheat Sheet
Press `,` and pause for 500ms. A popup lists all available leader bindings Press `,?` to open an inline reference covering modes, survival commands, search,
organized by group. Useful for onboarding and discovering shortcuts. code intelligence, git, and clipboard — without leaving Vim.
### Session Management ### Session Management
```vim ```vim
:Obsess " Start tracking session :Obsess " start tracking the current session
:Obsess! " Stop tracking :Obsess! " stop tracking
``` ```
Sessions stored in `~/.vim/sessions/` and automatically resumed by vim-prosession Sessions are stored in `~/.vim/sessions/` and automatically restored by vim-prosession
on the next Vim launch in the same directory. the next time you open Vim in the same directory.
### Project-Local Config ### Project-Local Config
Place a `.vimrc` in any project root: Drop a `.vimrc` in any project root to override settings for that project:
```vim ```vim
" project/.vimrc " project/.vimrc
@ -289,30 +350,53 @@ set shiftwidth=2
let g:ale_python_black_options = '--line-length=100' let g:ale_python_black_options = '--line-length=100'
``` ```
Loaded automatically. Security-restricted via `set secure`. 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.
**Vim side:** handled by vim-tmux-navigator (installed automatically).
**tmux side:** 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)?$'"
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-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`
> **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`.
### Large File Handling ### Large File Handling
Files over 10 MB automatically disable syntax highlighting and undo history Files over 10 MB automatically disable syntax highlighting, undo history, and
to prevent Vim from freezing. linting to prevent Vim from stalling.
### TTY / Console Support ### TTY / Console Support
Detected automatically when `$TERM` is `linux` or `screen`. In TTY mode: Detected automatically when `$TERM` is `linux` or `screen`. In TTY mode:
- True color and cursorline disabled - True color and cursorline disabled
- Powerline separators replaced with plain ASCII - Powerline separators replaced with plain ASCII
- FZF preview windows disabled - FZF preview windows disabled
- NERDTree auto-open skipped - IndentLine guides disabled
- Syntax column limit reduced to 120 - Syntax column limit reduced to 120 characters
- Simpler status line - Simpler built-in status line used instead of airline
--- ---
## Language Support ## Language Support
| Language | Indent | Formatter | Linter | LSP (CoC) | | Language | Indent | Formatter | Linter | LSP |
|----------|--------|-----------|--------|-----------| |----------|--------|-----------|--------|-----|
| Python | 4sp | black + isort | flake8, pylint | coc-pyright | | Python | 4 sp | black, isort | flake8, pylint | coc-pyright |
| JavaScript | 2 sp | prettier | eslint | coc-tsserver | | JavaScript | 2 sp | prettier | eslint | coc-tsserver |
| TypeScript | 2 sp | prettier | eslint, tsserver | coc-tsserver | | TypeScript | 2 sp | prettier | eslint, tsserver | coc-tsserver |
| Go | tab | gofmt, goimports | staticcheck | coc-go | | Go | tab | gofmt, goimports | staticcheck | coc-go |
@ -323,123 +407,187 @@ Detected automatically when `$TERM` is `linux` or `screen`. In TTY mode:
| CSS / SCSS | 2 sp | prettier | stylelint | coc-css | | CSS / SCSS | 2 sp | prettier | stylelint | coc-css |
| Less | 2 sp | prettier | — | — | | Less | 2 sp | prettier | — | — |
| JSON | 2 sp | prettier | — | coc-json | | JSON | 2 sp | prettier | — | coc-json |
| Markdown | 2sp | prettier | markdownlint | marksman (coc-settings.json) | | Markdown | 2 sp | prettier | markdownlint | marksman |
| SQL | 4 sp | sqlfluff | sqlfluff | — | | SQL | 4 sp | sqlfluff | sqlfluff | — |
| Dockerfile | 2 sp | — | hadolint | — | | Dockerfile | 2 sp | — | hadolint | — |
`install.sh` installs all linters and formatters automatically. `install.sh` installs all formatters and linters automatically.
ALE runs them asynchronously; format-on-save active when using CoC. ALE runs them asynchronously; format-on-save is active for all supported languages.
--- ---
## Plugin List ## Plugins
### Navigation ### Navigation
- **NERDTree**File tree explorer - **NERDTree**file tree explorer
- **fzf + fzf.vim**Fuzzy finder (file, buffer, tag, ripgrep) - **fzf + fzf.vim**fuzzy finder for files, buffers, tags, and ripgrep
### Git ### Git
- **vim-fugitive**Git commands inside Vim - **vim-fugitive**full Git integration inside Vim
- **vim-gitgutter**Diff signs in the sign column - **vim-gitgutter**diff signs in the sign column
### LSP and Completion ### LSP and Completion
- **coc.nvim**Full LSP + completion (requires Node.js 14.14+) - **coc.nvim**full LSP + completion via Node.js (recommended)
- **vim-lsp**Pure VimScript LSP client (fallback, no Node.js) - **vim-lsp**pure VimScript LSP client (Node.js-free fallback)
- **vim-lsp-settings**Auto-configure language servers for vim-lsp - **vim-lsp-settings**auto-configures language servers for vim-lsp
- **asyncomplete.vim**Async completion (used with vim-lsp) - **asyncomplete.vim**async completion engine (vim-lsp mode)
### Linting ### Linting
- **ALE**Asynchronous Lint Engine (always active) - **ALE**asynchronous lint engine, always active regardless of LSP backend
### UI ### UI
- **vim-airline**Status and tabline - **vim-airline**status line and tabline
- **vim-startify**Startup screen with sessions - **vim-startify**startup dashboard with session management
- **vim-which-key**Keybinding hint popup - **vim-which-key**keybinding hint popup on leader pause
- **indentLine**Indent guide lines (non-TTY) - **indentLine**indent guide lines (non-TTY only)
- **undotree**Undo history visualizer - **undotree**visual undo branch history
- **tagbar**Code structure sidebar - **tagbar**code structure sidebar via ctags
### Editing ### Editing
- **vim-surround**Change surrounding quotes, brackets, tags - **vim-surround**change surrounding quotes, brackets, and tags
- **vim-commentary**`gc` to toggle comments - **vim-commentary**`gc` to toggle comments
- **auto-pairs** — Auto-close brackets and quotes - **auto-pairs** — auto-close brackets and quotes
- **vim-easymotion** — Jump anywhere with 2 keystrokes - **vim-easymotion** — jump anywhere on screen with 2 keystrokes (`s`)
- **vim-unimpaired** — Bracket shortcut pairs - **vim-unimpaired** — bracket shortcut pairs (`[q`/`]q`, etc.)
- **targets.vim** — Extra text objects - **targets.vim** — additional text objects
- **vim-snippets** — Snippet library (used with CoC/UltiSnips) - **vim-snippets** — snippet library (used with CoC)
- **vim-tmux-navigator** — seamless `Ctrl+h/j/k/l` across Vim and tmux
### Language Packs ### Language Packs
- **vim-polyglot**Syntax for 100+ languages - **vim-polyglot**syntax for 100+ languages
- **vim-go** — Go development tools (formatting + highlighting; LSP handled by coc-go) - **vim-go** — Go syntax and tooling (LSP handled by coc-go)
### Session ### Session
- **vim-obsession**Continuous session saving - **vim-obsession**continuous session saving
- **vim-prosession**Project-level session management - **vim-prosession**project-level session management
### Color Schemes ### Color Schemes
- **gruvbox** (default), **dracula**, **solarized**, **onedark** - **gruvbox** (default), **dracula**, **solarized**, **onedark**
--- ---
## Color Scheme ## Customization
Change in `.vimrc` (find the `colorscheme` line): ### Change the color scheme
In `~/.vimrc`, find and update the `colorscheme` line:
```vim ```vim
colorscheme dracula " or: gruvbox, solarized, onedark colorscheme dracula " options: gruvbox, solarized, onedark
``` ```
True color is enabled automatically when the terminal supports it True color is enabled automatically when `$COLORTERM=truecolor`. Falls back to
(`$COLORTERM=truecolor`). Falls back to 256-color, then 16-color (TTY). 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:
```vim
" my-project/.vimrc
set shiftwidth=2
let g:ale_python_black_options = '--line-length=120'
```
### Modify keybindings
Edit `~/.vimrc` directly (`,ev` opens it from inside Vim). Reload with `,sv`.
--- ---
## Troubleshooting ## Troubleshooting
**Plugins not installed:** **Plugins not loading**
```vim ```vim
:PlugInstall :PlugInstall " install any missing plugins
:PlugUpdate :PlugUpdate " update all plugins
``` ```
**CoC not working:** **CoC not working**
```bash ```bash
node --version # must be >= 14.14 node --version # must be 14.14+
``` ```
**Markdown LSP not starting:** Inside Vim: `:CocInfo` for diagnostics, `:CocInstall <extension>` to add a language server.
```bash
marksman --version # must be installed separately **vim-lsp server not starting**
brew install marksman # macOS
sudo pacman -S marksman # Arch
# or: ./install.sh (installs automatically)
```
**vim-lsp server not starting:**
```vim ```vim
:LspInstallServer " install server for current filetype :LspInstallServer " install the correct server for the current filetype
:LspStatus " check server status :LspStatus " check server status
``` ```
**Colors look wrong:** **Markdown LSP not starting**
`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
```
**Colors look wrong**
```bash ```bash
export TERM=xterm-256color # add to ~/.bashrc or ~/.zshrc export TERM=xterm-256color # add to ~/.bashrc or ~/.zshrc
``` ```
**ALE not finding linters:** For true color: `export COLORTERM=truecolor`.
**ALE linters not found**
```bash ```bash
which flake8 black prettier eslint # confirm 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.
--- ---
## References ## Contributing
- [vim-plug](https://github.com/junegunn/vim-plug) Bug reports and pull requests are welcome. Please follow these guidelines:
- [coc.nvim](https://github.com/neoclide/coc.nvim)
- [vim-lsp](https://github.com/prabirshrestha/vim-lsp) ### Reporting a bug
- [vim-lsp-settings](https://github.com/mattn/vim-lsp-settings)
- [amix/vimrc](https://github.com/amix/vimrc) 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.
--- ---

View file

@ -382,6 +382,43 @@ else
SKIPPED+=("gopls" "goimports" "staticcheck") SKIPPED+=("gopls" "goimports" "staticcheck")
fi fi
# ============================================================================
# tmux: vim-tmux-navigator integration
# ============================================================================
step "tmux: vim-tmux-navigator integration"
if command -v tmux >/dev/null 2>&1; then
TMUX_CONF="$HOME/.tmux.conf"
# Check if already configured
if grep -q 'vim-tmux-navigator' "$TMUX_CONF" 2>/dev/null; then
ok "vim-tmux-navigator bindings already present in ~/.tmux.conf"
else
if ask "Append vim-tmux-navigator bindings to ~/.tmux.conf (enables seamless Ctrl+h/j/k/l across vim and tmux)?"; then
cat >> "$TMUX_CONF" << 'TMUXEOF'
# vim-tmux-navigator: seamless Ctrl+h/j/k/l navigation between vim and tmux
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-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-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
TMUXEOF
ok "vim-tmux-navigator bindings appended to ~/.tmux.conf"
warn "Reload tmux config now: tmux source-file ~/.tmux.conf"
warn "Note: C-l now navigates panes instead of clearing the screen."
warn " To restore clear: add 'bind C-l send-keys C-l' to ~/.tmux.conf"
INSTALLED+=("tmux-navigator-config")
else
skip "tmux navigator config"
SKIPPED+=("tmux-navigator-config")
fi
fi
else
skip "tmux not found — skipping navigator config"
SKIPPED+=("tmux-navigator-config")
fi
# ============================================================================ # ============================================================================
# CoC language server extensions # CoC language server extensions
# ============================================================================ # ============================================================================
@ -424,5 +461,21 @@ if [[ ${#FAILED[@]} -gt 0 ]]; then
fi fi
echo "" echo ""
echo "Run 'vim' and press ',' then wait 500ms for keybinding hints." echo -e "${BOLD}---------------------------------------${NC}"
echo -e "${BOLD} You're ready. Open Vim with:${NC}"
echo -e "${BOLD}---------------------------------------${NC}"
echo -e " ${CYAN}vim${NC} Launch startup dashboard"
echo -e " ${CYAN}vim .${NC} Open file tree + dashboard"
echo -e " ${CYAN}vim myfile${NC} Edit a specific file"
echo ""
echo -e "${BOLD} Survival Guide (first-time Vim users)${NC}"
echo -e " ${CYAN}Esc${NC} or ${CYAN}jk${NC} Exit insert mode → back to Normal"
echo -e " ${CYAN}:q!${NC} + Enter Emergency quit without saving"
echo -e " ${CYAN},x${NC} Save and quit"
echo -e " ${CYAN},?${NC} Open cheat sheet inside Vim"
echo -e " ${CYAN},${NC} + pause Interactive keybinding guide"
echo ""
echo -e "${YELLOW}[!]${NC} Ctrl+s is mapped to save in Vim."
echo " If it freezes your terminal, add this to ~/.bashrc or ~/.zshrc:"
echo -e " ${CYAN}stty -ixon${NC}"
echo "" echo ""