" vim:foldmethod=marker:foldlevel=0:foldenable " " this is my vimrc; part of https://code.p1k3.com/gitea/brennen/bpb-kit " " to use: " " mkdir -p ~/.vim " cp [this file] ~/vim/vimrc " mkdir -p ~/.vim/bundle " git clone https://github.com/VundleVim/Vundle.vim ~/.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 | https://p1k3.com | https://code.p1k3.com set nocompatible " Temporarily disable modelines (like the one at the top of this file), per: " https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md " 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' " https://langserver.org/ " 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 let g:startify_bookmarks = [ \ {'v': '~/.vimrc'}, \ {'l': '~/notes/vimwiki/log/index.wiki' }, \ '~/.zshrc', \ '~/notes/', \ '~/p1k3', \ ] Plugin 'mhinz/vim-startify' let g:startify_custom_header_quotes = [ \ ['the purpose of the system is what it does'], \ ['incremental progress is the only kind'], \ ['reality has a surprising amount of detail'], \ ] let g:startify_change_to_dir = 0 let g:startify_change_to_vcs_root = 1 " Vim Outliner of Markups - see :help voom - really nice 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 'airblade/vim-gitgutter' " 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 'https://tpope.io/vim/commentary.git' " 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' " beyondgrep.com: 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' " this seems really powerful & i've never quite gotten my head around it " Plugin 'Shougo/unite.vim' " fzf - fuzzy finding {{{ " https://github.com/junegunn/fzf 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(), 0, \ fzf#vim#with_preview({'dir': systemlist('git rev-parse --show-toplevel')[0]}), 0) " Use fzf for multi-definition tags: Plugin 'zackhsi/fzf-tags' nmap (fzf_tags) " }}} " distraction-free mode: Plugin 'junegunn/goyo.vim' " preview contents of named registers - this is brilliant 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 'https://code.p1k3.com/gitea/brennen/mru.git' " 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' " }}} " apt-get install shellcheck for shell linting " apt-get install perl-critic for perl " syntax checking {{{ Plugin 'dense-analysis/ale' " an alternative is syntastic - used this for ages, works pretty well but " doesn't have the async thing going on: " 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'] " " shut up, pylint: " let g:syntastic_python_checkers = [] " amenu Syntax.Toggle\ Syntastic :SyntasticToggleMode " }}} " 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' endif " integrate ale with airline: let g:airline#extensions#ale#enabled = 1 " Dr. Chip's debugging for syntax highlighting: Plugin 'gerw/vim-HiLinkTrace' " 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/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' " 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" : "", " \ "run_to_cursor" : "", " \ "step_over" : "", " \ "step_into" : "", " \ "step_out" : "", " \ "close" : "", " \ "detach" : "", " \ "set_breakpoint" : "", " \ "get_context" : "", " \ "eval_under_cursor" : "", " \ "eval_visual" : "e", " \} " let g:vdebug_options = { 'port' : 9003 } " Plugin 'https://github.com/vim-vdebug/vdebug' " 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.name = 'notes' let wiki.path = '~/notes/vimwiki/' let wiki.path_html = '~/workspace/notes-html/' let wiki.auto_tags = 1 let wiki.auto_diary_index = 1 let wiki.automatic_nested_syntaxes = 1 " i don't use this, but it seems to have regressed recently and I'll " need to test it again eventually " let wiki.links_space_char = '-' " a markdown wiki for testing purposes let markdownwiki = {} let markdownwiki.name = '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' " testing for https://github.com/vimwiki/vimwiki/issues/1256 " let g:vimwiki_markdown_link_ext = 1 " To test customwiki2html: " let markdownwiki.custom_wiki2html = $HOME . '/.vim/bundle/vimwiki/autoload/vimwiki/customwiki2html.sh' " 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 " You can adjust this to set the header level for a contents section let g:vimwiki_toc_header_level = 1 " Don't change working directory to page of current wiki, since " that'd mess with how I use my ~/notes (this is the default, " just wanted it documented here): let g:vimwiki_auto_chdir = 0 " there can be many of these let g:vimwiki_list = [wiki, markdownwiki] " span is here so :VimwikiColorize will work - it's weird that it's not in " the default list, since that's supported. let g:vimwiki_valid_html_tags = 'b,i,s,u,sub,sup,kbd,br,hr,span' " i think this _replaces_ the existing comment markers, in theory - not " clear if it works: " let g:vimwiki_commentstring = '' " 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 = '' " 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 " highlight checked list items " highlight VimwikiCheckBoxDone ctermbg=darkgrey ctermfg=white guibg=darkgrey guifg=white let g:vimwiki_hl_cb_checked = 2 " set to 0 to have newlines in list items get rendered to
let g:vimwiki_list_ignore_newline = 1 " disable table mappings: let g:vimwiki_key_mappings = \ { \ 'table_mappings': 0, \ 'table_format': 0 \ } " hit ,S to debug current syntax highlighting groups " https://vim.fandom.com/wiki/Identify_the_syntax_highlighting_group_used_at_the_cursor " map S :echo "hi<" . synIDattr(synID(line("."),col("."),1),"name") . '> trans<' \ . synIDattr(synID(line("."),col("."),0),"name") . "> lo<" \ . synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") . ">" " map 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: doesn't work here; I tried nmap b 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:' try " chop off the leading file: - see :h expr-[:] for syntax: execute ':split ' . a:link[5:] return 1 catch echo "Failed opening file in vim." endtry elseif a:link =~# '^workspace:' try " chop off the leading file: - see :h expr-[:] for syntax: execute ':split ' . '~/workspace/' . a:link[10:] return 1 catch echo "Failed opening workspace location in vim." endtry " elseif a:link =~# '^https\?:' " try " execute ':terminal lynx ' . a:link " return 1 " catch " echo "Failed executing Lynx." " endtry endif return 0 endfunction Plugin 'vimwiki/vimwiki' augroup bpb_vimwiki " TODO: i _think_ a lot of this could be pushed out into some file under " ~/.vim/ftplugin/vimwiki/*.vim - should it be? maybe! " clear any existing commands in this group: autocmd! " selectively activate foldcolumn: au FileType vimwiki setlocal foldcolumn=3 " vimwiki diary links for the ,td datestamp alias: au FileType vimwiki map td :.-1r !fragment-vimwiki-diarylink " 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 " run new diary entry template: au BufNewFile *vimwiki/diary/*.wiki :0r !fragment-vimwiki-diary '%' " run new log 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 LonglineMode() " XXX: this is a vulnerability - should only happen in _my specific_ " vimwiki: au BufReadPost *vimwiki/*.wiki call WikiBufReadPostOverrides() au BufWritePost *vimwiki/*.wiki call WikiBufWritePostOverrides() augroup END " }}} " snippets " Plugin 'SirVer/ultisnips' " Plugin 'honza/vim-snippets' " " trigger configuration " " don't use if you use https://github.com/Valloric/YouCompleteMe " let g:UltiSnipsExpandTrigger="" " let g:UltiSnipsJumpForwardTrigger="" " let g:UltiSnipsJumpBackwardTrigger="" " " 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 " https://unix.stackexchange.com/questions/50733/cant-use-mouse-properly-when-running-vim-in-tmux set ttymouse=xterm2 " 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 else set clipboard=unnamedplus,autoselect endif " 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 " http://stackoverflow.com/questions/19624105/how-can-i-make-vim-break-lines-only-on-whitespace au FileType markdown setlocal wrap linebreak breakat&vim " }}} " misc. autocommands {{{ " to get a list of current autocommands: " http://vim.wikia.com/wiki/Capture_ex_command_output " :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: " https://github.com/tpope/vim-fugitive/issues/834 au BufReadPost,BufNewFile * call FiletypeOverrides() au BufNewFile * call 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 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 - " 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 :NERDTreeToggle imap :NERDTreeToggle 650amenu Cheatsheet.NERDTreeF2 " F3 finds the current file in nerdtree map :NERDTreeFind amenu Cheatsheet.NERDTreeFindF3 " F4 toggles line numbers map :set invnumber imap :set invnumber " this version cycles through a couple versions of relative and absolute " line numbers: " map :call CycleLineNumbers() " imap :call CycleLineNumbers() amenu Cheatsheet.Toggle\ Line\ NumbersF4 " F5 saves everything map :wall imap amenu Cheatsheet.Write\ AllF5 " F6 brings up a recently-used file list using MRU " map :MRU " Bring up an fzf history window map :History imap amenu Cheatsheet.Most\ Recently\ UsedF6 " 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 amenu Cheatsheet.Open\ vimrcF7 " 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 map ww imap amenu Cheatsheet.Current\ DiaryF8 " ,td / ,tD insert dates (mnemonic: toDay) " this is overridden in vimwiki files to link to diary pages map td :r !date -IkJ map tD :r !date -IskJ " F9 toggles search highlighting and some other noise map :call Crosshairs() imap amenu Cheatsheet.CrosshairsF9 " F10 starts a git commit for recent changes map :Gcommit -av amenu Cheatsheet.GcommitF10 " 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+ amenu Cheatsheet.Copy\ AllF12 " add a menu separator menu Cheatsheet.-misc- : " split lines under the cursor (modeled on, maybe, emacs?) map K ig; amenu Cheatsheet.Split\ LineK K " an FZF fragment menu nmap F :call FragmentMenu() amenu Cheatsheet.Fragment\ Menu,F F " CUSTOMIZE: randomize certain text decorations - silly nmap D :call RunFilter("filter-decorate") amenu Cheatsheet.Randomize\ Decorations,D D nmap d i

:r !fragment-bulletkJA

amenu Cheatsheet.Insert\ Decoration,d d " CUSTOMIZE: find files with fzf fuzzy-finder (assumes FZF is installed) " https://github.com/junegunn/fzf " was :FZF, but :Files has a preview pane - which is awesome nmap f :Files amenu Cheatsheet.FZF\ Find,f f " i didn't wind up using this much, and it potentially messes " with vimwiki mappings: " nmap w :call CommandOutputInNewWindow("dict ")) " visual select inner word nmap v viW " pull up the last hundred git commits in a scratch buffer " nmap l :vnew:set buftype=nofile:set bufhidden=hide:setlocal noswapfile:r !git log -100:set ft=gitggrl nmap gl :Glog:copen amenu Cheatsheet.Git\ Log,gl gl nmap m :make amenu Cheatsheet.Make,m m " requires git-do, from bpb-kit, to execute make in root of current git repo nmap M :!git do make amenu Cheatsheet.Make\ (git\ root),M M " jump to next, previous errors nmap n :cnext amenu Cheatsheet.Next\ Error,n n nmap p :cprev amenu Cheatsheet.Prev\ Error,p p " generate a password-like string with apg " nmap pw :r !apg -a 0 -m 20 -n 1 " -a 0: use fully random string instead of pronounceable nmap pw :r !apg -a 1 -m 20 -n 1 amenu Cheatsheet.APG,pw pw " reformat a paragraph nmap q gqip amenu Cheatsheet.Reformat\ Para,q q " 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 " CUSTOMIZE: these are simple filter scripts to preprocess some " shell commands in HTML or Markdown files - see scripts for details nmap r :call RunFilter("filter-exec-raw"):call RunFilter("filter-exec"):call RunFilter("filter-exec-stdin") amenu Cheatsheet.Run\ Filters,r r " delete trailing whitespace, file-wide nmap s :%s/\s\+$//e amenu Cheatsheet.Zap\ Trailing\ Space,s s " tab navigation somewhat like firefox " http://vim.wikia.com/wiki/Alternative_tab_navigation nmap :tabprevious nmap :tabnext map :tabprevious map :tabnext imap :tabpreviousi imap :tabnexti " new tab: nmap tn :tabnew amenu Cheatsheet.New\ Tab,tn tn " run timeslice script for current file: nmap ts :call TimesliceForFile() amenu Cheatsheet.Timeslice,ts :call TimesliceForFile() " trigger unite.vim map u :Unite " split window navigation (ctrl-j/k, alt-arrows) map j_ map j map k_ map k map l map h " search the current vimwiki - fails if not in a vimwiki, which i should " really do something about map w/ :GGrep " create a new 'log' entry in vimwiki map l :tab drop `fragment-vimwiki-log-path`kA " view log for current file " TODO: consider extending this to all files in some way... map wl :call NotesLogsForFile() map wf :call NotesFullLogsForFile() " view backlinks for current file map wL :call NotesLinksForFile() " view summary for current wiki page map wS :call NotesMeta() map . :call VimwikiMakeLink() map J :call VimwikiJumpToPage() " }}} " 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 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 execute "normal! " . a:commands execute ":" . l:currentline endfunction " 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" return endif " using expand('%:p') instead of bufname("%") for full path, per: " http://vim.wikia.com/wiki/Get_the_name_of_the_current_file " \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 endif endfunction " take some custom actions after reading a wiki page: function! s:WikiBufReadPostOverrides() let realpath = system('readlink -fn ' . shellescape(expand('%'))) " regenerate wiki pages with `%% exec-raw auto` on load " (except for log scratch files - that could get real messy) if search("%% exec-raw auto", "nw") if match(realpath, '_logscratch') > -1 " no-op for the moment, might be other things to do here? " i'm not honestly sure if this is reachable because i'm not sure " that the postread here actually gets triggered at all. echom "logscratch - not honoring exec-raw auto" else call RunFilter("filter-exec-raw") endif endif " turn off wrapping for wiki pages with `%% nowrap` on load if search("%% nowrap", "nw") set nowrap endif endfunction " 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, '_logscratch') > -1 return endif silent execute ":!notes-collect-metadata " . realpath endfunction " 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 endif endfunction " 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 endfunction " select a fragment script using fzf and include its output in the " current buffer function! s:FragmentMenu() call fzf#run({ \ 'options': ['--reverse', '--preview={}'], \ 'sink': '.r !', \ 'source': 'find ~/bin/ -maxdepth 1 -name "fragment-*" -printf "%f\n"', \ 'down': '50%' \ }) endfunction " spit out a current timestamp function! s:Timestamp() .-1r !rightnow endfunction function! s:ColorSchemeOverrides() 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 " via maya: " https://occult.institute/@maya/111325120027749937 function! TwoWide() call setpos(".", [0, 1, 1, 0]) wincmd v call setpos(".", [0, 1, 1, 0]) execute "normal L" execute "normal zt" set scrollopt "ver,jump" windo set scrollbind 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 " cycle between no, absolute, and relative line numbers function! s:CycleLineNumbers() if (&number) set nonumber return endif if (&relativenumber) set number norelativenumber else set number relativenumber endif endfunction " this is pretty much horked from: " http://vim.wikia.com/wiki/Display_output_of_shell_commands_in_new_window 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, '') endif endfor 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 1 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 " try to run timeslice for current path function! g:TimesliceForFile() let realpath = system('readlink -fn ' . shellescape(expand('%'))) call CommandOutputInNewWindow('timeslice -f ' . realpath) endfunction " run notes-links 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\ --format\ location\ --file\ $* silent execute "silent lgrep! " . shellescape(realpath) " https://vim.fandom.com/wiki/Avoiding_the_%22Hit_ENTER_to_continue%22_prompts " https://vi.stackexchange.com/questions/2809/silent-makes-my-vim-go-blank " in short, this is necessary because otherwise the silent grep above can " leave the display in a bonk state: redraw! " an alternative to the above: " call CommandOutputInNewWindow('notes links --file ' . realpath) " restore global setting for grepprg: setlocal grepprg< lopen endfunction " this is fucking 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 function! s:AppendAtCursorAsVimwikiLink(string) let bracketed = '[[/' . a:string . ']]' call AppendAtCursor(bracketed) endfunc " Make a link from an fzf-found known tag name: function! s:VimwikiMakeLink() call fzf#run({ \ 'options': [ \ "--reverse", \ "--multi", \ "--preview=notes-tag-summary --color {}", \ ], \ 'sink': function("AppendAtCursorAsVimwikiLink"), \ 'source': "notes-tag-index", \ 'up': '50%' \ }) endfunction " Open a page in the default Vimwiki: function! s:VimwikiGotoPage(page) if ! exists(':VimwikiGoto') " :VimwikiGoto isn't a global command, so is only available if there's " a wiki open. Jump to the index of the default one: execute ':VimwikiIndex' endif execute ':VimwikiGoto ' . a:page endfunction " Jump to an fzf-found page or known tag name: function! s:VimwikiJumpToPage() call fzf#run({ \ 'options': ["--reverse", "--multi", "--preview=notes-tag-summary --color {}"], \ 'sink': function("VimwikiGotoPage"), \ 'source': "notes-tag-index", \ }) endfunction " Catenate log entries for current wiki page function! s:NotesFullLogsForFile() let realpath = system('readlink -fn ' . shellescape(expand('%'))) let hash = sha256(realpath) echom 'Finding logs for ' . realpath botright new " XXX: 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 links --with-date --format full --file ' . shellescape(realpath) 0delete " delete blank first line - get rid of this if you need debug msgs 1 endfunction " Location list with log entries for current file: function! s:NotesLogsForFile() let realpath = system('readlink -fn ' . shellescape(expand('%'))) " override default grep so we can populate the location list: setlocal grepprg=notes\ links\ --with-date\ --format\ location\ --file\ $* silent execute "silent lgrep! " . shellescape(realpath) redraw! " restore global setting for grepprg: setlocal grepprg< lopen endfunction " Jump to an fzf-found page or known tag name: function! s:NotesMeta() let realpath = system('readlink -fn ' . shellescape(expand('%'))) let hash = sha256(realpath) echom 'Finding logs for ' . realpath botright new " XXX: This should use the current wiki, not a harcoded path: execute 'edit ~/notes/vimwiki/_logscratch/meta-' . hash . '.wiki' 1,$d " delete everything in file execute '$read !' . 'notes tag-summary --file ' . shellescape(realpath) 0delete " delete blank first line - get rid of this if you need debug msgs 1 endfunction " 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 amenu Cheatsheet.List\ Keys:call\ ListBindings() :call ListBindings() " }}} " 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 ingretu colorscheme iceberg " colorscheme earthburn " }}} " 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: 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() " }}}