flymakeのポップアップを自動的に

Emacsネタです。


コーディング時にエラーやワーニングがないかチェックする
emacs lisp として flymake と flycheck があります。
個人的にC言語の対応が flymake の方が好きだったので
こちらを採用しました。

イメージはこんな感じです(右側)。
f:id:sarup:20150317175655p:plain

下記の参考URLを元に設定していったのですが、
ポップアップ表示は自動で表示されなかったので
自動で表示するようにしました。
ついでにエラー行にカーソルを合わせたときの待ち時間を
0.9秒から0.1秒に変えてみましたので、
以下に簡単な説明を。

自動で表示するために
flymake-cursor の flyc/show-stored-error-now () 関数を
下記参考URLにある flymake-show-and-sit () 関数で上書きします。

上書き処理

(eval-after-load "flymake-cursor"
  '(progn
     (fset 'flyc/show-fly-error-at-point-pretty-soon
	   (symbol-function 'flyc/show-fly-error-at-point-pretty-soon-quick))
     (fset 'flyc/show-stored-error-now (symbol-function 'flymake-show-and-sit))
     ))

flymake-cusor 自体が flymake に対し eval-after-load を行っているので、
更に flymake-cursor に対し eval-after-load を行っています。

待ち時間の変更に関しては、
flymake-cursor の flyc/show-fly-error-at-point-pretty-soon 関数の
run-at-time の時間を変えただけです。

flyc/show-fly-error-at-point-pretty-soon 関数の変更箇所のみ

	(setq flyc--e-at-point error-at-point
	      flyc--e-display-timer
	      (run-at-time  "0.1 sec" nil 'flyc/show-stored-error-now))

全体としてはこんな感じです。

flymake.el

(require 'flymake)

;; popup.el を使って tip として表示
(defun flymake-show-and-sit ()
  "Display a menu with errors/warnings for current line if it has errors and/or warnings."
  (interactive)
  (let* ((line-no            (flymake-current-line-no))
         (line-err-info-list (nth 0 (flymake-find-err-info flymake-err-info line-no)))
         (menu-data          (flymake-make-err-menu-data line-no line-err-info-list)))
    (if menu-data
      (popup-tip (mapconcat '(lambda (e) (nth 0 e))
                            (nth 1 menu-data)
                            "\n")))
    ))
(global-set-key "\C-cd" 'flymake-show-and-sit)

(defun flyc/show-fly-error-at-point-pretty-soon-quick ()
  "If the cursor is sitting on a flymake error, grab the error,
and set a timer for \"pretty soon\". When the timer fires, the error
message will be displayed in the minibuffer.

This allows a post-command-hook to NOT cause the minibuffer to be
updated 10,000 times as a user scrolls through a buffer
quickly. Only when the user pauses on a line for more than a
second, does the flymake error message (if any) get displayed.

"
  (if flyc--e-display-timer
      (cancel-timer flyc--e-display-timer))

  (let ((error-at-point (flyc/-get-error-at-point)))
    (if error-at-point
	(setq flyc--e-at-point error-at-point
	      flyc--e-display-timer
	      (run-at-time  "0.1 sec" nil 'flyc/show-stored-error-now))
      (setq flyc--e-at-point nil
	    flyc--e-display-timer nil))))


(load-library "flymake-cursor")
(eval-after-load "flymake-cursor"
  '(progn
     (fset 'flyc/show-fly-error-at-point-pretty-soon
	   (symbol-function 'flyc/show-fly-error-at-point-pretty-soon-quick))
     (fset 'flyc/show-stored-error-now (symbol-function 'flymake-show-and-sit))
     ))


参考URLはここら辺です。
Emacs で文法チェック
Emacs に Flymake を導入 | 永田 晴久
http://shnya.jp/blog/?p=477
emacsでミスを教えてくれるflymakeをC++のために使うための設定 - suztomoの日記