Dotfiles, utilities, and other apparatus.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1091 lines
35 KiB

" vim:foldmethod=marker:foldlevel=0:foldenable
" this is my vimrc; part of
" to use:
" mkdir -p ~/.vim
" cp [this file] ~/vim/vimrc
" mkdir -p ~/.vim/bundle
" git clone ~/.vim/bundle/Vundle.vim
" vim +PluginInstall
" if there are funny-looking folded sections below and you're confused,
" hitting zR will unfold them all, while zr will unfold the one your
" cursor is on. this note is as much for my benefit as yours.
" an increasing percentage of this config is very specific to my preferences.
" there are keybindings for filters i use regularly, things that automatically
" happen when i open certain files, and shortcuts bound to the F-keys. quite
" a lot of the behavior here also assumes it'll have scripts found in ~/bin
" - see home/bin in this repo - and may rely on tools i haven't yet published.
" items particularly likely to be personal preference are marked with the
" string CUSTOMIZE and a note.
" -- bpb | |
set nocompatible
" Temporarily disable modelines (like the one at the top of this file), per:
" TODO: Patch and/or look at securemodelines plugin
set nomodeline
" use comma for the leader key - this is used as a prefix for
" a bunch of bindings, mostly in the keybindings section. it's up
" here for things that might require it before plugins are invoked,
" such as vimwiki mappings.
let mapleader = ","
" let mapleader = " "
" vundle setup & vundle-managed plugins {{{
filetype off
set rtp+=~/.vim/bundle/Vundle.vim/
call vundle#begin()
" let Vundle manage Vundle - required:
Plugin 'VundleVim/Vundle.vim'
" TODO: language server stuff
" Plugin 'prabirshrestha/async.vim'
" Plugin 'prabirshrestha/vim-lsp'
" if executable('pyls')
" " pip install python-language-server
" au User lsp_setup call lsp#register_server({
" \ 'name': 'pyls',
" \ 'cmd': {server_info->['pyls']},
" \ 'whitelist': ['python'],
" \ })
" endif
" 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
" CUSTOMIZE: you'll probably want different bookmarks
Plugin 'mhinz/vim-startify'
" let g:startify_bookmarks = [ {'v': '~/.vimrc'}, '~/.zshrc', '~/notes/', '~/p1k3' ]
" 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://'
" match lots of things - this repo seems defunct; not sure who is
" currently maintaining this one:
" Plugin 'edsono/vim-matchit'
" 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'
" gc[motion] to comment, gcc to comment current line
Plugin ''
" a yank/paste ring - hit ctrl-p after pasting:
" let g:yankring_history_dir = '$HOME/.vim'
" Plugin 'vim-scripts/YankRing.vim'
" 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'
" some useful icons in various plugins, if you were willing to deal
" with the font hassles (i am not)
" Plugin 'ryanoasis/vim-devicons'
Plugin 'mileszs/ack.vim'
" navigate & control tmux windows + vim buffers - see also .tmux.conf
" Plugin 'christoomey/vim-tmux-navigator'
" Plugin 'benmills/vimux'
" find files / buffers / etc.:
" Plugin 'L9' " - required by FuzzyFinder
" Plugin 'FuzzyFinder'
Plugin 'Shougo/unite.vim'
" fzf - fuzzy finding {{{
let g:fzf_launcher = '/usr/bin/xterm'
Plugin 'junegunn/fzf'
" Some utility wrappers around fzf stuff:
Plugin 'junegunn/fzf.vim'
" Example git grep wrapper from fzf.vim readme
command! -bang -nargs=* GGrep
\ call fzf#vim#grep(
\ 'git grep --line-number -- '.shellescape(<q-args>), 0,
\ fzf#vim#with_preview({'dir': systemlist('git rev-parse --show-toplevel')[0]}), <bang>0)
" Use fzf for multi-definition tags:
Plugin 'zackhsi/fzf-tags'
nmap <C-]> <Plug>(fzf_tags)
" }}}
" Distraction-free mode:
Plugin 'junegunn/goyo.vim'
" preview contents of named registers
Plugin 'junegunn/vim-peekaboo'
" ASCII art
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 ''
" database stuffs
" Plugin 'dbext.vim'
" 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']
amenu Syntax.Toggle\ Syntastic :SyntasticToggleMode<CR>
" let g:syntastic_python_checkers = ['pylint']
" add option to show a diff when there's a swapfile on disk:
" Plugin 'chrisbra/Recover.vim'
" CUSTOMIZE: fancy status line; laststatus can be set so it always shows up
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
" set laststatus=2
" let g:airline#extensions#tabline#enabled = 1
let g:airline_theme = 'luna'
if has("gui_running")
let g:airline_theme = 'base16_ashes'
" Dr. Chip's debugging for syntax highlighting:
Plugin 'gerw/vim-HiLinkTrace'
" GUI font size - use <Leader><Leader>+ 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:
Plugin 'editorconfig-vim'
" a calendar - used in conjunction with vimwiki diaries
let g:calendar_keys = {
\ 'goto_next_month': '<C-Right>',
\ 'goto_prev_month': '<C-Left>',
\ 'goto_next_year': '<C-Up>',
\ 'goto_prev_year': '<C-Down>'
\ }
Plugin 'mattn/calendar-vim'
Plugin 'mbbill/undotree'
" Vdebug should work with xdebug - see help for XDEBUG_CONFIG stuffs,
" although they don't seem to have been translated for Xdebug 3.x. I've
" namespaced all the keymaps here so that when this is enabled it doesn't
" stomp all over my usual bindings.
let g:vdebug_keymap = {
\ "run" : "<Leader><F5>",
\ "run_to_cursor" : "<Leader><F9>",
\ "step_over" : "<Leader><F2>",
\ "step_into" : "<Leader><F3>",
\ "step_out" : "<Leader><F4>",
\ "close" : "<Leader><F6>",
\ "detach" : "<Leader><F7>",
\ "set_breakpoint" : "<Leader><F10>",
\ "get_context" : "<Leader><F11>",
\ "eval_under_cursor" : "<Leader><F12>",
\ "eval_visual" : "<Leader>e",
" The Xdebug 3.x default port is 9003:
let g:vdebug_options = { 'port' : 9003 }
Plugin ''
" minimap of code
" TODO: does this actually work?
" Plugin 'severin-lemaignan/vim-minimap'
" CUSTOMIZE: vimwikis - for notes, daily logs, etc. {{{
" main personal wiki
let wiki = {}
let wiki.path = '~/notes/vimwiki/'
let wiki.path_html = '~/notes/html/'
let wiki.auto_tags = 1
let wiki.auto_diary_index = 1
let wiki.automatic_nested_syntaxes = 1
" a markdown wiki for testing purposes
let markdownwiki = {}
let markdownwiki.path = '~/notes/markdownwiki'
let markdownwiki.path_html = '~/notes/markdownwiki/html/'
let markdownwiki.auto_tags = 1
let markdownwiki.auto_diary_index = 1
let markdownwiki.automatic_nested_syntaxes = 1
let markdownwiki.syntax = 'markdown'
let markdownwiki.ext = '.md'
" do syntax highlight in preformatted blocks - it's worth noting that if
" wiki.automatic_nested_syntaxes is on (it defaults to 1) this may not
" be necessary. it's off here for the moment because it was causing
" some weird collisions between embedded syntaxen - notably if the
" markdown one was loaded before the mediawiki one, indented lists in
" mediawiki blocks were getting false hits for markdown's bold. this
" may be a bug in vim-markdown, which is a little flaky to begin with.
" let wiki.nested_syntaxes = {
" \ 'python': 'python',
" \ 'ruby': 'ruby',
" \ 'perl': 'perl',
" \ 'sh': 'sh',
" \ 'dockerfile': 'dockerfile',
" \ 'go': 'go',
" \ 'yaml': 'yaml',
" \ 'mediawiki': 'mediawiki',
" \ 'markdown': 'markdown',
" \ }
" completion and dictionary stuff for Ctrl-P,Ctrl-N - uses an
" index built by an embedded script on my vimwiki index for
" keyword completion:
set dictionary+=~/notes/tag-index
set complete=.,w,b,u,t,i,k
" there can be many of these
let g:vimwiki_list = [wiki, markdownwiki]
" 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'
" links concealing, 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
" hit ,S to debug current syntax highlighting groups
" map <Leader>S :echo "hi<" . synIDattr(synID(line("."),col("."),1),"name") . '> trans<'
" \ . synIDattr(synID(line("."),col("."),0),"name") . "> lo<"
" \ . synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") . ">"<CR>
" map <Leader> b to go back - the plugin will check for this
" mapping and not associate it with regular backspace (which
" i kept hitting by accident)
" NOTE: <C-BS> doesn't work here; I tried
nmap <Leader>b <Plug>VimwikiGoBackLink
" au FileType vimwiki :set tw=80
" override default vimwiki link handling - could be extended to add
" custom link types, etc. Right now all it does is use vim itself
" to handle files, crudely.
function! VimwikiLinkHandler(link)
if a:link =~# 'file:'
" chop off the leading file: - see :h expr-[:] for syntax:
execute ':e ' . a:link[5:]
return 1
echo "Something went wrong..."
return 0
Plugin 'vimwiki/vimwiki'
augroup bpb_vimwiki
" clear any existing commands in this group:
" 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/ :VimwikiDiaryGenerateLinks
" run new diary entry template:
au BufNewFile *vimwiki/diary/*.wiki :0r !fragment-vimwiki-diary '%'
" run new diary entry template:
au BufNewFile *vimwiki/log/*.wiki :0r !fragment-vimwiki-log
" set up linewrapping so that long lines more or less work
au BufRead,BufNewFile *.wiki call <SID>LonglineMode()
au BufReadPost *.wiki call <SID>WikiBufReadPostOverrides()
au BufWritePost *vimwiki/*.wiki call <SID>WikiBufWritePostOverrides()
augroup END
" }}}
" snippets
" Plugin 'SirVer/ultisnips'
" Plugin 'honza/vim-snippets'
" " trigger configuration
" " don't use <tab> if you use
" let g:UltiSnipsExpandTrigger="<tab>"
" let g:UltiSnipsJumpForwardTrigger="<c-b>"
" let g:UltiSnipsJumpBackwardTrigger="<c-z>"
" " if you want :UltiSnipsEdit to split your window.
" let g:UltiSnipsEditSplit="vertical"
call vundle#end()
filetype plugin on
filetype indent on
" }}}
" misc 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 - seems to work in most terminals
set mouse=a
" render a useful popup menu for right-click instead of extending
" selection (good for spellchecking, etc.):
set mousemodel=popup_setpos
" let me delete stuff like crazy in insert mode
set backspace=indent,eol,start
" see :help virtualedit - you probably don't want this
" set virtualedit=onemore
" display commands as-typed + current position in file
set showcmd
set ruler
" 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
" add git status to statusline; otherwise emulate standard line with ruler
" -- mostly supplanted for the moment by vim-airline
set statusline=%<%{fugitive#statusline()}\ %f\ %h%m%r%=%-14.(%l,%c%V%)\ %P
" keep lots of command-line history - 10000 is currently the max value:
set history=10000
" search:
set incsearch
set ignorecase
set smartcase
set wrapscan
" CUSTOMIZE: neovim defaults hlsearch to on, which annoys me personally
set nohlsearch
" for gvim. no toolbar, otherwise these are the defaults
" set guioptions=aegimrLt
" use + register (x window clipboard) as unnamed register (copy to system
" clipboard on yy, for example):
if has('nvim')
set clipboard+=unnamedplus
set clipboard=unnamedplus,autoselect
" include '-' in words. counts for both movement commands and autocomplete.
" to test, try moving across and autocompleting for some-words-bunched-up
" this is an experiment - mainly i want to use inline dashes in identifiers
" in markdown documents, and so forth
set iskeyword+=-
" }}}
" 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
" CUSTOMIZE: disable swapfiles (you may not want this (but you probably do)):
set noswapfile
" }}}
" CUSTOMIZE: whitespace {{{
" 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
au FileType markdown setlocal wrap linebreak breakat&vim
" }}}
" misc. autocommands {{{
" to get a list of current autocommands:
" :redir @a
" :autocmd
" :redir END
" "ap
" assume *.t files are PHP - i was doing this to override the assumption
" that they're perl
" au BufRead,BufNewFile *.t set filetype=php
" retain view/folds on a specific file:
" au BufWinLeave notes.txt mkview
" au BufWinEnter notes.txt silent loadview
au BufReadPost,BufNewFile *.md set filetype=markdown
" CUSTOMIZE: this invokes a function for doing some custom filetype
" overrides, like treating blog entries as markdown. it is mostly
" for places where i couldn't figure out an autocmd, or needed something
" more complex than the pattern matching offered by au
" this used to fail for files named `index`, because of a fugitive bug:
au BufReadPost,BufNewFile * call <SID>FiletypeOverrides()
au BufNewFile * call <SID>NewFileOverrides()
" TODO: make a colorscheme logger here - it'd be nice to know all the
" schemes i ever use for later reference:
" au ColorScheme * call <SID>ColorSchemeOverrides()
" }}}
" keybindings {{{
" CUSTOMIZE: my keybinding habits may be idiosyncratic
" aside from function keys, i try not to stomp on the main keybinding
" 'namespace' too much, with the exception of replacing K with something
" useful.
" a handful of functions are called here, all with a prefix of <SID> -
" they can be found in the "functions" section below
" many things here have menu entries under 'Cheatsheet', as a cheatsheet for
" all the stuff i've defined. these can also be accessed with :emenu in
" terminal vim.
" wait longer than the default (1000ms) for keycodes and mapped keys:
set timeoutlen=3000
" i use the F-keys a _lot_. this is what makes NERDTree usable.
" F2 toggles the nerdtree file browser pane
map <F2> :NERDTreeToggle<CR>
imap <F2> <Esc>:NERDTreeToggle<CR>
650amenu Cheatsheet.NERDTree<Tab>F2 <F2>
" F3 finds the current file in nerdtree
map <F3> :NERDTreeFind<CR>
amenu Cheatsheet.NERDTreeFind<Tab>F3 <F3>
" F4 toggles line numbers
map <F4> :set invnumber<CR>
imap <F4> <Esc>:set invnumber<CR>
" this version cycles through a couple versions of relative and absolute
" line numbers:
" map <F4> :call <SID>CycleLineNumbers()<CR>
" imap <F4> <Esc>:call <SID>CycleLineNumbers()<CR>
amenu Cheatsheet.Toggle\ Line\ Numbers<Tab>F4 <F4>
" F5 saves everything
map <F5> :wall<CR>
imap <F5> <Esc><F5>
amenu Cheatsheet.Write\ All<Tab>F5 <F5>
" F6 brings up a recently-used file list using MRU
map <F6> :MRU<CR>
imap <F6> <Esc><F6>
amenu Cheatsheet.Most\ Recently\ Used<Tab>F6 <F6>
" F7 opens ~/.vim/vimrc (in existing tab if open, new otherwise)
" (7 kind of looks like a rotated v)
" see for
" rationale - the idea is to make changing vim configuration trivial
if has('nvim')
map <F7> :call <SID>TabDrop("~/.vim/vimrc")<CR>
map <F7> :call <SID>TabDrop($MYVIMRC)<CR>
imap <F7> <Esc><F7>
amenu Cheatsheet.Open\ vimrc<Tab>F7 <F7>
" F8 inserts an ISO-8601 datestamp (mnemonic: eight rhymes with date)
" (used to open the options window; use :options for that)
map <F8> :r !date -I<CR>kJ
" ,F8 inserts a date with seconds precision
map <Leader><F8> :r !date -Is<CR>kJ
" ,td / ,tD do the same (mnemonic: toDay)
map <Leader>td :r !date -I<CR>kJ
map <Leader>tD :r !date -Is<CR>kJ
imap <F8> <Esc><F8>
amenu Cheatsheet.Insert\ Datestamp<Tab>F8 <F8>
" F9 toggles search highlighting and some other noise
map <F9> :call <SID>Crosshairs()<CR>
imap <F9> <Esc><F9>
amenu Cheatsheet.Crosshairs<Tab>F9 <F9>
" F10 starts a git commit for recent changes
map <F10> :Gcommit -av<CR>
amenu Cheatsheet.Gcommit<Tab>F10 <F10>
" F11 i'm leaving unbound because of fullscreen shortcuts in various
" terminals and window managers
" in normal or insert mode, <F12> copies all in buffer
" in visual/select modes, it just yanks the selected bit
nmap <F12> :%y+<CR>
imap <F12> <Esc><F12>
vmap <F12> y+
amenu Cheatsheet.Copy\ All<Tab>F12 <F12>
" add a menu separator
menu Cheatsheet.-misc- :
" split lines under the cursor (modeled on, maybe, emacs?)
map K i<CR><Esc>g;
amenu Cheatsheet.Split\ Line<Tab>K K
" an FZF fragment menu
nmap <Leader>F :call <SID>FragmentMenu()<CR>
amenu Cheatsheet.Fragment\ Menu<Tab>,F <Leader>F
" CUSTOMIZE: randomize certain text decorations - silly
nmap <Leader>D :call <SID>RunFilter("filter-decorate")<CR>
amenu Cheatsheet.Randomize\ Decorations<Tab>,D <Leader>D
nmap <Leader>d i<p class="centerpiece"> <Esc>:r !fragment-bullet<CR>kJA </p><Esc>
amenu Cheatsheet.Insert\ Decoration<Tab>,d <Leader>d
" CUSTOMIZE: find files with fzf fuzzy-finder (assumes FZF is installed)
nmap <Leader>f :FZF<CR>
amenu Cheatsheet.FZF\ Find<Tab>,f <Leader>f
" i didn't wind up using this much, and it potentially messes
" with vimwiki mappings:
" nmap <Leader>w :call <SID>CommandOutputInNewWindow("dict <cword>"))<CR>
" visual select inner word
nmap <Leader>v viW
" pull up the last hundred git commits in a scratch buffer
" nmap <Leader>l :vnew<CR>:set buftype=nofile<CR>:set bufhidden=hide<CR>:setlocal noswapfile<CR>:r !git log -100<CR>:set ft=git<CR>gg<C-w>r<C-w>l
nmap <Leader>gl :Glog<CR>:copen<CR>
amenu Cheatsheet.Git\ Log<Tab>,gl <Leader>gl
nmap <leader>m :make<CR>
amenu Cheatsheet.Make<Tab>,m <Leader>m
" requires git-do, from bpb-kit, to execute make in root of current git repo
nmap <leader>M :!git do make<CR>
amenu Cheatsheet.Make\ (git\ root)<Tab>,M <Leader>M
" jump to next, previous errors
nmap <Leader>n :cnext<CR>
amenu Cheatsheet.Next\ Error<Tab>,n <Leader>n
nmap <Leader>p :cprev<CR>
amenu Cheatsheet.Prev\ Error<Tab>,p <Leader>p
" generate a password-like string with apg
" nmap <Leader>pw :r !apg -a 0 -m 20 -n 1<CR>
" -a 0: use fully random string instead of pronounceable
nmap <Leader>pw :r !apg -a 1 -m 20 -n 1<CR>
amenu Cheatsheet.APG<Tab>,pw <Leader>pw
" reformat a paragraph
nmap <Leader>q gqip
amenu Cheatsheet.Reformat\ Para<Tab>,q <Leader>q
" Q mapping (it usually enters ex mode) based on this mail from bram:
" note this is done by default in neovim
map Q gq
" CUSTOMIZE: these are simple filter scripts to preprocess some
" shell commands in HTML or Markdown files - see scripts for details
nmap <Leader>r :call <SID>RunFilter("filter-exec-raw")<CR>:call <SID>RunFilter("filter-exec")<CR>:call <SID>RunFilter("filter-exec-stdin")<CR>
amenu Cheatsheet.Run\ Filters<Tab>,r <Leader>r
" delete trailing whitespace, file-wide
nmap <Leader>s :%s/\s\+$//e<CR>
amenu Cheatsheet.Zap\ Trailing\ Space<Tab>,s <Leader>s
" tab navigation somewhat like firefox
nmap <C-S-Tab> :tabprevious<CR>
nmap <C-Tab> :tabnext<CR>
map <C-S-Tab> :tabprevious<CR>
map <C-Tab> :tabnext<CR>
imap <C-S-Tab> <Esc>:tabprevious<CR>i
imap <C-Tab> <Esc>:tabnext<CR>i
" new tab:
nmap <Leader>tn :tabnew<CR>
amenu Cheatsheet.New\ Tab<Tab>,tn <Leader>tn
" run timeslice script for current file:
nmap <Leader>ts :call TimesliceForFile()<CR>
amenu Cheatsheet.Timeslice<Tab>,ts :call TimesliceForFile()<CR>
" trigger unite.vim
map <Leader>u :Unite<CR>
" split window navigation (ctrl-j/k, alt-arrows)
map <C-J> <C-W>j<C-W>_
map <M-Down> <C-W>j
map <C-K> <C-W>k<C-W>_
map <M-Up> <C-W>k
map <M-Right> <C-W>l
map <M-Left> <C-W>h
" search the current vimwiki - fails if not in a vimwiki, which i should
" really do something about
map <Leader>w/ :GGrep<Space>
" create a new 'log' entry in vimwiki
map <Leader>wl :e `fragment-vimwiki-log-path`<CR>
" view log for current file
" TODO: consider extending this to all files in some way...
map <Leader>l :call <SID>LogForFile()<CR>
" view backlinks for current file
map <Leader>L :call <SID>NotesLinksForFile()<CR>
map <Leader>. :call <SID>VimwikiMakeLink()<CR>
" check php syntax - replaced by using Syntastic
" noremap <Leader>c :echom system('php -l ' . bufname('%'))<CR>
" }}}
" 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('.')
execute ":%!" . a:filter
execute ":" . l:currentline
" do some normal-mode commands and return the cursor to its previous location
function! s:ExecNormalAndReturnCursor(commands)
let l:currentline = line('.')
" see
execute "normal! " . a:commands
execute ":" . l:currentline
" set custom filetypes for some things - invoked by an autocommand above
function! s:FiletypeOverrides()
" make sure NERDTree windows don't get messed up
if bufname("%") =~ "NERD_tree"
" using expand('%:p') instead of bufname("%") for full path, per:
" \v is "very magic" - see :help \v
" the initial slash in the regex seems to be necessary to make \v work
" =~? is ignore case
" =~# is match case
" =~ uses the value of ignorecase
if expand('%:p') =~# "\\vp1k3\/archives.*\/([0-9]|[a-z])+$"
" echom 'p1k3 match - setting filetype to markdown'
set filetype=markdown
" take some custom actions after reading a wiki page:
function! s:WikiBufReadPostOverrides()
" regenerate wiki pages with `%% exec-raw auto` on load
if search("%% exec-raw auto", "nw")
call <SID>RunFilter("filter-exec-raw")
" turn off wrapping for wiki pages with `%% nowrap` on load
if search("%% nowrap", "nw")
set nowrap
" take some custom actions after writing a wiki page:
function! s:WikiBufWritePostOverrides()
" update link database
let realpath = system('readlink -fn ' . shellescape(expand('%')))
if match(realpath, '') > -1
silent execute ":!notes-collect-metadata " . realpath
" if editing a new p1k3 entry, auto-populate with a datestamp
function! s:NewFileOverrides()
if expand('%:p') =~# "\\vp1k3\/archives.*\/([0-9]|[a-z])+$"
silent 0r !fragment-entry
" spit out a date for today, using ~/bin/fragment-today, on the current line
" TODO: ideally this would context sensitive: if called inside a vimwiki
" diary file or a p1k3 blog entry, it would use that date instead.
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 !fragment-today
" 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"'
\ })
" spit out a current timestamp
function! s:Timestamp()
.-1r !rightnow
function! s:ColorSchemeOverrides()
" make things more amenable to editing long soft-wrapped lines
" mostly an attempt to make vimwiki a bit more ergonomic, this
" version adapted from:
function! s:LonglineMode()
setlocal wrap linebreak
set virtualedit=
setlocal display+=lastline
noremap <buffer> <silent> <Up> gk
noremap <buffer> <silent> k gk
noremap <buffer> <silent> <Down> gj
noremap <buffer> <silent> j gj
noremap <buffer> <silent> <Home> g<Home>
noremap <buffer> <silent> <End> g<End>
inoremap <buffer> <silent> <Up> <C-o>gk
inoremap <buffer> <silent> <Down> <C-o>gj
inoremap <buffer> <silent> <Home> <C-o>g<Home>
inoremap <buffer> <silent> <End> <C-o>g<End>
" 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
" i think this is relative to textwidth
set colorcolumn=+1
" cycle between no, absolute, and relative line numbers
function! s:CycleLineNumbers()
if (&number)
set nonumber
if (&relativenumber)
set number norelativenumber
set number relativenumber
" this is pretty much horked from:
function! s:CommandOutputInNewWindow(cmdline)
echo a:cmdline
let expanded_cmdline = a:cmdline
for part in split(a:cmdline, ' ')
if part[0] =~ '\v[%#<]'
let expanded_part = fnameescape(expand(part))
let expanded_cmdline = substitute(expanded_cmdline, part, expanded_part, '')
botright new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
" uncomment calls here for debug info:
" call setline(1, 'Command: ' . a:cmdline)
" call setline(2, 'Expanded: ' . expanded_cmdline)
" display underline with = to length of previous line (pretty clever):
" call setline(3, substitute(getline(2), '.', '=', 'g'))
execute '$read !' . expanded_cmdline
0delete " delete blank first line - get rid of this if you need debug msgs
setlocal nomodifiable
" enable folding with a column:
setlocal foldenable
setlocal foldcolumn=3
" 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
" try to run timeslice for current path
function! g:TimesliceForFile()
let realpath = system('readlink -fn ' . shellescape(expand('%')))
call <SID>CommandOutputInNewWindow('timeslice -f ' . realpath)
" run notes-links-for for current path and populate location list,
" like using grep:
function! s:NotesLinksForFile()
let realpath = system('readlink -fn ' . shellescape(expand('%')))
" override default grep so we can populate the location list:
setlocal grepprg=notes-links-for\ --file\ $*
silent execute "silent lgrep! " . shellescape(realpath)
" in short, this is necessary because otherwise the silent grep above can
" leave the display in a bonk state:
" an alternative to the above:
" call <SID>CommandOutputInNewWindow('notes-links-for --file ' . realpath)
" restore global setting for grepprg:
setlocal grepprg<
" this is fucking ridiculous
function! s:AppendAtCursor(string)
execute "normal! a\<C-r>\<C-r>=a:string\<CR>\<Space>\<Esc>"
" XXX: Experimental - make a link from an fzf-found page:
function! s:VimwikiMakeLink()
call fzf#run({
\ 'options': '--reverse',
\ 'sink': function("<SID>AppendAtCursor"),
\ 'source': "sed 's/^/[[\\//; s/$/]]/' ~/notes/tag-index"
\ })
" XXX: An ongoing experiment - catenate log entries for current wiki page
function! s:LogForFile()
let realpath = system('readlink -fn ' . shellescape(expand('%')))
let hash = sha256(realpath)
echom 'Finding logs for ' . realpath
botright new
" This should use the current wiki, not a harcoded path:
execute 'edit ~/notes/vimwiki/_logscratch/' . hash . '.wiki'
1,$d " delete everything in file
execute '$read !' . 'notes-logs-for ' . shellescape(realpath)
0delete " delete blank first line - get rid of this if you need debug msgs
" 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:
function! g:ListBindings()
redir! > ~/vim_keys.txt
silent verbose map
redir END
call <SID>TabDrop("~/vim_keys.txt")
amenu Cheatsheet.List\ Keys<Tab>:call\ ListBindings() :call ListBindings()<CR>
" }}}
" colors {{{
" CUSTOMIZE: you are gonna want some other colors i bet - 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
" colorscheme ingretu
" }}}
" folding {{{
" 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 Folded guibg=grey guifg=blue
highlight FoldColumn ctermbg=darkgrey ctermfg=white guibg=darkgrey guifg=white
" forked from:
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
set foldtext=BPB_NeatFoldText()
" }}}