App::Optionsでrequired引数チェックをしているスクリプトでflymakeが
Configuration error has occurred while running (perl -wc hoge_flymake.pl). Flymake will be switched OFF
とエラーを吐いてしまい、一度そのバッファを閉じてまた開くと今度はemacs全体がフリーズしてしまった。
なんだろう、と思って試しに
#!/usr/bin/perl BEGIN { exit 1; }
というスクリプトを書いてみたら同じことが起こった。
perlのflymakeはバックグラウンドで"perl -wc"でコンパイルしてエラーチェックを行うのだけど、"perl -c"はBEGINの中身は実行されてしまう。モジュールのuseも
BEGIN { require Hoge; import Hoge; }
という意味なのでuseされたモジュールimport()の中身などは実行される。
もしもその中で"0"以外のステータスでexitされてしまうと、flymakeはエラーを吐いてしまうようだ。該当箇所がflymake-post-syntax-checkの中。
(defun flymake-post-syntax-check (exit-status command) ... (if (equal 0 exit-status) (flymake-report-status "" "") ; PASSED (if (not flymake-check-was-interrupted) (flymake-report-fatal-status "CFGERR" (format "Configuration error has occurred while running %s" command)) (flymake-report-status nil ""))) ; "STOPPED" (flymake-report-status (format "%d/%d" err-count warn-count) ""))))
exit-statusが0以外で、かつflymake-check-was-interruptedがnilだとfatal-statusとなってしまうようで。
これを防ぐために、設定ファイルでは
(defadvice flymake-post-syntax-check (before flymake-force-check-was-interrupted) (setq flymake-check-was-interrupted t)) (ad-activate 'flymake-post-syntax-check)
と書いておくのがよさそうだ。
defadviceで定義済みの関数に処理を付け足す - すぎゃーんメモ
多くの人の設定ファイルで書いてあったけど何の意味かわからなかったのは、こういうことだったのねー。