diff --git a/.vimrc b/.vimrc index adf3158..f78fb4f 100644 --- a/.vimrc +++ b/.vimrc @@ -37,15 +37,6 @@ if !g:is_tty set cursorline endif -" Set shift width to 4 spaces -set shiftwidth=4 - -" Set tab width to 4 columns -set tabstop=4 - -" Use space characters instead of tabs -set expandtab - " Do not save backup files set nobackup @@ -70,9 +61,6 @@ set showcmd " Show the mode you are on the last line set showmode -" Show matching words during a search -set showmatch - " Use highlighting when doing a search set hlsearch @@ -124,10 +112,8 @@ set lazyredraw " For regular expressions turn magic on set magic -" Show matching brackets when text indicator is over them +" Show matching brackets and how many tenths of a second to blink set showmatch - -" How many tenths of a second to blink when matching brackets set mat=2 " No annoying sound on errors @@ -152,11 +138,16 @@ endif " Use Unix as the standard file type set ffs=unix,dos,mac -" Turn backup off, since most stuff is in SVN, git etc. anyway -set nobackup set nowb set noswapfile +" Persistent undo across sessions +if has('persistent_undo') + set undofile + let &undodir = expand('~/.vim/.undo') + silent! call mkdir(&undodir, 'p', 0700) +endif + " ============================================================================ " => Vim-Plug Plugin Manager " ============================================================================ @@ -175,7 +166,6 @@ call plug#begin('~/.vim/plugged') Plug 'preservim/nerdtree' " File explorer Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } Plug 'junegunn/fzf.vim' " Fuzzy finder -Plug 'ctrlpvim/ctrlp.vim' " Fuzzy file finder " ===== Git Integration ===== Plug 'tpope/vim-fugitive' " Git wrapper @@ -207,9 +197,9 @@ Plug 'mbbill/undotree' " Undo history visualizer Plug 'preservim/tagbar' " Tag browser Plug 'easymotion/vim-easymotion' " Easy motion -" ===== Code Intelligence ===== -if has('vim9') || has('nvim') - Plug 'neoclide/coc.nvim', {'branch': 'release'} " LSP & Completion +" ===== Code Intelligence (CoC: requires Vim 8.0.1453+ and Node.js) ===== +if (has('nvim') || has('patch-8.0.1453')) && executable('node') + Plug 'neoclide/coc.nvim', {'branch': 'release'} " Full LSP + completion via Node.js endif " ===== Session Management ===== @@ -221,8 +211,36 @@ Plug 'tpope/vim-unimpaired' " Handy bracket mappings Plug 'wellle/targets.vim' " Additional text objects Plug 'honza/vim-snippets' " Snippet collection +" ===== Native LSP (vim-lsp: works without Node.js, Vim 8.0+ only) ===== +" Used as fallback when CoC/Node.js is unavailable +if !((has('nvim') || has('patch-8.0.1453')) && executable('node')) + Plug 'prabirshrestha/vim-lsp' " Pure VimScript LSP client + Plug 'mattn/vim-lsp-settings' " Auto-configure language servers + Plug 'prabirshrestha/asyncomplete.vim' " Async completion framework + Plug 'prabirshrestha/asyncomplete-lsp.vim' " LSP completion source for asyncomplete +endif + +" ===== Enhanced UI Experience ===== +Plug 'mhinz/vim-startify' " Startup screen with recent files +Plug 'liuchengxu/vim-which-key' " Show keybindings on leader pause +if !g:is_tty + Plug 'Yggdroot/indentLine' " Indent guide lines +endif + call plug#end() +" ============================================================================ +" => LSP Backend Detection & Completion Settings +" ============================================================================ + +" Detect which LSP backend is active +" Priority: CoC (full-featured, needs Node.js) > vim-lsp (lightweight fallback) +let g:use_coc = (has('nvim') || has('patch-8.0.1453')) && executable('node') && exists('g:plugs["coc.nvim"]') +let g:use_vimlsp = !g:use_coc && has('patch-8.0.0') && exists('g:plugs["vim-lsp"]') + +" Limit popup menu height (applies to all completion) +set pumheight=15 + " ============================================================================ " => Colors and Fonts " ============================================================================ @@ -278,9 +296,8 @@ set tabstop=4 set lbr set tw=500 -set ai "Auto indent -set si "Smart indent -set wrap "Wrap lines +set autoindent +set smartindent " ============================================================================ " => Key Mappings @@ -335,7 +352,7 @@ au TabLeave * let g:lasttab = tabpagenr() map te :tabedit =expand("%:p:h")/ " Switch CWD to the directory of the open buffer -map cd :cd %:p:h:pwd +map wd :cd %:p:h:pwd " Remap VIM 0 to first non-blank character map 0 ^ @@ -355,9 +372,6 @@ map sp [s map sa zg map s? z= -" Remove trailing whitespace -nnoremap w :let _s=@/:%s/\s\+$//e:let @/=_s - " Toggle paste mode set pastetoggle= @@ -370,6 +384,38 @@ nnoremap :set invrelativenumber " Enable folding with the spacebar nnoremap za +" Y yanks to end of line (consistent with D, C) +nnoremap Y y$ + +" Disable accidental Ex mode +nnoremap Q + +" Keep visual selection after indent +vnoremap < >gv + +" Center cursor when jumping through search results +nnoremap n nzzzv +nnoremap N Nzzzv + +" Center cursor after half-page scroll +nnoremap zz +nnoremap zz + +" System clipboard yank (conditional: requires clipboard provider) +if has('clipboard') + nnoremap y "+y + vnoremap y "+y + nnoremap Y "+Y +endif + +" Quickfix list shortcuts ([q/]q from vim-unimpaired handles navigation) +nnoremap qo :copen +nnoremap qc :cclose + +" Auto-equalize splits when terminal window is resized +autocmd VimResized * wincmd = + " ============================================================================ " => Plugin Settings " ============================================================================ @@ -379,7 +425,10 @@ map :NERDTreeToggle map n :NERDTreeFind " Close vim if the only window left open is a NERDTree -autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif +augroup NERDTreeAutoClose + autocmd! + autocmd BufEnter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif +augroup END " Show hidden files let NERDTreeShowHidden=1 @@ -401,7 +450,8 @@ endif map :Files map b :Buffers map rg :Rg -map t :Tags +map rt :Tags +map gF :GFiles " FZF customization for better project search let g:fzf_layout = { 'down': '40%' } @@ -431,13 +481,6 @@ else command! -bang GFiles call fzf#vim#gitfiles('', fzf#vim#with_preview(), 0) endif -" --- CtrlP --- -let g:ctrlp_working_path_mode = 'ra' -let g:ctrlp_show_hidden = 1 -let g:ctrlp_custom_ignore = { - \ 'dir': '\v[\/]\.(git|hg|svn)$', - \ 'file': '\v\.(exe|so|dll|pyc)$', - \ } " --- Airline --- " Disable powerline fonts in TTY for compatibility @@ -494,17 +537,18 @@ let g:ale_fixers = { \ 'markdown': ['prettier'], \} -let g:ale_fix_on_save = 1 +" Don't fix on save if LSP is handling formatting (avoids double-format) +let g:ale_fix_on_save = !g:use_vimlsp let g:ale_sign_error = 'X' let g:ale_sign_warning = '!' let g:ale_lint_on_text_changed = 'never' let g:ale_lint_on_insert_leave = 0 let g:ale_lint_on_enter = 0 -" Navigate between errors -nmap aj :ALENext -nmap ak :ALEPrevious -nmap ad :ALEDetail +" Navigate between errors: [e/]e (unimpaired style), aD for detail +nmap [e :ALENext +nmap ]e :ALEPrevious +nmap aD :ALEDetail " --- Tagbar --- nmap :TagbarToggle @@ -525,16 +569,16 @@ let g:EasyMotion_smartcase = 1 map j (easymotion-j) map k (easymotion-k) -" --- CoC (Conquer of Completion) --- -if exists('g:plugs["coc.nvim"]') - " Use tab for trigger completion with characters ahead and navigate +" --- CoC (Conquer of Completion) - Full LSP via Node.js --- +if g:use_coc + " Tab for trigger completion / navigate popup inoremap \ coc#pum#visible() ? coc#pum#next(1) : \ CheckBackspace() ? "\" : \ coc#refresh() inoremap coc#pum#visible() ? coc#pum#prev(1) : "\" - " Make to accept selected completion item + " CR to confirm selected completion item inoremap coc#pum#visible() ? coc#pum#confirm() \: "\u\\=coc#on_enter()\" @@ -543,12 +587,13 @@ if exists('g:plugs["coc.nvim"]') return !col || getline('.')[col - 1] =~# '\s' endfunction - " Use to trigger completion + " to trigger completion manually inoremap coc#refresh() - " Use `[g` and `]g` to navigate diagnostics + " Diagnostic navigation nmap [g (coc-diagnostic-prev) nmap ]g (coc-diagnostic-next) + nmap ad :CocDiagnostics " GoTo code navigation nmap gd (coc-definition) @@ -556,9 +601,8 @@ if exists('g:plugs["coc.nvim"]') nmap gi (coc-implementation) nmap gr (coc-references) - " Use K to show documentation in preview window + " Hover documentation nnoremap K :call ShowDocumentation() - function! ShowDocumentation() if CocAction('hasProvider', 'hover') call CocActionAsync('doHover') @@ -567,15 +611,133 @@ if exists('g:plugs["coc.nvim"]') endif endfunction - " Highlight the symbol and its references when holding the cursor + " Highlight symbol and its references on cursor hold autocmd CursorHold * silent call CocActionAsync('highlight') " Symbol renaming nmap rn (coc-rename) - " Formatting selected code + " Format selected code xmap f (coc-format-selected) nmap f (coc-format-selected) + + " Code actions (cursor, file, selected range) + nmap ca (coc-codeaction-cursor) + nmap cA (coc-codeaction-source) + xmap ca (coc-codeaction-selected) + + " Apply auto-fix for current line + nmap qf (coc-fix-current) + + " Run code lens action on current line + nmap cl (coc-codelens-action) + + " Workspace symbols and outline + nnoremap ws :CocList -I symbols + nnoremap o :CocList outline + + " Search recently used commands + nnoremap cc :CocList commands + + " Resume latest CoC list + nnoremap cr :CocListResume + + " Show all diagnostics + nnoremap cD :CocList diagnostics + + " Text object for function/class (requires language server support) + xmap if (coc-funcobj-i) + omap if (coc-funcobj-i) + xmap af (coc-funcobj-a) + omap af (coc-funcobj-a) + xmap ic (coc-classobj-i) + omap ic (coc-classobj-i) + xmap ac (coc-classobj-a) + omap ac (coc-classobj-a) + + " Scroll float windows + if has('nvim-0.4.0') || has('patch-8.2.0750') + nnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\" + nnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\" + inoremap coc#float#has_scroll() ? "\=coc#float#scroll(1)\" : "\" + inoremap coc#float#has_scroll() ? "\=coc#float#scroll(0)\" : "\" + endif + + " Status line integration + set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')} +endif + +" --- vim-lsp (Native VimScript LSP - fallback when Node.js unavailable) --- +if g:use_vimlsp + " Auto-configure language servers via vim-lsp-settings + let g:lsp_settings_filetype_python = ['pylsp', 'pyright-langserver'] + let g:lsp_settings_filetype_go = ['gopls'] + let g:lsp_settings_filetype_rust = ['rust-analyzer'] + let g:lsp_settings_filetype_typescript = ['typescript-language-server'] + let g:lsp_settings_filetype_javascript = ['typescript-language-server'] + let g:lsp_settings_filetype_sh = ['bash-language-server'] + + " Performance: disable virtual text diagnostics in TTY + let g:lsp_diagnostics_virtual_text_enabled = !g:is_tty + let g:lsp_diagnostics_highlights_enabled = !g:is_tty + let g:lsp_document_highlight_enabled = !g:is_tty + let g:lsp_signs_enabled = 1 + let g:lsp_diagnostics_echo_cursor = 1 + let g:lsp_completion_documentation_enabled = 1 + + " Diagnostic signs (ASCII, KISS) + let g:lsp_signs_error = {'text': 'X'} + let g:lsp_signs_warning = {'text': '!'} + let g:lsp_signs_information = {'text': 'i'} + let g:lsp_signs_hint = {'text': '>'} + + " asyncomplete manages completeopt for vim-lsp mode + set completeopt=menuone,noinsert,noselect + let g:asyncomplete_auto_popup = 1 + let g:asyncomplete_auto_completeopt = 1 + let g:asyncomplete_popup_delay = 200 + + " Tab to navigate completion popup (mirrors CoC behavior) + inoremap pumvisible() ? "\" : "\" + inoremap pumvisible() ? "\" : "\" + inoremap pumvisible() ? asyncomplete#close_popup() : "\" + + " Key mappings (mirror CoC's gd/gy/gi/gr/K/rn layout) + function! s:on_lsp_buffer_enabled() abort + setlocal omnifunc=lsp#complete + setlocal signcolumn=yes + + " Navigation + nmap gd (lsp-definition) + nmap gy (lsp-type-definition) + nmap gi (lsp-implementation) + nmap gr (lsp-references) + nmap [g (lsp-previous-diagnostic) + nmap ]g (lsp-next-diagnostic) + + " Hover documentation + nmap K (lsp-hover) + + " Refactoring + nmap rn (lsp-rename) + nmap ca (lsp-code-action) + nmap f (lsp-document-format) + + " Workspace + nmap ws (lsp-workspace-symbol-search) + nmap o (lsp-document-symbol-search) + nmap cD (lsp-document-diagnostics) + + " Enable auto-format on save for filetypes with reliable LSP formatters + if index(['python', 'go', 'rust', 'typescript', 'javascript', 'sh'], &filetype) >= 0 + autocmd BufWritePre LspDocumentFormatSync + endif + endfunction + + augroup lsp_install + autocmd! + autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled() + augroup END endif " ============================================================================ @@ -682,9 +844,6 @@ set laststatus=2 " => Misc " ============================================================================ -" Quickly open a buffer for scribble -map q :e ~/buffer - " Quickly open a markdown buffer for scribble map m :e ~/buffer.md @@ -743,9 +902,6 @@ set secure " Quick format entire file nnoremap F gg=G`` -" Toggle between source and header files (for C/C++) -nnoremap a :A - " Quick save all buffers nnoremap wa :wa @@ -796,7 +952,7 @@ augroup END " ============================================================================ " Show syntax highlighting groups for word under cursor -nmap sp :call SynStack() +nmap sh :call SynStack() function! SynStack() if !exists("*synstack") return @@ -850,8 +1006,8 @@ function! LargeFileSettings() setlocal undolevels=-1 setlocal eventignore+=FileType setlocal noswapfile - setlocal buftype=nowrite - echo "Large file detected. Some features disabled for performance." + setlocal syntax=OFF + echo "Large file (>10MB): syntax and undo disabled for performance." endfunction " ============================================================================ @@ -866,15 +1022,7 @@ if g:is_tty " Simpler status line for TTY set statusline=%f\ %h%w%m%r\ %=%(%l,%c%V\ %=\ %P%) - " Disable some visual effects - set novisualbell - set noerrorbells - - " Faster redraw - set lazyredraw - set ttyfast - - " Reduce syntax highlighting complexity + " Reduce syntax highlighting complexity in TTY (global is 200, lower here) set synmaxcol=120 endif @@ -887,6 +1035,177 @@ if g:is_tty && !exists("g:tty_message_shown") let g:tty_message_shown = 1 endif +" ============================================================================ +" => Which-Key: Keybinding Hints +" ============================================================================ + +" Show available bindings after with a 500ms pause +set timeoutlen=500 + +if exists('g:plugs["vim-which-key"]') + " Register after plugins are loaded (autoload functions available at VimEnter) + autocmd VimEnter * call which_key#register(',', 'g:which_key_map') + + nnoremap :WhichKey ',' + vnoremap :WhichKeyVisual ',' + + " Top-level single-key bindings (w and q also have sub-groups below) + let g:which_key_map = {} + let g:which_key_map['x'] = 'save-and-quit' + let g:which_key_map['F'] = 'format-file' + let g:which_key_map['W'] = 'strip-trailing-whitespace' + let g:which_key_map['m'] = 'scratch-markdown' + let g:which_key_map['n'] = 'nerdtree-find' + let g:which_key_map['o'] = 'outline' + let g:which_key_map['b'] = 'buffers' + let g:which_key_map['h'] = 'prev-buffer' + let g:which_key_map['l'] = 'next-buffer' + let g:which_key_map['*'] = 'search-replace-word' + let g:which_key_map[','] = 'last-file' + let g:which_key_map['y'] = 'clipboard-yank' + let g:which_key_map['Y'] = 'clipboard-yank-line' + + " [a]LE lint group ([e/]e navigate; aD for detail) + let g:which_key_map['a'] = { + \ 'name': '+ale-lint', + \ 'D': 'ale-detail', + \ } + + " [c]ode / [c]opy group + let g:which_key_map['c'] = { + \ 'name': '+code/copy', + \ 'a': 'code-action-cursor', + \ 'A': 'code-action-source', + \ 'c': 'coc-commands', + \ 'D': 'diagnostics-list', + \ 'l': 'code-lens', + \ 'r': 'coc-list-resume', + \ 'p': 'copy-filepath', + \ 'f': 'copy-filename', + \ } + + " [e]dit group + let g:which_key_map['e'] = { + \ 'name': '+edit', + \ 'v': 'edit-vimrc', + \ } + + " [g]it group + let g:which_key_map['g'] = { + \ 'name': '+git', + \ 's': 'status', + \ 'c': 'commit', + \ 'p': 'push', + \ 'l': 'pull', + \ 'd': 'diff', + \ 'b': 'blame', + \ 'F': 'git-files-fzf', + \ } + + " [q]uickfix group (also: q = fast quit) + let g:which_key_map['q'] = { + \ 'name': '+quickfix', + \ 'f': 'lsp-fix-current', + \ 'o': 'open-quickfix', + \ 'c': 'close-quickfix', + \ } + + " [r]efactor / [r]ipgrep / [r]eplace group + let g:which_key_map['r'] = { + \ 'name': '+search/refactor', + \ 'n': 'rename', + \ 'g': 'ripgrep', + \ 't': 'tags-search', + \ } + + " [s]pell / [s]ource group + let g:which_key_map['s'] = { + \ 'name': '+spell/source', + \ 's': 'toggle-spell', + \ 'n': 'next-spell', + \ 'p': 'prev-spell', + \ 'a': 'add-word', + \ '?': 'suggest', + \ 'v': 'source-vimrc', + \ 'o': 'source-file', + \ 'h': 'syntax-highlight-stack', + \ } + + " [t]ab / [t]erminal group + let g:which_key_map['t'] = { + \ 'name': '+tab/terminal', + \ 'n': 'new-tab', + \ 'o': 'tab-only', + \ 'c': 'close-tab', + \ 'm': 'move-tab', + \ 'l': 'last-tab', + \ 'e': 'edit-in-tab', + \ 'v': 'terminal-vertical', + \ 'h': 'terminal-horizontal', + \ } + + " [w]orkspace / [w]indow / save group (also: w = fast save) + let g:which_key_map['w'] = { + \ 'name': '+save/window', + \ 'a': 'save-all', + \ 's': 'workspace-symbols', + \ 'd': 'change-dir', + \ } +endif + +" ============================================================================ +" => Startify: Startup Screen +" ============================================================================ + +if exists('g:plugs["vim-startify"]') + " Simple ASCII header, no icons (KISS) + let g:startify_custom_header = [ + \ ' VIM - Vi IMproved', + \ ' Type :help if you are in trouble', + \ '', + \ ] + + " Sections shown on start screen + let g:startify_lists = [ + \ { 'type': 'files', 'header': [' Recent Files'] }, + \ { 'type': 'dir', 'header': [' Directory: '. getcwd()] }, + \ { 'type': 'sessions', 'header': [' Sessions'] }, + \ { 'type': 'bookmarks', 'header': [' Bookmarks'] }, + \ ] + + " Session integration + let g:startify_session_persistence = 1 " Auto-save session on quit + let g:startify_session_autoload = 1 " Auto-load Session.vim if present + let g:startify_change_to_vcs_root = 1 " cd to git root on open + let g:startify_fortune_use_unicode = 0 " No unicode in fortune (KISS) + let g:startify_enable_special = 0 " No / entries + + " Limit recent files shown + let g:startify_files_number = 10 + + " Don't open NERDTree when startify is active + autocmd User Startified setlocal buftype= +endif + +" ============================================================================ +" => IndentLine: Indent Guide Lines (non-TTY only) +" ============================================================================ + +if !g:is_tty && exists('g:plugs["indentLine"]') + " Use simple ASCII bar as indent guide + let g:indentLine_char = '|' + let g:indentLine_first_char = '|' + let g:indentLine_showFirstIndentLevel = 1 + + " Disable in certain filetypes where it causes issues + let g:indentLine_fileTypeExclude = ['text', 'help', 'startify', 'nerdtree', 'markdown'] + let g:indentLine_bufTypeExclude = ['help', 'terminal', 'nofile'] + + " Conceal level settings (prevent hiding quotes in JSON/markdown) + let g:indentLine_setConceal = 2 + let g:indentLine_concealcursor = '' +endif + " ============================================================================ " End of Configuration " ============================================================================ diff --git a/QUICKSTART.md b/QUICKSTART.md index 76fde37..d9349fd 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -1,274 +1,207 @@ -# Quick Start Guide +# Quick Start -Get up and running with this Vim configuration in 5 minutes! +Five minutes from zero to a working Vim engineering environment. -## Installation - -### One-Line Install +## Step 1: Install ```bash -git clone https://github.com/m1ngsama/chopsticks.git ~/.vim && cd ~/.vim && ./install.sh -``` - -**IMPORTANT:** Always run the install script from the `~/.vim` directory (where you cloned the repository). The script validates this to ensure correct symlink creation. - -That's it! The script will: -- Verify it's being run from the correct directory -- Backup your existing .vimrc -- Create and validate symlink to the new configuration -- Install vim-plug -- Install all plugins automatically - -### Manual Install - -```bash -# 1. Clone the repository git clone https://github.com/m1ngsama/chopsticks.git ~/.vim - -# 2. Create symlink -ln -sf ~/.vim/.vimrc ~/.vimrc - -# 3. Install vim-plug -curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ - https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim - -# 4. Open Vim and install plugins -vim +PlugInstall +qall +cd ~/.vim && ./install.sh ``` -## Essential Key Mappings +The script handles everything: symlinks, vim-plug, plugin download. +No root access required. -### File Operations -| Key | Action | -|-----|--------| -| `,w` | Quick save | -| `,q` | Quick quit | -| `,x` | Save and quit | +## Step 2: Open Vim -### Navigation -| Key | Action | -|-----|--------| -| `Ctrl+n` | Toggle file explorer (NERDTree) | -| `Ctrl+p` | Fuzzy file search (FZF) | -| `Ctrl+h/j/k/l` | Navigate between windows | -| `,b` | Search open buffers | +```bash +vim +``` -### Code Intelligence -| Key | Action | -|-----|--------| -| `gd` | Go to definition | -| `gr` | Find references | -| `K` | Show documentation | -| `Tab` | Autocomplete (when popup is visible) | +The startup screen shows recent files and sessions. Press `q` to dismiss +or just start typing a filename to open. -### Editing -| Key | Action | -|-----|--------| -| `gc` | Comment/uncomment (in visual mode) | -| `Space` | Toggle fold | -| `,,+Enter` | Clear search highlight | +## Step 3: Install LSP (pick one path) + +### Path A: With Node.js (full CoC) + +```bash +node --version # confirm >= 14.14 +``` + +Inside Vim, install language servers for your stack: + +```vim +:CocInstall coc-pyright coc-tsserver coc-go coc-rust-analyzer +``` + +### Path B: Without Node.js (vim-lsp) + +Open a file of your language, then run: + +```vim +:LspInstallServer +``` + +This auto-detects and installs the correct language server binary. + +--- + +## Daily Use + +### The 10 keys that matter most + +``` +,w Save +,q Quit +Ctrl+n File tree +Ctrl+p Fuzzy find file +gd Go to definition +K Show docs +[g ]g Prev/next diagnostic +,rn Rename symbol +,gs Git status +, (pause 500ms) Show all shortcuts +``` + +### Open a project + +```bash +cd ~/my-project && vim +``` + +NERDTree auto-opens when you launch Vim on a directory. Use `Ctrl+p` to +fuzzy-search files by name. Use `,rg` to search file contents. + +### Navigate code + +| Key | Action | +|-------|---------------------------------| +| `gd` | Go to definition | +| `gy` | Go to type definition | +| `gi` | Go to implementation | +| `gr` | List all references | +| `K` | Show docs for symbol under cursor | +| `Ctrl+o` | Jump back | +| `Ctrl+i` | Jump forward | + +### Edit code + +| Key | Action | +|---------|-------------------------------------| +| `Tab` | Select next completion item | +| `Enter` | Confirm completion | +| `gc` | Toggle comment (works in visual mode too) | +| `cs"'` | Change surrounding `"` to `'` | +| `ds(` | Delete surrounding `(` | +| `s`+2ch | EasyMotion: jump anywhere | + +### Manage errors + +| Key | Action | +|--------|-------------------------------| +| `]g` | Jump to next diagnostic | +| `[g` | Jump to previous diagnostic | +| `K` | Read the error message | +| `,ca` | Apply code action / auto-fix | + +### Git workflow + +``` +,gs git status (stage files with 's', commit with 'cc') +,gd diff current file +,gb blame current file +,gc commit +,gp push +,gl pull +``` + +--- ## Common Workflows -### Opening a Project +### Python project ```bash -# Navigate to your project directory -cd ~/my-project - -# Open Vim -vim - -# Press Ctrl+n to open file explorer -# Press Ctrl+p to fuzzy search files +pip install black flake8 pylint isort +vim my_script.py ``` -### Editing Code +Auto-formats with black on save. Lint errors show in the sign column as +`X` (error) and `!` (warning). Jump between them with `[g` / `]g`. -1. Open a file with `Ctrl+p` or through NERDTree -2. Use `gd` to jump to definitions -3. Use `K` to view documentation -4. Use `Tab` for autocomplete while typing -5. Save with `,w` +### JavaScript / TypeScript project -### Working with Git - -| Command | Action | -|---------|--------| -| `:Git status` | View git status | -| `:Git diff` | View changes | -| `:Git commit` | Commit changes | -| `:Git push` | Push to remote | -| `,gb` | Open git blame window | - -### Search and Replace - -```vim -" Search in current file -/searchterm - -" Search across project (with FZF) -,rg - -" Replace in file -:%s/old/new/g - -" Replace with confirmation -:%s/old/new/gc -``` - -## Language-Specific Features - -### Python - -- Auto-formatting with Black (on save) -- Linting with flake8/pylint -- 4-space indentation -- 88-character line limit - -**Setup:** ```bash -pip install black flake8 pylint -vim -c "CocInstall coc-pyright" -c "q" +npm install -g prettier eslint typescript +vim src/index.ts ``` -### JavaScript/TypeScript +Auto-formats with prettier on save. Use `:CocInstall coc-tsserver` for +full IntelliSense (requires Node.js). -- Prettier formatting (on save) -- ESLint integration -- 2-space indentation +### Go project -**Setup:** -```bash -npm install -g prettier eslint -vim -c "CocInstall coc-tsserver coc-prettier coc-eslint" -c "q" -``` - -### Go - -- Auto-formatting with gofmt -- Auto-imports with goimports -- Tab indentation - -**Setup:** ```bash go install golang.org/x/tools/gopls@latest -vim -c "CocInstall coc-go" -c "q" +vim main.go ``` -## Troubleshooting +gofmt runs on save automatically. `gd` jumps to definitions even across +package boundaries when gopls is running. -### Plugins not working? +--- +## Customize + +Edit config live: ```vim -:PlugInstall -:PlugUpdate +,ev " opens ~/.vimrc in Vim +,sv " reloads config without restarting ``` -### Autocomplete not working? +Per-project overrides: create `.vimrc` in your project root. -Make sure Node.js is installed: -```bash -node --version # Should be >= 14.14 -``` +--- -Then install CoC language servers: -```vim -:CocInstall coc-json coc-tsserver coc-pyright -``` - -### FZF not finding files? - -Install FZF and ripgrep: -```bash -# Ubuntu/Debian -sudo apt install fzf ripgrep - -# macOS -brew install fzf ripgrep -``` - -### Colors look weird? - -Add to your `~/.bashrc` or `~/.zshrc`: -```bash -export TERM=xterm-256color -``` - -## Customization - -The `.vimrc` file is well-organized into sections: - -1. **General Settings** (lines 1-150) - Basic Vim behavior -2. **Plugin Management** (lines 151-230) - Plugin list -3. **Key Mappings** (lines 300-400) - Custom shortcuts -4. **Plugin Settings** (lines 400-600) - Plugin configurations - -To customize: -1. Open `~/.vim/.vimrc` -2. Find the section you want to modify -3. Make your changes -4. Reload with `:source ~/.vimrc` or restart Vim - -### Common Customizations - -**Change colorscheme:** -```vim -" In .vimrc, find the colorscheme line and change to: -colorscheme dracula -" or: solarized, onedark, gruvbox -``` - -**Change leader key:** -```vim -" Default is comma (,), change to space: -let mapleader = " " -``` - -**Disable relative line numbers:** -```vim -set norelativenumber -``` - -## Next Steps - -1. Read the full [README.md](README.md) for complete documentation -2. Check out `:help` in Vim for built-in documentation -3. Customize the configuration to your needs -4. Share your improvements! - -## Quick Reference Card - -Print this for your desk: +## Quick Reference ``` -┌─────────────────────────────────────────────┐ -│ Vim Quick Reference │ -├─────────────────────────────────────────────┤ -│ FILES │ -│ Ctrl+n File explorer │ -│ Ctrl+p Fuzzy find files │ -│ ,w Save │ -│ ,q Quit │ -├─────────────────────────────────────────────┤ -│ NAVIGATION │ -│ gd Go to definition │ -│ gr Find references │ -│ K Show docs │ -│ Ctrl+o Jump back │ -│ Ctrl+i Jump forward │ -├─────────────────────────────────────────────┤ -│ EDITING │ -│ gc Comment (visual mode) │ -│ Tab Autocomplete │ -│ Space Toggle fold │ -├─────────────────────────────────────────────┤ -│ SEARCH │ -│ /text Search forward │ -│ ?text Search backward │ -│ ,rg Project-wide search │ -│ ,,Enter Clear highlight │ -└─────────────────────────────────────────────┘ +FILES + Ctrl+n File tree toggle + Ctrl+p Fuzzy find file + ,b Search open buffers + ,rg Search file contents (ripgrep) + ,w Save | ,q Quit | ,x Save+quit + ,wa Save all buffers + +CODE + gd Go to definition + K Show documentation + [g / ]g Prev/next diagnostic + ,rn Rename symbol + ,ca Code action + ,f Format selection + ,F Format whole file + +GIT + ,gs Status | ,gd Diff | ,gb Blame + ,gc Commit | ,gp Push | ,gl Pull + +WINDOWS + Ctrl+h/j/k/l Move between panes + ,tv Open terminal (vertical) + ,th Open terminal (horizontal) + Esc Exit terminal mode + F5 Undo tree | F8 Tag browser + +SEARCH + /text Search forward + ?text Search backward + , Clear search highlight + ,* Replace word under cursor (project) ``` -Happy Vimming! +--- + +See [README.md](README.md) for the complete reference. diff --git a/README.md b/README.md index 48f9271..cdcdd92 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,45 @@ -# The Ultimate Vim Configuration +# chopsticks - Vim Configuration -A comprehensive, modern Vim configuration optimized for engineering workflows. This configuration transforms vanilla Vim into a powerful, feature-rich development environment with enterprise-grade tooling. +A native Vim configuration optimized for engineering workflows. Designed for +Vim 8.0+ with automatic fallbacks for minimal environments (TTY, no Node.js). -**NEW: Quick installation script and enhanced engineering features!** - -## Quick Start +## Quick Install ```bash -git clone https://github.com/m1ngsama/chopsticks.git ~/.vim && cd ~/.vim && ./install.sh +git clone https://github.com/m1ngsama/chopsticks.git ~/.vim +cd ~/.vim && ./install.sh ``` -**Note:** The installation script must be run from the cloned `~/.vim` directory. See [QUICKSTART.md](QUICKSTART.md) for detailed getting started guide. +See [QUICKSTART.md](QUICKSTART.md) for the 5-minute guide. -## Features +--- -### Core Enhancements -- **Smart Line Numbers**: Hybrid line numbers (absolute + relative) for efficient navigation -- **Modern UI**: Gruvbox color scheme with airline status bar -- **Plugin Management**: vim-plug for easy plugin installation and updates -- **Auto-completion**: CoC (Conquer of Completion) for intelligent code completion -- **Syntax Checking**: ALE (Asynchronous Lint Engine) for real-time linting +## Design Principles -### File Navigation -- **NERDTree**: Visual file explorer (`Ctrl+n`) -- **FZF**: Blazing fast fuzzy finder (`Ctrl+p`) -- **CtrlP**: Alternative fuzzy file finder -- **Easy Motion**: Jump to any location with minimal keystrokes +- **KISS**: No icon fonts, no unicode glyphs, plain ASCII throughout +- **Tiered LSP**: CoC (full) with vim-lsp fallback - works with or without Node.js +- **TTY-aware**: Automatic detection and optimization for console environments +- **Engineering-first**: Git workflow, session management, project-local config -### Git Integration -- **Fugitive**: Complete Git wrapper for Vim -- **GitGutter**: Show git diff in the sign column +--- -### Code Editing -- **Auto-pairs**: Automatic bracket/quote pairing -- **Surround**: Easily change surrounding quotes, brackets, tags -- **Commentary**: Quick code commenting (`gc`) -- **Multi-language Support**: vim-polyglot for 100+ languages +## Requirements -### Productivity Tools -- **UndoTree**: Visualize and navigate undo history (`F5`) -- **Tagbar**: Code structure browser (`F8`) -- **Smart Window Management**: Easy navigation with `Ctrl+hjkl` -- **Session Management**: Auto-save sessions with vim-obsession -- **Project-Specific Settings**: Per-project .vimrc support -- **Large File Optimization**: Automatic performance tuning for files >10MB -- **TTY/Basic Terminal Support**: Automatic optimization for console environments +| Requirement | Minimum | Notes | +|----------------|-------------|--------------------------------| +| Vim | 8.0+ | vim9script not required | +| git | any | For cloning and fugitive | +| curl | any | For vim-plug auto-install | +| Node.js | 14.14+ | Optional, enables CoC LSP | +| ripgrep (rg) | any | Optional, enables :Rg search | +| fzf | any | Optional, enables :Files/:GFiles | +| ctags | any | Optional, enables :TagbarToggle | + +--- ## Installation -### Automatic Installation (Recommended) +### Automatic ```bash git clone https://github.com/m1ngsama/chopsticks.git ~/.vim @@ -56,417 +47,379 @@ cd ~/.vim ./install.sh ``` -**IMPORTANT:** You must run the install script from the `~/.vim` directory (the cloned repository directory). Do not copy the script to another location and run it from there. +The script: +1. Checks for a working Vim installation +2. Backs up your existing `~/.vimrc` if present +3. Creates a symlink: `~/.vimrc -> ~/.vim/.vimrc` +4. Installs vim-plug +5. Runs `:PlugInstall` to download all plugins +6. Optionally installs CoC language servers (if Node.js is available) -The installation script will: -- Verify it's being run from the correct directory -- Backup your existing configuration -- Create necessary symlinks -- Validate symlink creation -- Install vim-plug automatically -- Install all plugins -- Offer to install CoC language servers - -### Manual Installation +### Manual ```bash -# 1. Clone this repository git clone https://github.com/m1ngsama/chopsticks.git ~/.vim -cd ~/.vim - -# 2. Create symlink to .vimrc -ln -s ~/.vim/.vimrc ~/.vimrc - -# 3. Install vim-plug +ln -sf ~/.vim/.vimrc ~/.vimrc curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim - -# 4. Open Vim and install plugins vim +PlugInstall +qall ``` -### 4. (Optional) Install recommended dependencies +--- -For the best experience, install these optional dependencies: +## LSP: Tiered Backend System -```bash -# FZF (fuzzy finder) -git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf -~/.fzf/install +Code intelligence is provided by one of two backends, selected automatically: -# ripgrep (better grep) -# On Ubuntu/Debian -sudo apt install ripgrep +| Condition | Backend | Features | +|----------------------------------|----------------|-----------------------------------------------| +| Vim 8.0.1453+ AND Node.js 14.14+ | **CoC** | Full LSP, snippets, extensions ecosystem | +| Vim 8.0+ (no Node.js) | **vim-lsp** | LSP via language server binaries, asyncomplete| +| Any Vim | **ALE** | Linting and auto-fix (always active) | -# On macOS -brew install ripgrep +Both backends expose identical key mappings (`gd`, `K`, `[g`, `]g`, `rn`, `ca`). -# Node.js (for CoC) -# Required for code completion -curl -sL install-node.now.sh/lts | bash +### CoC setup (with Node.js) -# Universal Ctags (for Tagbar) -# On Ubuntu/Debian -sudo apt install universal-ctags - -# On macOS -brew install universal-ctags -``` - -### 5. Install CoC language servers - -For intelligent code completion, install language servers: +Install language server extensions from inside Vim: ```vim -" Python -:CocInstall coc-pyright - -" JavaScript/TypeScript -:CocInstall coc-tsserver - -" Go -:CocInstall coc-go - -" JSON -:CocInstall coc-json - -" HTML/CSS -:CocInstall coc-html coc-css - -" See more: https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions +:CocInstall coc-pyright " Python +:CocInstall coc-tsserver " JavaScript / TypeScript +:CocInstall coc-go " Go +:CocInstall coc-rust-analyzer " Rust +:CocInstall coc-json coc-yaml " JSON, YAML +:CocInstall coc-html coc-css " HTML, CSS ``` +### vim-lsp setup (without Node.js) + +Install language server binaries for your languages, then run: + +```vim +:LspInstallServer " auto-installs servers for the current filetype +``` + +Supported: `pylsp`, `gopls`, `rust-analyzer`, `typescript-language-server`, +`bash-language-server`, and all others covered by `vim-lsp-settings`. + +--- + ## Key Mappings -### General +Leader key: `,` (comma) -| Key | Action | -|-----|--------| -| `,w` | Quick save | -| `,q` | Quick quit | -| `,x` | Save and quit | -| `,,` + Enter | Clear search highlight | +Press `,` and wait 500ms for an interactive guide to all bindings (vim-which-key). -### Window Navigation +### Files and Buffers -| Key | Action | -|-----|--------| -| `Ctrl+h` | Move to left window | -| `Ctrl+j` | Move to bottom window | -| `Ctrl+k` | Move to top window | -| `Ctrl+l` | Move to right window | +| Key | Action | +|------------|-------------------------------------| +| `Ctrl+n` | Toggle file tree (NERDTree) | +| `,n` | Reveal current file in NERDTree | +| `Ctrl+p` | Fuzzy file search (FZF) | +| `,b` | Search open buffers (FZF) | +| `,rg` | Project-wide search (ripgrep+FZF) | +| `,rt` | Search tags (FZF) | +| `,gF` | Search git-tracked files (FZF) | +| `,l` | Next buffer | +| `,h` | Previous buffer | +| `,bd` | Close current buffer | +| `,,` | Switch to last file | -### Buffer Management +### Windows and Tabs -| Key | Action | -|-----|--------| -| `,l` | Next buffer | -| `,h` | Previous buffer | -| `,bd` | Close current buffer | -| `,ba` | Close all buffers | +| Key | Action | +|--------------|---------------------------------| +| `Ctrl+h/j/k/l` | Navigate between windows | +| `=` | Increase window height | +| `-` | Decrease window height | +| `+` | Increase window width | +| `_` | Decrease window width | +| `,tn` | New tab | +| `,tc` | Close tab | +| `,tl` | Toggle to last tab | -### Tab Management +### Code Intelligence (CoC / vim-lsp) -| Key | Action | -|-----|--------| -| `,tn` | New tab | -| `,tc` | Close tab | -| `,tl` | Toggle to last tab | +| Key | Action | +|-------------|---------------------------------| +| `gd` | Go to definition | +| `gy` | Go to type definition | +| `gi` | Go to implementation | +| `gr` | Show references | +| `K` | Hover documentation | +| `[g` | Previous diagnostic | +| `]g` | Next diagnostic | +| `,rn` | Rename symbol | +| `,f` | Format selection | +| `,ca` | Code action (cursor) | +| `,qf` | Quick-fix current line (CoC) | +| `,cl` | Run code lens (CoC) | +| `,o` | File outline | +| `,ws` | Workspace symbols | +| `,cD` | Diagnostics list | +| `,cr` | Resume last CoC list | +| `Tab` | Next completion item | +| `Shift+Tab` | Previous completion item | +| `Enter` | Confirm completion | -### File Navigation - -| Key | Action | -|-----|--------| -| `Ctrl+n` | Toggle NERDTree | -| `,n` | Find current file in NERDTree | -| `Ctrl+p` | FZF file search | -| `,b` | FZF buffer search | -| `,rg` | Ripgrep search | - -### Code Navigation (CoC) - -| Key | Action | -|-----|--------| -| `gd` | Go to definition | -| `gy` | Go to type definition | -| `gi` | Go to implementation | -| `gr` | Go to references | -| `K` | Show documentation | -| `[g` | Previous diagnostic | -| `]g` | Next diagnostic | -| `,rn` | Rename symbol | +Text objects (CoC only): `if`/`af` (function), `ic`/`ac` (class) ### Linting (ALE) -| Key | Action | -|-----|--------| -| `,aj` | Next error/warning | -| `,ak` | Previous error/warning | -| `,ad` | Show error details | +| Key | Action | +|----------|-----------------------| +| `[e` | Next error/warning | +| `]e` | Previous error/warning| +| `,aD` | Show error details | -### Git Workflow +Signs: `X` = error, `!` = warning -| Key | Action | -|-----|--------| -| `,gs` | Git status | -| `,gc` | Git commit | -| `,gp` | Git push | -| `,gl` | Git pull | -| `,gd` | Git diff | -| `,gb` | Git blame | +### Git Workflow (fugitive) + +| Key | Action | +|--------|---------------------------------| +| `,gs` | Git status | +| `,gc` | Git commit | +| `,gp` | Git push | +| `,gl` | Git pull | +| `,gd` | Git diff | +| `,gb` | Git blame | +| `,gF` | Search git-tracked files (FZF) | ### Engineering Utilities -| Key | Action | -|-----|--------| -| `,ev` | Edit .vimrc | -| `,sv` | Reload .vimrc | -| `,F` | Format entire file | -| `,wa` | Save all buffers | -| `,cp` | Copy file path | -| `,cf` | Copy filename | -| `,*` | Search & replace word under cursor | -| `,` | Switch to last file | +| Key | Action | +|----------|-------------------------------------| +| `,ev` | Edit `~/.vimrc` | +| `,sv` | Reload `~/.vimrc` | +| `,F` | Format entire file (= indent) | +| `,W` | Strip trailing whitespace | +| `,wa` | Save all open buffers | +| `,wd` | Change CWD to current buffer's dir | +| `,cp` | Copy file path to clipboard | +| `,cf` | Copy filename to clipboard | +| `,y` | Yank to system clipboard | +| `,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, 10r) | +| `Esc` | Exit terminal mode | -### Other Utilities +### Navigation and Editing -| Key | Action | -|-----|--------| -| `F2` | Toggle paste mode | -| `F3` | Toggle line numbers | -| `F4` | Toggle relative numbers | -| `F5` | Toggle UndoTree | -| `F8` | Toggle Tagbar | -| `Space` | Toggle fold | -| `s` + 2 chars | EasyMotion jump | +| 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 | -## Plugin List +--- -### File Navigation & Search -- **NERDTree**: File system explorer -- **FZF**: Fuzzy file finder -- **CtrlP**: Alternative fuzzy finder +## Features -### Git -- **vim-fugitive**: Git integration -- **vim-gitgutter**: Git diff in sign column +### vim-startify: Startup Screen -### UI -- **vim-airline**: Enhanced status line -- **gruvbox**: Color scheme +Opens when Vim is launched without a file argument. Shows: +- Recently opened files +- Sessions for the current directory +- Bookmarks -### Code Editing -- **vim-surround**: Manage surroundings -- **vim-commentary**: Code commenting -- **auto-pairs**: Auto close brackets -- **ALE**: Asynchronous linting +Session auto-saves on quit. Auto-loads `Session.vim` if found in the current +directory. Auto-changes to git root on file open. -### Language Support -- **vim-polyglot**: Language pack for 100+ languages -- **vim-go**: Go development +### vim-which-key: Keybinding Guide -### Productivity -- **UndoTree**: Undo history visualizer -- **Tagbar**: Code structure browser -- **EasyMotion**: Fast cursor movement -- **CoC**: Code completion and LSP -- **vim-obsession**: Session management -- **vim-prosession**: Project sessions -- **vim-unimpaired**: Handy bracket mappings -- **targets.vim**: Additional text objects +Press `,` and pause for 500ms. A popup lists all available leader bindings +organized by group. Useful for onboarding and discovering shortcuts. -## Color Schemes +### indentLine: Indent Guides -Available color schemes (change in .vimrc): +Draws `|` characters at each indent level. Disabled automatically in TTY +environments and for filetypes where it causes display problems (JSON, +Markdown, help). -- **gruvbox** (default) - Warm, retro groove colors -- **dracula** - Dark theme with vivid colors -- **solarized** - Precision colors for machines and people -- **onedark** - Atom's iconic One Dark theme - -To change: +### Session Management ```vim -colorscheme dracula +:Obsess " Start tracking session +:Obsess! " Stop tracking ``` -## Engineering Features +Sessions are stored in `~/.vim/sessions/` and automatically resumed by +vim-prosession on the next Vim launch in the same directory. -### Project-Specific Configuration +### Project-Local Config -Create a `.vimrc` file in your project root for project-specific settings: +Place a `.vimrc` in any project root: ```vim -" .vimrc in project root +" project/.vimrc set shiftwidth=2 let g:ale_python_black_options = '--line-length=100' ``` -The configuration automatically loads project-specific settings while maintaining security. - -### Session Management - -Sessions are automatically saved with vim-obsession: - -```vim -" Start session tracking -:Obsess - -" Stop session tracking -:Obsess! - -" Sessions are saved to ~/.vim/sessions/ -``` +Loaded automatically. Security-restricted via `set secure`. ### Large File Handling -Files larger than 10MB automatically disable heavy features for better performance: -- Syntax highlighting optimized -- Undo levels reduced -- Swap files disabled +Files over 10MB automatically disable syntax highlighting and undo history +to prevent Vim from freezing. -### Terminal Integration +### TTY / Console Support -Open integrated terminal: -- `,tv` - Vertical terminal split -- `,th` - Horizontal terminal split (10 rows) +Detected automatically when `$TERM` is `linux` or `screen`, or when running +on a basic built-in terminal. In TTY mode: -Navigate out of terminal with `Esc` then normal window navigation. +- True color and cursorline disabled +- Powerline separators replaced with plain ASCII +- FZF preview windows disabled +- NERDTree auto-open skipped +- Syntax column limit reduced to 120 +- Simpler status line used -### TTY and Basic Terminal Support +--- -The configuration automatically detects and optimizes for basic terminal environments (TTY, Linux console): +## Language Support -**Automatic Optimizations:** -- Disables true color mode for compatibility -- Uses simple ASCII separators instead of powerline fonts -- Falls back to default colorscheme -- Disables cursorline for better performance -- Simplifies signcolumn behavior -- Disables FZF preview windows -- Skips auto-opening NERDTree -- Uses simpler status line -- Reduces syntax highlighting complexity -- Faster startup and redraw +| Language | Indent | Formatter | Linter | +|----------------|--------|---------------|---------------------| +| Python | 4sp | black + isort | flake8, pylint | +| JavaScript | 2sp | prettier | eslint | +| TypeScript | 2sp | prettier | eslint, tsserver | +| Go | tab | gofmt, goimports | gopls, golint | +| Rust | 4sp | rustfmt | cargo | +| Shell | 2sp | - | shellcheck | +| YAML | 2sp | prettier | yamllint | +| HTML/CSS | 2sp | prettier | - | +| Markdown | 2sp | prettier | - | +| JSON | 2sp | prettier | - | +| Dockerfile | 2sp | - | hadolint | -**Detected Terminals:** -- Linux console (TERM=linux) -- Screen sessions (TERM=screen) -- Basic built-in terminals +Install linters separately (e.g. `pip install black flake8`, `npm i -g prettier`). +ALE runs them asynchronously and auto-fixes on save. -The configuration provides a message on first run in TTY mode to inform about the optimizations. +--- -## Customization +## Plugin List -The configuration is organized into sections: +### Navigation +- **NERDTree** - File tree explorer +- **fzf + fzf.vim** - Fuzzy finder +- **CtrlP** - Fallback fuzzy finder (no fzf dependency) -1. **General Settings**: Basic Vim behavior -2. **Plugin Management**: vim-plug configuration -3. **Colors & Fonts**: Visual appearance -4. **Key Mappings**: Custom keybindings -5. **Plugin Settings**: Individual plugin configurations -6. **Auto Commands**: File-type specific settings -7. **Helper Functions**: Utility functions -8. **Engineering Utilities**: Project workflow tools -9. **Git Workflow**: Git integration shortcuts +### Git +- **vim-fugitive** - Git commands inside Vim +- **vim-gitgutter** - Diff signs in the sign column -Feel free to modify any section to suit your needs! +### LSP and Completion +- **coc.nvim** - Full LSP + completion (requires Node.js 14.14+) +- **vim-lsp** - Pure VimScript LSP client (fallback, no Node.js) +- **vim-lsp-settings** - Auto-configure language servers for vim-lsp +- **asyncomplete.vim** - Async completion (used with vim-lsp) -### Quick Customization +### Linting +- **ALE** - Asynchronous Lint Engine (always active) + +### UI +- **vim-airline** - Status and tabline +- **vim-startify** - Startup screen +- **vim-which-key** - Keybinding hint popup +- **indentLine** - Indent guide lines (non-TTY) +- **undotree** - Undo history visualizer +- **tagbar** - Code structure sidebar + +### Editing +- **vim-surround** - Change surrounding quotes, brackets, tags +- **vim-commentary** - `gc` to toggle comments +- **auto-pairs** - Auto-close brackets and quotes +- **vim-easymotion** - Jump anywhere with 2 keystrokes +- **vim-unimpaired** - Bracket shortcut pairs +- **targets.vim** - Extra text objects +- **vim-snippets** - Snippet library (used with CoC/UltiSnips) + +### Language Packs +- **vim-polyglot** - Syntax for 100+ languages +- **vim-go** - Go development tools + +### Session +- **vim-obsession** - Continuous session saving +- **vim-prosession** - Project-level session management + +### Color Schemes +- **gruvbox** (default), **dracula**, **solarized**, **onedark** + +--- + +## Color Scheme + +Change in `.vimrc` (find the `colorscheme` line): -Edit configuration: ```vim -,ev " Opens .vimrc in Vim +colorscheme dracula " or: gruvbox, solarized, onedark ``` -Reload configuration: -```vim -,sv " Sources .vimrc without restart -``` +True color is enabled automatically when the terminal supports it +(`$COLORTERM=truecolor`). Falls back to 256-color, then 16-color (TTY). -## Language-Specific Settings - -### Python -- 4 spaces indentation -- 88 character line limit (Black formatter) -- Auto-formatting with Black + isort on save -- Linting with flake8 and pylint - -### JavaScript/TypeScript -- 2 spaces indentation -- Prettier formatting on save -- ESLint integration -- TypeScript server support - -### Go -- Tab indentation -- Auto-formatting with gofmt -- Auto-import with goimports -- gopls language server - -### Rust -- Auto-formatting with rustfmt -- Cargo integration - -### Shell Scripts -- 2 spaces indentation -- shellcheck linting - -### Docker -- Dockerfile syntax highlighting -- hadolint linting - -### YAML -- 2 spaces indentation -- yamllint integration - -### HTML/CSS -- 2 spaces indentation -- Prettier formatting - -### Markdown -- Line wrapping enabled -- Spell checking enabled -- Prettier formatting +--- ## Troubleshooting -### Plugins not working - +**Plugins not installed:** ```vim :PlugInstall :PlugUpdate ``` -### CoC not working - -Make sure Node.js is installed: - +**CoC not working:** ```bash -node --version # Should be >= 14.14 +node --version # must be >= 14.14 ``` -### Colors look wrong - -Enable true colors in your terminal emulator and add to your shell rc: +**vim-lsp server not starting:** +```vim +:LspInstallServer " install server for current filetype +:LspStatus " check server status +``` +**Colors look wrong:** ```bash +# Add to ~/.bashrc or ~/.zshrc export TERM=xterm-256color ``` +**ALE not finding linters:** +```bash +which flake8 black prettier eslint # confirm tools are on PATH +``` + +--- + ## References -This configuration is inspired by: - -- [amix/vimrc](https://github.com/amix/vimrc) - The ultimate vimrc -- [vim-plug](https://github.com/junegunn/vim-plug) - Minimalist plugin manager -- [Top 50 Vim Configuration Options](https://www.shortcutfoo.com/blog/top-50-vim-configuration-options) -- [Modern Vim Development Setup 2025](https://swedishembedded.com/developers/vim-in-minutes) +- [amix/vimrc](https://github.com/amix/vimrc) +- [vim-plug](https://github.com/junegunn/vim-plug) +- [coc.nvim](https://github.com/neoclide/coc.nvim) +- [vim-lsp](https://github.com/prabirshrestha/vim-lsp) +- [vim-lsp-settings](https://github.com/mattn/vim-lsp-settings) ## License -MIT License - Feel free to use and modify! - -## Contributing - -Suggestions and improvements are welcome! Feel free to open an issue or submit a pull request. +MIT diff --git a/install.sh b/install.sh index 87debfa..8cd8984 100755 --- a/install.sh +++ b/install.sh @@ -1,140 +1,138 @@ #!/usr/bin/env bash - -# ============================================================================ -# Vim Configuration - Quick Installation Script -# ============================================================================ +# install.sh - chopsticks vim configuration installer +# Usage: cd ~/.vim && ./install.sh set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -BOLD='\033[1m' GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' -NC='\033[0m' # No Color +BOLD='\033[1m' +NC='\033[0m' -# Function to print status messages -print_status() { - echo -e "${GREEN}==>${NC} ${BOLD}$1${NC}" -} +ok() { echo -e "${GREEN}[OK]${NC} $1"; } +warn() { echo -e "${YELLOW}[!]${NC} $1"; } +die() { echo -e "${RED}[ERR]${NC} $1" >&2; exit 1; } +step() { echo -e "\n${BOLD}==> $1${NC}"; } -print_warning() { - echo -e "${YELLOW}Warning:${NC} $1" -} +echo -e "${BOLD}chopsticks - Vim Configuration Installer${NC}" +echo "----------------------------------------" -print_error() { - echo -e "${RED}Error:${NC} $1" -} +# --- Preflight checks --- -echo -e "${BOLD}========================================${NC}" -echo -e "${BOLD}Vim Configuration Installer${NC}" -echo -e "${BOLD}========================================${NC}\n" +step "Checking environment" -# Verify .vimrc exists in script directory -if [ ! -f "$SCRIPT_DIR/.vimrc" ]; then - print_error "Cannot find .vimrc in $SCRIPT_DIR" - echo "Please run this script from the chopsticks directory:" - echo " cd ~/.vim && ./install.sh" - exit 1 +[ -f "$SCRIPT_DIR/.vimrc" ] || die ".vimrc not found in $SCRIPT_DIR. Run from the cloned repo: cd ~/.vim && ./install.sh" + +command -v vim >/dev/null 2>&1 || die "vim not found. Install it first: + Ubuntu/Debian: sudo apt install vim + Fedora: sudo dnf install vim + macOS: brew install vim" + +VIM_VERSION=$(vim --version | head -n1) +ok "Found $VIM_VERSION" + +# Check Vim version >= 8.0 +vim --version | grep -q 'Vi IMproved 8\|Vi IMproved 9' || \ + warn "Vim 8.0+ recommended for full LSP support. Some features may be missing." + +# Detect Node.js for CoC +HAS_NODE=0 +if command -v node >/dev/null 2>&1; then + NODE_VER=$(node --version) + ok "Node.js $NODE_VER detected - CoC LSP will be available" + HAS_NODE=1 +else + warn "Node.js not found - will use vim-lsp (no Node.js required)" + echo " Install Node.js later to enable CoC: https://nodejs.org/en/download" fi -# Check if vim is installed -if ! command -v vim &> /dev/null; then - print_error "Vim is not installed. Please install Vim first." - echo " Ubuntu/Debian: sudo apt install vim" - echo " macOS: brew install vim" - echo " Fedora: sudo dnf install vim" - exit 1 -fi +# --- Symlink --- -print_status "Vim version: $(vim --version | head -n1)" +step "Setting up ~/.vimrc symlink" -# Backup existing .vimrc if it exists if [ -f "$HOME/.vimrc" ] && [ ! -L "$HOME/.vimrc" ]; then - BACKUP_FILE="$HOME/.vimrc.backup.$(date +%Y%m%d_%H%M%S)" - print_warning "Backing up existing .vimrc to $BACKUP_FILE" - mv "$HOME/.vimrc" "$BACKUP_FILE" + TS=$(date +%Y%m%d_%H%M%S) + warn "Backing up existing ~/.vimrc to ~/.vimrc.backup.$TS" + mv "$HOME/.vimrc" "$HOME/.vimrc.backup.$TS" fi -# Create symlink to .vimrc -print_status "Creating symlink: $HOME/.vimrc -> $SCRIPT_DIR/.vimrc" ln -sf "$SCRIPT_DIR/.vimrc" "$HOME/.vimrc" -# Verify symlink was created correctly -if [ -L "$HOME/.vimrc" ]; then - LINK_TARGET=$(readlink "$HOME/.vimrc") - if [ "$LINK_TARGET" = "$SCRIPT_DIR/.vimrc" ]; then - echo -e "${GREEN}[OK]${NC} Symlink created successfully" - else - print_warning "Symlink points to unexpected target: $LINK_TARGET" - fi +if [ "$(readlink "$HOME/.vimrc")" = "$SCRIPT_DIR/.vimrc" ]; then + ok "~/.vimrc -> $SCRIPT_DIR/.vimrc" else - print_error "Failed to create symlink" - exit 1 + die "Symlink verification failed" fi -# Install vim-plug if not already installed -VIM_PLUG_PATH="$HOME/.vim/autoload/plug.vim" -if [ ! -f "$VIM_PLUG_PATH" ]; then - print_status "Installing vim-plug..." - curl -fLo "$VIM_PLUG_PATH" --create-dirs \ +# --- vim-plug --- + +step "Installing vim-plug" + +VIM_PLUG="$HOME/.vim/autoload/plug.vim" +if [ ! -f "$VIM_PLUG" ]; then + curl -fLo "$VIM_PLUG" --create-dirs \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim - echo -e "${GREEN}[OK]${NC} vim-plug installed successfully" + ok "vim-plug installed" else - echo -e "${GREEN}[OK]${NC} vim-plug already installed" + ok "vim-plug already present" fi -# Install plugins -print_status "Installing Vim plugins..." +# --- Plugins --- + +step "Installing Vim plugins" + vim +PlugInstall +qall +ok "Plugins installed" -echo -e "\n${GREEN}[OK]${NC} ${BOLD}Installation complete!${NC}\n" +# --- Optional: CoC language servers --- -# Print optional dependencies -echo -e "${BOLD}Optional Dependencies (Recommended):${NC}" echo "" -echo -e "${BOLD}1. FZF (Fuzzy Finder):${NC}" -echo " Ubuntu/Debian: sudo apt install fzf ripgrep" -echo " macOS: brew install fzf ripgrep" -echo "" -echo -e "${BOLD}2. Node.js (for CoC completion):${NC}" -echo " Ubuntu/Debian: curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - && sudo apt install -y nodejs" -echo " macOS: brew install node" -echo "" -echo -e "${BOLD}3. Universal Ctags (for code navigation):${NC}" -echo " Ubuntu/Debian: sudo apt install universal-ctags" -echo " macOS: brew install universal-ctags" -echo "" -echo -e "${BOLD}4. Language-specific tools:${NC}" -echo " Python: pip install black flake8 pylint" -echo " JavaScript: npm install -g prettier eslint" -echo " Go: go install golang.org/x/tools/gopls@latest" -echo "" - -# Ask to install CoC language servers -read -p "Do you want to install CoC language servers now? (y/N) " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]]; then - print_status "Installing CoC language servers..." - - # Check if node is installed - if ! command -v node &> /dev/null; then - print_error "Node.js is not installed. Please install Node.js first." - else +if [ "$HAS_NODE" -eq 1 ]; then + read -p "Install CoC language servers for common languages? [y/N] " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + step "Installing CoC language servers" vim +'CocInstall -sync coc-json coc-tsserver coc-pyright coc-sh coc-html coc-css coc-yaml' +qall - echo -e "${GREEN}[OK]${NC} CoC language servers installed" + ok "CoC language servers installed" + echo " Add more with :CocInstall coc-go coc-rust-analyzer etc." fi +else + echo " To enable LSP without Node.js:" + echo " 1. Open a source file in Vim" + echo " 2. Run :LspInstallServer" + echo " 3. vim-lsp-settings will auto-install the right language server" fi +# --- Done --- + echo "" echo -e "${BOLD}========================================${NC}" -echo -e "${GREEN}All done!${NC} Open Vim and start coding!" +echo -e "${GREEN}Installation complete.${NC}" echo -e "${BOLD}========================================${NC}" echo "" -echo -e "Quick tips:" -echo " - Press ${BOLD}Ctrl+n${NC} to toggle file explorer (NERDTree)" -echo " - Press ${BOLD}Ctrl+p${NC} to fuzzy search files (FZF)" -echo " - Press ${BOLD},w${NC} to quick save" -echo " - Press ${BOLD}K${NC} on a function to see documentation" -echo " - See README.md for complete key mappings" +echo "Optional tools (install for best experience):" +echo "" +echo " ripgrep (,rg project search)" +echo " Ubuntu: sudo apt install ripgrep" +echo " macOS: brew install ripgrep" +echo "" +echo " fzf (Ctrl+p file search)" +echo " Ubuntu: sudo apt install fzf" +echo " macOS: brew install fzf" +echo "" +echo " ctags (F8 tag browser)" +echo " Ubuntu: sudo apt install universal-ctags" +echo " macOS: brew install universal-ctags" +echo "" +echo " Language linters:" +echo " Python: pip install black flake8 pylint isort" +echo " JS/TS: npm install -g prettier eslint typescript" +echo " Go: go install golang.org/x/tools/gopls@latest" +echo " Shell: sudo apt install shellcheck" +echo "" +echo "Getting started:" +echo " See QUICKSTART.md for the 5-minute guide" +echo " Run 'vim' and press ',' then wait 500ms for keybinding hints" echo ""