Bisakah saya mengulang makro dengan "operator titik"?


15

Bisakah saya mengulang makro dengan .perintah? Misalnya, saya ingin dapat mengetik:

@q...

dan memilikinya secara efektif memanggil @q4 kali. Dengan perilaku default, ini bekerja hanya jika 'q' memegang perintah tunggal, misalnya dw, xatau iHello<esc>. (Ini masuk akal, karena '.' Mengulangi perubahan terakhir , bukan penekanan tombol / perintah terakhir)

Saya juga senang memiliki pekerjaan ini dengan jumlah. Misalnya, mengetik:

3@q.

akan sama efektifnya dengan menjalankan @q6 kali. Bagaimana saya bisa mengkonfigurasi perilaku ini?


1
Bukan apa yang Anda minta, tapi mungkin itu akan membantu github.com/wincent/replay . Catatan-catatan ini merekam makro terakhir dan memainkannya kembali dengan menekanEnter
grodzik

FYI, @@ulangi makro terakhir, jadi jika Anda menanyakan ini demi pemetaan dan semacamnya, itu akan bekerja untuk Anda.
Shahbaz

Jawaban:


7

Cobalah ini. Memetakan kembali @sehingga g@(ditambah gerakan boneka l) digunakan setelahnya, sehingga menjadi operator terakhir dan dapat diulangi ..

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

Saya sudah mencoba untuk menangani banyak kasus sudut yang saya bisa pikirkan. Anda bisa mengulanginya @:dengan .. Hitungan ke @atau .dipertahankan untuk pers berikutnya ..

Ini rumit, dan saya tidak yakin bahwa sesuatu tidak akan pecah di suatu tempat di sepanjang jalan. Jadi tidak ada jaminan, garansi, atau janji dengan yang satu ini.

Secara pribadi, saya baik-baik saja memiliki perbedaan antara pengulangan berbutir halus .untuk perubahan terakhir, dan pengulangan makro @@.

EDIT

Saya pikir, setelah sejauh ini, saya mungkin juga menambahkan beberapa kode tambahan yang akan memungkinkan menekan .segera setelah merekam makro untuk memutarnya kembali.

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

Ini bekerja fantastis! Sejak memposting pertanyaan ini, alur kerja saya telah berubah, jadi saya tidak benar-benar ingin dapat mengulangi makro dengan titik lagi. Namun, ini bekerja dengan sangat baik, jadi saya tetap akan menerimanya (walaupun saya mungkin tidak akan menambahkannya ke saya .vimrc)
James

Jangan khawatir, masalah menarik!
Antony

1
Sunting: memungkinkan pemutaran makro dengan .segera setelah perekaman.
Antony

Saya pikir \<plug>qstopseharusnya sebelum qdalam fungsi QStart
Steve Vermeulen

6

Untuk mengulang makro terakhir Anda Anda dapat menggunakan @@sehingga 3@@pada dasarnya akan menjalankan @q 3 kali. Namun, keystrokes @ dapat menjadi sulit, jadi di .vimrc saya, saya memiliki baris:

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

Ini memungkinkan saya untuk menggunakan kunci pemimpin saya (,) plus m untuk menjalankan makro terakhir. Kemudian Anda bisa mengawali ini dengan angka untuk mengulang makro.

Sekarang 3,msetara dengan 3@@. Total kunci yang sama dan tidak perlu menahan shift.

EDIT : Setelah memikirkan kembali ini saya datang dengan makro baru. nmap <leader>. @@ Ini juga berfungsi ketika didahului oleh angka jadi 3,.sekarang 3@@Senang melihat karya ini sehingga saya bisa mengirimkan surat makro dan mengulangi makro bukannya makro terakhir.


OP ingin 3@q.menjalankan @q6 kali. Ini tidak melakukan itu.
user41805

Membaca ulang pertanyaan Anda, saya tidak yakin ini menjawabnya. Bisakah Anda memberi contoh kapan Anda akan menggunakannya 3@q.? Tampaknya Anda mungkin hanya menambahkannya dengan hitungan. Saya cenderung mengatur pencarian sebelum memulai makro kemudian gunakan ndi makro untuk melompat ke awal di mana ia dapat diputar ulang.
Shadoath

5

Anda bisa merekam penggunaan makro di makro lain, dan ulangi itu.

qqdwq
qr2@qq

Sekarang 3@rseperti berlari @qenam kali.


1

Secara default spacedi vim adalah "move right 1 karakter" yang sudah dicakup oleh l, jadi saya telah memetakan ulang ruang untuk menjalankan kembali makro dari buffer q:

noremap <Space> @q

Untuk menggunakan, cukup rekam makro dengan yang qqpertama, hentikan perekaman dengan qdan kemudian tekan spaceuntuk memutar ulang.


FYI, untuk alasan Anda menyatakan (itu bukan kunci yang diperlukan) banyak orang menggunakan ruang sebagai kunci pemimpin mereka sehingga mungkin tidak ada banyak orang dengan itu gratis seperti yang Anda pikirkan. :)
B Layer

0

Karena saya tidak menggunakan ,dan menyukai solusi sederhana yang mudah diketik, ini berfungsi untuk saya:

:map , @@
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.