" How to install me: " " git clone http://code.p1k3.com/gitea/brennen/wmf-engprod-offsite-slides.git " mkdir -p ~/.vim/bundle " cp wmf-engprod-offsite-slides/vim/vimrc ~/.vim/vimrc " git clone https://github.com/VundleVim/Vundle.vim ~/.vim/bundle/Vundle.vim " vim +PluginInstall " Use comma for the leader key let mapleader = "," " 1. Package management {{{ set nocompatible " Disable modelines for security: set nomodeline filetype off set rtp+=~/.vim/bundle/Vundle.vim/ call vundle#begin() " Let Vundle manage Vundle - required: Plugin 'VundleVim/Vundle.vim' " Really nice file tree - see keybindings section below for some tweaks: Plugin 'preservim/nerdtree' Plugin 'Xuyuanp/nerdtree-git-plugin' " Double click to open nodes: " (for directory nodes with a single click, set to 2) " (for all nodes with a single click, set to 3) let NERDTreeMouseMode = 1 " Fancy start screen with recent files & bookmarks Plugin 'mhinz/vim-startify' let g:startify_bookmarks = [ {'v': '~/code/wmf'}, '~/.bashrc', '~/notes/' ] " Vim Outliner of Markups - see :help voom - no idea yet if this is any good Plugin 'vim-voom/VOoM' " Align text vertically on a string: Plugin 'Align' " Wrap common version control commands: Plugin 'vcscommand.vim' Plugin 'tpope/vim-fugitive' " Visual marking of changes in working tree: Plugin 'git://github.com/airblade/vim-gitgutter.git' " commands for surrounding chars: Plugin 'tpope/vim-repeat' " used by vim-surround, commentary Plugin 'tpope/vim-surround' " Readline-style keybindings in command line / insert: Plugin 'tpope/vim-rsi' " Enable gc[motion] to comment, gcc to comment current line: Plugin 'https://tpope.io/vim/commentary.git' " A bunch of colorschemes + a gui menu listing them: Plugin 'flazz/vim-colorschemes' Plugin 'altercation/vim-colors-solarized' Plugin 'chriskempson/vim-tomorrow-theme.git' Plugin 'desert-warm-256' Plugin 'ColorSchemeMenuMaker' Plugin 'ScrollColors' " beyondgrep.com: Plugin 'mileszs/ack.vim' " fzf - fuzzy finding " https://github.com/junegunn/fzf let g:fzf_launcher = '/usr/bin/xterm' Plugin 'junegunn/fzf' " Preview contents of named registers: Plugin 'junegunn/vim-peekaboo' " ASCII art - ,di to start, arrow keys to draw lines, ,ds to stop: Plugin 'DrawIt' " Most recently used files - my fork allows for a top-level menu: let g:MRU_Menu_Path = '&Recent\ Files' let g:MRU_Max_Menu_Entries = 30 let g:MRU_Max_Submenu_Entries = 30 Plugin 'https://code.p1k3.com/gitea/brennen/mru.git' " Do stuff with tables - used by some vim-markdown features: Plugin 'godlygeek/tabular' " Filetypes / modes / language support {{{ let g:go_version_warning = 0 Plugin 'fatih/vim-go' " golang Plugin 'rust-lang/rust.vim' Plugin 'chikamichi/mediawiki.vim' Plugin 'plasticboy/vim-markdown' Plugin 'nginx.vim' Plugin 'jceb/vim-orgmode' " }}} " Graceful syntax checking for many languages: " - apt-get install shellcheck for shell linting Plugin 'vim-syntastic/syntastic' let g:syntastic_check_on_open = 1 let g:syntastic_php_checkers = ['php'] let g:syntastic_enable_perl_checker = 1 let g:syntastic_perl_lib_path = ['./lib', './lib/auto'] let g:syntastic_perl_checkers = ['perl', 'podchecker'] " Fancy status line; laststatus can be set so it always shows up: Plugin 'vim-airline/vim-airline' Plugin 'vim-airline/vim-airline-themes' let g:airline_theme = 'luna' if has("gui_running") let g:airline_theme = 'base16_ashes' endif " GUI font size - use + or - to adjust Plugin 'drmikehenry/vim-fontsize' " Ctrl-A increment / Ctrl-X decrement various date formats with this one: " try, for example: Tue, 26 Jan 2016 23:59:59 +0000 Plugin 'tpope/vim-speeddating' " Open files at the cursor position where you left off (awesome): Plugin 'farmergreg/vim-lastplace' " Handle .editorconfig files: " https://editorconfig.org/ " https://github.com/editorconfig/editorconfig-vim Plugin 'editorconfig-vim' " a calendar - used in conjunction with vimwiki diaries let g:calendar_keys = { \ 'goto_next_month': '', \ 'goto_prev_month': '', \ 'goto_next_year': '', \ 'goto_prev_year': '' \ } Plugin 'mattn/calendar-vim' Plugin 'mbbill/undotree' " Vimwiki - for notes, daily logs, etc. {{{ " Main personal wiki: let wiki = {} let wiki.path = '~/vimwiki/' let wiki.path_html = '~/html/' let wiki.auto_tags = 1 let wiki.auto_diary_index = 1 let wiki.automatic_nested_syntaxes = 1 " This could be a list containing many vimwikis: let g:vimwiki_list = [wiki] " Don't make temporary wikis based on file extensions in the list - this " is necessary to avoid .md files getting a filetype of vimwiki instead of " markdown: let g:vimwiki_global_ext = 0 let g:vimwiki_folding = 'expr' " let g:vimwiki_folding = 'syntax' " let g:vimwiki_folding = 'list' " Link concealing when cursor not on line, etc.: " let g:vimwiki_conceallevel = 0 " Don't obscure URLs in links: " let g:vimwiki_url_maxsave = 0 " Make links clickable and such: let g:vimwiki_use_mouse = 1 " Use colors in header highlighting let g:vimwiki_hl_headers = 1 Plugin 'vimwiki/vimwiki' augroup bpb_vimwiki " clear any existing commands in this group: autocmd! " selectively activate foldcolumn: au FileType vimwiki setlocal foldcolumn=3 " regenerate vimwiki diary on file load: " (with auto_diary_index, the index is updated every time you use " ,wi to open - this covers the rest of the cases, i guess) au BufReadPost,BufNewFile *vimwiki/diary/diary.wiki :VimwikiDiaryGenerateLinks " set up linewrapping so that long lines more or less work au BufRead,BufNewFile *.wiki call LonglineMode() augroup END " }}} call vundle#end() filetype plugin on filetype indent on " }}} " 2. miscellaneous UI {{{ " Set the window title (usually to filename plus some metadata): set title " Pretty colors: set t_Co=256 syntax on " Pretty characters: set encoding=utf-8 " Do not beep or flash at me: " vb is needed to stop beep " t_vb sets visual bell action, we're nulling it out here " note also that this may need to be repeated in .gvimrc set visualbell set t_vb= " Enable mouse for (a)ll, (n)ormal, (v)isual, (i)nsert, or (c)ommand line " mode - works in most terminals: set mouse=a " Let me delete stuff while in insert mode: set backspace=indent,eol,start " Display commands as-typed + current position in file: set showcmd set ruler " Set height of command line area - having it greater than one avoids some " hit-enter prompts: set cmdheight=2 " Display a visual menu for tab-completion of files: set wildmenu " Keep lots of command-line history - 10000 is currently the max value: set history=10000 " Search: set incsearch set ignorecase set smartcase set wrapscan " neovim defaults hlsearch to on, which annoys me personally set nohlsearch " use + register (x window clipboard) as unnamed register (copy to system " clipboard on yy, for example): if has('nvim') set clipboard+=unnamedplus else set clipboard=unnamedplus,autoselect endif " }}} " 3. File saving/loading/swap/backups {{{ " Read (unchanged) buffers when they're modified on filesystem. " this saves me a lot of time and agony because I switch git branches " constantly, but it might not be what you want: set autoread " Disable swapfiles (you may not want this (but you probably do)): set noswapfile " }}} " 4. Whitespace handling {{{ " Display tabs and trailing spaces: set listchars=tab:⇾\ ,trail:· set list " Display tab characters as 8 spaces, indent 2 spaces, " always use spaces instead of tabs: set tabstop=8 set shiftwidth=2 set softtabstop=2 set expandtab set autoindent " set smarttab " set smartindent " For c code, no tab expansion, turn off softtabstop au FileType c setlocal noexpandtab au FileType c setlocal shiftwidth=8 au FileType c setlocal softtabstop=0 " Turn off tab expansion for Makefiles and calendar files: au FileType make setlocal noexpandtab au FileType calendar setlocal noexpandtab " Wrap entire words in markdown files " http://stackoverflow.com/questions/19624105/how-can-i-make-vim-break-lines-only-on-whitespace au FileType markdown setlocal wrap linebreak breakat&vim " }}} " 5. Custom keybindings {{{ " F2 toggles the nerdtree file browser pane map :NERDTreeToggle imap :NERDTreeToggle " F3 finds the current file in nerdtree map :NERDTreeFind " F4 toggles line numbers map :set invnumber imap :set invnumber " F5 saves everything map :wall imap " F6 brings up a recently-used file list using MRU map :MRU imap " F7 opens ~/.vim/vimrc (in existing tab if open, new otherwise) " (7 kind of looks like a rotated v) " see http://learnvimscriptthehardway.stevelosh.com/chapters/07.html for " rationale - the idea is to make changing vim configuration trivial if has('nvim') map :call TabDrop("~/.vim/vimrc") else map :call TabDrop($MYVIMRC) endif imap " F8 inserts an ISO-8601 datestamp (mnemonic: eight rhymes with date) " (used to open the options window; use :options for that) map :r !date -IkJ " ,F8 inserts a date with seconds precision map :r !date -IskJ " ,td / ,tD do the same (mnemonic: toDay) map td :r !date -IkJ map tD :r !date -IskJ imap " F9 toggles search highlighting and some other noise map :call Crosshairs() imap " F10 starts a git commit for recent changes map :Gcommit -av " F11 i'm leaving unbound because of fullscreen shortcuts in various " terminals and window managers " in normal or insert mode, copies all in buffer " in visual/select modes, it just yanks the selected bit nmap :%y+ imap vmap y+ " add a menu separator menu Cheatsheet.-misc- : " split lines under the cursor (modeled on, maybe, emacs?) map K ig; " an FZF fragment menu nmap F :call FragmentMenu() " Find files with fzf fuzzy-finder (assumes FZF is installed) " https://github.com/junegunn/fzf nmap f :FZF " Pull up the git log: nmap gl :Glog:copen " Run any Makefile in the current directory: nmap m :make " Jump to next, previous errors: nmap n :cnext nmap p :cprev " Reformat a paragraph: nmap q gqip " Q mapping (it usually enters ex mode) based on this mail from bram: " https://groups.google.com/forum/#!search/vim/vim_use/iXH_Zxj8iBA/H7YDtbACBAAJ " note this is done by default in neovim map Q gq " Delete trailing whitespace, file-wide: nmap s :%s/\s\+$//e " New tab: nmap tn :tabnew " Split window navigation (ctrl-j/k, alt-arrows): map j_ map j map k_ map k map l map h " }}} " 6. Write custom functions {{{ " Run the file through a custom filter, leaving the cursor at its original " location in the file (or close) - there might be a better way to do this, " but I don't know what it is. function! s:RunFilter(filter) let l:currentline = line('.') exe ":%!" . a:filter exe ":" . l:currentline endfunction " Do some normal-mode commands and return the cursor to its previous location function! s:ExecNormalAndReturnCursor(commands) let l:currentline = line('.') " see http://learnvimscriptthehardway.stevelosh.com/chapters/30.html exe "normal! " . a:commands exe ":" . l:currentline endfunction " Spit out a date for today. function! s:Datestamp() " . is current line, -1 is 1 line above that, r would otherwise read " the output onto the line below the cursor .-1r !date endfunction " select a fragment script using fzf and include its output in the " current buffer function! s:FragmentMenu() call fzf#run({ \ 'options': '--reverse', \ 'sink': '.-1r !', \ 'source': 'find ~/bin/ -maxdepth 1 -name "fragment-*" -printf "%f\n"' \ }) endfunction " Make things more amenable to editing long soft-wrapped lines " mostly an attempt to make vimwiki a bit more ergonomic, this " version adapted from: " http://www.baryudin.com/blog/vim-line-wrapping-and-word-boundary.html function! s:LonglineMode() setlocal wrap linebreak set virtualedit= setlocal display+=lastline noremap gk noremap k gk noremap gj noremap j gj noremap g noremap g inoremap gk inoremap gj inoremap g inoremap g endfunction " add some display sugar that helps highlight cursor, searches, and " textwidth. good for fiddling with alignment, reflowing text, etc. function! s:Crosshairs() set invhlsearch set invcursorcolumn set invcursorline " Toggle a colorcolumn - will get weird if it's set outside this function if &colorcolumn == "+1" set colorcolumn=0 else " I think this is relative to textwidth: set colorcolumn=+1 endif endfunction " Tab drop (edit in existing or new tab) a file's real path, in case it is a " symlink - useful for, frex, symlinked .vimrc. does wildcard expansion on " the path. as usual, there are probably better ways to do all of this. function! s:TabDrop(path) let realpath = system('readlink -fn ' . shellescape(expand(a:path))) echom realpath execute 'tab drop ' . realpath endfunction " This is ridiculous: " https://vi.stackexchange.com/questions/21825/how-to-insert-text-from-a-variable-at-current-cursor-position function! s:AppendAtCursor(string) execute "normal! a\\=a:string\\\" endfunc " Get a list of key bindings, along with where they were defined, and " open it in a tab. This variant of redir and map seen at: " https://stackoverflow.com/questions/7642746/is-there-any-way-to-view-the-currently-mapped-keys-in-vim#7642762 function! g:ListBindings() redir! > ~/vim_keys.txt silent verbose map redir END call TabDrop("~/vim_keys.txt") endfunction " }}} " 7. Pick a colorscheme {{{ " I have used these all at one time or another and liked them for various " reasons: " colorscheme brookstream " colorscheme mustang " colorscheme dark-ruby " colorscheme Tomorrow-Night-Bright " colorscheme pyte " colorscheme wargrey " colorscheme hybrid " colorscheme icansee " colorscheme candycode " colorscheme peppers " colorscheme inkpot colorscheme iceberg " }}} " 8. Make folding suck less {{{ " Turn off folding by default - i constantly open some file and have to " expand folds to see what's going on; this is easy to get back with zi set nofoldenable " Use {{{ and }}} to denote a folded section (these can be adjusted by " setting foldmarker, but i'm sticking with the vim defaults): set foldmethod=marker " For custom foldline colors: highlight FoldColumn ctermbg=darkgrey ctermfg=white guibg=darkgrey guifg=white " forked from: http://dhruvasagar.com/2013/03/28/vim-better-foldtext function! BPB_NeatFoldText() let line = ' ' . substitute(getline(v:foldstart), '^\s*"\?\s*\|\s*"\?\s*{{' . '{\d*\s*', '', 'g') . ' ' let lines_count = v:foldend - v:foldstart + 1 let lines_count_text = '| ' . printf("%10s", lines_count . ' lines') . ' |' let foldchar = matchstr(&fillchars, 'fold:\zs.') let foldtextstart = strpart('+' . repeat(foldchar, v:foldlevel*2) . line, 0, (winwidth(0)*2)/3) let foldtextend = lines_count_text . repeat(foldchar, 8) let foldtextlength = strlen(substitute(foldtextstart . foldtextend, '.', 'x', 'g')) + &foldcolumn return foldtextstart . repeat(foldchar, winwidth(0)-foldtextlength) . foldtextend endfunction set foldtext=BPB_NeatFoldText() " }}}