シェルから Emacs を使って検索

昨日の続き。
shell から Emacsgrep-mode が使えれば便利なんじゃね、とか思ったのでやってみた。要 Emacs22 + gnuserv。(Emacs21 でもできる。後述)

# search with emacs
function se() {
    dir=.
    [ $# -gt 2 ] && dir=$3
    dir=$(readlink -f $dir)
    sexp=$(cat <<EOF
(progn
 ;; (grep-tree "$2" "*.$1" "$dir") ;; ちょっと古い版(4/28以前)のビルドはこっち
 (rgrep "$2" "*.$1" "$dir")        ;; 新しい CVS HEAD はこっち
 (select-window (get-buffer-window "*grep*")))
EOF
    )
    gnudoit "$sexp"
}

~/.zshrc あたりに書いておけば

se py import

とかでカレントディレクトリ以下の "*.py" なファイルから import を検索して結果を Emacs のウィンドウに表示。各行で Enter を押すと自動でファイルをオープンしてその行までジャンプしてくれる。

se el defun /usr/share/emacs/site-lisp

な感じで第3引数を指定すると検索ディレクトリも指定できる。多分 bash でも OK。

追記

はてなスタッフは反応早すぎだと思います。1時間もしないうちに・・・、まぁトラックバック飛ばしているのもあるけど。

  • 2006年10月09日 naoya naoya emacs, zsh gnudoit しらんかった。こういうとき Meadow だと損だなー。
  • 2006年10月09日 higepon higepon emacs gnudoit良いなぁ。grep-treeがvoid-functionと言われた。emacs22だからだろうか。

> id:naoya さん
Meadow インストール時に gnuserv も選択しておくと gnudoit も付いてきていると思います。すくなくとも自分の環境には RunMW32.exe と同じディレクトリにあります。
> id:higepon さん
Ubuntuemacs-snapshot では grep-tree なんですが、CVS HEAD では rgrep に rename されているようです。ということで代わりに rgrep を使ってください。

再追記

がんばれば Emacs21 でも動くので一応置いておく。

function se() {
    dir=.
    [ $# -gt 2 ] && dir=$3
    dir=$(readlink -f $dir)
    sexp=$(cat <<EOF
(progn
  (let ((default-directory "$dir/"))
    (grep "find -type d \\\\( -name .svn -o -name CVS \\\\) -prune \\\\
-o -type f -name '*.$1' -print0 | xargs -0 -e grep -n -e '$2' /dev/null"))
  (select-window (get-buffer-window "*grep*")))
EOF
    )
    gnudoit "$sexp"
}

CVS と .svn を無視するので、こっちのほうが便利かも。というか任意のコマンドを指定できるので

    (grep "ack --nocolor --nogroup $1 $2")

なんてのもあり。
あと何気に C-x ` (next-error) が使える。