Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display the total number of changes in Vim’s diff mode?

Tags:

vim

diff

When diffing two files in Vim, is it possible to display the total number of changes? I suppose, this is equivalent to counting the number of folds, but I don’t know how to do that either.

Ideally, I would like a message which says something like “Change 1 of 12”, which would update as I cycle through the changes with ]c.

I’m having great success converting some members of my office to the wonders of Vim, but Vimdiff is a consistent bugbear.

like image 861
Prince Goulash Avatar asked Jun 15 '12 07:06

Prince Goulash


1 Answers

Here is a slightly more refined solution. It uses the same technique as my previous answer to count the diffs, but it stores the first line of each hunk in a list asigned to a global variable g:diff_hunks. Then the number of hunks below the cursor can be found by finding the position of the line number in the list. Also notice that I set nocursorbind and noscrollbind and reset them at the end to ensure we don't break mouse scrolling in the diff windows.

function! UpdateDiffHunks()
    setlocal nocursorbind
    setlocal noscrollbind
    let winview = winsaveview() 
    let pos = getpos(".")
    sil exe 'normal! gg'
    let moved = 1
    let hunks = []
    while moved
        let startl = line(".")
        keepjumps sil exe 'normal! ]c'
        let moved = line(".") - startl
        if moved
            call add(hunks,line("."))
        endif
    endwhile
    call winrestview(winview)
    call setpos(".",pos)
    setlocal cursorbind
    setlocal scrollbind
    let g:diff_hunks = hunks
endfunction

The function UpdateDiffHunks() should be updated whenever a diff buffer is modified, but I find it sufficient to map it to CursorMoved and BufEnter.

function! DiffCount()
    if !exists("g:diff_hunks") 
        call UpdateDiffHunks()
    endif
    let n_hunks = 0
    let curline = line(".")
    for hunkline in g:diff_hunks
        if curline < hunkline
            break
        endif
        let n_hunks += 1
    endfor
    return n_hunks . '/' . len(g:diff_hunks)
endfunction

The output of DiffCount() can be used in the statusline, or tied to a command.

like image 196
Prince Goulash Avatar answered Oct 03 '22 15:10

Prince Goulash