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

Emacsのキーボードマクロ

プログラミング


Ubuntuで使ってたelispやキーボードマクロをそのままLeopardに持ってきたらその一部が動作しなかった。
正直なところ、普通に動くだろうと思ってたんけど、自分で書き換えたfind-tagが実行されず、元のfind-tagが実行されたり、
キーボードマクロがさっぱり動かなくなってたりして、かなり手間取ってしまった。


キーボードマクロは使い捨てのものが多いと前に読んだEmacsの本に書かれていたような気がするけど、
自分の場合は使い捨てのマクロを作成することはほとんどない。そういうのはdmacro.elがあれば大体事足りる。
dmacro.elは同じパターンの操作を2回連続で行った後、その動作を記録して繰り返し実行することができるelispだ。
例えば以下のように、

aa ⏎
aa ⏎

とやった後、dmacro-execを実行すると、(自分の場合はCtrl+tに割り当ててる)

aa ⏎
aa ⏎
aa ⏎

となる。これは繰り返し実行できる。


自分の場合、キーボードマクロはint mainなんたらかんたら、while、for、ifなど何らかの入れ子構造しているのを記述する際、
特にブラケットを入力するのが面倒な文法用に作成している。Hello, World!するのにも結構長いコードを書かないといけないとかで
非難されているJavaのmain関数もこれなら一瞬だ。*1しかも、mode-hookを使えば、マクロの名前が同じでもそれぞれの言語毎に
異なる動作をさせることができる。さらにEmacsのキーボードマクロは関数ランチャーとして起動できる。
関数ランチャーはキーボードショートカットよりは遅いが、覚える必要があるのは名前だけなので、
割り当てられる数の制限も(実質)ないし、どの動作をどのキーに割り当てたのかいちいち覚えている必要もない、というか覚えてられない。


で、Macで今までに作成したキーマクロを実行したらさっぱり動かず、書き直す羽目になったというのが今日のお話。(本題の方が短い(_ _))

Ubuntuから持ってきたマクロ

(fset 'create_nested_block_while
   [?w ?h ?i ?l ?e ?( ?) ?{ tab return tab return ?} tab ?\C-p tab ?\C-p ?\C-e ?\C-l ?\C-l])

Leopard上で作成したマクロ(キーの正確な順番は違うけど、やることは一緒)

(fset 'create_nested_block_while
   "\C-iwhile () {\C-m\C-m}\C-p\C-i\C-p\C-e\C-l\C-l\C-l")

後者はちゃんとwhileブロックを作ってくれるが、前者だと↓で終わってしまう。

    while () {

とりあえず、tabとかreturnの頭に?を付けてコマンド形式に変更してやったら動作した。

*1:というかそこは非難するところなのか?