Jak 'diff' dwie podprogramy w tym samym pliku w Vim?

Czy możliwe są diff lub nawet vimdiff dwie bardzo podobne podprogramy występujące w tym samym pliku? Jeśli tak, to w jaki sposób?

Mogę myśleć o skopiowaniu dwóch podprogramów w dwóch oddzielnych plikach, a następnie diff je, ale czy istnieje sposób, aby to zrobić w oryginalnym pliku?

Author: ib., 2010-09-01

6 answers

Nie można tego zrobić w oryginalnym pliku, ale można to zrobić bez użycia oddzielnych plików, tylko oddzielnych buforów. Powinno to zadziałać, jeśli skopiowałeś jeden podprogram w rejestrze a (na przykład z "ay wpisanym w trybie wizualnym), a drugi podprogram w rejestrze b:

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

Aby zautomatyzować:

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>

Zauważ, że możesz chcieć ustawić opcję hidden, Jeśli Vim odmawia porzucenia zmienionego pliku(zobacz :h abandon).

 24
Author: ZyX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-29 10:29:01

Plugin linediff.vim : Perform a interactive diff on two blocks of text jest podobny do tego wskazanego przez Vincenta z kilkoma dodatkowymi funkcjami:

  • posiada polecenie zamknięcia otwartego bufora
  • wydaje się działać bez GUI
  • Umieść wizualne wskazanie na oryginalnych plikach, które są diffed.

Aby go użyć, wykonaj wizualne zaznaczenie na pierwszym bloku do Diffa, wprowadź polecenie :Linediff i powtórz je do drugiego bloku. Aby zakończyć, :LineDiffReset

Znalazłem następujące Mapy pomocne:

noremap \ldt :Linediff<CR>
noremap \ldo :LinediffReset<CR>
 49
Author: mMontu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 11:35:39

Możesz zapisać te dwie części/podprogramy/sekcje do dwóch plików, a następnie użyć vimdiff, aby zobaczyć różnicę.

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

Jeśli nie podoba Ci się używanie numerów linii, możesz zatrzymać kursor na początku sekcji, nacisnąć v i wybrać do końca sekcji, a następnie nacisnąć : . pokaże :'. Następnie wpisz write, a następnie nazwę pliku w samym wierszu poleceń. Naciśnij enter. Podobnie, zrób dla drugiego również. Następnie możesz wykonać polecenie vimdiff zgodnie z powyższym opisem.

(polecenie Write zapisuje część do nowego pliku.) Pisanie nowego pliku może nie być dobrym pomysłem, ale to mi pomaga. Zwłaszcza, gdy musieliśmy przejść przez porównanie kilka razy.

Jest to jeden z najprostszych sposobów bez używania wtyczki lub jeśli nie martwisz się o pamięć.

 5
Author: SibiCoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-22 09:12:59

Bardzo podoba mi się odpowiedź Zyxa, ale musiałem wprowadzić dwie modyfikacje, aby działała bezproblemowo:

  1. Po zaimplementowaniu zastępuje aktywny bufor wyświetlaczem różnic dzielonych pionowo. Następnie, podczas gdy zamyka diff, nie przeładowuje oryginalnego bufora. Aby to naprawić, zmieniłem enew w trzeciej linii na execute 'tab split | enew'.

  2. Aby zminimalizować skutki uboczne, dodałem call remove(a:diffed_buffers, 0, -1) tuż przed końcem wipeoutdiffs().

HTH, - Stu

 3
Author: Stu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-09 01:10:14

Używam tej komendy:

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

Gdzie liczby podane do sed są numerem linii, którą chcę odróżnić w pliku. <(*) oznacza ewaluację i przekierowanie jako wejście.

 3
Author: kuzyn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-19 15:12:01

Możesz spróbować zablokować wtyczkę diff vim , spowoduje to utworzenie 2 Nowego bufora w nowej karcie, aby pokazać różnice.

 1
Author: Vincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-01 23:04:35