より快適に grep-find する

Emacs の機能の中でも M-x grep-find はお気に入りのひとつ。文字列検索に加え + *grep* バッファに移動してヒット箇所で Enter するとそこにジャンプしてくれる便利なヤツなのだ。

ただ、以下のような不満点もあったのでカイゼンしてみる。

  • - 検索する時にいちいちミニバッファにコマンドの文字列を打ち込むのがめんどくさい。


  • - ソースのみを対象にしたい場合、configure や m4 マクロ、*.html ファイル(htagsやdoxygenが生成)は対象外としたい。
  • - 現在のフレームとは別にフレームを作ってそこに結果を表示したい。

まず M-x help f grep-find (または f1 f grep-find) で関数定義 grep.el に飛び、grep-find のインタフェイスを確認する。

それから、C-x ESC ESC(repeat-command) と M-p を数回叩き、grep-find の呼び出し方を見てみる。なんのことはない grep-find に引数としてコマンドをあたえているだけだった。

(eval-expression (quote (grep-find "find . -name \"*.cpp\" | xargs grep debug")) nil)

最後に frame.el を参考に make-frame, select-frame 関数を引っ張ってきて終了。(最初は other-frame でイケるかなと思ったが浅はかだった)

(setq my-grep-find-topdir "/home/kyagi/src")

(defun my-grep-find (arg)
  (interactive "sInput string:")
  (if (not (string= (buffer-name) "*grep*"))
      (progn  
        (make-frame)
        ;(other-frame 1)
        (select-frame (next-frame nil t))))
  (switch-to-buffer "*grep*")
  (let ((topdir)(command))
    (setq topdir my-grep-find-topdir)
    (cd topdir) 
    (setq command "find . -name \"*.c\" -o -name \"*.cpp\" -o -name \"*.h\" -o -name \"*.ts\" | xargs grep -n ")
    (setq command (concat command arg))
    (grep-find command)))

(global-set-key [f9]  'my-grep-find)

不用意に *grep* バッファを映すフレームを作成してしまわないように buffer-name で制限をつけているが、これでもまだ「既に *grep* バッファがあるのに該当フレームが *grep* バッファでない場合」新しくフレームを作成してしまう。まだまだカイゼンの余地がアリ×2。