I'm pretty sure it's not possible to use Vim's backup
feature to do this, so instead I've written a proof of concept that achieves your goal (of being able to see the changes made since the beginning of the session) more directly, with autocommands.
It writes out a file containing the current contents of the buffer when the buffer is read, and then deletes it when you unload the buffer (with e.g. :bdelete
or by quitting Vim).
augroup MyInitialState
au!
au BufReadPost * call CreateInitialState()
au BufUnload * call DeleteInitialState()
augroup END
function! CreateInitialState() abort
let file_name = BackupFileName('<afile>')
if filewritable(file_name) == 1 ||
\ (!glob(file_name) &&
\ filewritable(fnamemodify(file_name, ':p:h')) == 2)
execute "write!" file_name
endif
endfunction
function! DeleteInitialState() abort
let file_name = BackupFileName('<afile>')
if filewritable(file_name) == 1
call delete(file_name)
endif
endfunction
function! BackupFileName(file_name) abort
return expand(a:file_name) . '.initstate'
endfunction
It will need a bit of tidying up if you want a really robust solution — for example it doesn't really work with Vim's default :set nohidden
(one solution would be to keep a list of backup files and delete them all when quitting Vim instead of individually on buffer unload), and I'd imagine there will be edge cases that need handling — but it should be enough to get you started.
Extra Credit
Here's a :CompareInitialState
command you can use to check your current file content against your "backups".
function! CompareInitialState() abort
let file_name = BackupFileName('%')
diffthis
vnew
setlocal buftype=nofile
setlocal bufhidden=delete
setlocal noswapfile
execute "read" file_name
1delete
diffthis
wincmd p
endfunction
command! CompareInitialState :call CompareInitialState()
Older version
Here's my initial version that I wrote before it occurred to me that you don't actually need the "backup" file to exist when you're not in Vim.
augroup MyInitialState
au!
au BufReadPost * write! <afile>.initstate
au BufUnload * call DeleteInitial()
augroup END
function! DeleteInitial() abort
let file_name = expand('<afile>') . '.initstate'
echom file_name
if filewritable(file_name)
call delete(file_name)
endif
endfunction
.swp
file?~
backup
option can do this by default. It might be easier just to make your own backup using theBufReadPre
andBufLeave
autocmds.