क्या मैं विम में अपनी फ़ाइल सहेजने से पहले परिवर्तन देख सकता हूँ?


135

मैं विम का उपयोग करता हूं। मैं एक फाइल खोलता हूं। मैं इसे संपादित करता हूं और मैं इसे सहेजने से पहले यह देखना चाहता हूं कि मैंने क्या संपादित किया है।

मैं विम में यह कैसे कर सकता हूं?

जवाबों:


57

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

फाइल सिस्टम में वर्तमान में संपादित फ़ाइल और इसके अनमॉडिफाइड संस्करण के बीच एक अंतर देखने के लिए एक फ़ंक्शन और कमांड है। बस इसे अपने vimrc या plugin directory में डालें, एक फ़ाइल खोलें, उन्हें सहेजे बिना कुछ संशोधन करें, और करें :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()

अलग-अलग दृश्य से बाहर निकलने के लिए आप :diffoffकमांड का उपयोग कर सकते हैं ।

नीचे एक समान फ़ंक्शन है, जो 'cvs diff'कमांड की नकल करने के लिए अनुकूलित है ...


7
@ ल्यूक-हर्मिट्ट वैकल्पिक :w !diff % -बेहतर नहीं है जब आप एक एवरचार्जिंग और बड़ी संख्या में बॉक्स पर विम का उपयोग कर रहे हैं जिसे आप आसानी से .vimrc के लिए बदल नहीं सकते हैं? (बशर्ते वे स्थापित हो गए हैं।)
थोमैंस्की

1
विम अंतिम आशा का उपकरण नहीं है। वह जो तब काम करेगा जब कुछ और उपलब्ध न हो। यह मेरा मुख्य काम करने का उपकरण है।
ल्यूक हरमिट

12
बस एक लिंक की आपूर्ति वास्तव में एक जवाब नहीं है
स्कर्पी

3
अराजकता का उत्तर श्रेष्ठ है और टोबीस के उत्तर में, स्पष्टीकरण पूर्ण है।
एवी कोहेन

1
क्या आप केवल एक लिंक के बजाय कुछ सामग्री जोड़ सकते हैं? SO दिशानिर्देश ...
Bła guidelinesej Michalik

160
:w !diff % -

4
क्या ऐसा करने का कोई तरीका है? मैंने कोशिश की: w! विमदिफ% - लेकिन सफलता के बिना।
जो जे

14
कोई समझा सकता है कि? मुझे समझ नहीं आ रहा है कि क्या हो रहा है। मुझे समझ में आ गया कि तुम बाहर आ रहे हो diff%वर्तमान में खुली फ़ाइलपथ को संदर्भित करता है। यह सब :wकमांड का तर्क क्यों है ? इसके अलावा, -काम करने वाले बफर की सामग्री को कैसे सौंपा जाता है? क्या यह स्वचालित रूप से है, कि बफर की सामग्री (या शायद बफर में एक विशिष्ट रेंज) शेल कमांड के लिए स्टड को सौंपी जाती है?
नाथन वालेस

9
@NathanWallace: यह एक तर्क है :wक्योंकि हम फाइल को कमांड पर ( stdin) पर लिख रहे हैं । कमांड में, -इसे पढ़ने के लिए कहता है stdin
अराजक

14
या :w !git diff % -एक रंगीन संस्करण के लिए उपयोग करें , अगर आपने गिट स्थापित किया है!
डर्गाचेव

5
@ डर्गाचेव मुझे fatal: bad flag '-' used after filenameचलाने पर त्रुटि मिलती है :w !git diff % -
ग्रेस्केल

100

क्योंकि कुछ लोगों ने कमांड के लिए स्पष्टीकरण के बारे में पूछा

:w !diff % -

यहाँ एक अधिक विस्तृत उत्तर लिखने का मेरा प्रयास है:

मैं मान रहा हूं कि आप एक सिस्टम पर काम कर रहे हैं catऔरecho इंस्टॉल किया हुआ है (उदाहरण के लिए लगभग कोई भी GNU / Linux, Mac OS, BSD और अन्य UNIX- जैसे सिस्टम)।

उपरोक्त आदेश निम्नानुसार काम करता है:

  1. फ़ाइल को सहेजने के लिए सिंटैक्स है:

    :w <filename>
    
  2. विम में शेल कमांड को निष्पादित करने के लिए सिंटैक्स है:

    :!<command>
    
  3. विम द्वारा जारी शेल पर्यावरण के अंदर %वर्तमान फ़ाइल नाम को इंगित करता है। आप निम्नलिखित को निष्पादित करके इसे सत्यापित कर सकते हैं:

    :!echo %
    

    यह फ़ाइल नाम (या एक त्रुटि, अगर विम फ़ाइल नाम के बिना चलाया गया था) का उत्पादन करना चाहिए।

    बिल्ली का उपयोग करके हम फ़ाइल की सामग्री को भी आउटपुट कर सकते हैं:

    :!cat %
    

    यह अपने अंतिम सहेजे गए राज्य में फ़ाइलों की सामग्री को वापस कर देना चाहिए या यदि इसे कभी सहेजा नहीं गया है, तो एक त्रुटि।

  4. कार्यक्रम अंतर मानक इनपुट (स्टडिन) से पढ़ने में सक्षम है। इसका मैन पेज निम्नलिखित बताता है:

    [...] यदि एक फ़ाइल '-' है, तो मानक इनपुट पढ़ें। [...]

  5. फ़ाइल नाम के बिना सेव कमांड को निष्पादित करना, बल्कि इसके पीछे एक शेल कमांड के कारण फ़ाइल सामग्री को शेल में स्टड करने के लिए लिखने के बजाय इसे भौतिक फ़ाइल में सहेजने का कारण बनता है। आप इसे निष्पादित करके सत्यापित कर सकते हैं

    :w !cat
    

    यह हमेशा फ़ाइलों को मुद्रित करना चाहिए वर्तमान सामग्री (जो इसके बजाय एक फ़ाइल में लिखी गई होगी)।

इसे एक साथ रखना (या tl; डॉ।): फ़ाइल को स्टड करने के लिए "सहेजा गया" है, फ़ाइल इनपुट के रूप में फ़ाइल नाम और स्टडिन के साथ चलाया जाता है।

यह जानने के बाद भी आप इस तरह से कुछ कर सकते हैं - vimdiff के साथ फ़ाइलों की तुलना कर सकते हैं - यह सिर्फ एक विचार है जो आप ऐसा नहीं करना चाहते हैं:

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

(इसके बाद आसानी से खोलें और उपयोग करते हुए बंद करें :qall)


Vimdiff का उपयोग करने के लिए एक अधिक समझदार दृष्टिकोण निम्नलिखित के साथ एक शेल स्क्रिप्ट vim - -c ":vnew $1 |windo diffthis"बना रहा होगा, जो इसे निष्पादन योग्य बना देगा, इसे PATH में सहेजना होगा उदाहरण के लिए vimdiffWithStdinऔर फिर vim में निम्नलिखित कमांड के साथ तुलना करना::w !vimdiffWithStdin %
Tobias Heinicke

और भी सरल :w !vimdiff % /dev/stdin:। मैं नहीं जानता कि क्या खिड़कियों के लिए एक समान चाल मौजूद है।
deft_code

12

मुझे हमेशा डिफरेंसेस पसंद हैं - अच्छा, सरल, काम करता है।


यह एक बहुत अधिक उत्थान विकल्पों की तुलना में बेहतर काम करता है। यह इसे टॉगल करने की क्षमता देता है।
स्टीवन लू

1
@StevenLu - मेह ... आप क्या कर सकते हैं? किसी भी मामले में, आप इसे पसंद करते हैं। मुझे यह दूसरे दृष्टिकोण से अधिक व्यावहारिक लगता है।
रूक

मैं, मैं दूसरा @Steven करता हूं, आपके सुझाए गए डिफरेंसेज बेहतरीन हैं। धन्यवाद!
AS

इसे उसी डेवलपर से प्लगइन के रूप में भी स्थापित किया जा सकता है: github.com/jmcantrell/vim-diffchanges
सुमंत लिंगप्पा

अच्छा प्लगइन, लेकिन यह बाद में इसे बनाता पैच को नष्ट नहीं करता है? संपादित करें: मेरा बुरा! ऐसा होता है। मैं इसे गलत तरीके से इस्तेमाल कर रहा था। मुझे इस्तेमाल करना था :DiffChangesDiffToggle
एड्रॉक्स

10

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 पर प्रलेखित है । इस पर लाभ यह w !diff % -है कि यह दूरस्थ स्रोतों पर भी काम करता है (उदाहरण के लिए vim sftp://example.com/foo.txt) :
लेकेन्स्टाइन

1
मुझे यह बेहतर लगता है क्योंकि हम एक टर्मिनल के बजाय विम बफर के अंदर ही अंतर को सही देखते हैं
निको बेलिक

एक बार मतभेदों की जांच करने के बाद आप सामान्य स्थिति में कैसे लौटेंगे?
निको बेलिक

यदि आप कमांड के साथ कमांड को प्रतिस्थापित करके यदि क्लॉज से छुटकारा पा सकते हैं! (देखें: एच

@ NikoBellic सबसे पहले ": q 'के साथ" पुरानी "विंडो (स्क्रैच बफर के रूप में चिह्नित) को बंद करें। आप सामान्य मोड में दो बार ctrl-W टैप करके खिड़कियों के बीच बदल सकते हैं। फिर आप अलग-अलग लिखकर टॉगल कर सकते हैं: diffoff
brunch875

2

निम्नलिखित स्रोत और उपयोग करें: DIFF कमांड

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

नहीं बिल्कुल वही जो आप ढूंढ रहे हैं लेकिन SCMDiff.vim वास्तव में अच्छा है। एक keypress, और यह एक स्रोत नियंत्रण रेपो में हेड संशोधन के साथ आपकी वर्तमान फ़ाइल को अलग करता है। यह कई SCMS के साथ काम करने के लिए है। मैं इसे पर्फेक्ट के साथ उपयोग करता हूं।


2

यहाँ एक प्लगइन है, जो विभिन्न उत्तरों पर आधारित है: https://github.com/gangleri/vim-diffsaved

यह :w !diff % -विधि और अधिक शामिल diffthisएक प्रदान करता है ।

इसके अलावा अंडरट्री इसे भी अनुमति देती है, लेकिन बहुत अधिक (विभिन्न पूर्ववत चौकियों के बीच भिन्नता)। गुंडो के समान ।


1

मैं histwin प्लगइन की सिफारिश कर सकते हैं ।

हालांकि यह करने के लिए अंतर नहीं है वर्तमान बचाया फ़ाइल का संस्करण (अन्य उत्तर की तरह), यह कर सकते हैं vimdiff में परिवर्तन के बाद से आप edting शुरू कर दिया , और यहां तक कि पुन: चलाने के क्रम में अपने परिवर्तन। अंतर दिखाता है यदि आप मध्यवर्ती रूप से बचत करते हैं।

इसके अतिरिक्त, यह सभी पूर्ववत इतिहास शाखाओं की एक सूची प्रदर्शित करता है और आपको उनके बीच स्विच या अंतर करने की अनुमति देता है।

पुनश्च: जबकि प्लगइन स्वचालित रूप से हर फ़ाइल को बदलने के बाद से संपादित इतिहास में क्षणों को ट्रैक नहीं करता है, आप उस पल को स्पष्ट रूप से "टैग" कर सकते हैं जब आप फ़ाइल को ऐसे सहेजते हैं कि आप बाद में इसके साथ विमीडिफ कर सकते हैं, यदि आप ऐसा चाहते हैं। शायद यह स्वचालित हो सकता है?


1

अगर आप vimdiff की तरह तुलना के लिए vim का उपयोग करना चाहते हैं, तो आप कुछ इस तरह कर सकते हैं:

अपना .vimrc संपादित करें और जोड़ें:

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

वहां से आप अपने परिवर्तनों को देखेंगे और qallकमांड मोड में F8 दबाकर vimdiff की तरह उपयोग करने वाले अलग-अलग दृश्य को छोड़ सकते हैं । अपनी पसंद की किसी भी कुंजी के साथ F8 बदलें।

संपादित करें: जोड़ा -M किसी भी संशोधन को अस्वीकार करने के लिए, क्योंकि यह बचा नहीं है।


यह कमांड मेरे लिए काम करना शुरू करता है, यह मुझे अलग-अलग पक्ष दिखाता है। हालांकि, जैसे ही मैं कोशिश करता हूं और कुछ भी संपादित करता हूं vim विंडो पागल हो जाती है। मैं टाइप करना शुरू करता हूं और मुझे स्क्रीन के दोनों ओर शब्दों के पीछे एक बैश प्रॉम्प्ट मिलता है। तो यह अंतर प्रदर्शित करने के लिए लगता है, लेकिन फिर दुर्घटनाग्रस्त हो जाता है। इसके अतिरिक्त, मुझे यह त्रुटि मिलती है Vim: Error reading input, exiting...कि यहां क्या गलत हो रहा है?
ट्रेवर

@ ट्रेवर: मैं केवल अनुमान लगा सकता हूं कि समस्याएं क्या हैं। यह वास्तव में इस तरह से अलग करते समय कोई संशोधन करने के लिए नहीं बचा है। इसलिए मैंने इसे पूरी तरह से हटाने के लिए "-M" पैरामीटर जोड़ा है। माफ़ करना।
टोबियास हेनिक

1

git निम्नलिखित कमांड का समर्थन करता है

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

इसे अपने ~ / .vimrc में निम्नलिखित जोड़कर एक कमांड में मैप करें

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

अब अमल करना :GitDiffएक छोटी सी आज्ञा बन जाता है ताकि प्रत्येक बचाने से पहले वह जल्दी से दिखाई दे सके।


0

आप एक अंतिम बैकअप बना सकते हैं और इसके साथ मूल बैकअप बना सकते हैं:

:set backup
:set patchmode=.orig 

इसके बाद, आप उन्हें एक विभाजन में खोल सकते हैं:

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

और वहाँ से:

:vimdiff in each buffer

यदि आप बिना किसी बचे हुए पर मर चुके हैं, लेकिन विमीडफ चाहते हैं, तो आप यह भी कर सकते हैं:

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

और फिर करते हैं: प्रत्येक विभाजन पर अंतर


0

आपके द्वारा अभी परिवर्तित किए गए परिवर्तन [ बफर ], अर्थात जो पिछले सहेजे गए संस्करण ( वर्किंग डीर एक्टोरी में) से भिन्न हैं, ये अंतिम इंडेक्स संस्करण ( Git ) के साथ भिन्न हो सकते हैं । मैंने दोनों को मैप किया:

" 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()

Vddiff बनाम Gdiff का उदाहरण।

  • vimdiff: : vimdiff
  • Gdiff: Gdiff परिवर्तन बदलते हुए, आप केवल Gdiff देखते हैं, क्या हो सकता है या vimdiff के समान परिवर्तन हो सकते हैं: परिवर्तनों का आना, आप केवल Gdiff देखते हैं, क्या हो सकता है, या vimdiff के समान परिवर्तन नहीं हो सकते हैं

इसके अलावा, vimdiffअन्य पथ में आसान होमलोन फ़ाइल के लिए:

    " 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
एक बस 1 मानचित्र बना सकता है जो निष्पादित करता है: Gdiffयदि संभव हो और अन्यथा (जैसे जीआईटी प्रोजेक्ट नहीं) तो प्रदर्शन करें :vimdiff। के साथ try-catch-endtry। लेकिन :DiffWithSavedएक गिट परियोजना में इस तरह की कमी है।
ज़ोपी गार्सिया

-2

ऊपर दिए गए सुझाव का पालन करें मैं git diff का उपयोग करता हूं जो मुझे बहुत पसंद है:

:w !git diff  % -
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.