Vimdiff: отображение общего количества изменений
При сравнении двух файлов в (g) vim, можно ли отобразить общее количество изменений? Я полагаю, это эквивалентно подсчету количества складок, но я не знаю, как это сделать.
В идеале я хотел бы написать сообщение, которое говорит что-то вроде "Change 1 of 12"
, которое будет обновляться по мере того, как я переключался через изменения с помощью ]c
.
Я с большим успехом превращаю некоторых членов моего офиса в чудеса Вима, но Vimdiff - постоянный жучок.
Ответы
Ответ 1
Вот немного более изысканное решение. Он использует ту же технику, что и мой предыдущий ответ, чтобы подсчитать различия, но он сохраняет первую строку каждого столбца в списке, присвоенном глобальной переменной g:diff_hunks
. Затем число кусков под курсором можно найти, найдя позицию номера строки в списке. Также обратите внимание, что я установил в конце nocursorbind
и noscrollbind
и reset их, чтобы убедиться, что мы не сломаем прокрутку мыши в окнах diff.
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()
должна обновляться всякий раз, когда изменяется буфер диффузии, но я считаю достаточным сопоставить ее с 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()
может использоваться в строке состояния или привязан к команде.
Ответ 2
Хорошо, здесь лучшее, что я мог придумать сам. Эта функция начинается в верхней части текущего буфера и с помощью движения ]c
она перемещается по изменениям до тех пор, пока ]c
больше не будет иметь эффекта. Он возвращает количество изменений (или 0
, если курсор, если он не является буфером diff).
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.