Vim: Updating a 'Last Modified' Tag

A while back I set up a system in my Vim configuration to template RST files if they were empty, or update the ":modified:" tag if they weren't. This has worked great for months, but it had some nagging problems:

  • the ":modified:" tag is updated even if I'm only opening the file to read, and make no other changes
  • the date written is the time at file open, not at file close - I sometimes open a file for a couple days while I'm working on it, so the date written at the beginning of the session becomes inaccurate
  • I realized that the way I was doing it wasn't "the Vim way," which would be to use one of the Buf* commands

With all that in mind, I updated the script:

" file: ~/.vim/ftplugin/rst.vim

function! UpdateLastMod()
    " Save window and cursor location:
    let l:winview = winsaveview()
    " Use rst's preferred format for the time:
    execute '1,10/^:modified:/s/:modified:.*/:modified: ' . strftime('%Y-%m-%d %H:%M') . '/'
    " Restore window and cursor location:
    call winrestview(l:winview)
endfunction

augroup filetype_rst
    autocmd!
    autocmd BufWritePre *.rst :call UpdateLastMod()
augroup END

let b:curFileSize = getfsize(@%)
if (b:curFileSize==0) || (b:curFileSize==-1)
    " template the file (see previous blog entry)
endif

"BufWritePre" assigns an event just before you write the file: the function "UpdateLastMod()" saves the window view, searches for and replaces the ":modified:" date, and then restores the window view. The window view actions are needed because the search-and-replace would otherwise relocate the cursor for you, abruptly changing the view you have of the file. If you search on this subject, you'll see lots of examples like the alternate answer at stackoverflow (below) that looks something like this: :noremap <F11> mkHmlggg?G`lzt`k. The actual command is gg?G and all the rest is attempting to save and restore window and cursor position. They all sort of work, but they're also a bit of a nightmare (not to mention that no two "solutions" are the same). This is why I was so happy to learn about winsaveview/winrestview: consistent and comprehensible.

Also, see Steve Losh's explanation (linked below) on why you should ALWAYS group autocommands, even if there's only one.

Bibliography