Fix slow write commands in vim

I found that when I work in a file for too long, vim gets slower and slower. I figured out it is because the undofile can get obese over time.

Here is a snippet I use in my .vimrc to solve this issue.

function! AskClearUndoHistory()
    if &undofile
        let undofile = undofile(expand('%'))
        if filereadable(undofile)
            let size = getfsize(undofile)
            let size_mb = size / (1024 * 1024)
            echo printf("Undo file: %.1f MB", size_mb)
            if size > 0
                let choice = confirm("Undo file is " . printf("%.1f", size_mb) . " MB. Clear it?", 
                                           \ "&Yes\n&No", 2)
                if choice == 1
                   call ClearUndoHistory()
                endif
            endif
        endif
    endif
endfunction


function! CheckUndoFileSizeMinimal()
    if &undofile
        try
            let size = getfsize(undofile(expand('%')))
            if size > 52428800  " 50MB in bytes, avoid float math
                echohl WarningMsg | echo "Large undo file! Call ClearUndo to clear it." | echohl None
            endif
        catch | endtry
    endif
endfunction

function! ClearUndoHistory()
    let old_undolevels = &undolevels
    set undolevels=-1
    exe "normal a \<BS>\<Esc>"
    let &undolevels = old_undolevels
    echo "Undo history cleared"
endfunction

autocmd InsertLeave,BufLeave,FocusLost * silent! update | call CheckUndoFileSizeMinimal()
autocmd BufWritePost * call CheckUndoFileSizeMinimal()
command! CheckUndoSize call AskClearUndoHistory()
command! ClearUndo call ClearUndoHistory()

Leave a Comment