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-max
をnil
にしておくと、メッセージは*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
ではMESSAGE
がnil
のときは元のメッセージをエコーエリアに復元してくないので、(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))))