grep-find のジャンプ先バッファで行番号を表示する

せっかく grep-find が行番号つきで検索箇所を表示してくれるのでジャンプした先でも行番号を表示するようにしたい。
ジャンプした後に C-x ESC ESC の repead-command で呼び出した関数を調べると compile-goto-error という関数であることがわかった。

じゃあ、こいつに defadvice で (setnu-mode t) をひもづけてやればいいのかと思うと、以下では *grep* バッファ自体が setnu-mode になってしまった。

;;; これではダメ…
(defadvice compile-goto-error (after compile-goto-error-and-setnu-mode (arg))
  "when call compile-goto-error, change the mode to setnu-mode"
  (setnu-mode t))
(ad-activate 'compile-goto-error)

ここで compile-goto-error を追っていき、さらに next-error-internal という関数を辿ると何やらアヤシゲなフックを発見。

;;; compile.el から抜粋
(defun compile-goto-error (&optional event)
  "Visit the source for the error message at point.
Use this command in a compilation log buffer.  Sets the mark at point there."
  (interactive (list last-input-event))
  (if event (posn-set-point (event-end event)))
  (or (compilation-buffer-p (current-buffer))
      (error "Not in a compilation buffer"))
  (if (get-text-property (point) 'directory)
      (dired-other-window (car (get-text-property (point) 'directory)))
    (push-mark)
    (setq compilation-current-error (point))
    (next-error-internal)))
;;; simple.el から抜粋
(defun next-error-internal ()
  "Visit the source code corresponding to the `next-error' message at point."
  (setq next-error-last-buffer (current-buffer))
  ;; we know here that next-error-function is a valid symbol we can funcall
  (with-current-buffer next-error-last-buffer
    (funcall next-error-function 0 nil)
    (run-hooks 'next-error-hook)))

この next-error-hook に add-hook してやればいいんじゃないのと思うとまさにビンゴ!だった。
結局以下の1行でジャンプ先でも行番号が表示されるようになった。満足。

;;; これで OK!
(add-hook 'next-error-hook '(lambda () (setnu-mode t)))