diff --git a/.vimrc b/.vimrc index 6762a4a..b47c76a 100644 --- a/.vimrc +++ b/.vimrc @@ -117,6 +117,7 @@ Plug 'tpope/vim-surround' Plug 'tpope/vim-commentary' Plug 'tpope/vim-repeat' Plug 'tpope/vim-unimpaired' +Plug 'tpope/vim-sleuth' Plug 'wellle/targets.vim' Plug 'jiangmiao/auto-pairs' Plug 'easymotion/vim-easymotion' @@ -136,8 +137,10 @@ Plug 'HerringtonDarkholme/yats.vim' Plug 'preservim/vim-markdown' Plug 'fatih/vim-go' -" ── Markdown Preview ────────────────────────────────────────────────────────── +" ── Markdown Preview & Writing ──────────────────────────────────────────────── Plug 'previm/previm' +Plug 'junegunn/goyo.vim' +Plug 'junegunn/limelight.vim' " ── UI ──────────────────────────────────────────────────────────────────────── Plug 'mbbill/undotree' @@ -359,12 +362,19 @@ function! s:SmartFiles() abort endfunction if exists('g:plugs["fzf.vim"]') - nnoremap :call SmartFiles() - nnoremap b :Buffers + nnoremap :call SmartFiles() + nnoremap b :Buffers nnoremap rg :Rg nnoremap rG :RgWord nnoremap rt :Tags nnoremap gF :GFiles + nnoremap fh :History + nnoremap fc :Commands + nnoremap fm :Marks + nnoremap fl :BLines + nnoremap fL :Lines + nnoremap f/ :History/ + nnoremap f: :History: endif let g:fzf_layout = { 'down': '40%' } @@ -595,6 +605,34 @@ if exists('g:plugs["previm"]') endif let g:previm_enable_realtime = 1 +" ============================================================================ +" => Goyo + Limelight (zen mode for focused writing) +" ============================================================================ + +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' + " ============================================================================ " => EasyMotion " ============================================================================ @@ -746,6 +784,16 @@ function! SLGit() abort return empty(l:b) ? '' : ' ' . l:b . ' ' endfunction +" ALE error/warning count +function! SLAle() abort + if !exists('*ale#statusline#Count') | return '' | endif + let l:c = ale#statusline#Count(bufnr('')) + let l:e = l:c.error + l:c.style_error + let l:w = l:c.warning + l:c.style_warning + if l:e == 0 && l:w == 0 | return '' | endif + return printf(' E:%d W:%d ', l:e, l:w) +endfunction + " Assemble the statusline on every redraw function! SLBuild() abort let [l:label, l:hl] = SLMode() @@ -753,6 +801,7 @@ function! SLBuild() abort let l:s .= '%#SLBody# %f ' let l:s .= '%#SLFlag#%m%r' let l:s .= '%#SLBody#%=' + let l:s .= '%#SLFlag#' . SLAle() let l:s .= '%#SLGit#' . SLGit() let l:s .= '%#SLFtype# %y ' let l:s .= '%#SLRight# %l:%c %P ' @@ -1041,89 +1090,71 @@ function! s:CheatSheet() abort call setline(1, [ \ '=== chopsticks — Quick Reference ===', \ '', - \ 'MODES', - \ ' Normal Default. Navigate and run commands.', - \ ' Insert Type text. Enter: i/a/o Leave: Esc or jk', - \ ' Visual Select. Enter: v/V Leave: Esc', - \ '', \ 'SURVIVAL', \ ' Esc / jk Exit insert or visual mode', \ ' :q! + Enter Quit without saving', - \ ' ,x Save and quit | ,w Save', - \ ' Ctrl+s Save (normal + insert mode)', + \ ' ,x Save+quit ,w Save Ctrl+s Save (any mode)', + \ ' :w!! Sudo save (when you forgot to open as root)', \ '', - \ 'FILES & NAVIGATION', - \ ' Ctrl+p Fuzzy find file (git-aware, FZF)', - \ ' ,e Open netrw file browser', - \ ' ,E Open netrw in vertical split', - \ ' ,b Search open buffers (FZF)', + \ 'FILES & SEARCH', + \ ' Ctrl+p Fuzzy find file (git-aware)', + \ ' ,e / ,E File browser / vertical split', + \ ' ,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+^)', - \ ' Ctrl+o / i Jump back / forward in history', \ '', \ 'CODE INTELLIGENCE (vim-lsp)', - \ ' gd Go to definition', - \ ' gy Go to type definition', - \ ' gi Go to implementation', - \ ' gr Show references', - \ ' K Hover documentation', - \ ' [g / ]g Prev / next LSP diagnostic', - \ ' [e / ]e Prev / next ALE error', - \ ' ,ca Code action', - \ ' ,rn Rename symbol', - \ ' ,f Format buffer (or visual selection)', - \ ' ,o File outline (symbols)', - \ ' ,ws Workspace symbols', + \ ' 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', - \ ' ,mp Open live browser preview (previm)', + \ 'MARKDOWN & WRITING', + \ ' ,mp Live browser preview (previm)', \ ' ,mt Table of contents', - \ ' zr Unfold all headings', - \ ' zm Fold all headings', + \ ' ,zen Zen mode (Goyo + Limelight)', + \ ' zr / zm Unfold / fold all headings', \ '', \ 'EDITING', \ ' gc Toggle comment (visual mode too)', - \ ' s + 2 chars EasyMotion — jump anywhere on screen', - \ ' ,j / ,k EasyMotion — line motions', - \ ' ,u / F5 Undo tree (visual branch history)', - \ ' ,y / ,Y Yank / yank line to system clipboard', - \ ' ,p / ,P Paste from system clipboard', - \ ' Alt+j / Alt+k Move line down / up (also visual mode)', - \ ' ,F Re-indent entire file', - \ ' ,W Strip trailing whitespace', + \ ' 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', \ '', - \ 'SPELLING', - \ ' ,ss Toggle spell checking', - \ ' ,sn / ,sp Next / prev misspelling', - \ ' ,sa Add word to dictionary', - \ ' ,s? Suggest corrections', - \ '', \ '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 Vim splits and tmux panes', - \ ' ,h / ,l Prev / next buffer', - \ ' ,bd Close buffer (keep layout)', - \ ' ,tn / ,tc New tab / close tab | ,tl Last tab', - \ ' ,tv / ,th Open terminal (vertical / horizontal)', + \ ' 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 (grow / shrink)', - \ ' ,+ / ,_ Resize width (grow / shrink)', + \ ' ,= / ,- 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 Open scratch markdown buffer', - \ ' ,cd Change CWD to current file directory', - \ ' F2 Paste F3 Line# F4 Relative# F6 Invisible', - \ '', - \ 'SESSION', - \ ' :Obsess Start tracking session', - \ ' :Obsess! Stop tracking', + \ ' ,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)', \ ]) @@ -1132,11 +1163,100 @@ function! s:CheatSheet() abort endfunction nnoremap ? :call CheatSheet() +" ============================================================================ +" => Yank Highlight (flash yanked region for visual feedback) +" ============================================================================ + +if exists('##TextYankPost') && has('timers') + function! s:YankHighlight() abort + if v:event.operator !=# 'y' | return | endif + let l:m = matchadd('IncSearch', + \ printf('\%%>%dl\%%<%dl', line("'[") - 1, line("']") + 1)) + call timer_start(150, {-> matchdelete(l:m)}) + endfunction + augroup ChopstickYankHL + autocmd! + autocmd TextYankPost * call s:YankHighlight() + augroup END +endif + +" ============================================================================ +" => Auto-Clear Search Highlight (clear after idle) +" ============================================================================ + +augroup ChopstickSearchHL + autocmd! + autocmd CursorHold * if get(v:, 'hlsearch', 0) | let v:hlsearch = 0 | endif +augroup END + +" ============================================================================ +" => Run Current File (,cr) +" ============================================================================ + +function! s:RunFile() abort + write + let l:ft = &filetype + let l:file = shellescape(expand('%:p')) + if l:ft ==# 'python' | execute '!python3 ' . l:file + elseif l:ft ==# 'javascript' | execute '!node ' . l:file + elseif l:ft ==# 'typescript' | execute '!npx ts-node ' . l:file + elseif l:ft ==# 'go' | execute '!go run ' . l:file + elseif l:ft ==# 'rust' | execute '!cargo run' + elseif l:ft ==# 'sh' | execute '!bash ' . l:file + elseif l:ft ==# 'c' | execute '!gcc -o /tmp/a.out ' . l:file . ' && /tmp/a.out' + elseif l:ft ==# 'lua' | execute '!lua ' . l:file + elseif l:ft ==# 'ruby' | execute '!ruby ' . l:file + elseif l:ft ==# 'perl' | execute '!perl ' . l:file + else | echo 'No runner for filetype: ' . l:ft + endif +endfunction +nnoremap cr :call RunFile() + +" ============================================================================ +" => Git Conflict Navigation ([x / ]x) +" ============================================================================ + +nnoremap ]x /^\(<<<<<<<\\|=======\\|>>>>>>>\) +nnoremap [x ?^\(<<<<<<<\\|=======\\|>>>>>>>\) + +" ============================================================================ +" => Window Maximize Toggle (,z) +" ============================================================================ + +function! s:ToggleMaximize() abort + if exists('t:maximize_session') + execute t:maximize_session + unlet t:maximize_session + else + let t:maximize_session = winrestcmd() + resize | vertical resize + endif +endfunction +nnoremap z :call ToggleMaximize() + +" ============================================================================ +" => Sudo Save (:w!! when you forget to open as root) +" ============================================================================ + +cnoremap w!! w !sudo tee > /dev/null % + +" ============================================================================ +" => QuickFix Improvements +" ============================================================================ + +augroup ChopstickQF + autocmd! + autocmd QuickFixCmdPost [^l]* cwindow + autocmd QuickFixCmdPost l* lwindow +augroup END + +nnoremap ]q :cnext +nnoremap [q :cprev + " ============================================================================ " => Debug Helpers " ============================================================================ -" Show syntax highlight stack for word under cursor nnoremap sh :call SynStack() function! SynStack() if !exists("*synstack") | return | endif diff --git a/QUICKSTART.md b/QUICKSTART.md index 28d44d9..30fbcfc 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -142,13 +142,15 @@ K Show documentation | `[g` | Jump to previous diagnostic | | `K` | Read the error message | | `,ca` | Apply code action / auto-fix | +| `,cr` | Run current file (auto-detects language) | -### Markdown +### Markdown & Writing | Key | Action | |-----|--------| | `,mp` | Open live preview in browser | | `,mt` | Table of contents (side window) | +| `,zen` | Zen mode (Goyo + Limelight) | | `zr` / `zm` | Unfold / fold all headings | Formatting in the buffer is live: `**bold**` renders as bold, @@ -164,6 +166,7 @@ the cursor enters that line. ,gc commit ,gp push ,gl pull +[x / ]x navigate conflict markers ``` --- @@ -192,28 +195,31 @@ CODE 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 - ,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 Terminal (vertical / horizontal) - Esc Esc Exit terminal mode - ,u Undo tree + ,rn Rename ,ca Code action ,f Format + ,cr Run current file SEARCH + ,rg Ripgrep ,rG Ripgrep word ,fh Recent files + ,fl Lines in buffer ,fc Commands ,fm Marks /text Forward | ?text Backward | n next | N prev // Search visually selected text ,* Replace word under cursor (file-wide) + +MARKDOWN + ,mp Preview | ,mt TOC | ,zen Zen mode + +GIT + ,gs Status ,gd Diff ,gb Blame + ,gc Commit ,gp Push ,gl Pull + [x / ]x Navigate conflict markers + +WINDOWS + Ctrl+h/j/k/l Navigate splits and tmux panes + ,z Maximize / restore window + ,h / ,l Prev / next buffer + ,tv / ,th Terminal (vertical / horizontal) + Esc Esc Exit terminal mode + ]q / [q Next / prev quickfix entry ``` --- diff --git a/README.md b/README.md index 2b64bbb..1d548ab 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,11 @@ # chopsticks > 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/) [![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) ```bash curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash @@ -16,45 +13,26 @@ curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | b --- -## Contents +## What You Get -- [Design Principles](#design-principles) -- [Requirements](#requirements) -- [Installation](#installation) -- [LSP](#lsp) -- [Key Mappings](#key-mappings) -- [Markdown](#markdown) -- [Features](#features) -- [Plugins](#plugins) -- [Customization](#customization) -- [Troubleshooting](#troubleshooting) +**30 plugins. One command. Zero Node.js dependency.** ---- - -## Design Principles - -| Principle | What it means | -|-----------|--------------| -| **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 | 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. +| Feature | What it does | +|---------|-------------| +| **LSP everywhere** | Completion, go-to-definition, hover docs, rename — pure VimScript, works over SSH | +| **Format on save** | ALE runs black, prettier, gofmt automatically. Errors show in statusline. | +| **Fuzzy everything** | Files, buffers, grep, tags, marks, command history — all via FZF with preview | +| **Zen mode** | Goyo + Limelight: distraction-free writing. `,zen` and the world disappears | +| **Run any file** | `,cr` detects filetype and runs it: Python, Go, Rust, JS, C, Shell, and more | +| **Smart indentation** | vim-sleuth auto-detects tabs vs spaces from existing files. No config needed. | +| **Yank highlight** | Yanked text flashes — instant visual feedback, never guess what you copied | +| **Search that clears** | Search highlights disappear after you stop moving. No more `,` spam. | +| **Git workflow** | Status, diff, blame, push, pull. Conflict marker navigation with `[x`/`]x`. | +| **Window maximize** | `,z` toggles current split to full screen and back. | +| **Sudo save** | `:w!!` when you forgot to open as root | +| **ALE in statusline** | Error and warning counts always visible — no surprises | +| **30+ key mappings** | Every common action is one or two keystrokes away. `,?` shows them all. | +| **TTY-aware** | SSH, console, slow connections — degrades gracefully, never breaks | --- @@ -66,12 +44,6 @@ curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | b curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash ``` -Non-interactive / CI: - -```bash -curl -fsSL https://raw.githubusercontent.com/m1ngsama/chopsticks/main/get.sh | bash -s -- --yes -``` - ### Git clone ```bash @@ -79,95 +51,48 @@ git clone https://github.com/m1ngsama/chopsticks.git ~/.vim cd ~/.vim && ./install.sh ``` -### What the installer does - -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 npm formatters (prettier, eslint, etc.) — requires Node.js -7. Offers to install Python formatters/linters (black, isort, flake8, etc.) -8. Offers to install Go tools (gopls, goimports, staticcheck) -9. Offers to append vim-tmux-navigator bindings to `~/.tmux.conf` - -**Supported platforms:** macOS (Homebrew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf). - ---- - -## LSP - -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. - -Install a language server for the current file: - -```vim -:LspInstallServer " auto-detects filetype and installs the correct server -:LspStatus " check server status -``` - -Supported languages and their servers: - -| Language | Server | -|----------|--------| -| Python | pylsp | -| 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 | - -**Note:** While vim-lsp itself needs no Node.js, some language servers (TypeScript, -HTML, CSS, JSON, YAML) are npm packages that require Node.js to run. Python (pylsp), -Go (gopls), and Rust (rust-analyzer) language servers do not need Node.js. - -**Markdown LSP** requires `marksman` as a standalone binary: +### Non-interactive / CI ```bash -brew install marksman # macOS -sudo pacman -S marksman # Arch -# or: install.sh handles it automatically +curl -fsSL ... | bash -s -- --yes ``` +**Supported:** macOS (Homebrew), Debian/Ubuntu (apt), Arch (pacman), Fedora (dnf). + +The installer detects your environment, installs vim-plug, plugins, and offers +system tools (ripgrep, fzf, ctags, shellcheck, marksman) plus language-specific +formatters and linters. + --- ## Key Mappings -**Leader key:** `,` (comma) +**Leader key:** `,` (comma). Press `,?` to open the built-in cheat sheet. -Press `,?` at any time to open the built-in cheat sheet. - -### Files and Buffers +### Files and Search | Key | Action | |-----|--------| -| `Ctrl+p` | Fuzzy file search — git-aware (FZF) | -| `,e` | Open netrw file browser | -| `,E` | Open netrw in vertical split | -| `,b` | Search open buffers (FZF) | -| `,rg` | Project-wide search (ripgrep + FZF) | -| `,rG` | Ripgrep word under cursor (fixed-string) | +| `Ctrl+p` | Fuzzy file search — git-aware | +| `,b` | Search open buffers | +| `,rg` | Project-wide ripgrep search | +| `,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 | +| `,e` / `,E` | File browser / vertical split | | `,,` | Switch to last file | -| `,l` / `,h` | Next / previous buffer | -| `,bd` | Close current buffer (preserves window layout) | -| `,wa` | Save all open buffers | -| `,cd` | Change working directory to current file's directory | +| `,cd` | Change CWD to current file's directory | ### Code Intelligence (vim-lsp) | Key | Action | |-----|--------| | `gd` | Go to definition | -| `gy` | Go to type definition | -| `gi` | Go to implementation | -| `gr` | Show references | +| `gy` | Type definition | +| `gi` | Implementation | +| `gr` | References | | `K` | Hover documentation | | `[g` / `]g` | Previous / next LSP diagnostic | | `[e` / `]e` | Previous / next ALE error | @@ -176,104 +101,91 @@ Press `,?` at any time to open the built-in cheat sheet. | `,ca` | Code action | | `,o` | File outline (symbols) | | `,ws` | Workspace symbols | -| `Tab` / `Shift+Tab` | Navigate completion popup | -| `Enter` | Confirm completion | +| `,cr` | **Run current file** (auto-detects language) | -### Markdown +Install LSP servers on demand: +```vim +:LspInstallServer " auto-detects filetype +:LspStatus " check server status +``` + +| Language | Server | +|----------|--------| +| Python | pylsp | +| JS / TS | typescript-language-server | +| Go | gopls | +| Rust | rust-analyzer | +| C / C++ | clangd | +| Shell | bash-language-server | +| HTML / CSS / JSON / YAML | vscode-*-language-server | +| Markdown | marksman | +| SQL | sqls | + +### Markdown and Writing | Key | Action | |-----|--------| -| `,mp` | Open live preview in browser (previm) | -| `,mt` | Table of contents (side window) | +| `,zen` | **Zen mode** — Goyo + Limelight, distraction-free | +| `,mp` | Live browser preview (previm) | +| `,mt` | Table of contents | | `zr` / `zm` | Unfold / fold all headings | -### Git (vim-fugitive) +Markdown buffers automatically enable `wrap`, `spell`, and concealment +(bold renders as bold, headings hide `#` markers, raw syntax shows on cursor line). + +### Git | Key | Action | |-----|--------| -| `,gs` | Git status | -| `,gc` | Git commit | -| `,gp` | Git push | -| `,gl` | Git pull | -| `,gd` | Git diff | -| `,gb` | Git blame | +| `,gs` | Status | +| `,gd` | Diff | +| `,gb` | Blame | +| `,gc` | Commit | +| `,gp` | Push | +| `,gl` | Pull | +| `[x` / `]x` | Navigate conflict markers | ### Editing | Key | Action | |-----|--------| | `s` + 2 chars | EasyMotion — jump anywhere on screen | -| `gc` | Toggle comment (visual mode too) | -| `Space` | Toggle code fold | +| `gc` | Toggle comment (works in visual mode) | | `Y` | Yank to end of line | -| `Ctrl+d` / `Ctrl+u` | Half-page scroll, cursor centred | -| `Alt+j` / `Alt+k` | Move line down / up (normal and visual) | +| `,y` / `,Y` | Yank to system clipboard | +| `Alt+j` / `Alt+k` | Move line down / up | | `,u` | Undo tree (visual branch history) | -| `F2` | Toggle paste mode | -| `F3` / `F4` | Toggle line numbers / relative numbers | -| `F5` | Toggle undo tree | -| `F6` | Toggle invisible characters | +| `,F` | Re-indent entire file | +| `,W` | Strip trailing whitespace | +| `,*` | Search and replace word under cursor | | `gV` | Reselect last paste | | `//` | Search visual selection | -### Survival - -| Key | Action | -|-----|--------| -| `jk` | Exit insert mode | -| `Esc` | Exit insert / visual mode | -| `jk` | Exit insert mode | -| `Ctrl+s` | Save (any mode) | -| `,w` | Save | -| `,x` | Save and quit | -| `,q` | Quit | -| `,?` | Open cheat sheet | - -### Windows, Tabs, tmux +### Windows and Navigation | Key | Action | |-----|--------| | `Ctrl+h/j/k/l` | Navigate Vim splits **and** tmux panes | -| `,tv` / `,th` | Open terminal (vertical / horizontal split) | +| `,z` | **Maximize / restore** current window | +| `,h` / `,l` | Previous / next buffer | +| `,bd` | Close buffer (keep window layout) | +| `,tv` / `,th` | Terminal (vertical / horizontal) | | `Esc Esc` | Exit terminal mode | -| `,tn` / `,tc` | New tab / close tab | -| `,tl` | Toggle to last tab | +| `]q` / `[q` | Next / previous quickfix entry | +| `Ctrl+d` / `Ctrl+u` | Half-page scroll, cursor centred | + +### Quick Reference + +| Key | Action | +|-----|--------| +| `,?` | Open built-in cheat sheet | +| `jk` | Exit insert mode | +| `Ctrl+s` | Save (any mode) | +| `:w!!` | Sudo save | +| `,w` / `,x` / `,q` | Save / save+quit / quit | | `,ev` / `,sv` | Edit / reload `~/.vimrc` | -| `,cp` / `,cf` | Copy file path / filename to clipboard | -| `,*` | Search and replace word under cursor | -| `,F` | Re-indent entire file | -| `,W` | Strip trailing whitespace | -| `,ms` | Open scratch markdown buffer | -| `,ss` | Toggle spell checking | - ---- - -## 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 side window — press Enter to jump to heading -``` +| `,so` | Source current vim file | +| `F2` Paste | `F3` Line# | `F4` Relative# | `F6` Invisible chars | --- @@ -281,15 +193,24 @@ No Node.js required. Uses `open` (macOS) or `xdg-open` (Linux). ### Statusline -A native, hand-written statusline using the Solarized palette: +Native, hand-written. Solarized palette. Shows mode, file, git branch, filetype, +ALE error/warning count, and cursor position. Background matches tmux bar. ``` - N ~/.vimrc [+] main [vim] 42:7 68% + N ~/.vimrc [+] E:1 W:3 main [vim] 42:7 68% ``` -- 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 +Mode block changes colour: Normal=yellow, Insert=blue, Visual=magenta, Replace=red. + +### Smart Defaults + +- **vim-sleuth** auto-detects indentation from existing files +- **Yank highlight** flashes copied text for 150ms +- **Search highlight** auto-clears after cursor stops moving +- **QuickFix** auto-opens after `:grep`, `:make`, or `:Rg` +- **Format on save** via ALE (black, prettier, gofmt, rustfmt, etc.) +- **Auto-create directories** on save — write to `new/path/file.txt` without `mkdir` first +- **Cursor restore** — reopens files at the last cursor position ### Session Management @@ -300,9 +221,20 @@ A native, hand-written statusline using the Solarized palette: Sessions auto-restore when you open Vim in the same directory. -### Project-Local Config +### TTY / SSH Support -Drop a `.vimrc` in any project root to override settings: +Detected automatically. In TTY mode: +- True colour and cursorline disabled +- FZF preview windows disabled +- IndentLine guides disabled +- Simplified statusline +- Syntax column limit reduced + +### Large File Handling + +Files over 10 MB: syntax highlighting, undo history, and linting automatically disabled. + +### Project-Local Config ```vim " my-project/.vimrc @@ -310,143 +242,44 @@ set shiftwidth=2 let g:ale_python_black_options = '--line-length=100' ``` -### tmux Integration - -`Ctrl+h/j/k/l` navigates seamlessly between Vim splits and tmux panes. - -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' -``` - -### TTY / SSH Support - -Detected automatically when `$TERM` is unset, `dumb`, `linux`, `screen`, or contains `builtin`. 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 stalling. - --- -## Plugins +## Plugins (30) -### Navigation -- **fzf + fzf.vim** — fuzzy finder for files, buffers, tags, ripgrep - -### Git -- **vim-fugitive** — full Git integration -- **vim-gitgutter** — diff signs in the sign column - -### LSP and Completion -- **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 and Formatting -- **ALE** — async linting and format-on-save - -### 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/delete/add surroundings -- **vim-commentary** — `gc` to toggle comments -- **vim-repeat** — repeat plugin maps with `.` -- **vim-unimpaired** — bracket shortcut pairs -- **targets.vim** — additional text objects -- **auto-pairs** — auto-close brackets and quotes -- **vim-easymotion** — `s` + 2 chars to jump anywhere - -### UI -- **vim-solarized8** — color scheme (truecolor support) -- **undotree** — visual undo branch history -- **vim-startify** — startup dashboard and session list -- **indentLine** — indent guides (non-TTY) - -### Session and Navigation -- **vim-obsession** — session tracking -- **vim-tmux-navigator** — seamless Vim/tmux pane navigation +| Category | Plugins | +|----------|---------| +| **Navigation** | fzf, fzf.vim | +| **Git** | vim-fugitive, vim-gitgutter | +| **LSP** | vim-lsp, vim-lsp-settings, asyncomplete.vim, asyncomplete-lsp.vim | +| **Lint/Format** | ALE | +| **Editing** | vim-surround, vim-commentary, vim-repeat, vim-unimpaired, vim-sleuth, targets.vim, auto-pairs, vim-easymotion | +| **Language** | vim-javascript, yats.vim, vim-markdown, vim-go | +| **Writing** | previm, goyo.vim, limelight.vim | +| **UI** | vim-solarized8, undotree, vim-startify, indentLine | +| **Session** | vim-obsession, vim-tmux-navigator | --- ## Customization -### Per-project overrides - -Create `.vimrc` in your project root: - -```vim -" 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`. +Edit `~/.vimrc` directly (`,ev` opens it, `,sv` reloads). Per-project overrides +go in a `.vimrc` at your project root. --- ## Troubleshooting -**Plugins not loading** - -```vim -:PlugInstall " install missing plugins -:PlugUpdate " update all plugins -``` - -**LSP server not starting** - -```vim -:LspInstallServer " install server for current filetype -:LspStatus " check server status -``` - -**Markdown preview not opening** - -`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 COLORTERM=truecolor # for true colour -``` - -**ALE linters not found** - -```bash -which flake8 black prettier eslint # verify tools are on PATH -``` - -**`Ctrl+s` freezes the terminal** - -Add `stty -ixon` to your `~/.bashrc`, `~/.zshrc`, or `~/.config/fish/config.fish`. +| Problem | Solution | +|---------|----------| +| Plugins not loading | `:PlugInstall` then `:PlugUpdate` | +| LSP not starting | `:LspInstallServer` for current filetype | +| Colors look wrong | `export COLORTERM=truecolor` in your shell rc | +| ALE linters missing | `which flake8 black prettier eslint` to verify PATH | +| `Ctrl+s` freezes terminal | Add `stty -ixon` to `~/.bashrc` or `~/.zshrc` | +| Markdown preview broken | Ensure `open` (macOS) or `xdg-open` (Linux) works | --- ## License -[MIT](LICENSE) © m1ng +[MIT](LICENSE)