1 ;;; gnus-demon.el --- daemonic Gnus behavior
3 ;; Copyright (C) 1995-2015 Free Software Foundation, Inc.
5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
27 (eval-when-compile (require 'cl))
35 (defgroup gnus-demon nil
39 (defcustom gnus-demon-handlers nil
40 "Alist of daemonic handlers to be run at intervals.
41 Each handler is a list on the form
45 FUNCTION is the function to be called. TIME is the number of
46 `gnus-demon-timestep's between each call.
47 If nil, never call. If t, call each `gnus-demon-timestep'.
49 If IDLE is t, only call each time Emacs has been idle for TIME.
50 If IDLE is a number, only call when Emacs has been idle more than
51 this number of `gnus-demon-timestep's.
52 If IDLE is nil, don't care about idleness.
53 If IDLE is a number and TIME is nil, then call once each time
54 Emacs has been idle for IDLE `gnus-demon-timestep's."
56 :type '(repeat (list function
58 (const :tag "never" nil)
60 (integer :tag "steps" 1))
62 (const :tag "don't care" nil)
63 (const :tag "for a while" t)
64 (integer :tag "steps" 1)))))
66 (defcustom gnus-demon-timestep 60
67 "Number of seconds in each demon timestep."
71 ;;; Internal variables.
73 (defvar gnus-demon-timers nil
74 "Plist of idle timers which are running.")
75 (defvar gnus-inhibit-demon nil
76 "If non-nil, no daemonic function will be run.")
80 (defun gnus-demon-add-handler (function time idle)
81 "Add the handler FUNCTION to be run at TIME and IDLE."
82 ;; First remove any old handlers that use this function.
83 (gnus-demon-remove-handler function)
84 ;; Then add the new one.
85 (push (list function time idle) gnus-demon-handlers)
88 (defun gnus-demon-remove-handler (function &optional no-init)
89 "Remove the handler FUNCTION from the list of handlers."
90 (gnus-alist-pull function gnus-demon-handlers)
94 (defun gnus-demon-idle-since ()
95 "Return the number of seconds since when Emacs is idle."
96 (if (featurep 'xemacs)
97 (itimer-time-difference (current-time) last-command-event-time)
98 (float-time (or (current-idle-time)
101 (defun gnus-demon-run-callback (func &optional idle time special)
102 "Run FUNC if Emacs has been idle for longer than IDLE seconds.
103 If not, and a TIME is given, restart a new idle timer, so FUNC
104 can be called at the next opportunity. Such a special idle run is
105 marked with SPECIAL."
106 (unless gnus-inhibit-demon
111 (setq gnus-demon-timers
112 (plist-put gnus-demon-timers func
113 (run-with-timer time time 'gnus-demon-run-callback
115 ((and idle (> idle (gnus-demon-idle-since)))
117 (nnheader-cancel-timer (plist-get gnus-demon-timers func))
118 (setq gnus-demon-timers
119 (plist-put gnus-demon-timers func
120 (run-with-idle-timer idle nil
121 'gnus-demon-run-callback
123 (return-from run-callback)))
128 (defun gnus-demon-init ()
129 "Initialize the Gnus daemon."
132 (dolist (handler gnus-demon-handlers)
134 (let* ((func (nth 0 handler))
135 (time (nth 1 handler))
136 (idle (nth 2 handler))
137 ;; Compute time according with timestep.
138 ;; If t, replace by 1
139 (time (cond ((eq time t)
144 (* (gnus-demon-time-to-step time) gnus-demon-timestep))
146 (* time gnus-demon-timestep))))
147 (idle (cond ((numberp idle)
148 (* idle gnus-demon-timestep))
149 ((and (eq idle t) (numberp time))
157 ;; Only call when Emacs has been idle for `idle'
158 ((and (null time) (numberp idle))
159 (run-with-idle-timer idle t 'gnus-demon-run-callback func))
163 (run-with-timer time time 'gnus-demon-run-callback