Wie kann ich die Granularität in Vim rückgängig machen?

11

Irgendwann machte mein Vim ein ganzes Wort rückgängig, wenn ich traf u.

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

Würde dazu führen

typing some

Die Rückgängig-Granularität scheint sich jedoch dahingehend geändert zu haben, dass jeweils nur ein Buchstabe gelöscht wird.

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

Ergebnisse in

typing some word

Ich erinnere mich, dass ich etwas über das Anpassen der Rückgängig-Granularität in Practical Vim gelesen habe, aber ich kann mich nicht erinnern, wie ich sie steuern soll. Jede Hilfe geschätzt!

Dan Prince
quelle
2
Es gibt wahrscheinlich etwas in Ihrem vimrc, das dies tut. Ich kann es nicht replizieren und kann in den :helpDateien nichts darüber finden ... Siehe: Wie debugge ich meine vimrc-Datei? ... Auch die Verwendung <C-c>kann zum Verlassen Einfügemodus Nebenwirkungen haben ( siehe diese ) und kann ein Teil des Problems sein ... Ich würde vorschlagen , mit Escoder <C-[>( siehe diese )
Martin Tournoij

Antworten:

11

Manuelles Unterbrechen der Rückgängig-Sequenz

Sie können die Rückgängig-Sequenz im Einfügemodus mit manuell unterbrechen <C-G>u. Aus der Hilfe :

CTRL-G u        break undo sequence, start new change

Beispiel

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

Dadurch erhalten Sie den Text

Hello

Aufschlüsselung der Befehle

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

Automatische Lösung

Feinkörnigere Undo-Level-Steuerung

Hier ist ein kleiner Ausschnitt aus VimScript , mit <C-G>udem Sie Rückgängig-Unterbrechungen erstellen, wenn Sie mit dem Löschen von Text beginnen und wenn Sie nach dem Löschen erneut Text eingeben .

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

Anmerkungen

Dies funktioniert für <BS>, <C-W>(löschen Sie ein Wort) und <C-U>(löschen von Zeile zu beginnen). Wenn es im Einfügemodus mehr Möglichkeiten zum Löschen gibt, können diese durch Hinzufügen zusätzlicher inoremapAufrufe am Ende unterstützt werden.

tommcdo
quelle
4
Das einzige Problem ist, dass Sie nicht vorhersehen, dass Sie später rückgängig machen werden (andernfalls werden Sie es gar nicht erst tun). So kommt es normalerweise zu einer Situation, in der Sie sich gewünscht haben , sie verwendet zu haben <C-G>u, was bereits zu spät ist.
Shahbaz
4
Ja. Eigentlich ist etwas, was ich selbst vermisst habe, dies. Manchmal mache ich das, igefolgt von einem langen Satz, gefolgt von einer Rücktaste, um einen Teil von dem zu entfernen, was ich geschrieben habe (alles im Einfügemodus). Dann wird mir klar, dass ich nicht zurücktreten sollte und was ich geschrieben hatte, war in Ordnung. Ich mache rückgängig, aber dann wird der gesamte eingefügte Text rückgängig gemacht. Entweder bleibt mir weder der lange Satz noch der Teil, der nicht zurückgesetzt ist. Es ist unmöglich, den zurückgesetzten Teil zurückzubekommen. Gibt es eine Möglichkeit, vim anzuweisen, die Rückgängig-Sequenz auf der Rücktaste zu unterbrechen? (Jetzt, wo ich es sage, mapist die Rücktaste natürlich eine Option).
Shahbaz
2
Für zukünftige Besucher habe ich außerdem hinzugefügt inoremap <CR> <C-G>u<CR>, dass jedes Rückgängigmachen in einer einzelnen Zeile enthalten ist (nicht mehr das Rückgängigmachen des gesamten Absatzes, den Sie ohne Unterbrechung eingegeben haben).
Shahbaz
1
@ Shahbaz, absolut :)
tommcdo
1
@ Shahbaz "Darf ich kopieren?" Siehe Link am Ende der Seite: "Benutzerbeiträge lizenziert unter cc by-sa 3.0 mit Namensnennung erforderlich"