Gibt es eine Möglichkeit zu erkennen, ob ich in Vimscript aufnehme?

11

Gibt es so etwas

eval("is_recording()")

dass ich mein Vimscript aufrufen kann, um herauszufinden, ob ich gerade ein Makro aufzeichne? Ich hätte gedacht, dass das funktioniert:

eval("mode(1)")

aber das kehrt gerade zurück "n".

Ich bin mir nicht sicher, ob es wichtig ist, aber ich verwende Neovim. Wenn es also exklusiv für Neovim ist, ist das in Ordnung.

James
quelle
3
IMHO wäre es eine schlechte Idee - "Aufnahme" würde in diesem Fall zu einem falschen Namen werden :) Ich weiß nicht, was Sie versuchen, aber vielleicht könnte das Stellen dieser Frage verschiedene Möglichkeiten bieten, es zu lösen.
VanLaser
@ VanLaser Was meinst du mit falschem Namen?
James
1
Wenn eine Vim-Aktion während der Aufnahme anders ist, bedeutet dies, dass der Aufnahmevorgang selbst die Aktion beeinflusst, wenn sie nur zur späteren Wiederholung "gespeichert" werden soll. Was erwarten Sie, wenn Sie das Makro ausführen?
VanLaser

Antworten:

4

Erstens denke ich, dass Ihr Problem hauptsächlich ein XY-Problem ist . Sie sollten uns am Ende mehr Informationen darüber geben, was Sie versuchen, und ich denke, wir könnten eine andere Lösung finden.

Hier ist eine Problemumgehung. Sie ist wahrscheinlich nicht ideal und sicherlich nicht sehr robust, aber Sie können diese Zeilen zu Ihrer hinzufügen .vimrc:

let g:isRecording = 0
nnoremap Q :call ToggleRecording()<CR>q

function! ToggleRecording()
    let g:isRecording = !g:isRecording
    echo "is recording " . g:isRecording
endfunction

Die Idee ist, dass der "Aufnahmemodus" ausschließlich umgeschaltet wird, wenn Sie qim normalen Modus drücken .

Basierend darauf erstellen Sie eine Variable, g:isRecordingdie jedes Mal umgeschaltet wird, wenn Sie eine Aufnahme starten oder stoppen. Auf diese Weise wird beim Starten der Aufnahme g:isRecordingauf 1und auf 0das Beenden der Aufnahme eingestellt. Sie können dann über den Wert der Variablen auf den Aufzeichnungsstatus zugreifen.

Der "Nachteil" ist, dass Sie, um eine rekursive Zuordnung zu vermeiden, Shit-q stattdessen die Aufnahme starten und stoppen müssen q. (Beachten Sie, dass dies kein so großes Problem ist: Ich habe den shift-qAufnahmemodus seit einiger Zeit umgeschaltet, weil mir das ursprüngliche shift-qVerhalten nicht gefällt. )

Das Hauptproblem dieser Lösung besteht darin, dass qdie Variable nicht umgeschaltet wird, wenn Sie sie vergessen und verwendet haben. Sie können sie jedoch nicht deaktivieren q(z. B. mit nnoremap q <nop>), da dies sonst shift-qnicht mehr funktioniert.

statox
quelle
2

Dies ist eine ziemlich merkwürdige Anfrage, da es keinen "Modus" zum Aufzeichnen eines Makros gibt. Nachdem ich einige Dokumente durchgesehen hatte, fand ich Folgendes inusr_10

Sie beginnen mit dem ersten Zeichen der ersten Zeile. Als nächstes führen Sie die folgenden Befehle aus:

qa Starten Sie die Aufzeichnung eines Makros in Register a .

^ Gehen Sie zum Zeilenanfang.

i # füge am Anfang der Zeile "String #include einfügen" ein.

$ Gehen Sie zum Ende der Zeile.

a "Fügen Sie das doppelte Anführungszeichen (") am Zeilenende hinzu.

j Gehen Sie zur nächsten Zeile.

q Beenden Sie die Aufzeichnung des Makros.

Das Besondere für mich war die Zeile "Starten Sie die Aufnahme eines Makros in Register a".

Da jedes Makro standardmäßig in einem Register gespeichert wird, hatte ich gehofft, dass wir es in der :regListe sehen können. Es stellt sich heraus, dass es wie ein Zauber wirkt!

Beispiel:

Im normalen Modus: qaisomething<Esc>

und drinnen sehen :regwir den Eintrag!

"a   isomething^[

Mit diesem Wissen sollten Sie in der Lage sein, die Register "auszuspionieren", um zu bestätigen, dass ein Makro aufgezeichnet wird (verwenden Sie bei jeder Aufzeichnung ein benanntes Register [Karte, qum immer dasselbe Register zu verwenden (oder so ähnlich)]

Wenn Sie auf Probleme stoßen, lassen Sie es mich wissen und ich werde versuchen, Ihnen zu helfen (da diese Funktionalität auch für mich neu ist: D)

Bearbeiten Um das Problem zu lösen, dass ein Register während des Ruckens verwendet wird, würde ich empfehlen, einen speziellen Registertyp zu untersuchen, den Sie nur für das vimLSchreiben verwenden können (kein Ruck würde jemals im Register beschäftigt sein ( "ay)).

Hier einige Informationen :help registerszu den verfügbaren Registern

Es gibt zehn Arten von Registern: Register E354

  1. Das unbenannte Register ""

  2. 10 nummerierte Register "0 bis" 9

  3. Das kleine Löschregister "-

  4. 26 benannte Register "a bis" z oder "A bis" Z.

  5. drei schreibgeschützte Register ":,"., "%

  6. alternatives Pufferregister "#

  7. das Ausdrucksregister "=

  8. Die Auswahl- und Ablage-Register "*," + und "~"

  9. Das Schwarze Loch Register "_

  10. Letztes Suchmusterregister "/

Angenommen, Sie haben ein Register, das Sie jetzt verwenden werden, lautet das Problem "Woher weiß ich, wann die Aufzeichnung gestoppt wurde?". Zur Pflege dieser ich einen Blick auf die nehmen würde autocmd-eventfür CursorHold; Der Hinweis in den Hilfedokumenten sieht ziemlich vielversprechend aus (ich würde versuchen herauszufinden, wie ich den normalen cursorHold von dem inaktiven / nicht vorhandenen Ereignis unterscheiden kann, das auftritt, wenn Ihr Register für die Zwecke des Makros geschrieben wird).

CursorHold

Wenn der Benutzer für die mit 'updatetime' angegebene Zeit keine Taste drückt. Wird nicht erneut ausgelöst, bis der Benutzer eine Taste gedrückt hat (dh nicht alle 'Aktualisierungszeit' ms ausgelöst, wenn Sie Vim verlassen, um Kaffee zu kochen. :) Siehe | CursorHold-Beispiel | zur Vorschau von Tags. Dieses Ereignis wird nur im Normalmodus ausgelöst. Es wird nicht ausgelöst, wenn auf die Eingabe eines Befehlsarguments oder einer Bewegung nach einem Operator gewartet wird. Während der Aufzeichnung wird das CursorHold-Ereignis nicht ausgelöst. | q |

Dan Bradbury
quelle
Ich sehe nicht wirklich, wie es das Problem löst: Wenn Sie mit dem Aufzeichnen Ihres Makros fertig sind, wird eine Zeichenfolge im Register gespeichert, aber wie unterscheiden Sie, wenn das Register ein Makro enthält oder wenn es beispielsweise etwas enthält, das von einem Yank-Befehl stammt? Außerdem wird das Register als eine Aufnahme gespeichert, wenn Sie die Aufnahme beenden. Wenn Sie also feststellen, dass sich der Inhalt des Registers geändert hat, befinden Sie sich nicht mehr im Aufnahmemodus.
Statox
Meine Hoffnung war, dass Sie so etwas wie das Blackhole-Register verwenden können (ein Register, an das niemals gerissen wird). Wenn Sie dieses Register gesperrt haben, können Sie CursorHold auschecken, das im Aufnahmemodus ein besonderes Verhalten aufweist (aktualisiert meine Antwort mit weiteren Informationen, um zu sehen, ob dies Ihnen hilft)
Dan Bradbury
Es wurden einige Informationen zu den anderen Registern hinzugefügt (um Konflikte mit dem Ruck zu vermeiden) und ein Hinweis darauf, wie wir möglicherweise die "Aufnahme" abfangen können, wenn CursorHold während der Makroaufnahme nicht aktiv ist. Wenn Sie nach diesen Notizen immer noch dagegen ankämpfen, lassen Sie es mich wissen und ich kann versuchen, es nach Beendigung der Arbeit umzusetzen. Als Hinweis blackhole registerwurde das nur als Hinweis und interessanter vim-Leckerbissen erwähnt, der zu etwas führen könnte (es wäre nicht nützlich, wenn Makros aufgezeichnet werden; da @_ nicht verwendbar ist.). Tatsächlich können Sie nicht einmal versuchen, das Makro zu speichern dazu ..
Dan Bradbury
Ich habe einige Zeit an diesem letzten Abend verbracht (Post Beer Keyboard Smashing) und fand es unglaublich schwierig, genau herauszufinden, wann die Aufnahme stattfindet und endet. Meine Vermutung CursorHoldscheint aufgrund der Verzögerung des CursorHold tatsächlichen Geschehens ein unmöglicher Traum zu sein (machte jedes Mal ein einfaches globales Inkrement, um dies zu beobachten). Immer noch unglaublich interessiert daran, einen Weg zu finden, dies zu tun, und werde mein Gesicht weiter gegen die Schlüssel schlagen, bis wir eine Lösung haben.
Dan Bradbury
Meiner Meinung nach haben Sie nicht tausend verschiedene Optionen: Sie müssen das Verhalten von überschreiben qund eine Variable umschalten und die Aufnahme starten / stoppen. Ein Autocomand kann hier nicht zuverlässig sein, da bei einem Tastendruck kein Autocmd ausgelöst wird und es aufgrund der Monothread-Natur von Vim nicht möglich ist, eine Abfragefunktion durchzuführen. Viel Glück bei Ihren zukünftigen Experimenten :-)
statox