saving on TextChanged event breaks vim-repeat
samuelallan72 opened this issue ยท 12 comments
Minimal vimrc displaying this behaviour:
set nocompatible
call plug#begin('~/.vim/plugged')
Plug 'tpope/vim-repeat'
Plug 'tpope/vim-surround'
call plug#end()
augroup save
au!
au TextChanged ?* silent! wa
augroup END
An example of what happens:
- perform
ysiw)
to surround a word with parentheses. - press
.
to repeat the surround on another word - the cursor appears at the bottom of the screen, waiting for the character to surround the word with (as if you did
ysiw
- pressing
)
completes the surround as expected.
I haven't read the source of vim-repeat, so not sure exactly why this might be happening. The help for TextChanged
says that it's fired when b:changedtick
is changed, so I'm guessing it saves the file halfway through the initial command, which makes only part of the commend registered with vim-repeat somehow...
Today I decided to figure out why does vim-repeat not work for me. Yes, basically due to this.
My autocmd is similar (a Vim hack auto-save):
augroup autoSave
autocmd!
autocmd TextChanged,InsertLeave,FocusLost * silent! wall
augroup END
In the meantime recording a macro is the way to go to do vim-surround repeats for those who do the above style TextChange
tricks: qq
then cs"'
then q
then lastly Q
(a mapping of mine) to run the macro.
Many thanks.
This reminds me - I should add that this only breaks with tpope/vim-surround
and tpope/vim-repeat
together. - ie. saving on textchanged breaks repeating vim-surround actions.
Interestingly, vim-sandwich works fine with vim-repeat and saving on textchanged. Minimal vimrc that works fine:
set nocompatible
call plug#begin('~/.vim/plugged')
Plug 'tpope/vim-repeat'
Plug 'machakann/vim-sandwich'
call plug#end()
" for vim-surround like mappings
runtime macros/sandwich/keymap/surround.vim
augroup vimrc
autocmd!
autocmd TextChanged ?* silent! wa
augroup END
Maybe this issue should be raised on vim-surround's issues instead?
I should add that this only breaks with tpope/vim-surround and tpope/vim-repeat together.
@swalladge this is not entirely correct. vim-repeat
is also needed for other plugins developed by @tpope. vim-commentary
comes to mind, but probably others as well.
vim-repeat is also needed for other plugins developed by @tpope. vim-commentary comes to mind, but probably others as well.
@ironhouzi yes it's needed for many plugins, but it doesn't break with all plugins that use it. That's the reason why I'm not sure if the issue is in vim-repeat, or the issue is with how other plugins use it.
FYI The HEAD version of commentary.vim no longer requires repeat.vim, which might be the source of some confusion. If you're looking for another plugin to test against, try [e
and [<Space>
in unimpaired.vim.
Worth noting, the vim-auto-save plugin does work with vim-repeat.
So if your only need to use the TextChanged
event was to initiate auto-saving (as I was) then I suggest just using the vim-auto-save plugin instead. Somehow it avoids the clash with vim-repeat that this snippet had.
These are the settings I use:
Plug '907th/vim-auto-save'
let g:auto_save = 1
let g:auto_save_silent = 1
let g:auto_save_events = ["InsertLeave", "TextChanged", "FocusLost"]
Thanks to @tpope for all your contributions.
@bluz71 great find! I believe I have found a lead based on this. vim-auto-save
uses nested
(reference) in the autocmd call to recurse autocmds when calling :w
or :e
from inside the autocmd. :h autocmd-nested
for more info. Modifying my original minimal vimrc to include nested in the autocmd fixes the original issue:
set nocompatible
call plug#begin('~/.vim/plugged')
Plug 'tpope/vim-repeat'
Plug 'tpope/vim-surround'
call plug#end()
augroup save
au!
au TextChanged ?* nested silent! wa
augroup END
Now it remains to be seen why this works...
Update: vim-repeat relies on the BufWrite*
events in
vim-repeat/autoload/repeat.vim
Line 141 in 8106e14
g:repeat_tick
will not be updated. It sounds like something similar to #63 where b:changedtick
is suddenly a value that vim-repeat isn't expecting.Is there a way to make vim-repeat work along with TextChanged
and TextChangedI
?
@MahbubAlam231 see my previous comment for a work around (add nested
to the autocmd).
Thanks @swalladge , it works. I do not quite understand vim script yet, I read :h autocmd-nested
, didn't get what's going on, can you please explain what is this nested thing and why it works?
nested
doesn't work with TextChangedI
though, the cursor shifts abruptly to left while inserting text.
Okay, makes sense, the old autocommand was broken and adding nested
fixes it. I don't think this is a repeat.vim bug.