Есть ли способ разграничить два регистра в vim?

Возможный дубликат:
(Vim) diff две подпрограммы в одном файле

Иногда я вижу блок кода, который, как я подозреваю, идентичен другому блоку в том же файле, но он слишком длинный для визуального осмотра, и я могу просто что-то упустить. Я попытался визуально выбрать блок и yank в регистр по умолчанию, поместить этот регистр в /(find), но он не соответствует даже исходному блоку.

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

РЕДАКТИРОВАТЬ. Мой вопрос в основном является дубликатом Этот. Я нашел этот ответ, чтобы быть наиболее полезным и самым близким к тому, что я искал. Единственное, что я изменил, это сделать его в Унифицированный формат, чтобы он выглядел как diff-выход я Используется (у него больше информации). Я предполагаю, что это означает использование другой утилиты diff.

Ответ 1

Вдохновленный из моей функция lh # path # strip_common():

echo matchstr(@a.'@@'[email protected], '^\zs\(.*\)\ze.\{-}@@\1.*$')

покажет, что общего между регистрами @a и @b.

Вы можете показать дополнительную информацию:

function ShowDiff(a,b)
    " I expect neither string to contain '@@'
    let start = matchstr(a:a.'@@'.a:b, '^\zs\(.*\)\ze.\{-}@@\1.*$')
    let end= matchstr(a:a.'@@'.a:b, '^.\{-}\zs\(.*\)\[email protected]@.\{-}\1$')
    let a = a:a[len(start): -len(end)-1]
    let b = a:b[len(start): -len(end)-1]
    echo "identical beginning: ".strlen(start )." chars -> ".start
    echo "identical ending   : ".strlen(end)." chars -> ".end
    echo "typical to a       : ".strlen(a)." chars -> ".a
    echo "typical to b       : ".strlen(b)." chars -> ".b
endfunction

Используется с:

:call ShowDiff(@a, @b)

Ответ 2

Вы можете использовать следующую последовательность, предполагая, что два сегмента уже находятся в регистре 'a и 'b. Возможно, можно добавить макрос или функцию.

new
only
put a
diffthis
vnew
put b
diffthis

Это создает новый буфер, делает его единственным видимым буфером, помещает в него 'a, устанавливает его для того, чтобы быть diff'd, затем открывает новый буфер в вертикальном расколе, помещает 'b в этот разделитель пустым буфером, а также устанавливает его для diff. Сразу же vim (или gvim) будут показаны различия.

По завершении введите :ls, чтобы получить список буферов, используйте :buffer *N* для возврата к исходному файлу и используйте :bdel! *N* для удаления созданных буферов (с именем "[No Name]" ).

Ответ 3

Здесь вы можете открыть два новых окна бок о бок, каждый из которых содержит указанное содержимое регистров (например, DiffRegs(@a, @1), например) и различает их. Новые буферы не будут записываться или модифицироваться:

" A list for bookkeeping..
let g:diffreg_buffers = []

function! DiffRegs(reg1, reg2)
    " Preserve the unnamed register
    let s:nonamereg = @@
    let @@ = a:reg1
    " new window
    :new
    normal P
    setlocal nomodifiable
    setlocal buftype=nofile
    diffthis
    call add(g:diffreg_buffers, bufnr('%'))

    let @@ = a:reg2
    :vsp +enew
    normal P
    setlocal nomodifiable
    setlocal buftype=nofile
    diffthis
    call add(g:diffreg_buffers, bufnr('%'))

    let @@ = s:nonamereg
endfunction " DiffRegs(reg1, reg2)

" Function to wipe all buffers we're diffing with the function above
function! EndDiffs()
    for buffer in g:diffreg_buffers
        exe ':buffer '  . buffer
        diffoff
        quit
    endfor
    let g:diffreg_buffers = []
endfunction " EndDiffs()

Вы можете привязать их к комбинациям клавиш по вашему выбору, но если вы не вызываете EndDiffs() после каждого вызова на DiffRegs(), вы столкнетесь с проблемами.

Ответ 4

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

  • :sp горизонтальный раскол

или

  • :vsp вертикальный сплит

Как только вы разделили экран, вы должны использовать :diffthis в каждом окне, чтобы освежить различия. (Затем :diffoff, чтобы оставить режим diff)

Затем, чтобы вернуться в одно окно, вы можете выйти из одного из них: q или использовать CTRL w o