tpope / vim-repeat

repeat.vim: enable repeating supported plugin maps with "."
http://www.vim.org/scripts/script.php?script_id=2136
2.58k stars 81 forks source link

Can vim-repeat be used to make insert and append operators repeatable? #75

Closed blasco closed 4 years ago

blasco commented 4 years ago

I'm trying to make the following operators repeatable:

https://github.com/mwgkgk/vim-operator-insert

I tried adding:

function! s:operator_insert_i(motion_wise)
  call cursor(getpos("'[")[1:])
  startinsert
  silent! call repeat#set("\<Plug>(operator-insert-i)", -1)
endfunction

But when I do giiw (go insert in word) and insert something, when I repeat it doesn't repeat the whole giiw, it just inserts at the current cursor position:

this is an exa<cursor>mple

giiw and type new_

this is an new_<cursor>example

ge then .

this is anew_n new_<cursor>example

instead of

this is new_an new_<cursor>example

Any idea on how to approach this? I think an insert and append operator would be quite useful (specially combined with vim-targets)

tpope commented 4 years ago

I think what is happening is the undo operation is created after leaving insert mode, which means the call to repeat#set() is superseded. You could maaaaaaybe leverage InsertLeave to pull this off, or some other clever trick, but I think you're on your own to figure that out.

blasco commented 4 years ago

Ok, thanks for the guidance.

blasco commented 4 years ago

If possible, could you clarify me a little bit how it works? Because there is only one call repeat#set(), which from what I've seen needs to be placed just after the operation is finished? But how does it know when it started? How does it know to what text object it applies?

tpope commented 4 years ago

I don't know that it can be done, but I would start by setting a private variable to b:changedtick in your function (and another variable for the text object etc) and then check that it's 1 higher in InsertLeave.