- (when gnus-demon-timer
- (nnheader-cancel-timer gnus-demon-timer))
- (setq gnus-demon-timer nil
- gnus-demon-idle-has-been-called nil)
- (condition-case ()
- (nnheader-cancel-function-timers 'gnus-demon)
- (error t)))
-
-(defun gnus-demon-is-idle-p ()
- "Whether Emacs is idle or not."
- ;; We do this simply by comparing the 100 most recent keystrokes
- ;; with the ones we had last time. If they are the same, one might
- ;; guess that Emacs is indeed idle. This only makes sense if one
- ;; calls this function seldom -- like once a minute, which is what
- ;; we do here.
- (let ((keys (recent-keys)))
- (or (equal keys gnus-demon-last-keys)
- (progn
- (setq gnus-demon-last-keys keys)
- nil))))
-
-(defun gnus-demon-time-to-step (time)
- "Find out how many seconds to TIME, which is on the form \"17:43\"."
- (if (not (stringp time))
- time
- (let* ((now (current-time))
- ;; obtain NOW as discrete components -- make a vector for speed
- (nowParts (decode-time now))
- ;; obtain THEN as discrete components
- (thenParts (parse-time-string time))
- (thenHour (elt thenParts 2))
- (thenMin (elt thenParts 1))
- ;; convert time as elements into number of seconds since EPOCH.
- (then (encode-time 0
- thenMin
- thenHour
- ;; If THEN is earlier than NOW, make it
- ;; same time tomorrow. Doc for encode-time
- ;; says that this is OK.
- (+ (elt nowParts 3)
- (if (or (< thenHour (elt nowParts 2))
- (and (= thenHour (elt nowParts 2))
- (<= thenMin (elt nowParts 1))))
- 1 0))
- (elt nowParts 4)
- (elt nowParts 5)
- (elt nowParts 6)
- (elt nowParts 7)
- (elt nowParts 8)))
- ;; calculate number of seconds between NOW and THEN
- (diff (+ (* 65536 (- (car then) (car now)))
- (- (cadr then) (cadr now)))))
- ;; return number of timesteps in the number of seconds
- (round (/ diff gnus-demon-timestep)))))
-
-(defun gnus-demon ()
- "The Gnus daemon that takes care of running all Gnus handlers."
- ;; Increase or reset the time Emacs has been idle.
- (if (gnus-demon-is-idle-p)
- (incf gnus-demon-idle-time)
- (setq gnus-demon-idle-time 0)
- (setq gnus-demon-idle-has-been-called nil))
- ;; Disable all daemonic stuff if we're in the minibuffer
- (when (and (not (window-minibuffer-p (selected-window)))
- (not gnus-inhibit-demon))
- ;; Then we go through all the handler and call those that are
- ;; sufficiently ripe.
- (let ((handlers gnus-demon-handler-state)
- (gnus-inhibit-demon t)
- ;; Try to avoid dialog boxes, e.g. by Mailcrypt.
- ;; Unfortunately, Emacs 20's `message-or-box...' doesn't
- ;; obey `use-dialog-box'.
- use-dialog-box (last-nonmenu-event 10)
- handler time idle)
- (while handlers
- (setq handler (pop handlers))
- (cond
- ((numberp (setq time (nth 1 handler)))
- ;; These handlers use a regular timeout mechanism. We decrease
- ;; the timer if it hasn't reached zero yet.
- (unless (zerop time)
- (setcar (nthcdr 1 handler) (decf time)))
- (and (zerop time) ; If the timer now is zero...
- ;; Test for appropriate idleness
- (progn
- (setq idle (nth 2 handler))
- (cond
- ((null idle) t) ; Don't care about idle.
- ((numberp idle) ; Numerical idle...
- (< idle gnus-demon-idle-time)) ; Idle timed out.
- (t (< 0 gnus-demon-idle-time)))) ; Or just need to be idle.
- ;; So we call the handler.
- (progn
- (ignore-errors (funcall (car handler)))
- ;; And reset the timer.
- (setcar (nthcdr 1 handler)
- (gnus-demon-time-to-step
- (nth 1 (assq (car handler) gnus-demon-handlers)))))))
- ;; These are only supposed to be called when Emacs is idle.
- ((null (setq idle (nth 2 handler)))
- ;; We do nothing.
- )
- ((and (not (numberp idle))
- (gnus-demon-is-idle-p))
- ;; We want to call this handler each and every time that
- ;; Emacs is idle.
- (ignore-errors (funcall (car handler))))
- (t
- ;; We want to call this handler only if Emacs has been idle
- ;; for a specified number of timesteps.
- (and (not (memq (car handler) gnus-demon-idle-has-been-called))
- (< idle gnus-demon-idle-time)
- (gnus-demon-is-idle-p)
- (progn
- (ignore-errors (funcall (car handler)))
- ;; Make sure the handler won't be called once more in
- ;; this idle-cycle.
- (push (car handler) gnus-demon-idle-has-been-called)))))))))
-
-(defun gnus-demon-add-nocem ()
- "Add daemonic NoCeM handling to Gnus."
- (gnus-demon-add-handler 'gnus-demon-scan-nocem 60 30))
-
-(defun gnus-demon-scan-nocem ()
- "Scan NoCeM groups for NoCeM messages."
- (save-window-excursion
- (gnus-nocem-scan-groups)))