18

Vim で 2 つのファイルを比較すると、変更の合計数を表示できますか? これは折り数を数えることと同じだと思いますが、それを行う方法もわかりません。

理想的には、「<em>Change 1 of 12」のようなメッセージが必要 ]cです。

私はオフィスの一部のメンバーを素晴らしい Vim に変換することに成功していますが、Vimdiff は一貫してバグベアです。

4

2 に答える 2

2

これがもう少し洗練されたソリューションです。これは、以前の回答と同じ手法を使用して差分をカウントしますが、各ハンクの最初の行をグローバル変数に割り当てられたリストに格納しますg:diff_hunks。次に、リスト内の行番号の位置を見つけることにより、カーソルの下のハンクの数を見つけることができます。また、差分ウィンドウでのマウススクロールが中断されないように、最後に設定およびリセットしたnocursorbindことにも注意してください。noscrollbind

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()は、diffバッファーが変更されるたびに更新する必要がありますが、とにマップするだけで十分だと思いCursorMovedます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 に答える
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 Web サイトにアップロードすることを検討するかもしれません。

于 2012-06-19T14:04:19.380 に答える