これは、vimの [cci]^A[/cci] および [cci]^X[/cci] が欲しいよという要望だ。これらは、カーソルの下にある数値らしきものを指定したカウンタの分だけ増減させる。[cci]^A[/cci] は増加させ、[cci]^X[/cci] は減少させる。
オプション [cci]nrformats[/cci] の値によって動作をカスタマイズできる。これはカンマ区切りで文字列を格納する前提になっていて、以下のコンポーネントが意味を持つ:
- alpha – \b[a-zA-Z]\b をアルファベットのリストアイテムと認識する。大文字か小文字かで分類し、それぞれ [a-z] と [A-Z] をローテーションする
- bin – 0b[01]+ を2進数表記と認識する
- hex – 0[xX][0-9a-fA-F]+ を16進数表記と認識する。大文字か小文字かどちらかを取るかは、マッチした文字列の最も右端に位置するアルファベットに依存する。アルファベットがない場合は、2文字目が x か X かに依存する。
- octal – 0[0-9]* にマッチし、かつ、0[0-7]* にもマッチする部分を8進数表記と認識する。なぜこれだけ判定がややこしいのかというと、00018 のような文字列を 0001 と 8 に分割されてしまうのを避けるため。またこのコンポーネントを有効にすると、どうでもいいことだが C 言語と同様 0 は8進数の0と認識される
これらのコンポーネントに対するマッチの最後に、必ず -?[0-9]+ を10進数表記と認識する処理が入る。で、カーソル行に対してマッチした文字列群のうち、カーソルの桁位置を内包するものが処理対象になり、指定したカウンタの分だけ値を増減する。基本的には以上だ。
いくつか気を付けるべきポイントがある。
- 0 で始まる、10進数以外の数値文字列の場合、値を増減してもできるだけ元の桁数を維持するよう適宜左に 0 をパディングする
- 10進数と認識される数値文字列(これには、0で始まるが [89] を含む数値文字列も含む)の場合は、逆にいかなる場合も先行する 0 をすべて削除する
- vim の仕様だと、-0001 みたいなのは octal を含んだ nrformats の場合に若干不自然な動作になる。つまり負の符号が先行しているが、正の8進数文字列と認識される。これはいいのか?
- Selenium のテストで、あるテスト中に複数のアサーションを行う時、”#1-1″ とか “#1-2” とかラベルをつけている(そもそも複数のアサーションを詰め込むべきでないとか、もっと自己記述的なラベルにすべきとかはこの際置いといて)このラベルの右端の数値を増減させたい場合、ハイフンが邪魔になり動作が反転してしまう。これはなんとかならないのか。つまり負の符号ではなくハイフン、あるいは減算の演算子であるかを判別できるといいんだけど
- vim では、nrformats の型は文字列だが、実質的にはカンマ区切りの配列構造として扱うことになる。これは身近な例で言えば DOM における className と classList の関係に似ている。全体をまるごと書き換えるのでなければ、classList を通して操作するほうが圧倒的に便利だ。同じことが vim にも言えて、[cci]set nrformats+=foo[/cci] とか、[cci]set nrformats-=bar[/cci] のような演算子が用意されている(vim の、というか vi の set 構文はいわゆる普通のプログラミング言語とは若干趣が異なるので演算子と言っていいのかはわからないが)。これを wasavi でもサポートすべきか?