" make vim unusable for anyone else " from the get-go, we assume version >= 703 set nocompatible " screw vi " hacks {{{1 if has('multi_byte') scriptencoding utf-8 " allow it in this script set termencoding=utf-8 " and this terminal supports it set encoding=utf-8 " and the default file is in it endif let g:rcvim=$HOME.'/.vim' let &backupdir=g:rcvim.'/backup' " stash tilde files elsewhere " using a double slash here enables file path inclusion for uniqueness: let &directory=g:rcvim.'/swp//' " stash swap files too let &undodir=g:rcvim.'/undo/' " undo files are cool try | call mkdir(&backupdir, "p") | catch /E739/ | endtry try | call mkdir(&directory, "p") | catch /E739/ | endtry try | call mkdir(&undodir, "p") | catch /E739/ | endtry " force colors on anything that looks reasonable if (&term =~ "^xterm") || (&term == "screen") let &t_Co=256 "let &t_AF="\e[38;5;%dm" "let &t_AB="\e[48;5;%dm" endif if &term =~ '^tmux' " https://unix.stackexchange.com/a/34723 " tmux will send xterm-style keys when xterm-keys is on exec "set =\e[1;*A" exec "set =\e[1;*B" exec "set =\e[1;*C" exec "set =\e[1;*D" endif " main config {{{1 if has('syntax') syntax enable " required for folding as well set hlsearch " highlight search results let c_syntax_for_h=1 " use C highlighting for .h files endif if has('gui_running') set guioptions-=M " skip loading $VIMRUNTIME/menu.vim set guioptions-=m " hide menu which isn't loaded anyway set guioptions-=T " hide toolbar set guioptions-=r " hide scrollbar if has("gui_gtk2") set guifont=Consolas\ 11 else set guifont=Consolas:h9 end set columns=84 set lines=36 cd $HOME " might not be ideal... endif if has('title') | set title | endif " terminal title set history=10000 " command lines to remember set number " lines set ruler " write out the cursor position set showcmd " show number of lines/etc. selected set lazyredraw " when executing macros, untyped things set shortmess=atI " be less verbose and shut up vim set suffixes=.bak,~,.swp,.o,.log,.out " lower tab-completion priority set noerrorbells visualbell t_vb= " disable bells set scrolloff=3 " rows of context when scrolling set sidescrolloff=2 " cols of context when scrolling set incsearch " show first search result as we type set ignorecase " insensitive searching set smartcase " except when uppercase is used set infercase " use existing case when ins-completing set smarttab " handle insertion and deletion of indents set noautoindent " some distros have this set by default set virtualedit=block " allow cursor anywhere in visual block set foldmethod=marker " (performance issues with other methods) set foldlevelstart=99 " start with everything unfolded...? set nowrap " word wrapping is pretty weak in vim set nojoinspaces " don't use double-spaces for J and gq set ffs=unix,dos " prefer unix-style EOLs (ffs indeed) set nobomb " don't mention these on planes set undofile " remember undos across files/sessions set diffopt+=iwhite " ignore whitespace in diff command set ttimeout ttimeoutlen=60 " make changing modes a bit snappier set hidden " allow swapping out of unsaved buffers set complete=.,w,b,u,t " don't scan every file with autocomplete set nrformats=bin,hex,unsigned " ctrl+a/x non-negative numbers, no octal set modeline modelines=5 " a file can specify its own vim settings if has('mksession') set sessionoptions=blank,buffers,curdir,folds,tabpages,winsize,resize,winpos end if has('wildignore') " ignore files that typically aren't interesting to text editors like vim " FWIW, these lines don't need trailing commas set wildignore="" set wildignore+=.git,.svn,.hg,pkg,tmp set wildignore+=*.bak,*.tmp,*.log,*.cache set wildignore+=Desktop.ini,Thumbs.db,*.lnk,.DS_Store set wildignore+=*.7z,*.tar,*.tar.*,*.tgz,*.zip set wildignore+=*.suo,*.sln,*.pch,*.pdb,*.pgc,*.pgd set wildignore+=*.o,*.obj,*.elf,*.lib,*.a,*.dll,*.so,*.so.*,*.exe,*.out set wildignore+=*.wav,*.mp3,*.ogg,*.m4a,*.opus,*.mp4,*.mkv set wildignore+=*.bmp,*.gif,*.jfif,*.jpeg,*.jpg,*.pdf,*.png,*.webp set wildignore+=__pycache__,*.pyc,*.pyo,*.pyd,*.npy,*.npz,*.h5,*.pkl set wildignore+=*.gem,.bundle set wildignore+=CMakeCache.txt,CMakeFiles,install_manifest.txt endif let $PATH .= ':'.$HOME.'/sh' " allow direct invocation of shell funcs " fun {{{1 fu! Colour(name) " go nuts. go wild. hi clear | syntax clear | syntax on " reset everything for sure (#4405) if has('termguicolors') if &term =~ "^tmux-256color" let &t_8f = "\[38;2;%lu;%lu;%lum" let &t_8b = "\[48;2;%lu;%lu;%lum" set termguicolors endif endif exe "colo " . a:name endf command! -nargs=* Colour call Colour() " lifted from BurntSushi: fu! GlobalReplace() normal! gv"ry let replacement = input("Replace " . @r . " with: ") if replacement != "" exe "%s/" . @r . "/" . replacement . "/g" endif endf " lifted from BurntSushi: fu! StripTrailingWhitespace() let l = line(".") let c = col(".") %s/\s\+$//e call cursor(l, c) endf fu! TabEight() setlocal tabstop=8 shiftwidth=8 noexpandtab softtabstop=0 endf fu! TabFour() setlocal tabstop=8 shiftwidth=4 expandtab softtabstop=4 endf fu! TabTwo() setlocal tabstop=2 shiftwidth=2 expandtab endf fu! TabBad() setlocal tabstop=4 shiftwidth=4 noexpandtab softtabstop=4 endf " set TabFour as default set tabstop=8 shiftwidth=4 expandtab softtabstop=4 fu! DetectShebang() " vim has some rudimentary detection, but sometimes i want to override it. " vim's version is typically found here: /usr/share/vim/vim82/scripts.vim let l = getline(1) if l[:1] !=# '#!' | return | endif let l = trim(l[2:], ' ', 1) " sometimes there are spaces after the #! let p = matchstr(l, '^\%(/usr\)\=/s\=bin/\%(env\%( \+-S\)\= \+\)\=\zs[^ ]*\ze') if p ==# 'bash' | setlocal ft=bash | endif if p ==# 'dash' | setlocal ft=bash | endif if p ==# 'false' | setlocal ft=bash | endif if p ==# 'kuroko' | setlocal ft=python | endif if p ==# 'lua' | setlocal ft=lua | endif if p ==# 'perl' | setlocal ft=perl | endif if p ==# 'perl6' | setlocal ft=raku | endif if p ==# 'python' | setlocal ft=python | endif if p ==# 'python3' | setlocal ft=python | endif if p ==# 'raku' | setlocal ft=raku | endif if p ==# 'sh' | setlocal ft=bash | endif if p ==# 'zsh' | setlocal ft=zsh | endif endf " autocmd {{{1 if has('autocmd') augroup tabs au! au BufRead,BufNewFile PKGBUILD call TabTwo() au FileType ruby call TabTwo() au FileType nim call TabTwo() au BufRead,BufNewFile *.bt,*.1sc call TabFour() au BufRead,BufNewFile *.ys call TabTwo() au FileType javascript,processing call TabTwo() au FileType seed7 call TabTwo() au BufRead,BufNewFile .gitconfig call TabEight() exec 'au' 'BufRead,BufNewFile' $HOME..'/src/bass/*' 'call TabTwo()' augroup END augroup filetypes au! au BufRead,BufNewFile *.lib setlocal ft=spice au BufRead,BufNewFile *.bt setlocal ft=c au BufRead,BufNewFile *.1sc setlocal ft=c au BufRead,BufNewFile *.fs setlocal ft=c au BufRead,BufNewFile *.glsl setlocal ft=c au BufRead,BufNewFile *.hlsl setlocal ft=c au BufRead,BufNewFile *.krk setlocal ft=python au BufRead,BufNewFile *.asm setlocal ft=lips au BufRead,BufNewFile *.nim setlocal ft=nim au BufRead,BufNewFile *.pde setlocal ft=processing au BufRead,BufNewFile,StdinReadPost * call DetectShebang() augroup END augroup insanity au! au FileType netrw setlocal bufhidden=wipe augroup END augroup nocomment au! " set or unset some convenient or annoying formatoptions au FileType * setlocal fo-=c fo-=r fo-=o fo-=j augroup END augroup forth au! " insert a newline every 64 bytes when reading au! BufReadCmd blkfs,*.scr call setline('1', split(join(readfile(expand('')), ''), '\%65c\zs')) " remove newlines when writing au! BufWriteCmd blkfs,*.scr call writefile([join(getline('^', '$'), '')], expand('')) augroup end augroup nobells " good lord vim you are archaic au! au GUIEnter * set vb t_vb= augroup END fu! ResCur() " attempt to preserve cursor position if line("'\"") > 1 && line("'\"") <= line("$") normal! g`" return 1 endif endf augroup resCur au! " au BufWinEnter * call ResCur() augroup END endif " keys/binds {{{1 set backspace=eol,start,indent " make backspace useful " tab completion in command-line if has('wildmenu') | set wildmenu | endif " mintty pls "exec "set =\e[Z" "map [Z "ounmap [Z " easy indent/unindent nn >> nn << " indentation without ending selection vn >gv vn ]\+>\s\+\)\+\zs') exec 'nn '.args[0].' '.args[1] exec 'ino '.args[0].' '.args[1] endf com! -nargs=+ Inn call Inn() Inn :w Inn :Next Inn :next Inn :e % Inn @@ Inn :bd Inn :w! Inn :e! % Inn :bd! Inn :wall " np++ habits Inn Inn Inn :m-2 Inn :m+1 Inn :tabm -1 Inn :tabm +1 " jump to top and bottom Inn gg Inn G nn [1;5H gg nn [1;5F G ino [1;5H gg ino [1;5F G " hide search highlighting Inn :nohls " rebind annoying things: " reflow text nn Q gq vn Q gq " split lines (opposite of J) nn K ik$ vn K " follow tag nn " delete line "nn D dd " execute vim commands in visual selection vmap "xy:@x " open a shell (only works if you `exec vim` instead of running it in a shell) nn :sh " this frees up x and X for rebinding if you like exec "set =\[3;2~" Inn X let leader="\\" "ino " this doesn't workkkkkkkkk nm a a?r nm i i?r nn , :Tab /,\zs nn . @: nn : nn :call StripTrailingWhitespace() "nn ? :exec getline(".") nn F :E . nn P "0P nn b :ls:b nn e :e **/* nn f :E nn p "0p "nn x :system('chmod +x %') | e nn d :cd %:p:h:pwd vn & :call GlobalReplace() " TODO: "nn ,, :call CommentLines() "nn ,. :call UncommentLines() " alias :W to :w, via https://stackoverflow.com/a/3879737 cnoreabbrev W ((getcmdtype() is# ':' && getcmdline() is# 'W')?('w'):('W')) " https://stackoverflow.com/a/58244921 fu! SynStack() for i1 in synstack(line("."), col(".")) let i2 = synIDtrans(i1) let n1 = synIDattr(i1, "name") let n2 = synIDattr(i2, "name") echo n1 "->" n2 endfor endfunction map gm :call SynStack() " misc {{{1 set list listchars=tab:»·,trail:·,extends:…,nbsp:‗ " including this in case i'm on a _really_ bad terminal: "set list listchars=tab:>-,trail:.,extends:>,nbsp:_ " deprecated, but still perfectly functional, and especially backwards compatible: try | exec pathogen#infect() | catch /E117/ | endtry let g:netrw_banner=0 " be quiet let g:netrw_fastbrowse = 0 " so THAT'S what's been causing me agony set background=dark try | colorscheme minimalist | catch /E185/ | colorscheme desert | endtry " ctrlp {{{1 map :CtrlPBuffer let g:ctrlp_match_window='bottom,order:btt,min:1,max:24,results:24' " machine-specific configs {{{1 let s:hostname=hostname() if s:hostname == "phantom-pi" || s:hostname == "wraith" colorscheme minimalist endif " macros {{{1 " to dump a macro, enter insert mode and hit [Ctrl+R] [Ctrl+R] [macro letter]. " note that this will not properly escape any single quotes used in the macro. let s:q="'" " explode: split an expression's right-hand-side by commas let @s= 'ma' let @s.=':sil s/ *= */&\r/e ' let @s.='-' let @s.='mb' " the next line may error, so set a mark now let @s.=':sil s/,/\r/g ' let @s.='-' let @s.='mb' "let @s.=s:q..'a' "let @s.='OEXPLODE=HERE;' "let @s.=s:q..'b' "let @s.='oEXPLODE=THERE;' let @s.=s:q..'a' let @s.=' ' " implode: join the previously split expression, sort -ui let @j= ':sil '..s:q..'a+1,'..s:q..'b'..'sor ui ' let @j.=':sil '..s:q..'a+1,'..s:q..'b-1'..'norm!A, ' let @j.=':sil '..s:q..'a,'..s:q..'b'..'j! ' let @j.=s:q..'a'