Vimdiff:显示更改总数

时间:2012-06-15 07:36:42

标签: vim diff

在(g)vim中区分两个文件时,是否可以显示更改总数?我想这相当于计算折叠次数,但我不知道如何做到这一点。

理想情况下,我想要一条消息,上面写着"Change 1 of 12"之类的消息,当我使用]c循环更改时,这些消息会更新。

我将办公室的一些成员转变为Vim的奇迹,取得了巨大的成功,但Vimdiff是一个坚持不懈的小熊。

2 个答案:

答案 0 :(得分:1)

好的,这是我能想出的最好的一面。此函数从当前缓冲区的顶部开始,并使用]c运动在整个更改中移动,直到]c不再有效。它返回更改的数量(如果光标不是差异缓冲区,则返回0。)

function! CountDiffs()
    let winview = winsaveview() 
    let num_diffs = 0
    if &diff
        let pos = getpos(".")
        keepj sil exe 'normal! G'
        let lnum = 1
        let moved = 1
        while moved
            let startl = line(".")
            keepj sil exe 'normal! [c'
            let moved = line(".") - startl
            if moved
                let num_diffs+=1
            endif
        endwhile
        call winrestview(winview)
        call setpos(".",pos)
    endif
    return num_diffs
endfunction

它似乎工作正常,并且在我的状态行中包含时并没有明显的性能损失。

对于查找当前更改的“数字”,这是一个使用向后[c运动来计算光标位置之前的更改数的函数。返回的值不太正确......我想也许它应该只返回一个数字,如果光标在更改的文本“内”,而不是在更改的第一行之后。

function! CurrentDiff()
    if &diff
        let num_diff = 0
        let winview = winsaveview() 
        let pos = getpos(".")
        let moved = 1
        while moved
            let startl = line(".")
            keepj sil exe 'normal! [c'
            let moved = line(".") - startl
            if moved
                let num_diff+=1
            endif
        endwhile
        call winrestview(winview)
        call setpos(".",pos)
        return num_diff
    endif
endfunction

同样,它似乎在我的状态行中表现出来并且不会影响光标的移动。当数据也从缓冲区复制时,数字会正确更新。

一旦问题得到解决,我可以考虑将其作为插件上传到Vim网站。

答案 1 :(得分:1)

这是一个稍微更精细的解决方案。它使用与我之前的答案相同的技术来计算差异,但它将每个块的第一行存储在一个列为全局变量g:diff_hunks的列表中。然后,通过查找列表中行号的位置,可以找到光标下方的数量。另请注意,我设置了nocursorbindnoscrollbind并在最后重置它们,以确保我们不会在差异窗口中破坏鼠标滚动。

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

每当修改差异缓冲区时,都应更新函数UpdateDiffHunks(),但我发现将其映射到CursorMovedBufEnter就足够了。

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

DiffCount()的输出可以在状态行中使用,也可以与命令绑定。