" 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,.hg,.svn,pkg,tmp set wildignore+=*.bak,*.cache,*.log,*.tmp set wildignore+=*.lnk,.DS_Store,Desktop.ini,Thumbs.db set wildignore+=*.7z,*.tar,*.tar.*,*.tgz,*.zip set wildignore+=*.pch,*.pdb,*.pgc,*.pgd,*.sln,*.suo set wildignore+=*.a,*.dll,*.elf,*.exe,*.lib,*.o,*.obj,*.out,*.so,*.so.* set wildignore+=*.m4a,*.mkv,*.mp3,*.mp4,*.ogg,*.opus,*.wav set wildignore+=*.bmp,*.gif,*.jfif,*.jpeg,*.jpg,*.pdf,*.png,*.webp set wildignore+=*.h5,*.npy,*.npz,*.pkl,*.pyc,*.pyd,*.pyo,__pycache__ 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 softtabstop=2 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 *.bt,*.1sc call TabFour() au BufRead,BufNewFile *.ys call TabTwo() au BufRead,BufNewFile .gitconfig call TabEight() au BufRead,BufNewFile PKGBUILD call TabTwo() au FileType html,css call TabTwo() au FileType javascript,processing call TabTwo() au FileType nim call TabTwo() au FileType ruby call TabTwo() au FileType seed7 call TabTwo() exec 'au' 'BufRead,BufNewFile' $HOME..'/src/bass/*' 'call TabTwo()' augroup END augroup filetypes au! au BufRead,BufNewFile *.1sc setlocal ft=c au BufRead,BufNewFile *.asm setlocal ft=lips au BufRead,BufNewFile *.bt 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 *.lib setlocal ft=spice 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 function! CheckFileEncoding() if exists('b:fenc_at_read') && &fileencoding != b:fenc_at_read exec 'e! ++enc=' . &fileencoding unlet b:fenc_at_read endif endfunction augroup fenc au! BufRead *.txt let b:fenc_at_read=&fileencoding au! BufWinEnter *.txt call CheckFileEncoding() 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 nn 2 :call TabTwo() nn 3 :call TabBad() nn 4 :call TabFour() nn 5 :call TabEight() 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 " barely any colorschemes set these to anything useful. negligence? indifference? hi diffRemoved ctermfg=168 guifg=#d75f87 hi diffAdded ctermfg=78 guifg=#5fd75f " 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.='-mb' " the next line may error, so set a mark now let @s.=':sil s/,/\r/g ' 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 ' " 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'