Vimで連番を入力するためのVim pluginを作った

この記事はVim Advent Calendar 2012の198日目の記事です。
197日目はyonchuさんによるVim Advent Calendar 2012 に’はてブ数’を表示させるグリモンとブックマークレットを作ったよ!でした。

Vimで連番を入力するためのVim pluginについての記事です。

6/16 18:30 追記(operatorを本体に統合したので記載を修正)

はじめに

文章で説明するより使用している様子を見たほうがわかりやすいと思うので、 まずは以下のGIFアニメをご覧ください。 これは、Vim scriptの配列の値として、 0〜99までを設定するために 今回ご紹介するVim pluginを使っている様子です。

使用感

0を100個入力するところまでは、本pluginは関係ありません。 その後のRengBangコマンドを実行して、連番に置き換えているところが 本pluginの機能です。

本pluginは、私がLingrでこんなplugin欲しいなぁとつぶやいたところ、 manga_osyoさんが原型のscriptをものの数分で作ってくださったという経緯があります。
それを元に色々機能追加してplugin化したのが本pluginです。 この場を借りてmanga_osyoさんにお礼を言いたいと思います。ありがとうございます。manga_osyo++

あと、rengbang(連番)という名前をつけていただいたのはujihisaさんです。 短くてわかりやすくて、とてもいいネーミングで気に入ってます。 この場を借りてujihisaさんにお礼を言いたいと思います。ありがとうございます。ujihisa++

インストール方法

プラグイン名はvim-rengbangという名前で、githubにあげてます。

NeoBundleを入れていれば.vimrcに以下を書いておけばインストール出来ます。

6/16 18:30 追記(operatorを本体に統合したので記載を修正)

operator-user用のplugin(vim-operator-rengbang)も用意したので、必要であれば合わせて入れてください。 vim-operator-rengbangは単体では動かず、使用するためにはvim-rengbangと kanaさんが作られたvim-operator-userが必要です。 vim-rengbang用operatorをvim-rengbang内に統合しました。 vim-operator-rengbangは不要です。vim-operator-userが インストールされていればoperatorは使えますが、されていなければ使えません。

NeoBundle 'deris/vim-rengbang'

もちろん、.vim(Winであればvimfiles)配下に直接入れても構いません。

使い方

本pluginのインターフェースは3つあります。

  • コマンド
  • 関数
  • operator

順に使い方を説明します。

コマンド

2つのコマンドを用意しています。

  • RengBang
  • RengBangUsePrev
" [range]RengBang [{pattern} {start} {step} {use_first}]
"   [range]で指定された範囲の中から、{pattern}にマッチする部分
"   を順に連番と置き換える。
"   引数はいずれもオプションで、指定されていなければ
"   デフォルト値を使う
"   {pattern}は連番を挿入したい箇所の正規表現を指定する。デフォルト値は\(\d\+\)
"   {start}は連番の開始時の値を指定する。デフォルト値は0
"   {step}は連番入力時の階数を指定する。デフォルト値は1
"   {use_first}は連番挿入時、一番最初にマッチした部分の数字を
"   起点として連番を挿入するかどうかを指定する。
"   0は起点としない。1は起点とする。デフォルト値は0
"   ※ただし、{start}も指定されている場合
"     マッチした部分の数字 + {start}が起点となる

" 例:{pattern}
" visual modeで選択下範囲の、配列内の添字を連番で置き換え
:'<,'>RengBang \[\zs\(\d\+\)\ze\]
" \(...\)で指定している場合、自動で\zs,\zeを挿入するので上記は以下と同様
:'<,'>RengBang \[\(\d\+\)\]

" 行頭に連番を挿入
:'<,'>RengBang ^

" 行末に連番を挿入
:'<,'>RengBang $

" hogeの後に連番を挿入
:'<,'>RengBang hoge\zs

" パターン内にspaceを使いたい場合は\でエスケープする必要があるので注意
:'<,'>RengBang \ \(\d\+\)\ 

" 例:{start}
" 5から連番を始める(5 6 7 8 9...)
:'<,'>RengBang \(\d\+\) 5

" 例:{step}
" 5階数で連番を入力(1 6 11 16 21...)
:'<,'>RengBang \(\d\+\) 1 5

" 例:{use_first}
" 最初にマッチした数字から連番入力
" (例えば最初にマッチした数字が10の場合、10 11 12 13 14...)
:'<,'>RengBang \(\d\+\) 0 1 1

" [range]RengBangUsePrev {start} {step} {use_first}
"   一つ前に実行したRengBangもしくはRengBangUsePrevもしくは
"   次章で記載する関数連番入力系関数で指定した
"   引数を使用してRengBangを実行する
"   引数が指定されていればそれを使用し、指定されていなければ
"   一つ前に実行したときの引数を使う
"   一度も実行されていなければデフォルト値を使う

" 下記の順にコマンドを実行すると、RenbBangUsePrevは上のRengBangと同等になる。
:'<,'>RengBang \(\d\+\) 0 1 1
:'<,'>RengBangUsePrev

関数

3つの関数を用意しています。

  • rengbang#rengbang()
  • rengbang#rengbang_use_prev()
  • rengbang#config()
" rengbang#rengbang([{pattern}, {start}, {step}, {use_first}]) [range]
"   RengBangと同等。
" rengbang#rengbang_use_prev([{start}, {step}, {use_first}]) [range]
"   RengBangUsePrevと同等。

" patternの文字列を''で囲むところ以外、コマンドとあまり変わらない
:'<,'>call rengbang#rengbang('\(\d\+\)')
:'<,'>call rengbang#rengbang_use_prev()

" rengbang#config([{pattern}, {start}, {step}, {use_first}])
"   デフォルト値を変更する。
"   vimrcなどに書いておくことでデフォルト値を変更できる。

" 以下でデフォルト値を変更できる
:call rengbang#config('\[\zs\(\d\+\)\ze\]', 1, 5, 1)

operator

2つのoperatorを用意しています。

  • (operator-rengbang)
  • (operator-rengbang-useprev)

6/16 18:30 追記(operatorを本体に統合したので記載を修正)

operatorを使用するには、上でも記載したとおり、operatorを使用するには 別途vim-operator-rengbangもインストールしておく必要があります。

" <Plug>(operator-rengbang)
"   operatorで指定した範囲を[range]としてRengBangを実行します。
"   引数は全てデフォルト値を使用します。
" <Plug>(operator-rengbang-useprev)
"   operatorで指定した範囲を[range]としてRengBangUsePrevを実行します。
"   引数は一つ前にRengBang系コマンドor関数を実行したときの引数を使用します。

" operatorを使用するには以下のようにvimrcにkey mappingを設定しておきます。
map <Leader>sr <Plug>(operator-rengbang)
map <Leader>sp <Plug>(operator-rengbang-useprev)

使用例

正規表現で指定できる箇所に連番を挿入(or置き換え)できるので、 大抵のことはできますが、3つほど使用例をあげます。

先頭に連番を挿入する

使用例1

fooの後に連番を挿入する

使用例2

配列の添字がずれてしまったのをなおす

使用例3

マクロと比較して

マクロを使って連番を入力している方も多いかと思います。 マクロ使えばできるからpluginなんていらないじゃんという方もいるかと思いますが、 まぁそれはその通りで、何事もそうですが要は使いやすいと思った方を選べばいいのです。

自分も連番入力にはマクロを使うことが多いですが、場合によってはマクロで やるのが結構面倒な場合があったので本pluginを作りました。

ちなみに、マクロを使った連番、およびちょっとした便利scriptについては以下の記事が詳しいです。 (私もここで紹介されているscriptとマクロを併用していました)

Vimで番号を順番につける方法

本pluginとマクロどちらを使えばいいか、個人的な感覚ですが、ケースによって分けてみました。

本pluginを使う

  • 本pluginのデフォルト値で事足りる(コマンドor関数を引数なしで呼び出す。できればoperator使ったほうが楽)。
  • 連番を入力したいパターンが決まりきっている(vimrcにデフォルト値を設定して使用)。
  • 連番を挿入したいパターンがぱっと思い浮かぶ(その場でコマンドor関数を実行)。

マクロを使う

  • 連番入力と合わせて何かする必要がある。
  • 単純な連番ではなく、この範囲の数字は1で統一、この範囲の数字は2で統一といった複雑なことをする必要がある。
  • マクロが大好きで使うのが苦にならない(考える前に手が勝手に動く)

まとめ

以上が、Vimで連番を入力するためのVim pluginについての記事でした。

本題とは関係ありませんが、Vimレベルが上がるのでvimrc読書会に参加することをおすすめします。毎週土曜日23時からやってます。

それではVim Advent Calendar 2012の198日目を終わります。

明日のVim Advent Calendar 2012はmanga_osyoさんです。