จะเปลี่ยนวิธีการยกเลิกแบบละเอียดเป็นกลุ่มได้อย่างไร?


11

uในบางจุดที่เป็นกลุ่มของฉันจะยกเลิกคำทั้งหมดเมื่อกด

[i]typing some words[C-c][u]

จะส่งผลให้

typing some

อย่างไรก็ตามการเลิกทำแบบย่อดูเหมือนจะเปลี่ยนเป็นการลบจดหมายทีละครั้ง

[i]typing some words[C-c][u]

ผลลัพธ์ใน

typing some word

ฉันจำได้ว่าอ่านอะไรบางอย่างเกี่ยวกับการปรับแต่งการเลิกเป็นกลุ่มใน Practical Vim แต่ฉันจำไม่ได้ว่าจะควบคุมมันอย่างไร ความช่วยเหลือใด ๆ ชื่นชม!


2
มีบางสิ่งใน vimrc ของคุณที่ทำสิ่งนี้ ฉันทำซ้ำไม่ได้และไม่พบสิ่งใดใน:helpไฟล์ที่เกี่ยวข้อง ... ดู: ฉันจะดีบักไฟล์ vimrc ของฉันได้อย่างไร ... นอกจากนี้การใช้<C-c>เพื่อออกจากโหมดแทรกอาจมีผลข้างเคียง ( ดูสิ่งนี้ ) และอาจเป็นส่วนหนึ่งของปัญหา ... ฉันขอแนะนำให้ใช้Escหรือ<C-[>( ดูสิ่งนี้ )
Martin Tournoij

คำตอบ:


11

ทำลายลำดับการเลิกทำด้วยตนเอง

<C-G>uคุณสามารถทำลายลำดับเลิกทำในโหมดแทรกด้วย จากความช่วยเหลือ :

CTRL-G u        break undo sequence, start new change

ตัวอย่าง

iHello<C-G>u world!<Esc>u

สิ่งนี้จะทำให้คุณมีข้อความ

Hello

รายละเอียดของคำสั่ง

i                           " Enter Insert mode
 Hello                      " Type 'Hello'
      <C-G>u                " Break the undo sequence
             world!         " Type ' world!'
                   <Esc>    " Return to Normal mode
                        u   " Undo

โซลูชันอัตโนมัติ

การควบคุมการยกเลิกระดับที่ละเอียดยิ่งขึ้น

นี่คือตัวอย่าง VimScriptขนาดเล็กที่ใช้<C-G>uในการสร้างการเลิกทำการเลิกเมื่อคุณเริ่มการลบข้อความและเมื่อคุณเริ่มป้อนข้อความอีกครั้งหลังจากการลบ

function! s:start_delete(key)
    let l:result = a:key
    if !s:deleting
        let l:result = "\<C-G>u".l:result
    endif
    let s:deleting = 1
    return l:result
endfunction

function! s:check_undo_break(char)
    if s:deleting
        let s:deleting = 0
        call feedkeys("\<BS>\<C-G>u".a:char, 'n')
    endif
endfunction

augroup smartundo
    autocmd!
    autocmd InsertEnter * let s:deleting = 0
    autocmd InsertCharPre * call s:check_undo_break(v:char)
augroup END

inoremap <expr> <BS> <SID>start_delete("\<BS>")
inoremap <expr> <C-W> <SID>start_delete("\<C-W>")
inoremap <expr> <C-U> <SID>start_delete("\<C-U>")

หมายเหตุ

นี้จะทำงาน<BS>, <C-W>(ลบคำ) และ<C-U>(ลบจุดเริ่มต้นของบรรทัด) หากมีวิธีการลบเพิ่มเติมในโหมดแทรกพวกเขาสามารถได้รับการสนับสนุนโดยการเพิ่มการinoremapโทรเพิ่มเติมในตอนท้าย


4
ปัญหาเดียวก็คือคุณไม่คาดว่าจะเลิกทำในภายหลัง (มิฉะนั้นคุณจะไม่ทำมันในตอนแรก) ดังนั้นคุณมักจะจบลงด้วยสถานการณ์ที่คุณต้องการให้คุณใช้<C-G>uซึ่งมันสายเกินไปแล้ว
Shahbaz

4
ใช่. จริงๆแล้วสิ่งที่ฉันคิดถึงตัวเองคือสิ่งนี้ บางครั้งฉันทำiตามด้วยประโยคยาวตามด้วย backspace เพื่อลบส่วนที่ฉันเขียน (ทั้งหมดในโหมดแทรก) จากนั้นฉันก็รู้ว่าฉันไม่ควรถอยกลับและสิ่งที่ฉันเขียนก็ใช้ได้ ฉันเลิกทำ แต่จากนั้นข้อความที่แทรกทั้งหมดจะถูกยกเลิก ดังนั้นฉันจะเหลือโดยไม่มีประโยคยาวหรือส่วนที่ไม่ได้สำรอง เป็นไปไม่ได้ที่จะเอาส่วนที่ถอยหลังออกมา มีวิธีที่จะบอกเป็นกลุ่มที่จะทำลายลำดับการเลิกทำเมื่อ backspace หรือไม่? (ตอนนี้ฉันพูดแล้วmapไอเอ็นจี backspace เป็นตัวเลือกแน่นอน)
Shahbaz

2
สำหรับผู้เยี่ยมชมในอนาคตฉันยังได้เพิ่มinoremap <CR> <C-G>u<CR>เพื่อให้การเลิกทำแต่ละครั้งอยู่ในบรรทัดเดียว (ไม่ต้องเลิกทำทั้งย่อหน้าที่คุณพิมพ์ไม่หยุด)
Shahbaz

1
@Shahbaz, แน่นอน :)
tommcdo

1
@Shahbaz "ฉันได้รับอนุญาตให้คัดลอกหรือไม่" ดูลิงค์ที่ด้านล่างของหน้า: "ผลงานผู้ใช้ที่ได้รับอนุญาตภายใต้ cc by-sa 3.0 พร้อมการระบุแหล่งที่มา"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.