Czy mogę powtórzyć makro za pomocą „operatora kropki”?

15

Czy mogę powtórzyć makro za pomocą .polecenia? Na przykład chciałbym móc pisać:

@q...

i niech zadzwoni @q4 razy. Z domyślnym zachowaniem, to działa tylko wtedy, „q” posiada jednego polecenia, na przykład dw, xalbo iHello<esc>. (Ma to jednak sens, ponieważ „.” Powtarza ostatnią zmianę , a nie ostatnie naciśnięcia klawiszy / polecenie)

Chciałbym też mieć tę pracę z hrabią. Na przykład wpisując:

3@q.

będzie efektywnie taki sam, jak bieganie @q6 razy. Jak mogę skonfigurować to zachowanie?

James
źródło
1
Nie do końca to, o co prosisz, ale może będzie pomocne github.com/wincent/replay . Zapisuje ostatnio zarejestrowane makro i odtwarza je po naciśnięciuEnter
grodzik
FYI, @@powtarza ostatnie makro, więc jeśli pytasz o to ze względu na mapowania i takie, powinno to działać dla ciebie.
Shahbaz

Odpowiedzi:

7

Spróbuj. Ponownie odwzorowuje, @tak że g@(plus ruch pozorowany l) jest następnie używany, stając się tym samym ostatnim operatorem i podlega powtórzeniu z ..

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

Próbowałem poradzić sobie z tyloma przypadkami narożnymi, ile tylko mogę sobie wyobrazić. Możesz powtórzyć za @:pomocą .. Liczy się do @lub .są zachowywane dla kolejnych pras ..

Jest to trudne i nie jestem przekonany, że coś gdzieś po drodze nie pęknie. W związku z tym nie ma żadnych gwarancji, gwarancji ani obietnic.

Osobiście nie mam nic przeciwko różnicy między drobnoziarnistymi powtórzeniami .ostatniej zmiany a makrami powtórzeń @@.

EDYTOWAĆ

Doszedłem do wniosku, że zaszedłem tak daleko, że równie dobrze mogę dodać dodatkowy kod, który pozwoli na naciśnięcie .natychmiast po nagraniu makra, aby go odtworzyć.

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()
Antony
źródło
Działa to fantastycznie! Od czasu opublikowania tego pytania mój przepływ pracy zmienił się, więc tak naprawdę nie chcę już więcej powtarzać makr z kropką. Działa to jednak bardzo dobrze, więc i tak to zaakceptuję (choć prawdopodobnie nie dodam tego do mojego .vimrc)
James
Bez obaw, niezależnie od interesującego problemu!
Antony
1
Edycja: pozwala na odtwarzanie makra .natychmiast po nagraniu.
Antony
Myślę, że \<plug>qstoppowinno być wcześniej qw funkcji QStart
Steve Vermeulen,
6

Aby powtórzyć ostatnią makra można użyć @@tak 3@@będzie w istocie uruchomić @q 3 razy. Jednak naciśnięcia klawiszy @ mogą być nieporęczne, więc w moim .vimrc mam linie:

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

To pozwala mi użyć mojego klucza wiodącego (,) plus m do uruchomienia ostatniego makra. Następnie możesz poprzedzić to liczbą, aby powtórzyć makro.

Teraz 3,mjest odpowiednikiem 3@@. Te same klucze i nie trzeba przytrzymywać klawisza Shift.

EDYCJA : Po przemyśleniu tego wymyśliłem nowe makro. nmap <leader>. @@ Działa to również wtedy, gdy poprzedza je liczba, więc 3,.teraz 3@@chciałbym zobaczyć tę pracę, abym mógł przekazać literę makra i powtórzyć to makro zamiast ostatniego makra.

Shadoath
źródło
OP chce 3@q.uruchomić @q6 razy. To nie robi tego.
user41805
Ponownie czytając twoje pytanie, nie jestem pewien, czy to odpowiada. Czy możesz podać przykład, kiedy chcesz użyć 3@q.? Wygląda na to, że równie dobrze możesz po prostu uzupełnić go rachunkiem. Zwykle ustawiam wyszukiwanie przed rozpoczęciem makra, a następnie używam ngo, aby przejść do miejsca, w którym można go odtworzyć.
Shadoath
5

Możesz zarejestrować użycie makra w innym makrze i powtórzyć to.

qqdwq
qr2@qq

Teraz 3@rjest jak bieganie @qsześć razy.

jjaderberg
źródło
1

Domyślnie spacew vimie jest „przesuń w prawo o 1 znak”, który jest już objęty l, więc zmieniłem mapowanie miejsca, aby ponownie uruchomić makro z bufora q:

noremap <Space> @q

Aby użyć, po prostu nagraj makro za pomocą qq, zatrzymaj nagrywanie za pomocą, qa następnie naciśnij, spaceaby odtworzyć.

brain_bacon
źródło
Do Twojej wiadomości, z tego powodu, że podajesz (nie jest to wymagany klucz), wiele osób używa przestrzeni jako klucza lidera, więc może nie być tak wielu ludzi z nią wolnych, jak myślisz. :)
B Layer
0

Ponieważ nie używam ,i jak proste rozwiązanie do pisania, działa to dla mnie:

:map , @@
Neil McGill
źródło