読者です 読者をやめる 読者になる 読者になる

submode.vim で特定の条件の時だけ submode に入る

vim event

Vim Advent Calendar 2013 の 23 日目の記事です。今年も Advent Calendar の季節がやってきましたね。

問題

submode.vim で submode を定義する際、トリガーとなるキーを押したときに特定の条件であった場合だけ submode に入りたい場合があります。
今回は yankround.vim と組み合わせた例を挙げます。yankround.vim は YankRing.vim のようにレジスタの履歴を順繰りに貼り付けてくれるプラグインです。
このプラグインを使った際に、p を連打すると順繰りに貼り付け、更にこの順繰りに貼り付けている間は n を押すと逆方向に貼り付けたいとします。
当然 submode の出番ですが、最初に1回だけ貼り付けた時には submode に入って欲しくありません。

解決

この場合、以下のようにします。*1

nmap <expr> p yankround#is_active() ?
\             '<Plug>(my-yankround-start)' : '<Plug>(yankround-p)'
call submode#enter_with('yankround', 'n', 'r',
\               '<Plug>(my-yankround-start)', '<Plug>(yankround-prev)')
call submode#map('yankround', 'n', 'r', 'p', '<Plug>(yankround-prev)')
call submode#map('yankround', 'n', 'r', 'n', '<Plug>(yankround-next)')

直接 p で submode を始めるのではなく、まずは p を押した時に、yankround が起動しているかどうかで貼り付けか submode に入るかを分岐します。
submode に入るには一旦 を経由させます。そして submode のトリガに を使うことで初めて submode に入ります。あとは通常の submode と同じです。

この設定の弱点は、yankround が貼り付けの度に :echo で表示してくれるレジスタの現在位置を示す (1/15) みたいな表示が、submode.vim のモード表示に消されてしまうことです。ちょっと困っているので、どうしようかなこれ…。

追記

上記の設定は、Vimの制限 により、通常の submode.vim では動作しませんでした。すいません。
私は魔改造したバージョンの submode.vim を使っています。


明日は @ さんです。

*1:今回直接関係ない P gp gP のキーマッピングは省略しました