Wie kann ich den VIM-Verlauf aussetzen?

8

Wenn wir eine Datei bearbeiten, machen wir normalerweise viele UNDO hintereinander, beispielsweise 20 Mal. In VIM wird dies normalerweise durch u20-maliges Drücken ausgeführt , wodurch VIM in den 20 Positionen des Verlaufsstapels "nach oben" geht. Wenn Sie dann eine bestimmte Option festlegen change, gehen alle letzten 20 Verlaufsbefehle verloren und werden durch ersetzt change. Ich würde das gerne machen, changeohne diese 20 Positionen zu verlieren. Ich möchte VIM also anweisen, die Aufzeichnung des Verlaufs zu beenden, bevor ich dies tue change, und den Verlauf danach fortzusetzen (nicht changein den Verlauf aufnehmen wollen ).

BEARBEITEN Um klarer zu sein: Ich habe eine Funktion FF, die die letzten Zeilen einer Datei aktualisiert, wenn der Puffer geschrieben wird. Wenn ich also spiele 20 undos + write, writeöffnet der letzte einen neuen Rückgängig-Zweig. Ich habe versucht, undojoininnen hinzuzufügen FF( ich habe versucht , einem Vorschlag von jlmg unten zu folgen), aber eine Sequenz Schreiben-Rückgängig-Schreiben gibt einen Fehler: Rückgängig machen nach Rückgängig nicht erlaubt . Ich könnte stattdessen einige tun, sed ....nachdem ich gegangen vimbin, aber da ich dies durch verwende, SSHbevorzuge ich eine Nur-Vim-Lösung (einen Befehl ausführen, nachdem der Puffer entladen wurde, wird nicht in die Datei geschrieben).

BEARBEITEN 2 Versuchen Sie dies in VIM: Öffnen Sie eine leere Datei und gehen Sie wie folgt vor:

i1<ESC>:wa2<ESC>:wa3<ESC>:wa4<ESC>uu:w

Wenn Sie jetzt eine machen <CTRL>R, schreibt VIM die '3' zurück, je weiter <CTRL>RSie die bekommen 4. Dies geschieht AUCH, wenn Sie :wnach jedem eine machen <CTRL>R. Wenn Sie jedoch jedes Mal, wenn Sie eine Funktion :wausführen, eine Funktion ausführen BufWritePre, <CTRL>Rwird die Funktion nicht 3zurückgeschrieben. Und das ist, was ich tun möchte, deshalb habe ich geschrieben, um "Hisotry auszusetzen", aber vielleicht ist das, was ich frage, nicht möglich, außer mit der vollen Arbeit zu arbeiten undotree().

Luis A. Florit
quelle
1
Diese Frage ist ein Thema für diese Site. Da es sich jedoch um eine ziemlich esoterische potenzielle Funktion von VIM handelt, haben Sie darüber nachgedacht, stattdessen vim.stackexchange.com zu versuchen? Ich meine, ich weiß , UNIX und ich weiß vi, aber für mich viist Undo Befehl rückgängig macht einmal, und dann , wenn Sie die Taste uwieder rückgängig macht es den Rückgängig ( ‚Redo‘). Das ist echt vi. Daher kennen ich und andere Benutzer dieser Website möglicherweise die Antwort auf Ihre Frage nicht.
Celada
2
@ Celada Ich glaube, es ist vi.stackexchange.com oder Vi und Vim .
Satō Katsura
@SatoKatsura du hast absolut recht!
Celada
1
@ Celada: Ich wusste nicht vim.se, das hätte ich versucht. Wie auch immer, Sato scheint zu helfen.
Luis A. Florit
Das Problem, das Sie "Alle diese letzten 20 Verlaufsbefehle sind verloren" geben, wird durch das Vorhandensein der Rückgängig-Zweige behoben. Daher ist es verwirrend, dass Sie Ihr Problem beheben möchten, indem Sie deren Erstellung vermeiden. Sie sagen, Sie können das gewünschte Ergebnis sederzielen, aber sed kann Ihre Rückgängigmachungen nicht ausführen. Wie wird das funktionieren? Wenn Sie in der Lage wären, den Verlauf auszusetzen, welches Verhalten würden Sie von vim erwarten, wenn Sie anschließend ein Rückgängigmachen durchführen? Das einzige Verhalten, das ich mir vorstellen konnte, war, diese Änderungen (zusammen mit den Rückgängigmachungen) in einem Rückgängig-Block zu gruppieren, daher meine Antwort. Aber wenn das nicht so ist, was ist es dann?
JoL

Antworten:

12

Sie müssen den Vim-Verlauf nicht aussetzen. Die tatsächlichen Daten bilden einen Baum, den Sie mit der undotree()Funktion abrufen können. Es gibt natürlich eine Reihe von Plugins, die daraus etwas benutzerfreundlicheres machen , z . B. gundo , mundo und undotree . Wenn Sie auch die Undo-Persistenz aktivieren (vgl. :h undo-persistence), Können Sie einfach durch den gesamten Änderungsverlauf einer Datei navigieren.

Satō Katsura
quelle
Interessant, ich wusste nicht, dass das Rückgängigmachen tatsächlich ein Baum ist. In meinem Fall möchte ich nur einmal zurückkehren, dh zum vorherigen Rückgängig-Zweig. Weißt du wie das geht? Es scheint undotree()sollte helfen?
Luis A. Florit
Eigentlich möchte ich in diesem speziellen Fall, der meine Frage motiviert hat, dass er changeweder irgendwo historynoch im undoBaum erscheint. Deshalb war meine Frage "Geschichte aussetzen".
Luis A. Florit
@ LuisA.Florit: Der schnelle und einfache Weg, dies zu tun, ist mit :earlier, das eine Zeiteinheit akzeptiert und bei Bedarf Verzweigungen rückgängig :earlier 1hmacht (z. B. lässt der Puffer so aussehen, wie er vor einer Stunde war). Wenn Sie keine Zeiteinheit verwenden können (weil die Änderungen zu nahe beieinander lagen?), Müssen Sie g-den Rückgängig-Baum einige Schritte nacheinander durchlaufen.
Kevin
0

Wenn ich Sie richtig verstehe, möchten Sie, dass nach dem Rückgängigmachen das changeund die 20 Rückgängigmachungen rückgängig gemacht werden.

Wenn vim eine Funktion oder einen Befehl ausführt, werden alle Aktionen, die es ausführt, zusammen rückgängig gemacht. Ich bin nicht sicher, ob diese Aktionen Rückgängigmachungen beinhalten können. Vielleicht kann dieser Teil der Dokumentation helfen:

3. Undo blocks                      *undo-blocks*

One undo command normally undoes a typed command, no matter how many changes
that command makes.  This sequence of undo-able changes forms an undo block.
Thus if the typed key(s) call a function, all the commands in the function are
undone together.

If you want to write a function or script that doesn't create a new undoable
change but joins in with the previous change use this command:

                        *:undoj* *:undojoin* *E790*
:undoj[oin]     Join further changes with the previous undo block.
            Warning: Use with care, it may prevent the user from
            properly undoing changes.  Don't use this after undo
            or redo.
            {not in Vi}

This is most useful when you need to prompt the user halfway through a change.
For example in a function that calls |getchar()|.  Do make sure that there was
a related change before this that you must join with.

This doesn't work by itself, because the next key press will start a new
change again.  But you can do something like this: >

    :undojoin | delete

After this an "u" command will undo the delete command and the previous
change.

To do the opposite, break a change into two undo blocks, in Insert mode use
CTRL-G u.  This is useful if you want an insert command to be undoable in
parts.  E.g., for each sentence.  |i_CTRL-G_u|
Setting the value of 'undolevels' also breaks undo.  Even when the new value
is equal to the old value.

Leider habe ich versucht, zu verwenden :undo 2 | undojoin | normal ohi, aber ich habe die Fehlermeldung erhalten E790: undojoin is not allowed after undo.

Wenn die Aktionen jedoch in einer Funktion wie der folgenden ausgeführt werden:

function F()
  undo 2
  normal ohi
endfunction

Wenn Sie es dann mit aufrufen :call F(), wird die undound eine andere Aktion in einem Rückgängig-Block ausgeführt. Beachten Sie, dass Sie einen neuen Rückgängig-Zweig erstellen, da Sie Rückgängig verwenden. Nachdem dies erledigt ist, können Sie den normalen Modus-Befehl verwenden g-, um rückgängig zu machen F(). Verwenden uwird wie :undo 3am Anfang getan haben .

JoL
quelle
Ich bin mir nicht sicher, ob dies funktioniert ... Ich möchte, dass undoalles, was Sie in Ihrer Funktion tun , nach einigen Schritten keinen F()neuen Rückgängig-Zweig öffnet. In meinem Fall F()wird jedes Mal ausgeführt, wenn ich undodie Datei schreibe. Wenn ich die Datei schreibe, F()wird ein neuer Rückgängig-Zweig geöffnet. Ich habe es undojoinam Anfang mit versucht F(), aber eine Sequenz Schreiben-Rückgängig-Schreiben gibt einen Fehler : undojoint not allowed after undo.
Luis A. Florit
Meine Frage wurde aktualisiert und versucht, klarer zu werden.
Luis A. Florit
@ LuisA.Florit Ich schrieb in die Antwort, :undojoindie nicht für das funktionierte, was Sie wollten, und erwähnte den gleichen Fehler, und ich schlug zu :undojoinBeginn nicht vor, sie zu verwenden F(). F()soll tun, was :undojoinnicht konnte, nämlich die Undos und andere Befehle in einem Undo-Block zu verbinden.
JoL
@ LuisA.Florit Du sagst, du willst vermeiden, einen Rückgängig-Zweig zu erstellen, aber ich kann den Grund nicht finden, warum du das willst. Ich dachte, der Punkt Ihrer Frage war, die Befehle und die mehreren Rückgängigmachungen auf einmal rückgängig machen zu können. Wenn ich zurückblicke, frage ich mich, ob es Ihr Ziel war, die Änderungen, die Sie rückgängig gemacht haben, nicht zu verlieren. Wenn dies der Fall ist, ist die Existenz des Rückgängig-Baums genau das, was Sie wollen. Sie können mit g-und navigieren g+.
JoL
Ja, es scheint, dass der Rückgängig-Baum das ist, was ich brauche.
Luis A. Florit