Come cambiare la granularità di annullamento in Vim?


11

Ad un certo punto il mio Vim avrebbe annullato un'intera parola quando ho colpito u.

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

Ne deriverebbe

typing some

Tuttavia, la granularità di annullamento sembra essere cambiata con l'eliminazione di una lettera alla volta.

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

Risultati in

typing some word

Ricordo di aver letto qualcosa sulla personalizzazione dell'annullamento della granularità in Practical Vim, ma non ricordo come controllarlo. Qualsiasi aiuto apprezzato!


2
Probabilmente c'è qualcosa nel tuo vimrc che lo fa. Non riesco a replicarlo e non riesco a trovare nulla nei :helpfile al riguardo ... Vedi: Come posso eseguire il debug del mio file vimrc? ... Inoltre, l'uso <C-c>per uscire dalla modalità di inserimento può avere effetti collaterali ( vedi questo ) e può essere parte del problema ... Suggerirei di usare Esco <C-[>( vedi questo )
Martin Tournoij

Risposte:


11

Interruzione manuale della sequenza di annullamento

È possibile interrompere manualmente la sequenza di annullamento in modalità Inserisci con <C-G>u. Da l'aiuto :

CTRL-G u        break undo sequence, start new change

Esempio

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

Questo ti lascerà con il testo

Hello

Ripartizione dei comandi

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

Soluzione automatica

Controllo di livello inferiore a grana più fine

Ecco un piccolo frammento di VimScript che utilizza <C-G>uper creare interruzioni di annullamento quando si avvia l'eliminazione del testo e anche quando si inizia a immettere nuovamente il testo dopo l'eliminazione.

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

Appunti

Questo funzionerà per <BS>, <C-W>(elimina una parola) e <C-U>(elimina all'inizio della riga). Se ci sono altri modi per eliminare in modalità Inserisci, possono essere supportati aggiungendo ulteriori inoremapchiamate alla fine.


4
L'unico problema è che non prevedi di annullare più tardi (altrimenti non lo farai in primo luogo). Quindi di solito si finisce con una situazione in cui si desidera si fosse usato <C-G>u, che è già troppo tardi.
Shahbaz,

4
Sì. In realtà qualcosa che mi è mancato è questo. A volte lo faccio iseguito da una lunga frase seguita da backspace per rimuovere parte di ciò che ho scritto (tutto in modalità inserimento). Poi mi rendo conto che non avrei dovuto tornare indietro e quello che avevo scritto andava bene. Annulla, ma l'intero testo inserito viene annullato. Quindi o non mi rimane nessuna delle frasi lunghe o la parte che non è in backspacing. È impossibile riavere la parte posteriore. C'è un modo per dire a Vim di interrompere la sequenza di annullamento sul backspace? (Ora che lo dico, maping backspace è ovviamente un'opzione).
Shahbaz,

2
Per i futuri visitatori, ho anche aggiunto in inoremap <CR> <C-G>u<CR>modo che ogni annullamento sia contenuto in una singola riga (non più annullamento dell'intero paragrafo che stavi digitando senza sosta).
Shahbaz,

1
@Shahbaz, assolutamente :)
tommcdo

1
@Shahbaz "Posso copiare?" Vedi link in fondo alla pagina: "contributi degli utenti concessi in licenza in cc by-sa 3.0 con attribuzione obbligatoria"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.