Thursday, January 19, 2012

One Key To Toggle Them All

...whether to paste or to nopaste, that is the quintain
Real estate in the Vim Keymap World is a bit sparse. Vim steals for itself nearly every sane key combination, leaving the paltry <leader> basement space for us lowly users to occupy. Vim does leave most of the Function Keys alone, though, making them a popular squatters choice in ~/.virmc . But there’s only twelve of them (on non superhero keyboards) so you don’t want to go wasting them either. The Vim docs (:help 'pastetoggle) suggest mapping <F10> to enable paste mode and <F11> to disable it. Meh. That’s TWO WHOLE F keys for one logical operation (and its inversion - its… toggle). Surely we can do better…
Paste Toggle on a Single Key
" Paste Toggle
" Barry Arthur, Jan 2012

" show paste toggle in insert mode
set showmode

" toggle (invert) the current paste state and show new state
function! PasteToggle()
  set invpaste
  set paste?

" map for normal mode
nnoremap <F11> :call PasteToggle()<CR>

" map for visual mode
vnoremap <F11> :<c-u>call PasteToggle()<CR>gv

" insert mode handled by pastetoggle option
set pastetoggle=<f11>

Now we have paste toggle on a single key, working from most places you’d want it. Copy that code and put it in ~/.vim/plugin/paste_toggle.vim on linux and mac. On windows, copy it to $HOME/vimfiles/plugin/paste_toggle.vim. Make that path if you don’t already have it. Restart your vim and test your shiny new <F11> key in normal, visual and insert modes.Of course, you can make it any key you want instead of <F11>. Joy.

Thanks to osse for catching a silly bug on the vnoremap - forgetting to put <c-u> at the start of the map will cause the function to be called for each line currently selected - definitely not the behaviour we want here.