diff --git a/.vimrc b/.vimrc index de12a69..827d725 100644 --- a/.vimrc +++ b/.vimrc @@ -16,6 +16,5 @@ call s:load('navigation') call s:load('lsp') call s:load('lint') call s:load('git') -call s:load('writing') call s:load('languages') call s:load('tools') diff --git a/README.md b/README.md index 24be6be..1d2a5b7 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

chopsticks

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

@@ -30,7 +30,7 @@ You SSH into a server. You need to edit code. You want LSP, fuzzy find, git inte 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. +**24 plugins**, LSP, linting, and a hand-built statusline. No bloat, no decorations, just tools. ## What's in the box @@ -40,10 +40,8 @@ chopsticks gives you a production-ready Vim config in one command. Pure VimScrip | **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 @@ -64,15 +62,15 @@ First launch installs plugins automatically (30-60s). Restart vim when done. ## Keys -Leader: `,` — press `,?` for the full cheat sheet inside vim. +Leader: `,` ``` Ctrl+p fuzzy find file gd go to definition ,rg ripgrep project K hover docs -,gs git status ,cr run current file -,zen zen mode ,f format +,e toggle file sidebar ,cr run current file +,gs git status ,f format ,w save ,q quit -jk exit insert mode ,? cheat sheet +jk exit insert mode ,bd close buffer ```

@@ -100,7 +98,7 @@ jk exit insert mode ,? cheat sheet ### Writing -`,zen` zen mode | `,mp` markdown preview | `,mt` table of contents +`,mt` table of contents
@@ -119,10 +117,10 @@ ALE and vim-lsp coexist cleanly (`ale_disable_lsp=1`). ALE handles linting + for ``` ~/.vim/ -├── .vimrc thin loader (12 lines) +├── .vimrc thin loader ├── modules/ │ ├── env.vim TTY detection, truecolor -│ ├── plugins.vim vim-plug + 29 plugins +│ ├── plugins.vim vim-plug + 24 plugins │ ├── core.vim settings, keymaps, performance │ ├── ui.vim solarized, statusline, startify │ ├── editing.vim easymotion, yank highlight @@ -130,35 +128,21 @@ ALE and vim-lsp coexist cleanly (`ale_disable_lsp=1`). ALE handles linting + for │ ├── lsp.vim vim-lsp, asyncomplete │ ├── lint.vim ale, format-on-save │ ├── git.vim fugitive, gitgutter -│ ├── writing.vim markdown, previm, zen mode -│ ├── languages.vim vim-go, filetype settings -│ └── tools.vim cheat sheet, run file, helpers -└── tutor/ - └── chopsticks.tutor +│ ├── languages.vim vim-go, markdown, filetype settings +│ └── tools.vim run file, quickfix, helpers ``` 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 -,? " cheat sheet (every binding) -``` - ## Performance | Metric | Value | |--------|-------| -| Startup time | **19ms** (29 plugins loaded) | -| Lazy-loaded | 8 plugins (on command or filetype) | +| Lazy-loaded | 6 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 | diff --git a/modules/core.vim b/modules/core.vim index 55848c1..2db7a13 100644 --- a/modules/core.vim +++ b/modules/core.vim @@ -100,20 +100,6 @@ nnoremap ba :bufdo bd nnoremap l :bnext nnoremap h :bprevious -nnoremap tn :tabnew -nnoremap to :tabonly -nnoremap tc :tabclose -nnoremap tm :tabmove -nnoremap t :tabnext - -let g:lasttab = 1 -nnoremap tl :exe "tabn ".g:lasttab -augroup ChopstickTabHistory - autocmd! - autocmd TabLeave * let g:lasttab = tabpagenr() -augroup END - -nnoremap te :tabedit =expand("%:p:h")/ nnoremap cd :lcd %:p:h:pwd nnoremap 0 ^ @@ -128,10 +114,6 @@ vnoremap :m '>+1gv=gv vnoremap :m '<-2gv=gv nnoremap ss :setlocal spell!:echo 'Spell: ' . (&spell ? 'ON' : 'OFF') -nnoremap sn ]s -nnoremap sp [s -nnoremap sa zg -nnoremap s? z= nnoremap :set paste!:echo 'Paste: ' . (&paste ? 'ON' : 'OFF') nnoremap :set invnumber:echo 'Line numbers: ' . (&number ? 'ON' : 'OFF') diff --git a/modules/languages.vim b/modules/languages.vim index 19ee563..7175832 100644 --- a/modules/languages.vim +++ b/modules/languages.vim @@ -1,4 +1,21 @@ -" languages.vim — vim-go config, per-filetype autocmds +" languages.vim — vim-go, vim-markdown, per-filetype autocmds + +" ── vim-markdown ─────────────────────────────────────────────────────────── + +let g:vim_markdown_conceal = 1 +let g:vim_markdown_conceal_code_blocks = 0 +let g:vim_markdown_folding_disabled = 0 +let g:vim_markdown_folding_level = 2 +let g:vim_markdown_frontmatter = 1 +let g:vim_markdown_toml_frontmatter = 1 +let g:vim_markdown_json_frontmatter = 1 +let g:vim_markdown_follow_anchor = 1 +let g:vim_markdown_new_list_item_indent = 2 +let g:vim_markdown_strikethrough = 1 + +if exists('g:plugs["vim-markdown"]') + nnoremap mt :Toc +endif " ── vim-go (syntax only — vim-lsp handles intelligence) ───────────────────── diff --git a/modules/plugins.vim b/modules/plugins.vim index 9c066b2..0b6c75d 100644 --- a/modules/plugins.vim +++ b/modules/plugins.vim @@ -24,10 +24,6 @@ Plug 'airblade/vim-gitgutter' Plug 'tpope/vim-surround' Plug 'tpope/vim-commentary' Plug 'tpope/vim-repeat' -" tpope/vim-unimpaired removed: 2.5ms startup cost, we define our own -" [q/]q (quickfix), [e/]e (ALE), [x/]x (conflict) — unimpaired's [b/]b -" is covered by ,h/,l. Blank line insertion ([) added below. - Plug 'tpope/vim-sleuth' Plug 'wellle/targets.vim' Plug 'jiangmiao/auto-pairs' @@ -36,7 +32,7 @@ Plug 'easymotion/vim-easymotion', { 'on': '(easymotion' } " ── Linting & Formatting ──────────────────────────────────────────────────── Plug 'dense-analysis/ale' -" ── LSP + Completion (no Node.js required) ────────────────────────────────── +" ── LSP + Completion ───────────────────────────────────────────────────────── Plug 'prabirshrestha/vim-lsp' Plug 'mattn/vim-lsp-settings' Plug 'prabirshrestha/asyncomplete.vim' @@ -48,21 +44,10 @@ Plug 'HerringtonDarkholme/yats.vim', { 'for': ['typescript', 'typescript.tsx'] } Plug 'preservim/vim-markdown', { 'for': 'markdown' } Plug 'fatih/vim-go', { 'for': 'go' } -" ── Markdown Preview & Writing ─────────────────────────────────────────────── -Plug 'previm/previm', { 'on': 'PrevimOpen' } -Plug 'junegunn/goyo.vim', { 'on': 'Goyo' } -Plug 'junegunn/limelight.vim', { 'on': ['Limelight', 'Limelight!'] } - " ── UI ─────────────────────────────────────────────────────────────────────── Plug 'mbbill/undotree', { 'on': 'UndotreeToggle' } Plug 'mhinz/vim-startify' Plug 'lifepillar/vim-solarized8' -if !g:is_tty - Plug 'Yggdroot/indentLine' -endif - -" ── Session & Navigation ──────────────────────────────────────────────────── -Plug 'tpope/vim-obsession' Plug 'christoomey/vim-tmux-navigator' call plug#end() diff --git a/modules/tools.vim b/modules/tools.vim index 235744b..c352f7c 100644 --- a/modules/tools.vim +++ b/modules/tools.vim @@ -1,11 +1,6 @@ -" tools.vim — cheat sheet, run file, sudo save, quickfix, helpers +" tools.vim — run file, sudo save, quickfix, helpers -" ── Helper Functions ──────────────────────────────────────────────────────── - -function! HasPaste() - if &paste | return 'PASTE MODE ' | endif - return '' -endfunction +" ── Buffer Close ─────────────────────────────────────────────────────────── command! Bclose call BufcloseCloseIt() function! BufcloseCloseIt() @@ -24,38 +19,18 @@ function! BufcloseCloseIt() endif endfunction -fun! CleanExtraSpaces() - let save_cursor = getpos(".") - let old_query = getreg('/') - silent! %s/\s\+$//e - call setpos('.', save_cursor) - call setreg('/', old_query) -endfun - -function! ToggleNumber() - if(&relativenumber == 1) - set norelativenumber - set number - else - set relativenumber - endif -endfunc - -" ── Additional Utilities ──────────────────────────────────────────────────── +" ── Utilities ────────────────────────────────────────────────────────────── nnoremap F gg=G`` nnoremap wa :wa nnoremap = :exe "resize " . (winheight(0) * 3/2) nnoremap - :exe "resize " . (winheight(0) * 2/3) -nnoremap + :exe "vertical resize " . (winwidth(0) * 3/2) -nnoremap _ :exe "vertical resize " . (winwidth(0) * 2/3) nnoremap nnoremap W :%s/\s\+$//:let @/='' -nnoremap so :if &filetype ==# 'vim' source % echo "Sourced " . expand('%') else echo "Not a vim file" endif nnoremap ev :edit $MYVIMRC nnoremap sv :source $MYVIMRC:echo "vimrc reloaded" @@ -66,8 +41,6 @@ if has('clipboard') nnoremap cf :let @+ = expand("%:t"):echo "Copied: " . expand("%:t") endif -nnoremap ms :e ~/buffer.md - " ── Auto-Create Directories ───────────────────────────────────────────────── function! s:MkNonExDir(file, buf) @@ -105,14 +78,6 @@ augroup ChopstickLargeFile \ endif augroup END -if g:is_tty && !exists("g:tty_message_shown") - augroup TTYMessage - autocmd! - autocmd VimEnter * echom "TTY mode — visual features disabled" - augroup END - let g:tty_message_shown = 1 -endif - " ── Run Current File (,cr) ────────────────────────────────────────────────── function! s:RunFile() abort @@ -138,7 +103,7 @@ nnoremap cr :call RunFile() cnoremap w!! w !sudo tee > /dev/null % -" ── QuickFix Improvements ─────────────────────────────────────────────────── +" ── QuickFix ──────────────────────────────────────────────────────────────── augroup ChopstickQF autocmd! @@ -148,113 +113,3 @@ augroup END nnoremap ]q :cnext nnoremap [q :cprev - -" ── Debug Helpers ─────────────────────────────────────────────────────────── - -nnoremap sh :call SynStack() -function! SynStack() - if !exists("*synstack") | return | endif - echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")') -endfunc - -" ── Cheat Sheet (,?) ──────────────────────────────────────────────────────── - -function! s:CheatSheet() abort - let l:name = '__ChopsticksCheatSheet__' - if bufwinnr(l:name) > 0 - execute bufwinnr(l:name) . 'wincmd w' - return - endif - execute 'botright new ' . l:name - setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile - call setline(1, [ - \ '=== chopsticks — Quick Reference ===', - \ '', - \ 'SURVIVAL', - \ ' Esc / jk Exit insert or visual mode', - \ ' :q! + Enter Quit without saving', - \ ' ,x Save+quit ,w Save Ctrl+s Save (any mode)', - \ ' :w!! Sudo save (when you forgot to open as root)', - \ '', - \ 'FILES & SEARCH', - \ ' Ctrl+p Fuzzy find file (git-aware)', - \ ' ,e / ,E Toggle tree sidebar (cwd / file dir)', - \ ' ,b Search open buffers', - \ ' ,rg Search project contents (ripgrep)', - \ ' ,rG Ripgrep word under cursor', - \ ' ,fh Recent files history', - \ ' ,fl / ,fL Search lines in buffer / all buffers', - \ ' ,fc Commands | ,fm Marks', - \ ' ,f/ / ,f: Search / command history', - \ ' ,, Switch to last file (Ctrl+^)', - \ '', - \ 'CODE INTELLIGENCE (vim-lsp)', - \ ' gd Definition gy Type def gi Impl gr Refs', - \ ' K Hover documentation', - \ ' [g / ]g Prev / next LSP diagnostic', - \ ' [e / ]e Prev / next ALE error', - \ ' ,ca Code action ,rn Rename ,f Format', - \ ' ,o File outline ,ws Workspace symbols', - \ ' ,cr Run current file', - \ '', - \ 'MARKDOWN & WRITING', - \ ' ,mp Live browser preview (previm)', - \ ' ,mt Table of contents', - \ ' ,zen Zen mode (Goyo + Limelight)', - \ ' zr / zm Unfold / fold all headings', - \ '', - \ 'EDITING', - \ ' gc Toggle comment (visual mode too)', - \ ' s + 2 chars EasyMotion jump anywhere', - \ ' ,u / F5 Undo tree', - \ ' ,y / ,Y Yank to system clipboard', - \ ' Alt+j / Alt+k Move line down / up', - \ ' ,F Re-indent file ,W Strip trailing whitespace', - \ ' ,* Search and replace word under cursor', - \ '', - \ 'GIT', - \ ' ,gs Status ,gd Diff ,gb Blame', - \ ' ,gc Commit ,gp Push ,gl Pull', - \ ' [x / ]x Navigate git conflict markers', - \ '', - \ 'WINDOWS & PANES', - \ ' Ctrl+h/j/k/l Navigate splits and tmux panes', - \ ' ,h / ,l Prev / next buffer ,bd Close buffer', - \ ' ,z Maximize / restore current window', - \ ' ,tv / ,th Terminal (vertical / horizontal)', - \ ' Esc Esc Exit terminal mode', - \ ' ,= / ,- Resize height ,+ / ,_ Resize width', - \ '', - \ 'QUICKFIX', - \ ' ,qo / ,qc Open / close quickfix', - \ ' ]q / [q Next / prev quickfix entry', - \ '', - \ 'UTILITIES', - \ ' ,ev / ,sv Edit / reload ~/.vimrc', - \ ' ,cp / ,cf Copy file path / filename to clipboard', - \ ' ,ms Scratch buffer ,cd CD to file dir', - \ ' ,ss Toggle spell ,so Source current vim file', - \ ' F2 Paste F3 Line# F4 Relative# F6 Invisible', - \ '', - \ '(press q to close)', - \ ]) - setlocal nomodifiable readonly - nnoremap q :bd -endfunction -nnoremap ? :call CheatSheet() - -" ── Interactive Tutorial ──────────────────────────────────────────────────── - -function! s:ChopsticksLearn() abort - let l:tutor = g:chopsticks_dir . '/tutor/chopsticks.tutor' - if !filereadable(l:tutor) - echo "Tutorial not found: " . l:tutor - return - endif - execute 'edit ' . fnameescape(l:tutor) - setlocal nomodifiable readonly - setlocal buftype=nofile bufhidden=wipe - setlocal filetype=text - setlocal wrap linebreak -endfunction -command! ChopsticksLearn call s:ChopsticksLearn() diff --git a/modules/ui.vim b/modules/ui.vim index a313d1f..4c3543c 100644 --- a/modules/ui.vim +++ b/modules/ui.vim @@ -1,4 +1,4 @@ -" ui.vim — colorscheme, statusline, startify, indentline +" ui.vim — colorscheme, statusline, startify " ── Colorscheme (Solarized Dark — matches tmux palette) ──────────────────── @@ -28,49 +28,16 @@ if has("gui_running") endif endif -" ── IndentLine (non-TTY only) ─────────────────────────────────────────────── - -if !g:is_tty && exists('g:plugs["indentLine"]') - let g:indentLine_char = '|' - let g:indentLine_first_char = '|' - let g:indentLine_showFirstIndentLevel = 1 - let g:indentLine_fileTypeExclude = ['text', 'help', 'startify', 'markdown'] - let g:indentLine_bufTypeExclude = ['help', 'terminal', 'nofile'] - let g:indentLine_setConceal = 2 - let g:indentLine_concealcursor = '' -endif - " ── Startify ──────────────────────────────────────────────────────────────── if exists('g:plugs["vim-startify"]') - let g:startify_custom_header = [ - \ ' ██████╗██╗ ██╗ ██████╗ ██████╗ ███████╗████████╗██╗ ██████╗██╗ ██╗███████╗', - \ ' ██╔════╝██║ ██║██╔═══██╗██╔══██╗██╔════╝╚══██╔══╝██║██╔════╝██║ ██╔╝██╔════╝', - \ ' ██║ ███████║██║ ██║██████╔╝███████╗ ██║ ██║██║ █████╔╝ ███████╗', - \ ' ██║ ██╔══██║██║ ██║██╔═══╝ ╚════██║ ██║ ██║██║ ██╔═██╗ ╚════██║', - \ ' ╚██████╗██║ ██║╚██████╔╝██║ ███████║ ██║ ██║╚██████╗██║ ██╗███████║', - \ ' ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝', - \ '', - \ ] - let g:startify_lists = [ \ { 'type': 'sessions', 'header': [' Sessions'] }, \ { 'type': 'files', 'header': [' Recent Files'] }, \ { 'type': 'dir', 'header': [' Current Dir'] }, - \ { 'type': 'bookmarks', 'header': [' Bookmarks'] }, \ ] - let g:startify_bookmarks = [{'v': '~/.vimrc'}] - if filereadable(expand('~/.zshrc')) - call add(g:startify_bookmarks, {'z': '~/.zshrc'}) - endif - if filereadable(expand('~/.bashrc')) - call add(g:startify_bookmarks, {'b': '~/.bashrc'}) - endif - if filereadable(expand('~/.config/fish/config.fish')) - call add(g:startify_bookmarks, {'f': '~/.config/fish/config.fish'}) - endif - + let g:startify_bookmarks = [{'v': '~/.vimrc'}] let g:startify_session_persistence = 1 let g:startify_session_autoload = 1 let g:startify_change_to_vcs_root = 1 @@ -158,39 +125,13 @@ function! SLAle() abort return printf(' E:%d W:%d ', l:e, l:w) endfunction -function! SLBufCount() abort - let l:n = len(filter(range(1, bufnr('$')), 'buflisted(v:val)')) - return l:n > 1 ? ' ' . l:n . ' bufs ' : '' -endfunction - function! SLFlags() abort let l:f = '' if &paste | let l:f .= ' PASTE' | endif if &spell | let l:f .= ' SPELL' | endif - if exists('t:maximize_session') | let l:f .= ' MAX' | endif return empty(l:f) ? '' : l:f . ' ' endfunction -function! SLLsp() abort - if !exists('*lsp#get_server_names') | return '' | endif - let l:servers = lsp#get_server_names() - if empty(l:servers) | return '' | endif - let l:status = lsp#get_server_status(l:servers[0]) - if l:status ==# 'running' - return ' ' . l:servers[0] . ' ' - elseif l:status ==# 'starting' || l:status ==# 'not running' - return ' ' . l:servers[0] . '… ' - endif - return '' -endfunction - -function! SLEncoding() abort - let l:enc = &fileencoding !=# '' ? &fileencoding : &encoding - let l:fmt = &fileformat - if l:enc ==? 'utf-8' && l:fmt ==# 'unix' | return '' | endif - return ' ' . l:enc . '[' . l:fmt . '] ' -endfunction - function! SLBuild() abort let [l:label, l:hl] = SLMode() let l:s = '%#' . l:hl . '#' . l:label @@ -198,11 +139,8 @@ function! SLBuild() abort let l:s .= '%#SLFlag#%m%r' let l:s .= '%#SLFlag#' . SLFlags() let l:s .= '%#SLBody#%=' - let l:s .= '%#SLBody#' . SLBufCount() let l:s .= '%#SLFlag#' . SLAle() - let l:s .= '%#SLRight#' . SLLsp() let l:s .= '%#SLGit#' . SLGit() - let l:s .= '%#SLRight#' . SLEncoding() let l:s .= '%#SLFtype# %y ' let l:s .= '%#SLRight# %l:%c %P ' return l:s diff --git a/modules/writing.vim b/modules/writing.vim deleted file mode 100644 index 732407f..0000000 --- a/modules/writing.vim +++ /dev/null @@ -1,56 +0,0 @@ -" writing.vim — vim-markdown, previm, goyo + limelight zen mode - -" ── vim-markdown ──────────────────────────────────────────────────────────── - -let g:vim_markdown_conceal = 1 -let g:vim_markdown_conceal_code_blocks = 0 -let g:vim_markdown_folding_disabled = 0 -let g:vim_markdown_folding_level = 2 -let g:vim_markdown_frontmatter = 1 -let g:vim_markdown_toml_frontmatter = 1 -let g:vim_markdown_json_frontmatter = 1 -let g:vim_markdown_follow_anchor = 1 -let g:vim_markdown_new_list_item_indent = 2 -let g:vim_markdown_strikethrough = 1 - -if exists('g:plugs["vim-markdown"]') - nnoremap mt :Toc -endif - -" ── previm (Markdown browser preview) ─────────────────────────────────────── - -if has('macunix') - let g:previm_open_cmd = '/usr/bin/open' -elseif executable('xdg-open') - let g:previm_open_cmd = 'xdg-open' -endif -if exists('g:plugs["previm"]') - nnoremap mp :PrevimOpen -endif -let g:previm_enable_realtime = 1 - -" ── Goyo + Limelight (zen mode) ──────────────────────────────────────────── - -if exists('g:plugs["goyo.vim"]') - let g:goyo_width = 80 - let g:goyo_height = '85%' - nnoremap zen :Goyo - - function! s:goyo_enter() - if exists('g:plugs["limelight.vim"]') | Limelight | endif - set wrap linebreak scrolloff=999 - endfunction - function! s:goyo_leave() - if exists('g:plugs["limelight.vim"]') | Limelight! | endif - set nowrap nolinebreak scrolloff=10 - endfunction - - augroup ChopstickGoyo - autocmd! - autocmd User GoyoEnter nested call s:goyo_enter() - autocmd User GoyoLeave nested call s:goyo_leave() - augroup END -endif - -let g:limelight_conceal_ctermfg = 240 -let g:limelight_conceal_guifg = '#586e75' diff --git a/tutor/chopsticks.tutor b/tutor/chopsticks.tutor deleted file mode 100644 index c9289b1..0000000 --- a/tutor/chopsticks.tutor +++ /dev/null @@ -1,269 +0,0 @@ -================================================================================ -= C H O P S T I C K S I N T E R A C T I V E T U T O R = -================================================================================ - -This tutorial teaches the key features of the chopsticks Vim configuration. -It assumes you already know basic Vim (if not, run :Tutor first). - -Leader key is , (comma) throughout this tutorial. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 1: SURVIVAL BASICS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -These four commands get you out of any situation: - - 1. Press Esc or type jk to return to Normal mode - 2. Type ,w to save the current file - 3. Type ,x to save and quit - 4. Type ,q to quit (without saving) - -TIP: You can also press Ctrl+s to save from ANY mode (normal, insert, - or visual). Try it now — press i to enter insert mode, then Ctrl+s - to save without leaving insert mode. - -When completely lost, press ,? to open the cheat sheet with every -keybinding. Press q to close it. - - >>> Try it now: press ,? then read through the sheet, then press q - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 2: FINDING FILES -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -chopsticks uses FZF (fuzzy finder) for fast navigation. - - Ctrl+p Fuzzy find files (git-aware — ignores .gitignore'd files) - ,b Search open buffers - ,fh Recent file history - ,rg Search file contents with ripgrep - ,rG Search for the word under your cursor - - >>> Try it now: press Ctrl+p and start typing a filename - -You can also browse files with the built-in file browser: - - ,e Open netrw file browser in current window - ,E Open netrw in a vertical split - -Inside netrw: - Enter Open file - - Go up one directory - % Create new file - d Create new directory - gh Toggle hidden files - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 3: CODE INTELLIGENCE -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -chopsticks uses vim-lsp for code intelligence — no Node.js required. - -First, install a language server for your filetype: - - :LspInstallServer (auto-detects the language) - :LspStatus (check if it's running) - -Once a server is running, these keys become available: - - gd Go to definition - gy Go to type definition - gi Go to implementation - gr List all references - K Show hover documentation - - [g / ]g Jump to previous / next diagnostic - ,rn Rename symbol under cursor - ,ca Code action (auto-fix) - ,f Format buffer (or selection in visual mode) - ,o File outline (symbols) - - >>> Open a source file and try: gd on a function call, then Ctrl+o - to jump back - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 4: EDITING POWER -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -These editing features make chopsticks faster than vanilla Vim. - -EASYMOTION — jump anywhere on screen: - Press s then type two characters from your target location. - Matching positions light up — press the highlighted letter to jump. - - >>> Try it now: press s then type two letters you can see on screen - -MOVE LINES — rearrange code without cut/paste: - Alt+j Move current line down - Alt+k Move current line up - (Works in visual mode too — select lines first with V ) - -SURROUND — change surrounding characters: - cs"' Change surrounding " to ' - cs'
Change surrounding ' to
...
- ds( Delete surrounding parentheses - ysiw" Surround word with " - -COMMENT — toggle comments: - gc Toggle comment (works in visual mode on selections) - gcc Toggle comment on current line - -VISUAL FEEDBACK: - - Yanked text flashes briefly so you know what was copied - - Search highlights auto-clear after you stop moving - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 5: GIT WORKFLOW -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -All git operations through vim-fugitive: - - ,gs Git status (press s to stage, press cc to commit) - ,gd Diff current file (side-by-side split) - ,gb Git blame (who changed each line) - ,gc Git commit - ,gp Git push - ,gl Git pull - -GitGutter shows changes in the sign column (left margin): - + Added line - ~ Modified line - - Deleted line - -Navigate git conflict markers: - ]x Jump to next conflict marker - [x Jump to previous conflict marker - - >>> Try ,gs in a git repository to see the status view - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 6: MARKDOWN & WRITING -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Markdown files get special treatment automatically: - - Word wrap enabled - - Spell checking enabled - - Syntax concealment (bold renders as bold, headings hide # markers) - - Folding by heading level - -Key bindings for markdown: - - ,mp Open live browser preview (auto-refreshes as you type) - ,mt Table of contents in a side window - ,zen Enter zen mode — Goyo + Limelight - (distraction-free writing, only current paragraph highlighted) - zr Unfold all headings - zm Fold all headings - - >>> Open a .md file and try ,zen to enter zen mode. - Press ,zen again to leave. - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 7: WINDOW MANAGEMENT -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Navigate between splits (works with tmux panes too): - - Ctrl+h Move to left split - Ctrl+j Move to split below - Ctrl+k Move to split above - Ctrl+l Move to right split - -Buffer navigation: - - ,h Previous buffer - ,l Next buffer - ,bd Close buffer (keeps window layout) - ,, Switch to last file (toggle between two files) - -Window tricks: - - ,z Maximize current window (press again to restore) - ,= / ,- Resize window height (bigger / smaller) - ,+ / ,_ Resize window width (bigger / smaller) - -Terminal: - - ,tv Open terminal (vertical split) - ,th Open terminal (horizontal, 10 rows) - Esc Esc Exit terminal mode back to normal - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 8: LINTING & FORMATTING -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -ALE runs linters and formatters automatically: - - - Linting happens as you type (normal mode) and on save - - Format-on-save is enabled by default (black, prettier, gofmt, etc.) - -Navigate errors: - - [e / ]e Previous / next ALE error - ,aD Show error detail in a popup - -Supported out of the box: - Python: flake8 + pylint (lint), black + isort (format) - JS/TS: eslint (lint), prettier + eslint (format) - Go: staticcheck (lint), goimports (format) - Rust: cargo (lint), rustfmt (format) - Shell: shellcheck (lint) - And more: yaml, dockerfile, css, markdown, sql - - >>> Write some intentionally bad code and watch the sign column - light up with X (error) and ! (warning) markers - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 9: RUNNING CODE -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Press ,cr to run the current file. It auto-detects the language: - - Python → python3 file.py - JavaScript → node file.js - TypeScript → npx ts-node file.ts - Go → go run file.go - Rust → cargo run - Shell → bash file.sh - C → gcc + run - Lua, Ruby, Perl also supported - - >>> Create a test file (e.g. test.py with: print("hello")) - and press ,cr to run it - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lesson 10: DAILY TIPS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -SEARCH AND REPLACE: - ,* Replace word under cursor throughout the file - // In visual mode, search for selected text - -USEFUL SHORTCUTS: - Y Yank to end of line (consistent with D and C) - ,y / ,Y Yank to system clipboard - ,F Re-indent entire file - ,W Strip all trailing whitespace - :w!! Sudo save (when you forgot to open as root) - ,ev Edit your vimrc - ,sv Reload your vimrc - -SESSIONS: - :Obsess Start recording session (auto-restores next time) - :Obsess! Stop recording - -The startup screen (Startify) shows recent files, sessions, and bookmarks. - - >>> Press ,? one more time to review the full cheat sheet. - You now know the essential chopsticks features. Happy editing! - -================================================================================