2008-04-25 18:24:17 -04:00
|
|
|
" repeat.vim - Let the repeat command repeat plugin maps
|
|
|
|
" Maintainer: Tim Pope
|
2018-01-30 23:08:02 -05:00
|
|
|
" Version: 1.2
|
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.
|
2011-12-02 16:20:46 -05:00
|
|
|
"
|
|
|
|
" 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
|
2012-11-29 04:19:30 -05:00
|
|
|
" \ :<C-U>execute 'silent! call repeat#setreg("\<lt>Plug>MyMap", v:register)'<Bar>
|
2011-12-02 16:20:46 -05:00
|
|
|
" \ 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
|
2011-12-02 16:20:46 -05:00
|
|
|
let g:repeat_reg = ['', '']
|
2008-04-25 18:24:17 -04:00
|
|
|
|
2011-12-02 16:00:36 -05: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()
|
2015-01-10 20:47:31 -05:00
|
|
|
autocmd! repeat_custom_motion
|
2011-12-02 16:00:36 -05:00
|
|
|
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
|
2013-12-24 10:43:24 -05:00
|
|
|
augroup repeat_custom_motion
|
|
|
|
autocmd!
|
|
|
|
autocmd CursorMoved <buffer> let g:repeat_tick = b:changedtick | autocmd! repeat_custom_motion
|
|
|
|
augroup END
|
2008-04-25 18:24:17 -04:00
|
|
|
endfunction
|
|
|
|
|
2011-12-02 16:20:46 -05:00
|
|
|
function! repeat#setreg(sequence,register)
|
|
|
|
let g:repeat_reg = [a:sequence, a:register]
|
|
|
|
endfunction
|
|
|
|
|
2012-11-03 13:37:05 -04:00
|
|
|
function! repeat#run(count)
|
2015-04-22 18:27:56 -04:00
|
|
|
try
|
|
|
|
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
|
2011-12-02 16:20:46 -05:00
|
|
|
endif
|
|
|
|
|
2015-04-22 18:27:56 -04:00
|
|
|
let c = g:repeat_count
|
|
|
|
let s = g:repeat_sequence
|
|
|
|
let cnt = c == -1 ? "" : (a:count ? a:count : (c ? c : ''))
|
|
|
|
if ((v:version == 703 && has('patch100')) || (v:version == 704 && !has('patch601')))
|
|
|
|
exe 'norm ' . r . cnt . s
|
2019-01-29 05:19:42 -05:00
|
|
|
elseif v:version <= 703
|
|
|
|
call feedkeys(r . cnt, 'n')
|
|
|
|
call feedkeys(s, '')
|
2015-04-22 18:27:56 -04:00
|
|
|
else
|
|
|
|
call feedkeys(s, 'i')
|
|
|
|
call feedkeys(r . cnt, 'ni')
|
|
|
|
endif
|
2015-01-19 17:09:05 -05:00
|
|
|
else
|
2015-04-22 18:27:56 -04:00
|
|
|
if ((v:version == 703 && has('patch100')) || (v:version == 704 && !has('patch601')))
|
|
|
|
exe 'norm! '.(a:count ? a:count : '') . '.'
|
|
|
|
else
|
|
|
|
call feedkeys((a:count ? a:count : '') . '.', 'ni')
|
|
|
|
endif
|
2015-01-17 09:55:08 -05:00
|
|
|
endif
|
2015-04-22 19:45:15 -04:00
|
|
|
catch /^Vim(normal):/
|
|
|
|
return 'echoerr v:errmsg'
|
2015-04-22 18:27:56 -04:00
|
|
|
endtry
|
2015-04-22 19:45:15 -04:00
|
|
|
return ''
|
2008-04-25 18:24:17 -04:00
|
|
|
endfunction
|
|
|
|
|
2012-11-26 05:24:10 -05:00
|
|
|
function! repeat#wrap(command,count)
|
2008-04-25 18:24:17 -04:00
|
|
|
let preserve = (g:repeat_tick == b:changedtick)
|
2018-01-21 18:45:49 -05:00
|
|
|
call feedkeys((a:count ? a:count : '').a:command, 'n')
|
|
|
|
exe (&foldopen =~# 'undo\|all' ? 'norm! zv' : '')
|
2008-04-25 18:24:17 -04:00
|
|
|
if preserve
|
|
|
|
let g:repeat_tick = b:changedtick
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2015-04-22 19:45:15 -04:00
|
|
|
nnoremap <silent> <Plug>(RepeatDot) :<C-U>exe repeat#run(v:count)<CR>
|
2015-02-20 15:14:38 -05:00
|
|
|
nnoremap <silent> <Plug>(RepeatUndo) :<C-U>call repeat#wrap('u',v:count)<CR>
|
|
|
|
nnoremap <silent> <Plug>(RepeatUndoLine) :<C-U>call repeat#wrap('U',v:count)<CR>
|
|
|
|
nnoremap <silent> <Plug>(RepeatRedo) :<C-U>call repeat#wrap("\<Lt>C-R>",v:count)<CR>
|
|
|
|
|
2015-05-07 14:29:12 -04:00
|
|
|
if !hasmapto('<Plug>(RepeatDot)', 'n')
|
|
|
|
nmap . <Plug>(RepeatDot)
|
|
|
|
endif
|
|
|
|
if !hasmapto('<Plug>(RepeatUndo)', 'n')
|
|
|
|
nmap u <Plug>(RepeatUndo)
|
|
|
|
endif
|
2015-02-20 15:14:38 -05:00
|
|
|
if maparg('U','n') ==# '' && !hasmapto('<Plug>(RepeatUndoLine)', 'n')
|
|
|
|
nmap U <Plug>(RepeatUndoLine)
|
2012-05-02 19:13:33 -04:00
|
|
|
endif
|
2015-05-07 14:29:12 -04:00
|
|
|
if !hasmapto('<Plug>(RepeatRedo)', 'n')
|
|
|
|
nmap <C-R> <Plug>(RepeatRedo)
|
|
|
|
endif
|
2008-04-25 18:24:17 -04:00
|
|
|
|
|
|
|
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:
|