Emacs クイズ

日記を書く[・ _ゝ・]はやみずさん - Emacs クイズ より

パッと閃いた一問だけ答えさせてください。

q5. "hello"という文字列が名前に含まれるコマンドの一覧を取得する方法は?

普通は M-x apropos-command で調べるのが良いと思うんですが、個人的にはこういうやり方をすることが多いです。

クラッチ・バッファにて

(mapatoms (lambda (s)
            (if (and (string-match "hello" (symbol-name s))
                     (interactive-form s))
                (insert (format "%s\n" s)))))

を実行する、というものです。

いちおう参考のために説明させていただきますと、mapatoms はインターンされている全シンボルを枚挙する関数です。

で、シンボルが特定パタン (正規表現) にマッチするか、そしてそれがコマンド (interactive な関数) かどうかをテストし、バッファに書き出しています。

テストの順序は重要です。interactive-form は、もし引数がコマンドならばリストを返すため、最初に持ってくるとコンシングを大量に生じてしまうからです。

(訂正 [20071012]: interactive-form よりも commandp という、そのものズバリな述語がありました。こちらを使うべきでしたね。)

ちなみに、特定の文字列を含む「変数」を得たければ boundp、「関数」一般を得るには fboundp を用います。

例えば、

q8. foo-bar<1>, foo-bar<2>, foo-bar<3>, ... , foo-bar<1000> という名前の1000個のバッファを開いているとする。これらのバッファを全てkillする方法は?

を解くために、とりあえず "buffer" を含む関数の一覧を

(mapatoms (lambda (s)
	    (if (and (fboundp s)
		     (string-match "buffer" (symbol-name s)))
		(insert (format "%s\n" s)))))

で得るわけです。さらに順序をソートしたければ、出力された領域を選択して C-u M-| sort RET とします。


P.S.

ついでなので q8 も解答してみます。

(dolist (b (buffer-list))
  (if (string-match "^foo-bar" (buffer-name b))
      (kill-buffer b)))