" ============================================================================= " ~/.vim/vimrc " Vim config — no plugins, ported from Neovim config. " Symlink: ln -sf ~/.local/share/Panama/config/dot/vim/vimrc ~/.vim/vimrc " ============================================================================= " ============================================================================= " GENERAL / COMPATIBILITY " ============================================================================= " Disable Vi compatibility. Must be first. set nocompatible " Enable filetype detection, plugins, and indent files. filetype plugin indent on " Enable syntax highlighting. syntax enable " ============================================================================= " LEADER KEY " ============================================================================= " Must be set before any mappings. let mapleader = ' ' let maplocalleader = '\' " ============================================================================= " LINE NUMBERS " ============================================================================= set number " Absolute line number on current line set relativenumber " Relative line numbers on all other lines " ============================================================================= " INDENTATION " ============================================================================= set tabstop=2 " A displays as 2 columns set softtabstop=2 " in insert mode inserts 2 spaces set shiftwidth=2 " >> and << shift by 2 spaces set expandtab " Use spaces instead of tab characters set smartindent " Auto-indent new lines based on context " ============================================================================= " SWAP / UNDO " ============================================================================= set noswapfile " Persistent undo — ~/.vim/undodir must exist (it already does on this machine). set undodir=~/.vim/undodir set undofile " ============================================================================= " SEARCH " ============================================================================= set hlsearch " Highlight all matches set incsearch " Show matches as you type set ignorecase " Case-insensitive by default... set smartcase " ...unless the query has uppercase " ============================================================================= " APPEARANCE " ============================================================================= " 24-bit color — requires a true-color terminal (kitty, ghostty, etc.). set termguicolors " Keep 4 lines visible above/below cursor when scrolling. set scrolloff=4 " Always show the sign column to prevent layout shifts. set signcolumn=yes " Reduce delay before CursorHold fires. set updatetime=50 " Show invisible characters: trailing spaces and non-breaking spaces as ⋅, " tabs as two spaces so they are visible but not distracting. set list set listchars=trail:⋅,nbsp:⋅,tab:\ \ " Always show statusline even with a single window. set laststatus=2 " habamax is a good built-in dark theme in Vim 9+; fall back to slate. if v:version >= 900 colorscheme habamax else colorscheme slate endif " Transparent statusline background (mirrors the Neovim setup). highlight StatusLine guibg=NONE ctermbg=NONE highlight StatusLineNC guibg=NONE ctermbg=NONE " ============================================================================= " STATUS LINE " ============================================================================= " Mirrors lualine layout: mode | filepath [+][RO] ... filetype | enc | line:col | % set statusline= set statusline+=\ %{toupper(mode())} set statusline+=\ \|\ %f\ %m%r set statusline+=%= set statusline+=%y\ \|\ %{&fileencoding?&fileencoding:&encoding} set statusline+=\ \|\ %l:%c\ \|\ %p%%\ " ============================================================================= " MISCELLANEOUS " ============================================================================= set ttyfast " Assume a fast terminal connection set backspace=indent,eol,start " Backspace over everything in insert mode set nowrap " Don't wrap long lines set showcmd " Show partial commands in last line set showmatch " Briefly jump to matching bracket on insert " ============================================================================= " KEYMAPS — WINDOW NAVIGATION " ============================================================================= nnoremap h h nnoremap j j nnoremap k k nnoremap l l vnoremap h h vnoremap j j vnoremap k k vnoremap l l " ============================================================================= " KEYMAPS — FILE OPERATIONS " ============================================================================= nnoremap w :write nnoremap q :quit " Source the vimrc (mirrors s in Neovim). nnoremap s :update:source $MYVIMRC " Make the current file executable. nnoremap x :!chmod +x % " ============================================================================= " KEYMAPS — LINE MANIPULATION " ============================================================================= " Move selected lines down / up in visual mode. vnoremap J :m '>+1gv=gv vnoremap K :m '<-2gv=gv " Join lines in normal mode while keeping the cursor position fixed. nnoremap J mzJ`z " ============================================================================= " KEYMAPS — SCROLL AND SEARCH WITH RECENTERING " ============================================================================= nnoremap zz nnoremap zz " Next / previous search result: center view and open any fold. nnoremap n nzzzv nnoremap N Nzzzv " ============================================================================= " KEYMAPS — CLIPBOARD (SYSTEM) " ============================================================================= " Requires Vim compiled with +clipboard. " On Fedora, install vim-X11 if needed: sudo dnf install vim-X11 " Verify with :version — look for +clipboard. nnoremap p "+p nnoremap P "+P vnoremap p "+p vnoremap P "+P nnoremap y "+y vnoremap y "+y nnoremap yy "+yy " Yank entire buffer to system clipboard. nnoremap YY :%y+ " Visual: replace selection from clipboard without clobbering the clipboard. xnoremap v "_dP " ============================================================================= " KEYMAPS — VOID-REGISTER DELETE " ============================================================================= " Delete without touching the unnamed register, preserving the last yank. nnoremap d "_d vnoremap d "_d nnoremap dd "_dd " ============================================================================= " KEYMAPS — SEARCH AND REPLACE " ============================================================================= " Replace the word under the cursor across the whole file. " Cursor is placed inside the replacement text for immediate editing. nnoremap sr :%s/\<\>//gI " ============================================================================= " KEYMAPS — DISABLED KEYS " ============================================================================= nnoremap Q " ============================================================================= " KEYMAPS — COMMENT TOGGLE (c) " ============================================================================= " Toggles `// ` comments on the current line (normal) or each line in a " visual selection. Not filetype-aware — works for C, C++, JS, TS, Go, Rust. " For language-aware comments a plugin like vim-commentary would be needed. function! ToggleComment() range let l:first_line = getline(a:firstline) if l:first_line =~ '^\s*\/\/ ' execute a:firstline . ',' . a:lastline . 's/^\(\s*\)\/\/ /\1/' else execute a:firstline . ',' . a:lastline . 's/^\(\s*\)/\1\/\/ /' endif endfunction nnoremap c :call ToggleComment() vnoremap c :call ToggleComment() " ============================================================================= " AUTOCOMMANDS " ============================================================================= augroup VimRCGroup autocmd! " Strip trailing whitespace on every save. autocmd BufWritePre * :%s/\s\+$//e " Auto-source this vimrc whenever it is saved. autocmd BufWritePost vimrc source $MYVIMRC augroup END " ============================================================================= " HIGHLIGHT YANK " ============================================================================= " Briefly highlights yanked text using IncSearch colors, then clears it. " Implements Neovim's vim.highlight.on_yank() using matchadd + timer_start. " Requires Vim 8.0.1422+ (for v:event) and Vim 8.0+ (for timer_start). augroup HighlightYank autocmd! autocmd TextYankPost * call s:HighlightYank() augroup END function! s:HighlightYank() if v:event.operator !=# 'y' return endif let l:match_id = matchadd('IncSearch', \ '\%' . line("'[") . 'l\%' . col("'[") . 'c\_.*' . \ '\%' . line("']") . 'l\%' . col("']") . 'c') call timer_start(150, {-> s:ClearYankHighlight(l:match_id)}) endfunction function! s:ClearYankHighlight(match_id) silent! call matchdelete(a:match_id) endfunction