tpope.vim-repeat/autoload/repeat.vim
Illia Bobyr 0eaf1f2da0
Move required machinery into plugin/repeat.vim.
`repeat.vim` was written to be used as either an autoloaded script or a
normally loaded script.

In particular, as mappings used to be defined by the autoload script,
they would only be actually injected if any other plugin has used the
repeat functionality.

In practice, this creates problems as the mapping is not stable.  One
cannot define a custom mapping to `<Plug>(RepeatUndo)`, as the existence
of the mapping from `<Plug>(RepeatUndo)` is subject to the prior
execution of any code that uses the repeat functionality.

Similarly, when loading a session that was stored when `u` was remapped
to `<Plug>(RepeatUndo)` is almost guaranteed to be an issue.  As `u` is
already remapped, but the plugin has not constructed the next step,
mapping `<Plug>(RepeatUndo)` to the correct function.

Just setting up the mappings seems like a solid solution to these
problems.  While it is a bit less efficient, if the user has enabled
this plugin, they probably rely on it, and so the optimizations are most
likely negligible.

Also updated the installation instructions.  I would imagine most people
use plugin managers today.  And so it is no longer useful, in my mind,
to be able to decide if the plugin will be eagerly or lazily loaded.  It
just complicates the installation process.
2025-07-24 00:38:27 -07:00

81 lines
2.6 KiB
VimL

" repeat.vim - Let the repeat command repeat plugin maps
" Special function to avoid spurious repeats in a related, naturally repeating
" mapping when your repeatable mapping doesn't increase b:changedtick.
function! repeat#invalidate()
autocmd! repeat_custom_motion
let g:repeat_tick = -1
endfunction
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
augroup repeat_custom_motion
autocmd!
autocmd CursorMoved <buffer> let g:repeat_tick = b:changedtick | autocmd! repeat_custom_motion
augroup END
endfunction
function! repeat#setreg(sequence,register)
let g:repeat_reg = [a:sequence, a:register]
endfunction
function! s:default_register()
let values = split(&clipboard, ',')
if index(values, 'unnamedplus') != -1
return '+'
elseif index(values, 'unnamed') != -1
return '*'
else
return '"'
endif
endfunction
function! repeat#run(count)
let s:errmsg = ''
try
if g:repeat_tick == b:changedtick
let r = ''
if g:repeat_reg[0] ==# g:repeat_sequence && !empty(g:repeat_reg[1])
" Take the original register, unless another (non-default, we
" unfortunately cannot detect no vs. a given default register)
" register has been supplied to the repeat command (as an
" explicit override).
let regname = v:register ==# s:default_register() ? g:repeat_reg[1] : v:register
if regname ==# '='
" This causes a re-evaluation of the expression on repeat, which
" is what we want.
let r = '"=' . getreg('=', 1) . "\<CR>"
else
let r = '"' . regname
endif
endif
let c = g:repeat_count
let s = g:repeat_sequence
let cnt = c == -1 ? "" : (a:count ? a:count : (c ? c : ''))
call feedkeys(s, 'i')
call feedkeys(r . cnt, 'ni')
else
call feedkeys((a:count ? a:count : '') . '.', 'ni')
endif
catch /^Vim(normal):/
let s:errmsg = v:errmsg
return 0
endtry
return 1
endfunction
function! repeat#errmsg()
return s:errmsg
endfunction
function! repeat#wrap(command,count)
let foldopen = &foldopen =~# 'undo\|all' ? 'zv' : ''
let preserve = g:repeat_tick == b:changedtick ? ":let g:repeat_tick = b:changedtick\r" : ''
return (a:count ? a:count : '') . a:command . preserve . foldopen
endfunction
" vim:set ft=vim et sw=4 sts=4: