blog dds

2008.08.25

Saving the Editor's History

I recently spent a few days writing some tricky bit-twiddling code to implement a radix tree. I found myself making many programming mistakes, and I thought it would be interesting to study them, examine their contributing factors, and think how each of them could be prevented.

As a step toward this direction I wrote a small vim script that walks back in the editor's undo history, saving a snapshot of the file after each change. Unfortunately, after an ungraceful shutdown (or crash; I am not sure) of Windows, I lost the editor's session (about 400 changes), and I was thus unable to complete my study. I am including here the script, in the hope that somebody else will find it useful.

"
" :source this vim script to generate a log of all changes to the file
" being edited.  The script will create a directory named by appending
" .log to the name of the file, and save in it numbered files, representing
" the snapshot of the file before each change.  A separate file, named
" log, contains the timestamp of each change.
"
" Copyright (c) 2008, Diomidis Spinellis. All rights reserved.
"
" Redistribution and use in source and binary forms, with or without
" modification, are permitted provided that the following conditions
" are met:
" 1. Redistributions of source code must retain the above copyright
"   notice, this list of conditions and the following disclaimer.
" 2. Redistributions in binary form must reproduce the above copyright
"   notice, this list of conditions and the following disclaimer in the
"   documentation and/or other materials provided with the distribution.
"
" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
" ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
" SUCH DAMAGE.

call mkdir(expand('%') . ".log")
let s:current = changenr()
let s:log = []
while 1
        let s:n = changenr()
        redir @a
        echo "Change: " s:n "\n"
        undo
        redir END
        if match(@a, 'Already at oldest change') != -1
                break
        endif
        let s:log = add(s:log, @a)
        execute "write " . expand("%") . ".undo/" . s:n
endwhile
call writefile(s:log, expand("%") . ".log/log")
execute "undo " . s:current

Read and post comments    AddThis Social Bookmark Button


Creative Commons License Last modified: Monday, August 25, 2008 3:32 pm
Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-Share Alike 3.0 Greece License.