Dosyamı Vim'e kaydetmeden önce değişiklikleri görebilir miyim?


135

Vim kullanıyorum. Bir dosya açıyorum. Düzenliyorum ve kaydetmeden önce ne düzenlediğimi görmek istiyorum.

Bunu Vim'de nasıl yapabilirim?

Yanıtlar:


57

http://vim.wikia.com/wiki/Diff_current_buffer_and_the_original_file

Şu anda düzenlenmiş olan dosya ile dosya sistemindeki değiştirilmemiş sürümü arasındaki farkı görmek için bir işlev ve komut. Bunu vimrc veya plugin dizinine koyun, bir dosya açın, kaydetmeden bazı değişiklikler yapın ve yapın :DiffSaved.

function! s:DiffWithSaved()
  let filetype=&ft
  diffthis
  vnew | r # | normal! 1Gdd
  diffthis
  exe "setlocal bt=nofile bh=wipe nobl noswf ro ft=" . filetype
endfunction
com! DiffSaved call s:DiffWithSaved()

Farklı görünümden çıkmak için :diffoffkomutu kullanabilirsiniz .

Aşağıda, 'cvs diff'komutu taklit etmek için uyarlanmış benzer bir işlev var ...


7
@ luc-hermitte .vimrc'yi :w !diff % -kolayca değiştiremeyeceğiniz sürekli değişen ve çok sayıda kutuda vim kullanırken alternatif üstün değil mi? (
Farkı

1
Vim son umudun aracı değildir. Başka hiçbir şey olmadığında çalışacak olan. Bu benim ana çalışma aracım.
Luc Hermitte

12
Sadece bir bağlantı sağlamak gerçekten bir cevap değildir
Skurpi

3
Chaos'un cevabı üstündür ve Tobias'ın cevabında açıklama tamamlanmıştır.
Avi Cohen

1
Lütfen sadece bağlantı yerine içerik ekleyebilir misiniz? SO yönergeleri ...
Błażej Michalik

160
:w !diff % -

4
Bunu vimdiff ile yapmanın bir yolu var mı? Denedim: w! Vimdiff% - ama başarılı olamadı.
Joe J

14
Birisi bunu açıklayabilir mi? Ne olduğunu anlamıyorum. Anladığınızı anlıyorum diff. %şu anda açık olan dosyayolunu ifade eder. Bütün bunlar neden :wkomuta karşı bir argüman ? Ayrıca, -çalışma arabelleğinin içeriğine nasıl atanır? Bu otomatik olarak vim, arabellek içeriği (veya arabellekteki belirli bir aralık) kabuk komutları için stdin'e atanır mı?
Nathan Wallace

9
@NathanWallace: Bu bir argüman :wçünkü dosyayı komuta yazıyoruz (açık stdin). Komutta, -okumasını söyler stdin.
kaos

14
Veya :w !git diff % -git yüklü ise renklendirilmiş bir sürüm için kullanın !
Dergachev

5
@Dergachev fatal: bad flag '-' used after filenameÇalıştırdığımda hatayı alıyorum :w !git diff % -.
Gri Tonlamalı

100

Çünkü bazı insanlar komuta için bir açıklama istedi

:w !diff % -

İşte daha ayrıntılı bir cevap yazma girişimim:

Yüklü catve echokurulu bir sistem üzerinde çalıştığınızı varsayıyorum (örneğin hemen hemen tüm GNU / Linux, Mac OS, BSD ve diğer UNIX benzeri sistemler).

Yukarıdaki komut aşağıdaki gibi çalışır:

  1. Bir dosyayı vim'e kaydetmek için sözdizimi:

    :w <filename>
    
  2. Vim'de shell komutu yürütmenin sözdizimi şöyledir:

    :!<command>
    
  3. Vim tarafından verilen kabuk ortamının içinde %mevcut dosya adını gösterir. Aşağıdakileri yürüterek bunu doğrulayabilirsiniz:

    :!echo %
    

    Bu, dosya adını (veya vim dosya adı olmadan çalıştırıldıysa bir hatayı) çıkarmalıdır.

    Cat kullanarak dosyanın içeriğini de çıkarabiliriz:

    :!cat %
    

    Bu, dosya içeriğini son kaydedildiği durumuna veya hiç kaydedilmemişse bir hataya dönmelidir.

  4. Program farkı standart girişten (stdin) okuyabilir. Kılavuz sayfası şunları belirtir:

    [...] Bir DOSYA '-' ise standart girişi okuyun. [...]

  5. Save komutunu bir dosya adı olmadan yürütmek yerine arkasında bir kabuk komutu kullanmak, vim'in dosya içeriğini fiziksel bir dosyaya kaydetmek yerine kabuğun stdinine yazmasına neden olur. Bunu yürüterek doğrulayabilirsiniz.

    :w !cat
    

    Bu her zaman dosyaların geçerli içeriğini yazdırmalıdır (bunun yerine bir dosyaya yazılır).

Bir araya getirmek (veya tl; dr): Dosya stdin'e "kaydedilir", diff dosya adı ve stdin girdi olarak çalıştırılır.

Bunu bilmek vimdiff ile böyle bir şey yaparak dosyaları karşılaştırabilir - bu sadece bunu yapmak istemediğiniz bir fikir:

:w !cat > /tmp/tempFile && vimdiff /tmp/tempFile % && rm /tmp/tempFile

(Sonra salt okunur olarak açın ve vimdiff kullanarak kapatın :qall)


Vimdiff'i kullanmak için daha akılcı bir yaklaşım, aşağıdakileri içeren bir kabuk komut dosyası oluşturmak vim - -c ":vnew $1 |windo diffthis", çalıştırılabilir hale getirmek, örneğin PATH'e kaydetmek vimdiffWithStdinve daha sonra :w !vimdiffWithStdin %
vim'de

Hatta daha basit: :w !vimdiff % /dev/stdin. Pencereler için benzer bir hile olup olmadığını bilmiyorum.
deft_code

12

Her zaman farklılıkları severim - güzel, basit, çalışır.


Bu, daha yüksek oranda oylanan seçeneklerden çok daha iyi çalışıyor. Bu, geçiş yapma yeteneği verir.
Steven Lu

1
@StevenLu - Meh ... ne yapabilirsin? Her durumda, sevmene sevindim. Diğer yaklaşımdan daha pratik buluyorum.
Kale

Ben ikinci @Steven yapıyorum, önerilen değişiklikleriniz mükemmel. Teşekkürler!
AS

Bu aynı geliştiriciden bir eklenti olarak da yüklenebilir: github.com/jmcantrell/vim-diffchanges
Sumanth Lingappa

güzel bir eklenti, ancak daha sonra oluşturduğu yamayı silmez mi? Düzenleme: Benim kötü! Öyle. Yanlış kullanıyordum. Kullanmak zorunda kaldım :DiffChangesDiffToggle.
aderchox

10

from vimrc_example.vim:

" Convenient command to see the difference between the current buffer and the
" file it was loaded from, thus the changes you made.
if !exists(":DiffOrig")
  command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
          \ | wincmd p | diffthis
endif

... vimdoc.sourceforge.net/htmldoc/diff.html#:DiffOrig adresinde belgelendiği gibi . Bu over Avantajı w !diff % -çok üzerinde uzak kaynaklardan çalışır (örneğin: vim sftp://example.com/foo.txt)
Lekensteyn

1
Bunu daha iyi seviyorum çünkü farkı bir terminal yerine vim tamponunun içinde görüyoruz
Niko Bellic

Farklılıkları inceledikten sonra normale nasıl dönersiniz?
Niko Bellic

Komutu komut ile değiştirerek if yan tümcesinden kurtulabilirsiniz! (bkz: s E174)
elig

@NikoBellic Önce "eski" pencereyi (çizik tamponu olarak işaretlenir) ': q' ile kapatın. Normal moddayken ctrl-W öğesine iki kez dokunarak pencereler arasında geçiş yapabilirsiniz. Daha sonra fark yazarak kapatabilirsiniz: diffoff
brunch875

2

Aşağıdakileri kaynaklayın ve kullanın: DIFF komutu

function! s:diff()
    let tmpa = tempname()
    let tmpb = tempname()
    earlier 100h
    exec 'w '.tmpa
    later 100h
    exec 'w '.tmpb
    update
    exec 'tabnew '.tmpa
    diffthis
    vert split
    exec 'edit '.tmpb
    diffthis
endfunction
command! -nargs=0 DIFF call <SID>diff()

2

Tam olarak aradığınız şey değil ama SCMDiff.vim gerçekten harika. Bir tuşa basıldığında, kaynak kontrol deposundaki kafa revizyonu ile mevcut dosyanızı farklı şekilde vurgular. Birçok SCMS ile çalışmak içindir. Performansla kullanıyorum.



1

Ben tavsiye edebilir histwin eklentisi.

O değil fark yok iken akım kaydedilmiş (diğer cevaplar gibi) dosyanın sürümü, olabilir sen edting başladıktan sonra vimdiff değiştirir ve hatta tekrar sırayla değişiklikleri. Aradaki farkı kaydedip kaydetmediğinizi gösterir.

Ayrıca, tüm geri alma geçmişi dallarının bir listesini görüntüler ve bunlar arasında geçiş yapmanızı veya aralarında değişiklik yapmanızı sağlar.

Not: Eklenti, her dosya değiştiğinden beri düzenleme geçmişindeki anları otomatik olarak izlemese de, dosyayı kaydettiğiniz anı daha sonra onunla birlikte vimdiff yapabileceğiniz şekilde açıkça "etiketleyebilirsiniz". Belki bu otomatik olabilir?


1

Vimdiff gibi karşılaştırma için vim kullanmak istiyorsanız, böyle bir şey yapabilirsiniz:

.Vimrc dosyanızı düzenleyin ve ekleyin:

nmap <F8> :w !vim -M -R - -c ":vnew % \| windo diffthis"<CR><CR>

Oradan değişikliklerinizi göreceksiniz ve qallkomut modunda F8'e basarak vimdiff'deki gibi kullanarak diff görünümünden çıkabilirsiniz. F8'i istediğiniz herhangi bir anahtarla değiştirin.

Düzenleme: Herhangi bir değişikliğe izin vermemek için -M eklendi, çünkü kaydedilmedi.


Bu komut benim için çalışmaya başlıyor, farkımı yan yana gösteriyor. Ancak, bir şeyi denemeye ve düzenlemeye başlar başlamaz vim penceresi çıldırır. Yazmaya başladım ve ekranın her iki tarafında vim'deki kelimelerin arkasında bir bash istemi alıyorum. Bu yüzden farkı gösteriyor gibi görünüyor, ama sonra vim çöküyor. Ayrıca, Vim: Error reading input, exiting...burada yanlış giden herhangi bir fikir bu hatayı alıyorum ?
Trevor

@Trevor: Sadece sorunların ne olduğunu tahmin edebildim. Aslında bu şekilde farklılık gösterirken herhangi bir değişiklik yapmaktan tasarruf edilmiyor. Bu yüzden tamamen izin vermemek için "-M" parametresini ekledim. Afedersiniz.
Tobias Heinicke

1

git aşağıdaki komutu destekler

:w !git diff --no-index -- % -

~ / .vimrc'nize aşağıdakileri ekleyerek komutla eşleştirin

command GitDiff execute "w !git diff --no-index -- % -"

Şimdi yürütme :GitDiff, her kaydetmeden önce farkı hızlı bir şekilde göstermek için kullanışlı küçük bir komut haline gelir.


0

Vim'in aşağıdakilerle bir son yedekleme ve orijinal yedekleme oluşturmasını sağlayabilirsiniz:

:set backup
:set patchmode=.orig 

Bundan sonra, bunları bir bölünmüş olarak açabilirsiniz:

:vsp %:p~ or :vsp %:.orig

Ve oradan:

:vimdiff in each buffer

Artıklar üzerinde ölmediyseniz ancak vimdiff istiyorsanız, şunları da yapabilirsiniz:

ggVGy    # copy the whole buffer
:vnew    # open a split
CTRL-W w # switch to it
shift-P  # paste at start

ve sonra şunu yapın:


0

Az önce düzenlediğiniz değişiklikler [ arabellek ], yani son kaydedilen sürümden ( çalışma dizininde) farklı olanlar, bunlar son dizin sürümüyle ( Git ) farklılık gösterebilir . Her ikisini de eşledim:

" Find diff inbetween currrent buffer and ... A{last index version} vs B{last saved version in working directory}
"  - A{last index version}: the file as you last commited it
    " git diff to vimdiff against the index version of the file:
    nnoremap <leader>gd <Esc>:Gvdiff<CR><Esc>:echo "currentBuffer vs lastIndexVersion (last commited)"<CR>
"  - B{last saved version in working directory}: the file you last :w,
"   not neccesary commited it (not commited for sure if it is in NO git project)
    " https://vim.fandom.com/wiki/Diff_current_buffer_and_the_original_file
    nnoremap <leader>gd2 <Esc>:DiffSaved<CR><Esc>:echo "currentBuffer vs lastSaved (not neccesary equal to last commited)"<CR>
    function! s:DiffWithSaved()
        let filetype=&ft
        diffthis
        vnew | r # | normal! 1Gdd
        diffthis
        exe "setlocal bt=nofile bh=wipe nobl noswf ro ft=" . filetype
    endfunction
    com! DiffSaved call s:DiffWithSaved()

Vimdiff vs Gdiff örneği.

  • vimdiff: : vimdiff
  • Gdiff: Gdiff Değişiklikleri yürütmek, yalnızca Gdiff'i görüyorsunuz, vimdiff ile aynı değişikliklere sahip olabilir veya aynı değişiklikleri olabilir: değişiklikleri yaparken, sadece Gdiff'i görürsünüz, vimdiff ile aynı değişikliklere sahip olabilir veya olmayabilir

Ayrıca, vimdiffdiğer yoldaki kolay homonym dosyasına:

    " vimdiff homonym file 
   nnoremap <leader>dh  <Esc>:vsplit %:p:h/../__/%:t <bar> :windo diffthis<Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left>
        "E.g."$ vim /path01/proj02_pg064/processorder.php
        ":vsplit %:p:h/../proj01_pg05/%:t | :windo diffthis

1
Biri sadece 1 harita yapabilir: Gdiffmümkünse ve başka bir şekilde (örneğin bir Git projesi değil) a :vimdiff. İle try-catch-endtry. Ancak :DiffWithSavedbir Git projesinde bu şekilde eksiktir.
Xopi García

-2

Yukarıdaki izleyin ben çok sever git fark kullanın önerir:

:w !git diff  % -
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.