vim-repeat/autoload/repeat.vim

116 lines
4.0 KiB
VimL
Raw Normal View History

2008-04-25 18:24:17 -04:00
" repeat.vim - Let the repeat command repeat plugin maps
" Maintainer: Tim Pope
" Version: 1.0
2011-08-29 02:47:25 -04:00
" GetLatestVimScripts: 2136 1 :AutoInstall: repeat.vim
2008-04-25 18:24:17 -04:00
" Installation:
" Place in either ~/.vim/plugin/repeat.vim (to load at start up) or
" ~/.vim/autoload/repeat.vim (to load automatically as needed).
"
2011-08-29 16:11:07 -04:00
" License:
" Copyright (c) Tim Pope. Distributed under the same terms as Vim itself.
" See :help license
"
2008-04-25 18:24:17 -04:00
" Developers:
" Basic usage is as follows:
"
" silent! call repeat#set("\<Plug>MappingToRepeatCommand",3)
"
" The first argument is the mapping that will be invoked when the |.| key is
" pressed. Typically, it will be the same as the mapping the user invoked.
" This sequence will be stuffed into the input queue literally. Thus you must
" encode special keys by prefixing them with a backslash inside double quotes.
"
" The second argument is the default count. This is the number that will be
" prefixed to the mapping if no explicit numeric argument was given. The
" value of the v:count variable is usually correct and it will be used if the
" second parameter is omitted. If your mapping doesn't accept a numeric
" argument and you never want to receive one, pass a value of -1.
"
" Make sure to call the repeat#set function _after_ making changes to the
" file.
"
" For mappings that use a register and want the same register used on
" repetition, use:
"
" silent! call repeat#setreg("\<Plug>MappingToRepeatCommand", v:register)
"
" This function can (and probably needs to be) called before making changes to
" the file (as those typically clear v:register). Therefore, the call sequence
" in your mapping will look like this:
"
" nnoremap <silent> <Plug>MyMap
" \ :<C-U>silent! call repeat#setreg("\<lt>Plug>MyMap", v:register)<Bar>
" \ call <SID>MyFunction(v:register, ...)<Bar>
" \ silent! call repeat#set("\<lt>Plug>MyMap")<CR>
2008-04-25 18:24:17 -04:00
if exists("g:loaded_repeat") || &cp || v:version < 700
finish
endif
let g:loaded_repeat = 1
let g:repeat_tick = -1
let g:repeat_reg = ['', '']
2008-04-25 18:24:17 -04:00
" Special function to avoid spurious repeats in a related, naturally repeating
" mapping when your repeatable mapping doesn't increase b:changedtick.
function! repeat#invalidate()
let g:repeat_tick = -1
endfunction
2008-04-25 18:24:17 -04:00
function! repeat#set(sequence,...)
let g:repeat_sequence = a:sequence
let g:repeat_count = a:0 ? a:1 : v:count
let g:repeat_tick = b:changedtick
endfunction
function! repeat#setreg(sequence,register)
let g:repeat_reg = [a:sequence, a:register]
endfunction
2008-04-25 18:24:17 -04:00
function! s:repeat(count)
if g:repeat_tick == b:changedtick
let r = ''
if g:repeat_reg[0] ==# g:repeat_sequence && !empty(g:repeat_reg[1])
if g:repeat_reg[1] ==# '='
" This causes a re-evaluation of the expression on repeat, which
" is what we want.
let r = '"=' . getreg('=', 1) . "\<CR>"
else
let r = '"' . g:repeat_reg[1]
endif
endif
2008-04-25 18:24:17 -04:00
let c = g:repeat_count
let s = g:repeat_sequence
let cnt = c == -1 ? "" : (a:count ? a:count : (c ? c : ''))
call feedkeys(r . cnt, 'n')
call feedkeys(s)
2008-04-25 18:24:17 -04:00
else
call feedkeys((a:count ? a:count : '') . '.', 'n')
endif
endfunction
function! s:wrap(command,count)
let preserve = (g:repeat_tick == b:changedtick)
2012-08-22 11:30:12 -04:00
exe 'norm! '.(a:count ? a:count : '').a:command . (&foldopen =~# 'undo' ? 'zv' : '')
2008-04-25 18:24:17 -04:00
if preserve
let g:repeat_tick = b:changedtick
endif
endfunction
nnoremap <silent> . :<C-U>call <SID>repeat(v:count)<CR>
nnoremap <silent> u :<C-U>call <SID>wrap('u',v:count)<CR>
if maparg('U','n') ==# ''
nnoremap <silent> U :<C-U>call <SID>wrap('U',v:count)<CR>
endif
2008-04-25 18:24:17 -04:00
nnoremap <silent> <C-R> :<C-U>call <SID>wrap("\<Lt>C-R>",v:count)<CR>
augroup repeatPlugin
autocmd!
autocmd BufLeave,BufWritePre,BufReadPre * let g:repeat_tick = (g:repeat_tick == b:changedtick || g:repeat_tick == 0) ? 0 : -1
autocmd BufEnter,BufWritePost * if g:repeat_tick == 0|let g:repeat_tick = b:changedtick|endif
augroup END
" vim:set ft=vim et sw=4 sts=4: