I’m trying to modify the file in BufWritePre when written to disk,
and then undo those modifications in BufWritePost so
text in working buffer remains unchanged. The problem is that
the undo operation always seems to undo the last undo operation
before what was done in BufWritePre, along with the changes
done in BufWritePre.
Here is the code:
" BufWritePre function
function! <SID>GlobalUnconvertTags()
let g:save_cursor = getpos(".")
g/^\*\+\s/call UnconvertTags(line("."))
endfunction
" BufWritePost function
function! <SID>UndoUnconvertTags()
undo
call setpos(".",g:save_cursor)
endfunction
Is something different from a simple undo required? Given these two
functions as they are, if I continually issue the command ‘:w’ the
undostate of my buffer will go incrementally backward, one undo
each time I issue the w command.
To explain the problem another way, what I see in my buffer when I continually issue :w commands is identical to what I would see if I were issuing :undo commands. The changes are indeed made in the BufWritePre function when writing, but when undo they always undo the BufWritePre changes, plus one more undo that moves actual buffer state backward.
I’ve tried altering the functions to explicitly referance an undo
state (as below) but this isn’t working either:
" BufWritePre function
function! <SID>GlobalUnconvertTags()
let g:save_cursor = getpos(".")
let s:undostate = changenr()
g/^\*\+\s/call UnconvertTags(line("."))
endfunction
" BufWritePost function
function! <SID>UndoUnconvertTags()
execute "undo ".s:undostate
call setpos(".",g:save_cursor)
endfunction
I assume I’m missing something simple about how undo is supposed to work
between these two events, but I can’t figure out what. The docs
for BufWritePost seem to indicate a simple ‘undo’ would be all that’s needed. But that doesn’t work for me. Any hints appreciated.
I finally quashed this bug by myself. Somehow there were two entries getting entered for both BufWritePre and BufWritePost, so both were getting called twice and second undo was undoing an extra time. I’m still not sure how this was happening, but using au! to clear autocommands before issuing them results in only one set of au commands getting logged. I’m also not sure why even with two sets there was a problem with undos, since I made sure that at least one change was made in BufWritePre each time it was called. In any case, it seems to be working okay now.