js2-modeでエラー箇所を行き来する

設定を見直し中 - すぎゃーんメモ シリーズ。
今まで使っていなかったのだけど、今回初めてjs2-modeを使ってみている。巨大ではあるものの、elispで実装されたJavaScriptパーサを持っていてリアルタイムにsyntax checkをしてくれるのが魅力。なので、flymakeを使わなくても構文エラーの箇所がhighlightされる。

例えばこんなカンジ。4行目は末尾のセミコロンがないのでオレンジ色の下線で警告を、6行目では括弧の対応が取れていないため末尾が赤文字でエラーを知らせている。それぞれその箇所にカーソルを持っていくとmissing ; after statement, missing ) after argument listといったメッセージがmini bufferに表示される。

で、これくらいの数行のjsなら良いのだけど、それなりに行数が大きくなってくるとどこで警告やエラーが出てるか分かりにくくなってくる。そんなときのためにjs2-next-errorというコマンドが用意されていて、これを呼ぶことでカーソル位置より後ろの直近のエラーにジャンプしてくれる。デフォルトではC-c C-`バインディングされている。
ただコレは下へ下へと辿っていくだけで、上の行の方に遡っていくことが出来ない。末尾まで辿れば一周して先頭に戻ってくるのだけど、普通にカーソル位置直前のエラーとかにジャンプしたい。
js2-next-errorの定義は以下のようになっていて、

(defun js2-next-error (&optional arg reset)
  "Move to next parse error.
Typically invoked via \\[next-error].
ARG is the number of errors, forward or backward, to move.
RESET means start over from the beginning."
  (interactive "p")
...

引数に-1を渡せば前のエラー箇所に戻れるようなので、以下のように設定ファイルを書いた。

(defun js2-prev-error ()
  (interactive)
  (js2-next-error -1))
(define-key js2-mode-map (kbd "M-n") 'js2-next-error)
(define-key js2-mode-map (kbd "M-p") 'js2-prev-error))

これだけで、js2-prev-errorコマンドを使って上の行に遡る方向でエラー箇所にジャンプできる。

と思ったけど

ドキュメントをよく読んでなかった。そもそもこれは

  (set (make-local-variable 'next-error-function) #'js2-next-error)

という具合にバッファローカルな変数next-error-functionで使われていて、simple.elではnext-errorコマンドが内部的にこれを呼んでいるそうで。

C-x ` normally uses the most recently started compilation, grep, or occur buffer. It can also operate on any buffer with output from the M-x compile, M-x grep commands, or, more generally, on any buffer in Compilation mode or with Compilation Minor mode enabled, or any buffer in which `next-error-function' is bound to an appropriate function. To specify use of a particular buffer for error messages, type C-x ` in that buffer when it is the only one displayed in the current frame.

で、同じくprevious-errorコマンドが

(defun previous-error (&optional n)
  "Visit previous `next-error' message and corresponding source code.

Prefix arg N says how many error messages to move backwards (or
forwards, if negative).

This operates on the output from the \\[compile] and \\[grep] commands."
  (interactive "p")
  (next-error (- (or n 1))))

と定義してあったので、これを呼ぶことで同様に上に遡りながらエラー箇所にジャンプできる。

結論

そんなわけでjs2-prev-errorコマンドを自分で書く必要は無いみたい。普通にnext-errorとprevious-errorを呼べばよい。ちゃんとドキュメントを読みましょう。