Как «отличить» две подпрограммы в одном файле в Vim?

Возможно ли diff или даже vimdiff две очень похожие подпрограммы в одном и том же файле? Если да, то как?

Я могу подумать о том, чтобы скопировать две подпрограммы в два отдельных файла, а затем diff их, но есть ли способ сделать это в исходном файле?


person Nigu    schedule 01.09.2010    source источник


Ответы (6)


Вы не можете сделать это внутри исходного файла, но вы можете сделать это без использования отдельных файлов, только отдельных буферов. Это должно работать, если вы скопировали одну подпрограмму в регистр a (например, с набранным "ay в визуальном режиме), а другую подпрограмму в регистр b:

enew | call setline(1, split(@a, "\n")) | diffthis | vnew | call setline(1, split(@b, "\n")) | diffthis

Чтобы автоматизировать:

let g:diffed_buffers = []

function DiffText(a, b, diffed_buffers)
    enew
    setlocal buftype=nowrite
    call add(a:diffed_buffers, bufnr('%'))
    call setline(1, split(a:a, "\n"))
    diffthis
    vnew
    setlocal buftype=nowrite
    call add(a:diffed_buffers, bufnr('%'))
    call setline(1, split(a:b, "\n"))
    diffthis
endfunction

function WipeOutDiffs(diffed_buffers)
    for buffer in a:diffed_buffers
        execute 'bwipeout! ' . buffer
    endfor
endfunction

nnoremap <special> <F7> :call DiffText(@a, @b, g:diffed_buffers)<CR>
nnoremap <special> <F8> :call WipeOutDiffs(g:diffed_buffers) | let g:diffed_buffers=[]<CR>

Обратите внимание, что вы можете установить опцию hidden, если Vim отказывается отказаться от измененного файла (см. :h abandon).

person ZyX    schedule 01.09.2010
comment
Это отлично работает, но я продолжаю получать Буферы не были стерты: bwitpeout! 2 (номер меняется) при вызове WipeOutDiffs через f8. Что вызывает это? Спасибо!! - person Stop Slandering Monica Cellio; 09.09.2011

Плагин linediff.vim: выполнение интерактивного сравнения двух блоков текста похож на тот, на который указал Винсент, с некоторыми дополнительными функциями:

  • имеет команду закрыть открытый буфер
  • вроде работает без графического интерфейса
  • вставьте некоторую визуальную индикацию исходного файла(ов), который(е) diffed.

Чтобы использовать его, вы выполняете визуальный выбор на первом блоке для сравнения, вводите команду :Linediff и повторяете ее для второго блока. Чтобы выйти, :LineDiffReset

Я нашел следующие карты полезными:

noremap \ldt :Linediff<CR>
noremap \ldo :LinediffReset<CR>
person mMontu    schedule 09.01.2012
comment
Этот плагин работает очень хорошо. Он задокументирован и поддерживается в git. Он выделяет выбранные блоки в исходных файлах. Это не требует gvim. Я не вижу, как это можно улучшить, и, на мой взгляд, это лучшее решение. Пожалуйста, попробуйте и проголосуйте. - person Sam Watkins; 18.05.2012

Вы можете записать эти две части/подпрограммы/разделы в два файла, а затем использовать vimdiff, чтобы увидеть разницу.

    :1, 39 write part1          //any line range or marks can be used
    :40, 79 write part2
    :!vimdiff part1 part2

Если вам неудобно использовать номера строк, вы можете оставить курсор в начале раздела, нажать v и выбрать до конца раздела, а затем нажать : . он покажет: '‹,'>. Затем введите запись, а затем имя файла в самой командной строке. Нажмите Ввод. Аналогично, сделайте и для второго. Затем вы можете выполнить команду vimdiff, как указано выше.

(Команда записи сохраняет деталь в новый файл.) Запись нового файла может быть плохой идеей, но мне это помогает. Особенно, когда нам приходилось проходить сравнение несколько раз.

Это один из самых простых способов без использования плагина или если вы не беспокоитесь о памяти.

person SibiCoder    schedule 22.04.2016

Мне очень нравится ответ ZyX, но мне нужно было внести две модификации, чтобы он работал без проблем:

  1. Как реализовано, ‹F7› заменяет активный буфер отображением различий по вертикали. Затем, хотя ‹F8› закрывает diff, исходный буфер не перезагружается. Чтобы исправить это, я изменил enew в третьей строке на execute 'tab split | enew'.

  2. Чтобы свести к минимуму побочные эффекты, я добавил call remove(a:diffed_buffers, 0, -1) непосредственно перед окончанием WipeOutDiffs().

HTH, - Стью

person Stu    schedule 09.09.2011

Я использовал эту команду:

vimdiff <(cat file.foo | sed -n 10,15p) <(cat file.foo | sed -n 20,25p)

Где числа, переданные в sed, являются номером строки, которую я хочу сравнить в файле. <(*) означает оценку и перенаправление в качестве входных данных.

person kuzyn    schedule 19.09.2016
comment
читая это через некоторое время, все еще задаюсь вопросом, почему я использовал cat... его отсутствие также должно работать: vimdiff <(sed -n 10,15p file.foo) <(sed -n 20,25p file.foo) - person kuzyn; 17.04.2017

вы можете попробовать заблокировать плагин diff vim, это создаст 2 новых буфера в новой вкладке, чтобы показать различия.

person Vincent    schedule 01.09.2010
comment
Я видел его код: он делает почти то же, что и мое решение выше, но не умеет закрывать открытые буферы нажатием одной клавиши. - person ZyX; 02.09.2010
comment
Очень хорошо, но это работает только тогда, когда у вас есть графический интерфейс, что не всегда бывает, когда я работаю на удаленном сервере. Итак, я решил принять ответ ZyX. Спасибо, в любом случае! - person Nigu; 15.09.2010
comment
На самом деле он работает с версией vim без графического интерфейса (с использованием vim 7.3). Он использует реализацию вкладок без графического интерфейса, может быть, этого не было, когда плагин был написан, поэтому теперь он просто работает? - person lessthanideal; 06.11.2012