「ドット演算子」でマクロを繰り返すことはできますか?


15

.コマンドでマクロを繰り返すことはできますか?たとえば、次のように入力できるようにしたいと思います。

@q...

効果的に@q4回呼び出す。デフォルトの動作では、これは「Q」は、たとえば、単一のコマンドを保持している場合にのみ動作しdwxまたはiHello<esc>。(ただし、「。」は最後のキーストローク/コマンドではなく、最後の変更を繰り返すため、これは理にかなっています)

私もこの作品を数に入れてみたいです。たとえば、次のように入力します。

3@q.

実質的に@q6回実行するのと同じです。この動作を構成するにはどうすればよいですか?


1
正確にあなたが求めているものではありませんが、多分それはgithub.com/wincent/replayに役立つでしょう。これは最後に記録されたマクロを記録し、押すとそれを再生しますEnter
grodzik 2017年

参考までに@@、最後のマクロを繰り返すので、マッピングなどのためにこれを求めている場合は、うまくいくはずです。
Shahbaz

回答:


7

これを試してみてください。(さらにダミーモーション)が後で使用される@ように再マップするため、最後の演算子になり、で繰り返す必要があります。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

心配ありません、興味深い問題はありません!
アントニー

1
編集:.記録直後にマクロを再生できるようにします。
アントニー2017年

QStart関数の\<plug>qstopqにいる必要があると思います
Steve Vermeulen

6

最後のマクロを繰り返すには、基本的に@qを3回実行する@@ように使用できます3@@。ただし、@キーストロークは扱いにくいので、.vimrcには次の行があります。

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

これにより、リーダーキー(、)とmを使用して最後のマクロを実行できます。その後、マクロを繰り返すために、この前に番号を付けることができます。

現在3,mはと同等です3@@。同じ合計キーで、Shiftキーを押す必要はありません。

編集:これを再考すると、私は新しいマクロを思いつきました。 nmap <leader>. @@ これ3,.は、数字が前に付いている場合にも機能するので3@@、マクロ文字を渡して、最後のマクロの代わりにそのマクロを繰り返すことができるように、この機能を見たいと思います。


OPは6回3@q.実行する必要があります@q。これはそれをしません。
user41805 2017

あなたの質問をもう一度読んで、これが答えになるとは思いません。いつ使用する3@q.かの例を挙げられますか?カウントを前に付けるだけでもいいかもしれません。マクロを開始する前に検索を設定してから、マクロで使用nして、再生可能な場所の先頭にジャンプする傾向があります。
Shadoath 2017

5

マクロの使用を別のマクロに記録して、それを繰り返すことができます。

qqdwq
qr2@qq

3@r@q6回走るようなものです。


1

デフォルトspaceでは、vimは「右に1文字移動する」であり、すでにでカバーされているlため、qバッファーからマクロを再実行するためにスペースを再マップしました。

noremap <Space> @q

使用するには、qq最初にでマクロを記録しq、で記録を停止し、次にspaceを押して再生します。


参考までに、あなたが述べた理由で(必須のキーではありません)、多くの人々がスペースをリーダーキーとして使用しているため、自由にそれを持っている人は思っているほど多くないかもしれません。:)
Bレイヤー

0

私は使用せず,、単純な入力が簡単なソリューションのように、これは私にとってはうまくいきます:

:map , @@
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.