18

在 Vim 中比较两个文件时,是否可以显示更改的总数?我想,这相当于计算折叠次数,但我也不知道该怎么做。

理想情况下,我想要一条消息,上面写着“<em>Change 1 of 12”,当我使用 ]c.

我在将我办公室的一些成员转变为使用 Vim 的奇迹方面取得了巨大成功,但 Vimdiff 始终是个问题。

4

2 回答 2

2

好的,这是我能想到的最好的自己。此函数从当前缓冲区的顶部开始,并使用]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 网站上。

于 2012-06-19T14:04:19.380 回答
2

这是一个稍微更精致的解决方案。它使用与我之前的答案相同的技术来计算差异,但它将每个大块的第一行存储在分配给全局变量的列表中g:diff_hunks。然后可以通过查找行号在列表中的位置来找到光标下方的hunk个数。另请注意,我在最后设置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()每当修改差异缓冲区时,都应该更新该函数,但我发现将其映射到CursorMovedand就足够了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

的输出DiffCount()可以在状态行中使用,或者与命令相关联。

于 2012-12-18T11:14:20.000 回答