シンプルなテンプレートフレームワークtemplate-replace.elを作ってみた

二ヶ月振りに散髪してさっぱりしました。いやー風が冷たい。

久々にemacs lispをがっつりと書いてみました。中身があるかと言われれば困るのですが。
どんなものかというと、「現在位置の文字列を元にした置換用テンプレート」・・・いやそれだけなのですが。これだけだと自分でもさっぱりわかりませんので、具体的な動作をば。

例えば、以下のような文字列があるとします。(本当は画像があったほうがいいのですが、用意するのが面倒なもので)

unsigned int i = 100;
if (1 != i) {printf("hoge");}

C++をイメージしています。さて、gccで-Wallのオプションを指定していたりすると、こんな場合、「符号無整数と符号有整数の比較が行われています」というような警告が出ます。私は警告まで全部潰すようにしているので、これも潰したいです。

なんですが、C++形式のキャストは面倒です。この場合、static_cast(1) とやるか、static_cast(i)とやってやる必要があります。それはひどく面倒です。
そんな時に、今回作成したやつを使います。

unsigned int i = 100;
if (|1 != i) {printf("hoge");}
    ^ここにカーソルを置いて・・・

M-x template-replace
で、ミニバッファに "s" 、 unsigned intと入力すると

unsigned int i = 100;
if (static_cast<unsigned int>(1)| != i) {printf("hoge");}
                                ^ここにカーソルがくる

な感じに置換されます。iもついでに同じようにやりたい、という時には、

unsigned int i = 100;
if (static_cast<unsigned int>(1) != |i) {printf("hoge");}
                                    ^ここにカーソルを置いて
↓
M-x template-replace-resume
↓
if (static_cast<unsigned int>(1) != static_cast<unsigned int>(i)|) {printf("hoge");}
                                                                ^ここにカーソルが来ます

こんな感じになります。ぶっちゃけ機能はこれだけなんですが、パターンなんかも色々指定することができます。
今回のような場合、以下のような設定になっています。

(setq template-replace-alist
      '(("s" ((pattern . (lambda () (bounds-of-thing-at-point 'symbol)))
              (template . "static_cast<%s>(%s)")
              (input . "type to cast: ")))
        ("r" ((pattern . (lambda () (bounds-of-thing-at-point 'symbol)))
              (template . "reinterpret_cast<%s>(%s)")
              (input . "type to cast: ")))
        ("c" ((pattern . (lambda () (bounds-of-thing-at-point 'symbol)))
              (template . "const_cast<%s>(%s)")
              (input . "type to cast: ")))
        ))

・・・かなり見づらいリストになっていますが、(プレフィックス (設定のalist))という形式になっています。プレフィックスは、template-resumeの実行時に、利用する設定を選択するためのものです。上の例だと "s" と入力している部分です。
pattern には、関数のリストを渡して、それをpopup.elで選択する、といったことも出来るようになっています。
input は、ミニバッファから追加で入力を行うためのプロンプトを指定します。これも文字列のリストを渡すことで、一度に複数の入力を行うことができます。上の例だと、unsigned intと入力した部分になります。

もし興味がありましたら、http://github.com/derutakayu/template-replace/tree/master/template-replace.el ←こちらから眺めてみてください。まだ練りきれてないですが。大したロジックではないので、眺めるのに丁度よいかと思います。
人柱になった方で、エラー等ありましたら、コメント等で連絡頂ければありがたいです。

さて、本当はelispじゃなくてC++を書かなければならないんですが・・・orz。ううむ、もっと真面目にならなければ。