ฉันใช้ Vim ฉันเปิดไฟล์ ฉันแก้ไขและฉันต้องการดูสิ่งที่ฉันแก้ไขก่อนที่จะบันทึก
ฉันจะทำสิ่งนี้ใน Vim ได้อย่างไร?
ฉันใช้ Vim ฉันเปิดไฟล์ ฉันแก้ไขและฉันต้องการดูสิ่งที่ฉันแก้ไขก่อนที่จะบันทึก
ฉันจะทำสิ่งนี้ใน Vim ได้อย่างไร?
คำตอบ:
http://vim.wikia.com/wiki/Diff_current_buffer_and_the_original_file
นี่คือฟังก์ชันและคำสั่งเพื่อดูความแตกต่างระหว่างไฟล์ที่แก้ไขในปัจจุบันกับเวอร์ชันที่ไม่ได้แก้ไขในระบบไฟล์ เพียงแค่ใส่ใน vimrc
: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'
คำสั่ง ...
:w !diff % -
diff
เราเข้าใจว่าคุณปลอกกระสุนออกไป %
หมายถึง filepath ที่เปิดอยู่ในปัจจุบัน เหตุใดทั้งหมดนี้จึงเป็นการโต้แย้ง:w
คำสั่ง นอกจากนี้จะ-
กำหนดให้กับเนื้อหาของบัฟเฟอร์การทำงานได้อย่างไร? เป็นแบบกลุ่มโดยอัตโนมัติหรือไม่ที่เนื้อหาของบัฟเฟอร์ (หรืออาจเป็นช่วงเฉพาะในบัฟเฟอร์) ได้รับการกำหนดให้กับ stdin สำหรับคำสั่งเชลล์?
:w
เนื่องจากเรากำลังเขียนไฟล์ไปยังคำสั่ง (on stdin
) ในคำสั่งที่บอกว่ามันอ่านจาก-
stdin
:w !git diff % -
สำหรับเวอร์ชัน colorized หากคุณติดตั้งคอมไพล์แล้ว!
fatal: bad flag '-' used after filename
:w !git diff % -
เพราะบางคนถามเกี่ยวกับคำอธิบายสำหรับคำสั่ง
:w !diff % -
นี่คือความพยายามของฉันในการเขียนคำตอบโดยละเอียด:
ฉันสมมติว่าคุณกำลังทำงานกับระบบที่มีcat
และecho
ติดตั้ง (เช่นเกือบทุกระบบ GNU / Linux, Mac OS, BSD และระบบอื่น ๆ ที่คล้าย UNIX)
คำสั่งดังกล่าวทำงานดังนี้:
ไวยากรณ์สำหรับการบันทึกไฟล์ในกลุ่มคือ:
:w <filename>
ไวยากรณ์สำหรับการเรียกใช้คำสั่งเชลล์ในกลุ่มคือ:
:!<command>
ภายในสภาพแวดล้อมเชลล์ที่ออกโดยกลุ่ม%
จะชี้ไปที่ชื่อไฟล์ปัจจุบัน คุณสามารถตรวจสอบได้โดยดำเนินการดังต่อไปนี้:
:!echo %
สิ่งนี้ควรส่งออกชื่อไฟล์ (หรือข้อผิดพลาดหากเรียกใช้ vim โดยไม่มีชื่อไฟล์)
การใช้ cat เราสามารถส่งออกเนื้อหาของไฟล์:
:!cat %
สิ่งนี้ควรส่งคืนเนื้อหาไฟล์ในสถานะที่บันทึกล่าสุดหรือเกิดข้อผิดพลาดหากไม่เคยบันทึก
โปรแกรม diff สามารถอ่านได้จากอินพุตมาตรฐาน (stdin) หน้าคนระบุสิ่งต่อไปนี้:
[... ] ถ้า FILE เป็น "-" ให้อ่านอินพุตมาตรฐาน [... ]
การดำเนินการคำสั่ง save โดยไม่มีชื่อไฟล์ แต่เป็นคำสั่งเชลล์ที่อยู่เบื้องหลังทำให้ vim เขียนเนื้อหาไฟล์ไปยัง stdin ของเชลล์แทนที่จะบันทึกในฟิสิคัลไฟล์ คุณสามารถตรวจสอบได้โดยดำเนินการ
:w !cat
สิ่งนี้ควรพิมพ์ไฟล์เนื้อหาปัจจุบันเสมอ (ซึ่งจะถูกเขียนลงในไฟล์แทน)
รวมเข้าด้วยกัน (หรือ tl; dr): ไฟล์ถูก "บันทึก" ไปยัง stdin, diff ถูกรันโดยใช้ชื่อไฟล์และ stdin เป็นอินพุต
การรู้ว่าไฟล์นี้สามารถเปรียบเทียบไฟล์กับ vimdiff ที่ทำสิ่งนี้ได้ - นี่เป็นเพียงความคิดที่คุณไม่ต้องการทำสิ่งนี้:
:w !cat > /tmp/tempFile && vimdiff /tmp/tempFile % && rm /tmp/tempFile
(จากนั้นเปิดแบบอ่านอย่างเดียวและปิด vimdiff โดยใช้:qall
)
vim - -c ":vnew $1 |windo diffthis"
ทำให้สามารถเรียกใช้งานได้บันทึกไว้ใน PATH เป็นตัวอย่างvimdiffWithStdin
จากนั้นเปรียบเทียบกับคำสั่งต่อไปนี้ในกลุ่ม::w !vimdiffWithStdin %
:w !vimdiff % /dev/stdin
. ฉันไม่รู้ว่ามีเคล็ดลับที่คล้ายกันสำหรับ windows หรือไม่
ฉันชอบความแตกต่างเสมอ- ดีเรียบง่ายใช้งานได้
:DiffChangesDiffToggle
.
จาก 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
w !diff % -
ก็คือการทำงานระยะไกลผ่านแหล่งเกินไป (ตัวอย่างเช่น: vim sftp://example.com/foo.txt
)
จัดหาสิ่งต่อไปนี้และใช้: คำสั่ง 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()
ไม่ใช่สิ่งที่คุณกำลังมองหา แต่SCMDiff.vimนั้นยอดเยี่ยมจริงๆ กดปุ่มเดียวและไฮไลต์ไฟล์ปัจจุบันของคุณต่างกันด้วยการแก้ไขส่วนหัวใน repo การควบคุมแหล่งที่มา หมายถึงการทำงานกับ SCMS จำนวนมาก ฉันใช้มันกับ perforce
มีปลั๊กอินตามคำตอบต่างๆที่นี่: https://github.com/gangleri/vim-diffsaved
จะให้:w !diff % -
วิธีการและอีกdiffthis
วิธีหนึ่งที่เกี่ยวข้อง
นอกจากundotreeนั้นยังอนุญาตให้ทำสิ่งนี้ได้เช่นกัน แต่ยังมีอีกมากมาย (แตกต่างระหว่างจุดตรวจเลิกทำที่แตกต่างกัน) คล้ายกับGundo
ฉันสามารถแนะนำปลั๊กอินhistwin
แม้ว่าจะไม่แตกต่างจากไฟล์เวอร์ชันที่บันทึกไว้ในปัจจุบัน (เช่นคำตอบอื่น ๆ ) แต่ก็สามารถเปลี่ยนแปลงได้เป็นกลุ่มตั้งแต่คุณเริ่มแก้ไขและยังเล่นซ้ำการเปลี่ยนแปลงตามลำดับ ความแตกต่างแสดงให้เห็นว่าคุณบันทึกกลางหรือไม่
นอกจากนี้ยังแสดงรายการสาขาประวัติการเลิกทำทั้งหมดและช่วยให้คุณสามารถสลับหรือแตกต่างกันได้
PS: แม้ว่าปลั๊กอินจะไม่ติดตามช่วงเวลาในประวัติการแก้ไขโดยอัตโนมัติเนื่องจากทุกไฟล์มีการเปลี่ยนแปลง แต่คุณสามารถ "แท็ก" อย่างชัดเจนในช่วงเวลาที่คุณบันทึกไฟล์เพื่อที่คุณจะสามารถ vimdiff กับมันในภายหลังได้หากคุณต้องการ บางทีอาจเป็นไปโดยอัตโนมัติ?
หากคุณต้องการใช้ vim เพื่อเปรียบเทียบเช่นใน vimdiff คุณสามารถทำสิ่งนี้ได้:
แก้ไข. vimrc ของคุณและเพิ่ม:
nmap <F8> :w !vim -M -R - -c ":vnew % \| windo diffthis"<CR><CR>
จากตรงนั้นคุณจะเห็นการเปลี่ยนแปลงของคุณและสามารถออกจากมุมมองที่แตกต่างได้โดยใช้qall
like ใน vimdiff โดยกด F8 ในโหมดคำสั่ง แทนที่ F8 ด้วยคีย์ที่คุณต้องการ
แก้ไข: เพิ่ม -M เพื่อไม่อนุญาตให้แก้ไขใด ๆ เนื่องจากไม่ได้บันทึก
Vim: Error reading input, exiting...
ว่าเกิดอะไรขึ้นที่นี่?
git รองรับคำสั่งต่อไปนี้
:w !git diff --no-index -- % -
แมปกับคำสั่งโดยเพิ่มสิ่งต่อไปนี้ใน ~ / .vimrc ของคุณ
command GitDiff execute "w !git diff --no-index -- % -"
ตอนนี้การเรียกใช้งาน:GitDiff
กลายเป็นคำสั่งเล็ก ๆ ที่มีประโยชน์ในการแสดงความแตกต่างอย่างรวดเร็วก่อนบันทึกแต่ละครั้ง
คุณสามารถสร้างกลุ่มสร้างการสำรองข้อมูลล่าสุดและการสำรองข้อมูลต้นฉบับด้วย:
:set backup
:set patchmode=.orig
หลังจากนั้นคุณสามารถเปิดแยกได้:
:vsp %:p~ or :vsp %:.orig
และจากนั้นทำ:
:vimdiff in each buffer
หากคุณตายโดยไม่มีของเหลือ แต่ต้องการ vimdiff คุณสามารถทำได้:
ggVGy # copy the whole buffer
:vnew # open a split
CTRL-W w # switch to it
shift-P # paste at start
แล้วทำ: แตกต่างกันในแต่ละแยก
การเปลี่ยนแปลงที่คุณเพิ่งแก้ไข [ บัฟเฟอร์ ] นั่นคือการเปลี่ยนแปลงที่แตกต่างจากเวอร์ชันที่บันทึกไว้ล่าสุด (ในการทำงานของ dir ectory) สิ่งเหล่านี้อาจแตกต่างกับเวอร์ชันดัชนีล่าสุด ( 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()
ตัวอย่าง vimdiff vs Gdiff
นอกจากนี้ไปยัง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
Gdiff
ถ้าเป็นไปได้หรืออย่างอื่น (เช่นไม่ใช่โปรเจ็กต์ Git) จากนั้นทำไฟล์:vimdiff
. ด้วยtry-catch-endtry
. แต่วิธีนี้:DiffWithSaved
ในโครงการ Git ขาด
ทำตามคำแนะนำด้านบนฉันใช้ git diff ที่ฉันชอบมาก:
:w !git diff % -
:w !diff % -
ดีกว่าเมื่อคุณใช้ vim บนกล่องที่เปลี่ยนแปลงตลอดเวลาและมีจำนวนมากที่คุณไม่สามารถเปลี่ยน. vimrc ได้อย่างง่ายดาย? (หากมีการติดตั้งต่างกัน)