Edited at

エコーエリアや *Messages* バッファにメッセージを表示させたくない

More than 5 years have passed since last update.

messageを呼んでもエコーエリアや*Messages*バッファにメッセージを表示させたくない場合があります。

具体的にはrun-with-idle-timerを使ってrecentf-save-listをアイドル時に自動的に実行させるようにしているのですが、実行時にWrote /home/itiut/.emacs.d/.recentfというのがいちいちエコーエリアに表示されて少しうるさく感じます。


方法

defadviceを使ってmessageをフックさせて何かするとかも考えられるのですが、わりとベーシックな関数だと思われるのであまり弄りたくありません。

マクロのwith-temp-messageを使えばそれっぽく見せることができました。

(with-temp-message MESSAGE &rest BODY)は、BODYを実行している間はMESSAGEをエコーエリアに表示させておき、BODYの実行が完了したらエコーエリアに元のメッセージを復元してくれるというものです。

MESSAGE(current-message)で現在のメッセージをセットすれば、BODYの実行時にも現在のメッセージが引き継がれ、BODY内でmessageが呼ばれてもBODYの実行が一瞬で完了するようであれば、あたかもメッセージがエコーエリアに表示されなかったように見えます。

そしてwith-temp-messageを使うときにmessage-log-maxnilにしておくと、メッセージは*Messages*バッファに追記されません。

以上を元にwith-suppressed-messageというマクロを作成しました。

(defmacro with-suppressed-message (&rest body)

"Suppress new messages temporarily in the echo area and the `*Messages*' buffer while BODY is evaluated."
(declare (indent 0))
(let ((message-log-max nil))
`(with-temp-message (or (current-message) "") ,@body)))

with-temp-messageではMESSAGEnilのときは元のメッセージをエコーエリアに復元してくないので、(current-message)nilとなる場合には空文字列をMESSAGEにセットしています。


使用例

with-suppressed-message中でmessageを呼んでも、メッセージが表示されていないように見えます。

(with-suppressed-message

(message "foo")
(message "bar")
(message "baz"))

冒頭のrun-with-idle-timerの部分はこうなりました。

(run-with-idle-timer 30 t '(lambda ()

(with-suppressed-message (recentf-save-list))))