AppointmentMode

DiaryMode is good for keeping daily tasks (things like anniversaries and such). With the addition of appt.el it can also be useful for time specific appointments. Here’s the setup I have:

(if (not (featurep 'appt))(require 'appt))
(appt-initialize)                                             ; XEmacs; use (appt-activate 1) for GNU Emacs
(setq appt-msg-countdown-list '(10 5 1)                       ; XEmacs
      appt-audible (cons 3 .5)
      appt-check-time-syntax nil                              ; XEmacs
      appt-announce-method 'appt-persistent-message-announce  ; XEmacs
      appt-display-duration 59)                               
(defun diary-save-hook ()
"Stuff to do when saving the diary files."
  (appt-initialize))
(defun add-diary-save-hook ()
  "find-file-hooks hook to add the diary-save-hook when appropriate"
  (if (string-match "diary" (buffer-name))
      (add-hook 'after-save-hook 'diary-save-hook)))
(add-hook 'find-file-hooks 'add-diary-save-hook)

The appt-initialize function is what does all the dirty work. It actually scans the diary-file for appointments and adds them to the list of reminders. If you add an appointment to your diary and don’t run appt-initialize, you won’t be reminded. That’s why I set the after-save-hook for the diary buffer to call appt-initialize. Because after-save-hook is always buffer local, you have to set it after the buffer is created. That’s why I had to add another hook to find-file-hooks.

Check the variable docs (C-h v) on each of the variables to see what they do. The docs are self-explanatory.

Enjoy! Update with suggestions and improvements.

DougAlcorn 15 Aug 2002


Here’s nice way to highlight an appointment in a brighter face on the modeline so that you actually notice it’s appeared! (Doesn’t work for me in GNU Emacs CVS unfortunately – ColinMarquardt)

;; ---great bit of code from Jeff Miller to highlight appointments in red on modeline---
(defface appt-face
  '((t (:foreground "red" :background "white")))
  "Face to indicate a current appointment."
  :group 'appt)

(defadvice appt-disp-window (before appt-hilite-more activate)
  (when appt-mode-string
    (put-text-property 1 (- (length appt-mode-string) 1)
		       'face 'appt-face appt-mode-string)))

(defadvice appt-check (after appt-hilite activate)
  (when appt-mode-string
    (put-text-property 1 (- (length appt-mode-string) 1)
		       'face 'appt-face appt-mode-string)
    (force-mode-line-update)))

;; ---------------------------------

Here’s my work in progress. This code should let the xemacs appt.el (which is more featureful) work with GNU Emacs 21.2 at least. The save hook is made buffer local this time. Note that the window announce method seems to be broken.

;; show the time in the status bar. i have customized the form so that it
;; does not display the load average, as i find that distracting
(display-time)

;; compatability - we don't really miss the aliases appt defines anyway.
;; there's no need for this in xemacs or emacs 21.3+
(when (not (fboundp 'defvaralias))
  (defun defvaralias (&rest args)))

(when (require 'appt nil t)
  (setq appt-msg-countdown-list '(10 5 1 0)
        appt-audible (cons 3 .5)
        appt-check-time-syntax nil
        appt-announce-method 'appt-persistant-message-announce
        appt-display-duration 360)

  ;; ding takes a different number of args in gnu emacs - eventually i'll
  ;; redefine this to use my soundcard anyway
  (when (not (featurep 'xemacs))
    (defun appt-beep (&rest args)))

  (defun diary-save-hook ()
    "Stuff to do when saving the diary files."
    (appt-activate 1))

  (defun add-diary-save-hook ()
    "find-file-hooks hook to add the diary-save-hook when appropriate"
    (let* ((diary-file-components (split-string diary-file "/"))
           (diary-buffer-name
            (nth (1- (length diary-file-components)) diary-file-components)))
      (if (string= (buffer-name) diary-buffer-name)
          (add-hook (make-variable-buffer-local 'after-save-hook)
          'diary-save-hook))))

  (add-hook 'find-file-hooks 'add-diary-save-hook)
  (appt-activate 1))

DamienElmes

Is all that stuff supposed to work with EmacsCvs ? Apparently, I have a void-function error with appt-initialize here – zeDek


That was a quick response! I tried the clarification about appt-initialize and replaced all the (appt-initialize)’s with (appt-activate 1)’s in my .emacs, but now I get basically the same message: “Symbol’s function definition is void: appt-activate”. Maybe I’m doing things in the wrong order? – WebMayfield


The info documentation for appointments in 21.1.3 has the following code to be added to ~/.emacs:

     (display-time)
     (add-hook 'diary-hook 'appt-make-list)
     (diary 0)

This has the unfortunate effect that appointments added by ‘appt-add’ are deleted whenever you call ‘M-x diary’ because one of the first things that ‘appt-make-list’ does is set ‘appt-time-msg-list’ to ‘nil’. I fixed this with the following code in my ~/.emacs file:

    (require 'appt)
    (defun my/refresh-appt-list ()
      "Retain currently set appointments."
      (let ((my/appt-list (copy-sequence appt-time-msg-list)))
        (appt-make-list)
        (setq appt-time-msg-list 
              (appt-sort-list
               (nconc appt-time-msg-list my/appt-list)))))
    (add-hook 'diary-hook 'my/refresh-appt-list)

CategoryCalendar DiaryMode CalendarMode