Jak zmienić cofanie ziarnistości w Vimie?

11

W pewnym momencie mój Vim cofnie całe słowo, kiedy uderzę u.

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

Spowodowałoby to

typing some

Wydaje się jednak, że ziarnistość cofania zmieniła się na usuwanie jednej litery na raz.

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

Prowadzi do

typing some word

Pamiętam, że czytałem o dostosowywaniu ziarnistości w Practical Vim, ale nie pamiętam, jak to kontrolować. Każda pomoc doceniona!

Dan Prince
źródło
2
Prawdopodobnie jest coś w twoim vimrc, który to robi. Nie mogę go zreplikować i nie mogę znaleźć niczego w :helpplikach na ten temat ... Zobacz: Jak debugować mój plik vimrc? ... Również użycie, <C-c>aby wyjść z trybu wstawiania, może mieć skutki uboczne ( zobacz to ) i może być częścią problemu ... Sugeruję użycie Esclub <C-[>( zobacz to )
Martin Tournoij

Odpowiedzi:

11

Ręczne przerywanie sekwencji cofania

Możesz ręcznie przerwać sekwencję cofania w trybie wstawiania za pomocą <C-G>u. Z pomocy :

CTRL-G u        break undo sequence, start new change

Przykład

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

Zostawi Ci to tekst

Hello

Podział poleceń

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

Automatyczne rozwiązanie

Dokładniejsza kontrola cofania poziomu

Oto mały fragment kodu VimScript, który służy <C-G>udo tworzenia podziałów cofania po rozpoczęciu usuwania tekstu, a także po ponownym wprowadzeniu tekstu po usunięciu.

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

Notatki

Będzie to działać dla <BS>, <C-W>(usuń słowo) i <C-U>(usuń do początku wiersza). Jeśli istnieje więcej sposobów usuwania w trybie wstawiania, można je obsłużyć, dodając dodatkowe inoremappołączenia na końcu.

tommcdo
źródło
4
Jedynym problemem jest to, że nie przewidujesz, że cofniesz się później (inaczej nie zrobisz tego w pierwszej kolejności). Zwykle kończy się to sytuacją, w której chciałbyś skorzystać <C-G>u, a jest już za późno.
Shahbaz
4
Tak. Właściwie to za czymś tęskniłem. Czasami robię to, ipo czym następuje długie zdanie, a następnie backspace, aby usunąć część tego, co napisałem (wszystko w trybie wstawiania). Potem zdaję sobie sprawę, że nie powinienem był cofać się i to, co napisałem, było w porządku. Cofam, ale następnie cały wstawiany tekst jest cofany. Więc albo nie zostało mi długie zdanie, albo część, która nie ma odstępu. Nie można odzyskać części z odstępem. Czy istnieje sposób, aby powiedzieć vimowi, aby przerwał sekwencję cofania na backspace? (Teraz, gdy to mówię, mapopcja backspace jest oczywiście opcją).
Shahbaz
2
Dla przyszłych gości dodałem również inoremap <CR> <C-G>u<CR>, aby każde cofnięcie było zawarte w jednym wierszu (nie cofam już całego akapitu, który wpisujesz bez przerwy).
Shahbaz,
1
@Shahbaz, absolutnie :)
tommcdo,
1
@Shahbaz „Czy wolno mi kopiować?” Zobacz link na dole strony: „wkład użytkowników licencjonowany na licencji CC by-sa 3.0 z wymaganą atrybucją”