Kann ich ein Makro mit dem Punktoperator wiederholen?


15

Kann ich mit dem .Befehl ein Makro wiederholen ? Zum Beispiel möchte ich Folgendes eingeben können:

@q...

und lassen Sie es effektiv @q4 mal anrufen . Mit dem Standardverhalten, das funktioniert nur , wenn ‚q‘ hält einen einzigen Befehl, zum Beispiel dw, xoder iHello<esc>. (Dies ist jedoch sinnvoll, da '.' Die letzte Änderung wiederholt , nicht die letzten Tastenanschläge / Befehle)

Ich würde diese Arbeit auch gerne mit Zählungen haben. Beispiel: Geben Sie Folgendes ein:

3@q.

wäre effektiv das gleiche wie @q6 mal laufen . Wie kann ich dieses Verhalten konfigurieren?


1
Nicht genau das, wonach Sie fragen, aber vielleicht ist es hilfreich, github.com/wincent/replay . Dies zeichnet zuletzt aufgenommenes Makro auf und spielt es beim Drücken vonEnter
grodzik

Zu Ihrer Information, @@wiederholt das letzte Makro. Wenn Sie dies also wegen Zuordnungen und dergleichen fragen, sollte es für Sie funktionieren.
Shahbaz

Antworten:


7

Probieren Sie es aus. Es wird neu zugeordnet, @so dass g@(plus eine Dummy-Bewegung l) danach verwendet wird, wodurch der letzte Operator wird und mit wiederholt werden muss ..

" When . repeats g@, repeat the last macro.
fun! AtRepeat(_)
    " If no count is supplied use the one saved in s:atcount.
    " Otherwise save the new count in s:atcount, so it will be
    " applied to repeats.
    let s:atcount = v:count ? v:count : s:atcount
    " feedkeys() rather than :normal allows finishing in Insert
    " mode, should the macro do that. @@ is remapped, so 'opfunc'
    " will be correct, even if the macro changes it.
    call feedkeys(s:atcount.'@@')
endfun

fun! AtSetRepeat(_)
    set opfunc=AtRepeat
endfun

" Called by g@ being invoked directly for the first time. Sets
" 'opfunc' ready for repeats with . by calling AtSetRepeat().
fun! AtInit()
    " Make sure setting 'opfunc' happens here, after initial playback
    " of the macro recording, in case 'opfunc' is set there.
    set opfunc=AtSetRepeat
    return 'g@l'
endfun

" Enable calling a function within the mapping for @
nno <expr> <plug>@init AtInit()
" A macro could, albeit unusually, end in Insert mode.
ino <expr> <plug>@init "\<c-o>".AtInit()

fun! AtReg()
    let s:atcount = v:count1
    let c = nr2char(getchar())
    return '@'.c."\<plug>@init"
endfun

nmap <expr> @ AtReg()

Ich habe versucht, so viele Eckfälle zu behandeln, wie ich mir vorstellen kann. Sie können wiederholen @:mit .. Zählt zu @oder .wird für nachfolgende Pressen von beibehalten ..

Das ist schwierig und ich bin nicht davon überzeugt, dass irgendwo auf dem Weg etwas nicht kaputt geht. Also keine Garantien, Gewährleistungen oder Versprechen mit diesem.

Persönlich bin ich in Ordnung, wenn ich einen Unterschied zwischen den feinkörnigen Wiederholungen .der letzten Änderung und den Makro-Wiederholungen von habe @@.

BEARBEITEN

Nachdem ich so weit gegangen war, dachte ich mir, dass ich auch zusätzlichen Code hinzufügen könnte, der es ermöglicht, .unmittelbar nach der Aufnahme eines Makros zu drücken , um es wiederzugeben.

fun! QRepeat(_)
    call feedkeys('@'.s:qreg)
endfun

fun! QSetRepeat(_)
    set opfunc=QRepeat
endfun

fun! QStop()
    set opfunc=QSetRepeat
    return 'g@l'
endfun

nno <expr> <plug>qstop QStop()
ino <expr> <plug>qstop "\<c-o>".QStop()

let s:qrec = 0
fun! QStart()
    if s:qrec == 1
        let s:qrec = 0
        return "q\<plug>qstop"
    endif
    let s:qreg = nr2char(getchar())
    if s:qreg =~# '[0-9a-zA-Z"]'
        let s:qrec = 1
    endif
    return 'q'.s:qreg
endfun

nmap <expr> q QStart()

Das funktioniert fantastisch! Seit ich diese Frage gestellt habe, hat sich mein Workflow geändert, sodass ich Makros nicht mehr mit Punkt wiederholen möchte. Dies funktioniert jedoch sehr gut, so dass ich es trotzdem akzeptieren werde (obwohl ich es wahrscheinlich nicht zu meinem hinzufügen werde .vimrc)
James

Keine Sorge, trotzdem interessantes Problem!
Antony

1
Bearbeiten: Ermöglicht die Wiedergabe eines Makros .unmittelbar nach der Aufnahme.
Antony

Ich denke, \<plug>qstopsollte vorher qin der QStart-Funktion sein
Steve Vermeulen

6

Um es zu wiederholen Ihre letzte Makro können Sie verwenden , @@so 3@@würde im Wesentlichen laufen @q 3 mal. Die @ -Tastenanschläge können jedoch unhandlich sein, daher habe ich in meiner .vimrc die Zeilen:

  "- Lazy macro repeat
  nmap <leader>m @@

Dadurch kann ich meine Führungstaste (,) plus m verwenden, um das letzte Makro auszuführen. Dann können Sie eine Zahl voranstellen, um das Makro zu wiederholen.

Jetzt 3,mist gleichbedeutend mit 3@@. Gleiche Gesamttasten und keine Notwendigkeit, die Umschalttaste zu halten.

EDIT : Als ich das überdachte, kam ich auf ein neues Makro. nmap <leader>. @@ Dies funktioniert auch, wenn eine Zahl vorangestellt 3,.ist. 3@@Ich würde diese Arbeit gerne sehen, damit ich einen Makrobuchstaben übergeben und dieses Makro anstelle des letzten Makros wiederholen kann.


Das OP möchte 6 Mal 3@q.laufen @q. Das macht das nicht.
user41805

Ich bin mir nicht sicher, ob dies Ihre Frage beantwortet, wenn ich Ihre Frage erneut lese. Können Sie ein Beispiel geben, wann Sie verwenden würden 3@q.? Es scheint, Sie könnten es genauso gut mit einer Zählung voranstellen. Ich neige dazu, eine Suche vor dem Beginn eines Makros festzulegen und dann nim Makro zum Anfang zu springen, wo es wiedergegeben werden kann.
Shadoath

5

Sie können die Verwendung eines Makros in einem anderen Makro aufzeichnen und wiederholen.

qqdwq
qr2@qq

Jetzt 3@rist wie @qsechs Mal laufen .


1

Standardmäßig ist spacein vim "1 Zeichen nach rechts verschieben", was bereits abgedeckt list. Daher habe ich den Speicherplatz neu zugeordnet, um ein Makro aus dem q-Puffer erneut auszuführen:

noremap <Space> @q

Um es zu verwenden, nehmen Sie einfach zuerst ein Makro mit auf qq, beenden Sie die Aufnahme mit qund spacedrücken Sie dann, um es wiederzugeben.


Zu Ihrer Information, aus dem Grund, den Sie angeben (es ist kein erforderlicher Schlüssel), verwenden viele Leute Speicherplatz als ihren Hauptschlüssel, so dass möglicherweise nicht so viele Personen frei sind, wie Sie denken. :)
B-Schicht

0

Da ich keine ,einfache, einfach zu tippende Lösung verwende und mag, funktioniert dies für mich:

:map , @@
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.