From 5604eddbdbdb2c7fb76bfb68fd805386d0792916 Mon Sep 17 00:00:00 2001 From: m1ngsama Date: Wed, 15 Apr 2026 10:15:07 +0800 Subject: [PATCH] fix: remaining usability and design improvements .vimrc: - Remove path+=** (hangs on large repos with node_modules) - Add plugin guards for FZF, Git, ALE, Markdown, EasyMotion, UndoTree mappings (prevent E492 when plugins not loaded) - Replace SmartFiles system() subprocess with isdirectory/finddir (no more synchronous fork on every Ctrl+p) - Remove duplicate SLDefineColors VimEnter call (ColorScheme alone suffices) - Convert all remaining nmap/map to nnoremap/noremap (eliminate recursive mapping risk and visual/operator-pending mode contamination) - Expand cheat sheet with spell checking, utilities, window resize, F-key toggles, EasyMotion line motions, buffer management get.sh: - Support NO_COLOR and non-TTY output - Show version tag or commit hash after clone/pull QUICKSTART.md: - Warn about first-launch plugin install (30-60s wait) - Note that some language servers need Node.js --- .vimrc | 110 +++++++++++++++++++++++++++++++++----------------- QUICKSTART.md | 8 +++- get.sh | 10 +++-- 3 files changed, 86 insertions(+), 42 deletions(-) diff --git a/.vimrc b/.vimrc index d3e001f..e03a289 100644 --- a/.vimrc +++ b/.vimrc @@ -44,7 +44,7 @@ set wildmode=list:longest set wildignorecase set wildignore=*.docx,*.jpg,*.png,*.gif,*.pdf,*.pyc,*.exe,*.flv,*.img,*.xlsx set wildignore+=*/node_modules/*,*/.git/*,*/__pycache__/*,*/dist/*,*/build/* -set path+=** +" path+=** removed: hangs on large repos (node_modules); use Ctrl+p (FZF) instead set mouse=a set encoding=utf-8 set foldmethod=indent @@ -214,9 +214,9 @@ set smartindent let mapleader = "," " Saving / quitting -nmap w :w! -nmap q :q -nmap x :x +nnoremap w :w! +nnoremap q :q +nnoremap x :x " Clear search highlight nnoremap :noh @@ -235,7 +235,7 @@ nnoremap tm :tabmove nnoremap t :tabnext let g:lasttab = 1 -nmap tl :exe "tabn ".g:lasttab +nnoremap tl :exe "tabn ".g:lasttab augroup ChopstickTabHistory autocmd! autocmd TabLeave * let g:lasttab = tabpagenr() @@ -248,8 +248,8 @@ nnoremap cd :lcd %:p:h:pwd nnoremap e :Explore nnoremap E :Vexplore -" Remap 0 to first non-blank -map 0 ^ +" Remap 0 to first non-blank (all modes intentional) +noremap 0 ^ " Reselect last paste nnoremap gV `[v`] @@ -354,19 +354,21 @@ let g:netrw_list_hide .= ',\.pyc$,node_modules,\.git,__pycache__,\.DS_Store' " Ctrl+p: git-aware file search (GFiles inside repo, Files outside) function! s:SmartFiles() abort - if !empty(system('git rev-parse --show-toplevel 2>/dev/null')) + if isdirectory('.git') || finddir('.git', '.;') !=# '' GFiles else Files endif endfunction -map :call SmartFiles() -map b :Buffers -map rg :Rg -map rG :RgWord -map rt :Tags -map gF :GFiles +if exists('g:plugs["fzf.vim"]') + nnoremap :call SmartFiles() + nnoremap b :Buffers + nnoremap rg :Rg + nnoremap rG :RgWord + nnoremap rt :Tags + nnoremap gF :GFiles +endif let g:fzf_layout = { 'down': '40%' } @@ -458,9 +460,11 @@ let g:ale_lint_on_text_changed = 'normal' let g:ale_lint_on_insert_leave = 1 let g:ale_lint_on_enter = 1 -nmap [e :ALEPrevious -nmap ]e :ALENext -nmap aD :ALEDetail +if exists('g:plugs["ale"]') + nnoremap [e :ALEPrevious + nnoremap ]e :ALENext + nnoremap aD :ALEDetail +endif " ============================================================================ " => vim-go @@ -573,15 +577,19 @@ let g:vim_markdown_follow_anchor = 1 let g:vim_markdown_new_list_item_indent = 2 let g:vim_markdown_strikethrough = 1 -" Table of contents in quickfix -nnoremap mt :Toc +" Table of contents (side window) +if exists('g:plugs["vim-markdown"]') + nnoremap mt :Toc +endif " ============================================================================ " => previm (Markdown browser preview) " ============================================================================ " mp open live-reloading preview in browser -nnoremap mp :PrevimOpen +if exists('g:plugs["previm"]') + nnoremap mp :PrevimOpen +endif let g:previm_enable_realtime = 1 " ============================================================================ @@ -591,19 +599,22 @@ let g:previm_enable_realtime = 1 let g:EasyMotion_do_mapping = 0 let g:EasyMotion_smartcase = 1 -" s + two chars: jump anywhere on screen -nmap s (easymotion-overwin-f2) - -" Line motions -nmap j (easymotion-j) -nmap k (easymotion-k) +if exists('g:plugs["vim-easymotion"]') + " s + two chars: jump anywhere on screen + nmap s (easymotion-overwin-f2) + " Line motions + nmap j (easymotion-j) + nmap k (easymotion-k) +endif " ============================================================================ " => UndoTree " ============================================================================ -nnoremap :UndotreeToggle -nnoremap u :UndotreeToggle +if exists('g:plugs["undotree"]') + nnoremap :UndotreeToggle + nnoremap u :UndotreeToggle +endif " ============================================================================ " => IndentLine (non-TTY only) @@ -713,7 +724,6 @@ endfunction augroup SLColors autocmd! autocmd ColorScheme * call s:SLDefineColors() - autocmd VimEnter * call s:SLDefineColors() augroup END " Current mode → [label, highlight-group] @@ -949,12 +959,14 @@ augroup END " => Git Shortcuts " ============================================================================ -nnoremap gs :Git status -nnoremap gc :Git commit -nnoremap gp :Git push -nnoremap gl :Git pull -nnoremap gd :Gdiffsplit -nnoremap gb :Git blame +if exists('g:plugs["vim-fugitive"]') + nnoremap gs :Git status + nnoremap gc :Git commit + nnoremap gp :Git push + nnoremap gl :Git pull + nnoremap gd :Gdiffsplit + nnoremap gb :Git blame +endif " ============================================================================ " => Terminal Integration @@ -1073,9 +1085,20 @@ function! s:CheatSheet() abort \ 'EDITING', \ ' gc Toggle comment (visual mode too)', \ ' s + 2 chars EasyMotion — jump anywhere on screen', - \ ' ,u Undo tree (visual branch history)', + \ ' ,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 (after / before)', + \ ' ,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', + \ ' ,* 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', @@ -1084,8 +1107,19 @@ function! s:CheatSheet() abort \ '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)', \ ' Esc Esc Exit terminal mode', + \ ' ,= / ,- Resize height (grow / shrink)', + \ ' ,+ / ,_ Resize width (grow / shrink)', + \ '', + \ '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', @@ -1103,7 +1137,7 @@ nnoremap ? :call CheatSheet() " ============================================================================ " Show syntax highlight stack for word under cursor -nmap sh :call SynStack() +nnoremap sh :call SynStack() function! SynStack() if !exists("*synstack") | return | endif echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")') diff --git a/QUICKSTART.md b/QUICKSTART.md index 3390b8c..28d44d9 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -56,6 +56,10 @@ vim . # startup dashboard, current directory listed vim myfile # edit a specific file ``` +> **First launch:** Vim will automatically install plugins on the first open +> (takes 30–60 seconds depending on network). This is normal — wait for it +> to finish, then restart Vim. + --- ## Step 3: Set Up LSP @@ -67,7 +71,9 @@ Open a source file, then run: ``` This auto-detects the filetype and installs the correct language server. -No Node.js required — vim-lsp runs on pure VimScript. +vim-lsp itself runs on pure VimScript — no Node.js required. However, +some language servers (JS/TS, HTML, CSS, JSON, YAML) are npm packages +that need Node.js to run. Python, Go, and Rust servers don't need it. Check status: ```vim diff --git a/get.sh b/get.sh index c1a0577..63e4a5a 100644 --- a/get.sh +++ b/get.sh @@ -10,7 +10,11 @@ set -eo pipefail REPO="https://github.com/m1ngsama/chopsticks.git" DEST="$HOME/.vim" -GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BOLD='\033[1m'; NC='\033[0m' +if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then + GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BOLD='\033[1m'; NC='\033[0m' +else + GREEN=''; YELLOW=''; RED=''; BOLD=''; NC='' +fi ok() { echo -e "${GREEN}[OK]${NC} $1"; } warn() { echo -e "${YELLOW}[!]${NC} $1"; } die() { echo -e "${RED}[FATAL]${NC} $1" >&2; exit 1; } @@ -42,7 +46,7 @@ if [[ -d "$DEST/.git" ]]; then warn "$DEST already exists — pulling latest changes" git -C "$DEST" pull --ff-only origin main 2>/dev/null || \ warn "Could not pull latest — using existing version (run: git -C ~/.vim pull)" - ok "Repository updated" + ok "Repository updated ($(git -C "$DEST" describe --tags 2>/dev/null || git -C "$DEST" rev-parse --short HEAD))" elif [[ -d "$DEST" ]]; then die "$HOME/.vim exists but is not a chopsticks git repo. Back it up first: mv ~/.vim ~/.vim.bak @@ -50,7 +54,7 @@ elif [[ -d "$DEST" ]]; then else git clone --depth=1 "$REPO" "$DEST" || \ die "Clone failed — check your network connection" - ok "Cloned to $DEST" + ok "Cloned to $DEST ($(git -C "$DEST" describe --tags 2>/dev/null || git -C "$DEST" rev-parse --short HEAD))" fi # ── Run installer ─────────────────────────────────────────────────────────────