Gnusではメールの自動受信がデフォルトでは無効になっている
最近Gnusを使ってみてます。
メールの送受信はできるようになったのですが、どうも受信メールの確認が自動で実行されていないようで、
メールサーバに新着メールが届いても、グループバッファが一向に更新されません。
先に結論
以下の設定を行うことで、新着メールの自動確認が行われグループバッファが更新されるようになります。
(require 'gnus-demon) (defun my:gnus-setup-demon () (setq gnus-demon-timestep 1) (gnus-demon-add-handler 'gnus-demon-scan-news 300 nil)) (add-hook 'gnus-started-hook 'my:gnus-setup-demon t)
上記設定により、5分(300秒)毎に新着メール確認処理が実行されます。
詳しくは以下を。
調査
高機能という触れ込みのGnusにその機能が無い訳はないだろうと思ったんですが。
gnus-group-get-new-newsで新着メール確認ができることはわかったんですが、
それを自動実行することに関しての情報が見つかりませんでした。
しょうがないので、gnus-group-get-new-newsでGnusのソースを検索してみると以下の定義が見つかりました。
(defun gnus-demon-add-rescan () "Add daemonic scanning of new articles from all backends." (gnus-demon-add-handler 'gnus-demon-scan-news 120 60))
gnus-demon-scan-newsがgnus-group-get-new-newsを実行していて、
gnus-demon-add-handlerは指定関数をタイマーに登録(指定時間毎に定期実行)していました。
なので、gnus-demon-add-rescanを実行すれば良さそうなんですが、
gnus-demon-add-rescanを実行している箇所が見つかりませんでした。
タイマー(定期実行処理)を保持していると思われる変数gnus-demon-timersの値もnilになっているので、
どうやらデフォルトでは新着メールの自動確認は行われないようです。
んじゃ、Gnus開始時に実行するようにすれば良いよね。というわけで、
(add-hook 'gnus-started-hook 'gnus-demon-add-rescan t)
として解決。・・・とはいきませんでした。。
タイマーは登録されているが・・・
上記設定により、Gnus開始後、gnus-demon-timersにgnus-demon-add-rescanを実行するタイマーは
登録されていたのですが、実行間隔が7200とか3600とかになっていました。
新着メール確認が1時間(3600秒)毎とか。どんなゆとり世代やねん。。
何故なのかとソースを見てみると、指定された時間にgnus-demon-timestepという変数の値を掛けていました。
gnus-demon-timestepはデフォルトで60になっていましたが、ややこしいので1を設定しました。
これで、1分毎に実行されるだろ!・・・とはいきませんでした。。
タイマーは1分になっているが・・・
それでもgnus-demon-scan-newsは実行されないので、edebugを以下の関数に仕掛けてデバッグしました。
(defun gnus-demon-run-callback (func &optional idle) "Run FUNC if Emacs has been idle for longer than IDLE seconds." (unless gnus-inhibit-demon (when (or (not idle) (and (eq idle t) (> (gnus-demon-idle-since) 0)) (<= idle (gnus-demon-idle-since))) (with-local-quit (ignore-errors (funcall func))))))
gnus-demon-run-callbackは、タイマーが実行する関数で、引数でgnus-demon-scan-newsが渡されます。
で、第2引数のidleには
(gnus-demon-add-handler 'gnus-demon-scan-news 120 60)
と指定された場合は60が渡ってくるのですが、gnus-demon-idle-sinceが0.0を返すため、 funcallステートメント(gnus-demon-scan-news)が実行されません。
gnus-demon-idle-sinceという関数の定義は以下のようになっています。
(defun gnus-demon-idle-since () "Return the number of seconds since when Emacs is idle." (if (featurep 'xemacs) (itimer-time-difference (current-time) last-command-event-time) (float-time (or (current-idle-time) '(0 0 0)))))
私にはロジックがよく理解できなかったんですが(待機秒数を返している?)、
デバッグした限りでは、戻り値は0.0となり、idleに正の整数が渡ってくると一向にfuncallまで処理がいかないため、
(gnus-demon-add-handler 'gnus-demon-scan-news 120 nil)
上記のようにnilを指定することで、ようやくgnus-demon-scan-newsが実行されるようになりました。
gnus-demon-add-handleの指定方法
上記した通り、Gnusのソースでは第2引数、第3引数、ともに数値を指定している場合もあるので、
gnus-demon-idle-sinceが0.0以外の数値を返し、処理が実行されるケースもあるのでしょうが、
以下のように指定するのが良いのではと思われます。
; 普通のタイマーで登録する場合(Emacsの状態に関わらず定期実行) (gnus-demon-add-handler 'gnus-demon-scan-news 120 nil) ; アイドルタイマーで登録する場合(Emacsが待機状態の時のみ定期実行) (gnus-demon-add-handler 'gnus-demon-scan-news nil 120)
gnus-demon-add-handlerの、
第2引数が指定された場合、run-with-timerが実行され、
第2引数がnilで第3引数が指定された場合、run-with-idle-timerが実行されます。
その他
あとがき
何で新着メールの自動確認ごときで、こんなにてこずるのか・・・。
カスタマイズ変数設定でOKな感じにしとくのが普通じゃないの?
多機能かもしんないけど、使いにくさハンパねぇ・・・。
サマリバッファは更新されないままなので、それも何とかしたいなぁ。