ฉันสามารถทำซ้ำแมโครด้วย“ ตัวดำเนินการ dot” ได้หรือไม่


15

ฉันสามารถทำซ้ำแมโครด้วย.คำสั่งได้หรือไม่ ตัวอย่างเช่นฉันต้องการพิมพ์:

@q...

และให้มีประสิทธิภาพการโทร@q4 ครั้ง ด้วยการทำงานเริ่มต้นนี้จะทำงานเฉพาะถ้า 'Q' ถือเป็นคำสั่งเดียวเช่นdw, หรือx iHello<esc>(สิ่งนี้สมเหตุสมผลเนื่องจาก '.' ซ้ำการเปลี่ยนแปลงครั้งสุดท้ายไม่ใช่การกดแป้น / คำสั่งสุดท้าย)

ฉันชอบที่จะมีงานนี้ด้วยการนับ ตัวอย่างเช่นการพิมพ์:

3@q.

จะมีประสิทธิภาพเช่นเดียวกับการทำงาน@q6 ครั้ง ฉันจะกำหนดค่าพฤติกรรมนี้ได้อย่างไร


1
ไม่ว่าสิ่งที่คุณกำลังถามหา แต่บางทีมันอาจจะเป็นประโยชน์github.com/wincent/replay บันทึกนี้จะบันทึกแมโครครั้งสุดท้ายและเล่นซ้ำเมื่อกดEnter
grodzik

FYI @@ทำซ้ำแมโครสุดท้ายดังนั้นหากคุณขอสิ่งนี้เพื่อประโยชน์ในการจับคู่และควรได้ผลสำหรับคุณ
Shahbaz

คำตอบ:


7

ลองดูสิ มัน remaps @เพื่อให้g@(บวกการเคลื่อนไหวหุ่นl) .ถูกนำมาใช้หลังจากนั้นจึงกลายเป็นผู้ประกอบการที่ผ่านมาและอาจมีการทำซ้ำกับ

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

ฉันพยายามที่จะจัดการกับกรณีมุมมากที่สุดเท่าที่ฉันสามารถคิด คุณสามารถทำซ้ำกับ@: .นับไป@หรือจะถูกเก็บไว้สำหรับกดที่ตามมาของ..

นี่คือเล่ห์เหลี่ยมและฉันไม่เชื่อว่าบางสิ่งบางอย่างจะไม่แตกไปตามทาง ดังนั้นจึงไม่มีการรับประกันรับประกันหรือสัญญากับสิ่งนี้

ส่วนตัวผมโอเคที่มีความแตกต่างระหว่างซ้ำเม็ดเล็กของการเปลี่ยนแปลงที่ผ่านมาและซ้ำมาโคร.@@

แก้ไข

ฉันคิดว่าได้ไปไกลขนาดนี้แล้วฉันอาจเพิ่มรหัสเพิ่มเติมที่จะอนุญาตให้กด.ทันทีหลังจากบันทึกแมโครเพื่อเล่น

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

มันใช้งานได้ยอดเยี่ยม! ตั้งแต่โพสต์คำถามนี้เวิร์กโฟลว์ของฉันเปลี่ยนไปดังนั้นฉันจึงไม่ต้องการให้แมโครทำซ้ำด้วยจุดอีกต่อไป อย่างไรก็ตามมันใช้งานได้ดีจริง ๆ ดังนั้นฉันจะยอมรับมันต่อไป (แม้ว่าฉันอาจจะไม่เพิ่มลงในของฉัน.vimrc)
James

ไม่ต้องกังวลปัญหาที่น่าสนใจไม่ว่า!
Antony

1
แก้ไข: อนุญาตให้เล่นมาโครด้วย.ทันทีหลังจากบันทึก
Antony

ฉันคิดว่า\<plug>qstopควรมาก่อนqในฟังก์ชั่น QStart
Steve Vermeulen

6

หากต้องการทำซ้ำแมโครสุดท้ายของคุณคุณสามารถใช้@@เพื่อ3@@เรียกใช้ @q 3 ครั้ง อย่างไรก็ตาม @ keystrokes สามารถเทอะทะได้ดังนั้นใน. vimrc ของฉันฉันมีบรรทัด:

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

สิ่งนี้ทำให้ฉันสามารถใช้รหัสผู้นำของฉัน (,) บวก m เพื่อเรียกใช้แมโครสุดท้าย จากนั้นคุณสามารถนำหน้าสิ่งนี้ด้วยตัวเลขเพื่อทำซ้ำแมโคร

ตอนนี้จะมีค่าเท่ากับ3,m 3@@ปุ่มกดทั้งหมดเหมือนกันและไม่จำเป็นต้องกดปุ่ม shift ค้าง

แก้ไข : เมื่อคิดใหม่นี้ฉันมากับแมโครใหม่ nmap <leader>. @@ สิ่งนี้ยังใช้งานได้เมื่อนำหน้าด้วยตัวเลขดังนั้น3,.ตอนนี้3@@จะรักที่จะเห็นงานนี้เพื่อให้ฉันสามารถส่งผ่านตัวอักษรแมโครและมีการทำซ้ำแมโครแทนแมโครสุดท้าย


OP ต้องการ3@q.รัน@q6 ครั้ง นี่ไม่ได้ทำอย่างนั้น
user41805

อ่านคำถามของคุณอีกครั้งฉันไม่แน่ใจว่าสิ่งนี้จะตอบได้ คุณสามารถยกตัวอย่างว่าคุณจะใช้เมื่อไหร่3@q.? ดูเหมือนว่าคุณอาจจะแค่เพิ่มด้วยการนับ ฉันมักจะตั้งค่าการค้นหาก่อนที่จะเริ่มแมโครจากนั้นใช้nในแมโครเพื่อข้ามไปยังจุดเริ่มต้นที่สามารถเล่นซ้ำได้
Shadoath

5

คุณสามารถบันทึกการใช้แมโครในแมโครอื่นและทำซ้ำได้

qqdwq
qr2@qq

ตอนนี้3@rก็เหมือนวิ่ง@qหกครั้ง


1

โดยค่าเริ่มต้นspaceในกลุ่มคือ "ย้ายไปทางขวา 1 ตัวอักษร" ซึ่งครอบคลุมอยู่แล้วlดังนั้นฉันจึงได้แมปพื้นที่เพื่อเรียกใช้แมโครใหม่จากบัฟเฟอร์ q:

noremap <Space> @q

หากต้องการใช้เพียงบันทึกแมโครด้วยqqอันดับแรกให้หยุดการบันทึกด้วยqแล้วกดspaceเพื่อเล่นซ้ำ


FYI ด้วยเหตุผลที่คุณระบุ (ไม่ใช่คีย์ที่จำเป็น) ผู้คนจำนวนมากใช้พื้นที่เป็นคีย์ผู้นำของพวกเขาดังนั้นอาจไม่มีคนจำนวนมากที่ว่างเปล่าอย่างที่คุณคิด :)
B Layer

0

เนื่องจากฉันไม่ได้ใช้,และชอบวิธีแก้ปัญหาที่ง่ายต่อการพิมพ์สิ่งนี้เหมาะสำหรับฉัน:

:map , @@
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.