" Tom Ryder (tejr)’s Literate Vimrc " ================================= " " Last updated: Thu, 27 Jun 2019 00:23:17 +0000 " " │ And I was lifted up in heart, and thought " │ Of all my late-shown prowess in the lists, " │ How my strong lance had beaten down the knights, " │ So many and famous names; and never yet " │ Had heaven appeared so blue, nor earth so green, " │ For all my blood danced in me, and I knew " │ That I should light upon the Holy Grail. " │ " │ —Tennyson " " This is an attempt at something like a “literate vimrc”, in the tradition of " Donald Knuth’s “literate programming”: " " The dotfiles project containing this file is maintained here: " " " This is a long file, and comments abound within. Should this be bothersome, " one could execute this command in Vim itself to strip out all lines either " blank or comprising solely comments: " " :g/\m^$\|^\s*"/d " " This file should be saved as ‘vimrc’—no leading period—in the user runtime " directory. On Unix-like operating systems, hereinafter referred to as " “*nix”, that directory is ‘~/.vim’; on Windows, it’s ‘~/vimfiles’. " Fortunately, those are the only two kinds of operating systems that exist, " anywhere in the world. " " It requires Vim 7.0 or newer, with the +eval feature, and the 'compatible' " option turned off, chiefly to allow line continuations. The vimrc stub at " ~/.vimrc (Unix) or ~/_vimrc (Windows) should check that these conditions are " met before loading this file with ‘:runtime vimrc’. " " All of this should survive a pass of the Vim script linter Vint with no " errors, warnings, or style problems: " " We’ll begin by making sure we’re all speaking the same language. Since it’s " been the future for a few years now, this file has characters outside the " ASCII character set, which prompts Vint to suggest declaring the file " encoding with a :scriptencoding command. The :help for that command " specifies that this should be done after 'encoding' is set, so we’ll do that " here, too. " " On *nix, I keep the primary locale environment variable $LANG defined, and " it almost always specifies a multibyte locale. This informs Vim’s choice of " internal character encoding, but the default for the 'encoding' option in " the absence of a valid $LANG is ‘latin1’. Since this is almost never what " I want, we’ll manually choose the UTF-8 encoding for Unicode in the absence " of any other explicit specification. " if &encoding ==# 'latin1' && !exists('$LANG') set encoding=utf-8 endif scriptencoding utf-8 " With encoding handled, we’ll turn our attention to the value of the " 'runtimepath' option, since any scripts loaded from the paths specified " therein control so much of the behaviour of Vim. " " Working with 'runtimepath' and other options set with comma-separated " strings is error-prone, whether the strings are paths or not. In " particular, splitting the list is surprisingly complicated, as revealed by " the tokenizer function copy_option_part in src/misc2.c in Vim’s source code. " This awkwardness is largely because commas within each list item need to be " escaped with backslashes, but backslashes themselves are not. To make it " even more complicated, each separating comma may be followed by any number " of spaces, or more commas, that will be ignored. This means that you can " have a path starting with spaces or commas as the first value in the list, " but not any of the following values. Worse, there’s no way to escape " leading whitespace characters to prevent them being skipped; backslashes " don’t work, because they only escape commas in this context. Read the " source code if you don’t believe me. Vim, I love you, but you are really " weird. " " In an effort to abstract this away a bit, we’ll define a script-local " function that can split such values into their constituent parts. The " pattern required for the split() breaks down like this: " " \\ ← Literal backslash " \@ 1 echoerr 'Too many arguments' endif let [expr, keepempty] = [a:expr, a:0 ? a:1 : 0] return map( \ split(expr, '\\\@ 0 let s:runtimepath = s:OptionSplit(&runtimepath) let $MYVIM = s:runtimepath[0] endif function! s:Mkpath(path) abort let [path] = [a:path] return isdirectory(path) \ || exists('*mkdir') && mkdir(path) endfunction let s:cache = $MYVIM.'/cache' call s:Mkpath(s:cache) let &viminfo .= ',n'.s:cache.'/viminfo' set backup let s:backupdir = s:cache.'/backup' call s:Mkpath(s:backupdir) execute 'set backupdir^='.s:EscItemExec( \ s:backupdir.(has('patch-8.1.251') ? '//' : ''), \) if has('unix') if !has('patch-8.1.1519') set backupskip& endif set backupskip^=/dev/shm/*,/usr/tmp/*,/var/tmp/* endif let s:directory = s:cache.'/swap' call s:Mkpath(s:directory) execute 'set directory^='.s:EscItemExec(s:directory) if has('persistent_undo') set undofile let s:undodir = s:cache.'/undo' call s:Mkpath(s:undodir) execute 'set undodir^='.s:EscItemExec(s:undodir) endif filetype plugin indent on function! s:ReloadFileType() abort if exists('g:did_load_filetypes') doautocmd filetypedetect BufRead endif endfunction command! -bar ReloadFileType \ call s:ReloadFileType() function! s:ReloadVimrc() abort ReloadFileType redraw echomsg fnamemodify($MYVIMRC, ':p:~').' reloaded' endfunction command! -bar ReloadVimrc \ noautocmd source $MYVIMRC | call s:ReloadVimrc() augroup vimrc autocmd! augroup END autocmd vimrc BufWritePost $MYVIMRC,$MYVIM/vimrc \ ReloadVimrc if exists('##SourceCmd') autocmd vimrc SourceCmd $MYVIMRC,$MYVIM/vimrc \ ReloadVimrc endif set history=10000 set spelllang=en_nz let s:spellfile = s:cache.'/spell/'.join([ \ split(&spelllang, '_')[0], \ &encoding, \ 'add', \], '.') execute 'set spellfile='.s:EscItemExec(s:spellfile) let &spellcapcheck = '[.?!]\%( \|[\n\r\t]\)' set dictionary^=/usr/share/dict/words let s:ref = $MYVIM.'/ref' let s:dictionary = s:ref.'/dictionary.txt' execute 'set dictionary^='.s:EscItemExec(s:dictionary) let s:thesaurus = s:ref.'/thesaurus.txt' execute 'set thesaurus^='.s:EscItemExec(s:thesaurus) set comments= commentstring= define= include= set path-=/usr/include set autoindent set expandtab set shiftwidth=4 set smarttab if v:version > 703 || v:version == 703 && has('patch693') set softtabstop=-1 else let &softtabstop = &shiftwidth endif set backspace+=eol set backspace+=indent set backspace+=start set linebreak if has('multi_byte_encoding') set showbreak=… else set showbreak=... endif if exists('+breakindent') set breakindent endif set confirm set noesckeys set formatoptions+=l set formatoptions+=1 if v:version > 703 || v:version == 703 && has('patch541') set formatoptions+=j endif set cpoptions+=J if has('patch-8.1.728') set formatoptions+=p endif if has('gui_running') set guioptions+=M endif set hidden set hlsearch nohlsearch set incsearch set lazyredraw set listchars+=tab:>- set listchars+=trail:- set listchars+=nbsp:+ if has('multi_byte_encoding') set listchars+=extends:»,precedes:« else set listchars+=extends:>,precedes:< endif set nomodeline set nrformats-=octal set noruler set sessionoptions-=localoptions set sessionoptions-=options set noshowcmd set shortmess+=I if !&loadplugins || globpath(&runtimepath, 'plugin/matchparen.vim') ==# '' set showmatch matchtime=3 endif set splitbelow splitright set synmaxcol=500 if &term =~# '^putty\|^tmux' set ttyfast endif set ttymouse= set virtualedit+=block set visualbell t_vb= set wildmenu set wildmode=list:longest,full set wildignore=*~,#*# \,*.7z \,.DS_Store \,.git \,.hg \,.svn \,*.a \,*.adf \,*.asc \,*.au \,*.aup \,*.avi \,*.bin \,*.bmp \,*.bz2 \,*.class \,*.db \,*.dbm \,*.djvu \,*.docx \,*.exe \,*.filepart \,*.flac \,*.gd2 \,*.gif \,*.gifv \,*.gmo \,*.gpg \,*.gz \,*.hdf \,*.ico \,*.iso \,*.jar \,*.jpeg \,*.jpg \,*.m4a \,*.mid \,*.mp3 \,*.mp4 \,*.o \,*.odp \,*.ods \,*.odt \,*.ogg \,*.ogv \,*.opus \,*.pbm \,*.pdf \,*.png \,*.ppt \,*.psd \,*.pyc \,*.rar \,*.rm \,*.s3m \,*.sdbm \,*.sqlite \,*.swf \,*.swp \,*.tar \,*.tga \,*.ttf \,*.wav \,*.webm \,*.xbm \,*.xcf \,*.xls \,*.xlsx \,*.xpm \,*.xz \,*.zip if exists('+wildignorecase') set wildignorecase endif if !exists('syntax_on') syntax enable endif autocmd vimrc ColorScheme * \ let &cursorline = g:colors_name ==# 'sahara' if !exists('$COLORFGBG') && get(v:, 'termrbgresp', '') ==# '' set background=dark endif if &background ==# 'dark' \ && (has('gui_running') || &t_Co >= 256) \ && globpath(&runtimepath, 'colors/sahara.vim') !=# '' colorscheme sahara endif nnoremap nnoremap \ line('w$') < line('$') \ ? "\" \ : ":\next\" if &loadplugins && globpath(&runtimepath, 'plugin/insert_cancel.vim') !=# '' imap (InsertCancel) endif imap (DigraphSearch) nnoremap \ :nohlsearch inoremap :execute "normal \" vmap gv noremap & \ :&& ounmap & sunmap & nmap g: (ColonOperator) nnoremap [a \ :previous nnoremap ]a \ :next nnoremap [b \ :bprevious nnoremap ]b \ :bnext nnoremap [c \ :cprevious nnoremap ]c \ :cnext nnoremap [l \ :lprevious nnoremap ]l \ :lnext nmap [ (PutBlankLinesAbove) nmap ] (PutBlankLinesBelow) let mapleader = '\' let maplocalleader = ',' if maplocalleader ==# ',' noremap ,, , sunmap ,, endif nnoremap \ :set autoindent! autoindent? nnoremap c \ :set cursorline! cursorline? nnoremap h \ :set hlsearch! hlsearch? nnoremap i \ :set incsearch! incsearch? nnoremap s \ :set spell! spell? noremap C \ :set cursorcolumn! cursorcolumn? ounmap C sunmap C noremap l \ :set list! list? ounmap l sunmap l noremap n \ :set number! number? ounmap n sunmap n noremap N \ :set ruler! ruler? ounmap N sunmap N noremap w \ :set wrap! wrap? ounmap w sunmap w nnoremap f \ :set formatoptions? nnoremap u \ :set spelllang=en_us nnoremap z \ :set spelllang=en_nz nmap b (CopyLinebreakToggle) nnoremap a \ :ToggleFlagLocal formatoptions a noremap L \ :ToggleFlagLocal colorcolumn +1 ounmap L sunmap L nmap p PasteInsert nnoremap F \ :ReloadFileType nnoremap t \ :set filetype? nnoremap T \ :set filetype= nnoremap d \ :PutDate nnoremap D \ :PutDate! nnoremap g \ :echo expand('%:p') nnoremap G \ :cd %:hpwd nnoremap P \ :Establish %:h nnoremap H \ :history : nnoremap k \ :marks nnoremap K \ :function nnoremap m \ :nmap nnoremap M \ :nmap nnoremap S \ :scriptnames nnoremap U \ :command nnoremap v \ :let g: v: nnoremap V \ :let b: t: w: nnoremap y \ :registers nnoremap \ :bdelete nnoremap \ :enew nnoremap e \ :set modifiable noreadonly nnoremap E \ :set nomodifiable readonly nnoremap j \ :buffers:buffer nmap o (SelectOldFiles) noremap x \ :StripTrailingWhitespace ounmap x sunmap x noremap X \ :SqueezeRepeatBlanks ounmap X sunmap X nnoremap = \ :KeepPosition execute 'normal! 1G=G' nnoremap + \ :KeepPosition execute 'normal! 1GgqG' onoremap _ \ :execute 'normal! `[v`]' onoremap % \ :execute 'normal! 1GVG' omap 5 % map { (VerticalRegionUp) sunmap { map } (VerticalRegionDown) sunmap } noremap \ `" sunmap \ nnoremap \ :'[,'] nnoremap > \ :'[,']> nnoremap / \ :vimgrep /\c/j ** nnoremap ? \ :lhelpgrep \c nnoremap . \ :lmake! nnoremap q gqap map r (ReplaceOperator) sunmap r ounmap r nnoremap ! \ :! nmap 1 ! nmap # (AlternateFileType) nmap 3 # nmap $ (Fortune) nmap 4 $ nmap & (RegexEscape) nmap 7 & xmap & (RegexEscape) xmap 7 & nnoremap * *N nmap 8 * nnoremap ` \ :ScratchBuffer nnoremap ~ \ :vertical ScratchBuffer nnoremap R \ :ReloadVimrc inoreabbrev tr@ tom@sanctum.geek.nz inoreabbrev tr/ inoreabbrev almsot almost inoreabbrev wrnog wrong inoreabbrev Fielding Feilding inoreabbrev THe The inoreabbrev THere There " Here endeth the literate vimrc. Let us praise God. " " │ Consequently, it is soon recognized that they write for the sake of " │ filling up the paper, and this is the case sometimes with the best " │ authors…as soon as this is perceived the book should be thrown away, " │ for time is precious. " │ " │ —Schopenhauer "