Source

calendar / appt.el

Diff from to
 ;;; appt.el --- appointment notification functions.
 ;; Keywords: calendar
 
-;; Copyright (C) 1989, 1990, 1994 Free Software Foundation, Inc.
+;; Copyright (C) 1989, 1990, 1994, 1998 Free Software Foundation, Inc.
 
 ;; Author: Neil Mager <neilm@juliet.ll.mit.edu>
 ;; Maintainer: FSF
 
 ;;
 ;; appt.el - visible and/or audible notification of
-;;           appointments from ~/diary file generated from
-;;           Edward M. Reingold's calendar.el.
+;;           appointments from ~/diary file.
 ;;
 ;; Version 2.1
 ;;
 ;;; ******* It is necessary to invoke 'display-time' and ********
 ;;; ******* 'appt-initialize' for this to work properly. ********
 ;;; 
-;;; A message will be displayed in the mode line of the emacs buffer 
-;;; and (if the user desires) the terminal will beep and display a message 
-;;; from the diary in the mini-buffer, or the user may select to 
+;;; A message will be displayed in the mode line of the Emacs buffer 
+;;; and (if you request) the terminal will beep and display a message 
+;;; from the diary in the mini-buffer, or you can choose to 
 ;;; have a message displayed in a new buffer.
 ;;;
 ;;; Variables of note:
 ;;; 
 ;;; Based upon the above lines in your .emacs and diary files, 
 ;;; the calendar and diary will be displayed when you enter
-;;; emacs and your appointments list will automatically be created.  
+;;; Emacs and your appointments list will automatically be created.  
 ;;; You will then be reminded at 9:20am about your coffee break 
 ;;; and at 11:50am to go to lunch.
 ;;;
 ;;; Meta-x appt-add and Meta-x appt-delete.  (This does not modify your 
 ;;; diary file, so these will be forgotten when you exit emacs.)
 ;;;
-;;; Additionally, the appointments list is recreated automatically at 12:01am 
-;;; for those who do not logout every day or are programming late.
+;;;  Additionally, the appointments list is recreated automatically 
+;;;  at 12:01am for those who do not logout every day or are programming 
+;;;  late.
 ;;;
 ;;; You can have special appointments which execute arbitrary code rather than
 ;;; simply notifying you -- sort of like the unix "cron" facility.  The syntax
   :type 'boolean
   :group 'appt)
 
+;;;###autoload
 (defcustom appt-display-duration 10
   "*The number of seconds an appointment message is displayed in its own 
  window if appt-announce-method is 'appt-window-announce."
 The original list is generated from the today's `diary-entries-list'. 
 The number before each time/message is the time in minutes from midnight.")
 
-(defconst max-time 1439
+(defconst appt-max-time 1439
   "11:59pm in minutes - number of minutes in a day minus 1.")
 
 (defconst appt-check-tick -1)
       (message "%s" str))
     ))
 
-
+(defvar appt-buffer-name " *appt-buf*"
+  "Name of the appointments buffer.")
 
 (defvar appt-frame-defaults nil)
 (defvaralias 'appt-screen-defaults 'appt-frame-defaults)
 	  ((= n 1) (message "1 appointment today."))
 	  (t (message "%d appointments today." n)))))
 
-(defvar appt-buffer-name " *appt-buf*"
-  "Name of the appointments buffer.")
 
 (defun appt-beep (&optional final-p)
   (cond ((null appt-audible) nil)
               Thursday
                 11:45am Lunch meeting.
   
- The following variables control the action of the notification:
+The following variables control appointment notification:
  
 `appt-issue-message'
        If t, the diary buffer is checked for appointments.
 		 (cur-min (nth 1 now))
 		 (cur-comp-time (+ (* cur-hour 60) cur-min))
 
+	       ;; At the first check in any given day, update our 
+	       ;; appointments to today's list.
+
 	    ;; If the current time is the same as the tick, just return.
 	    ;; This means that this function has been called more than once
 	    ;; in the current minute, which is not useful.
        ;; today's list.  Show the diary entries (tjc).
        (if turnover-p (diary 1))
        ;;
-       ;; Get the first time off of the list and calculate the number
-       ;; of minutes until the appointment.
+	  ;; If there are entries in the list, and the
+	  ;; user wants a message issued,
+	  ;; get the first time off of the list 
+	  ;; and calculate the number of minutes until the appointment.
+
        (if (and appt-issue-message appt-time-msg-list)
 	   (let ((appt-comp-time (car (car (car appt-time-msg-list)))))
 	     (setq min-to-app (- appt-comp-time cur-comp-time))
 		   (setq appt-comp-time 
 			 (car (car (car appt-time-msg-list))))))
 	     ;;
-	     ;; If we have an appointment between midnight and warning-time
-	     ;; minutes after midnight, we must begin to issue a message
-	     ;; before midnight.  Midnight is considered 0 minutes and 11:59pm
-	     ;; is 1439 minutes. Therefore we must recalculate the minutes to
-	     ;; appointment variable. It is equal to the number of minutes
-	     ;; before midnight plus the number of minutes after midnight our
-	     ;; appointment is.
-	     ;;
-	     ;; ## I don't think this does anything -- it would if it were
-	     ;; (for example) a 12:01am appt on the list at 11:55pm, but that
-	     ;; can't ever happen, because the applicable 12:01am appt is for
-	     ;; tomorrow, not today, and we only have today's diary list.
-	     ;; It's not simply a matter of concatenating two days together,
-	     ;; either, because then tuesday's appts would be signalled on
-	     ;; monday.  We have to do a real one-day lookahead -- keep a list
-	     ;; of tomorrow's appts, and check it when near midnight.
-	     ;;
-	     (if (and (< appt-comp-time (apply 'max appt-msg-countdown-list))
-		      (> (+ cur-comp-time (apply 'max appt-msg-countdown-list))
-			 max-time))
-		 (setq min-to-app (+ (- (1+ max-time) cur-comp-time))
+		;; If we have an appointment between midnight and
+		;; warning-time minutes after midnight, we must begin
+		;; to issue a message before midnight.  Midnight is
+		;; considered 0 minutes and 11:59pm is 1439
+		;; minutes. Therefore we must recalculate the minutes
+		;; to appointment variable. It is equal to the number
+		;; of minutes before midnight plus the number of
+		;; minutes after midnight our appointment is.
+		;;
+		;; ## I don't think this does anything -- it would if
+		;; it were (for example) a 12:01am appt on the list at
+		;; 11:55pm, but that can't ever happen, because the
+		;; applicable 12:01am appt is for tomorrow, not today,
+		;; and we only have today's diary list.  It's not
+		;; simply a matter of concatenating two days together,
+		;; either, because then tuesday's appts would be
+		;; signalled on monday.  We have to do a real one-day
+		;; lookahead -- keep a list of tomorrow's appts, and
+		;; check it when near midnight.
+		;;
+		(if (and (< appt-comp-time 
+			    (apply 'max appt-msg-countdown-list))
+			 (> (+ cur-comp-time 
+			       (apply 'max appt-msg-countdown-list))
+			    appt-max-time))
+		    (setq min-to-app (+ (- (1+ appt-max-time) cur-comp-time))
 		       appt-comp-time))
 	     ;;
 	     ;; issue warning if the appointment time is within warning-time
 			 (car appt-time-msg-list))
 		;; update mode line and expire if necessary
 		(appt-display-mode-line min-to-app)
-		;; if it's expired, remove it.
+		  ;; When an appointment is reached,
+		  ;; delete it from the list.
+		  ;; Reset the count to 0 in case we display another
+		  ;; appointment on the next cycle.
 		(if (= min-to-app 0)
 		    (setq appt-time-msg-list 
-			  (cdr appt-time-msg-list))))
+			    (cdr appt-time-msg-list)
+			    )))
 	       (t
 		;; else we're not near any appointment, or there are no
 		;; apointments; make sure mode line is clear.
 		 ") %-"))
 	     (pop-to-buffer appt-disp-buf)
 	     (insert (car (cdr appt)))
-	     (shrink-window-if-larger-than-buffer
-	       (get-buffer-window appt-disp-buf))
+	      (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf))
 	     (set-buffer-modified-p nil)
 	     (sit-for appt-display-duration))
 	(and appt-disp-buf (kill-buffer appt-disp-buf)))))))
 ;;;###autoload
 (defun appt-make-list ()
   "Don't call this directly; call appt-initialize or appt-diary-entries."
+  ;; Clear the appointments list, then fill it in from the diary.
   (setq appt-time-msg-list nil)
   (if diary-entries-list
 
            ;; appt-time-msg-list. Then sort the list.
 
       (let ((entry-list diary-entries-list)
-	    (new-appts '()))
+	    (new-appts '())
+	    (new-time-string ""))
+	;; Skip diary entries for dates before today.
+	(while (and entry-list
+		    (calendar-date-compare
+		     (car entry-list) (list (calendar-current-date))))
+	  (setq entry-list (cdr entry-list)))
+	;; Parse the entries for today.
 	(while (and entry-list
 		    (calendar-date-equal
 		      (calendar-current-date) (car (car entry-list))))
 ;;Append the smallest element left into the new list, and remove
 ;;it from the original list.
 (defun appt-sort-list (appt-list)
-  (sort (copy-sequence appt-list)
-	(function (lambda (x y)
-	  (< (car (car x)) (car (car y)))))))
+  (let ((order-list nil))
+    (while appt-list
+      (let* ((element (car appt-list))
+             (element-time (car (car element)))
+             (tmp-list (cdr appt-list)))
+        (while tmp-list
+          (if (< element-time (car (car (car tmp-list))))
+              nil
+            (setq element (car tmp-list))
+            (setq element-time (car (car element))))
+          (setq tmp-list (cdr tmp-list)))
+        (setq order-list (append order-list (list element)))
+        (setq appt-list (delq element appt-list))))
+    order-list))
+
 
 (defun appt-convert-time (time2conv)
   "Convert hour:min[am/pm] format to minutes from midnight."
 	((string-match "^[ \t]*noon[ \t]*\\'" time2conv)
 	 (* 12 60))
 	(t
-         (let ((hr 0)
+         (let ((conv-time 0)
+	       (hr 0)
                (min 0))
            (or (string-match
                  "\\`[ \t]*\\([0-9][0-9]?\\)[ \t]*\\(:[ \t]*\\([0-9][0-9]\\)\\)?[ 
      (setq display-time-hook (cons appt-check display-time-hook)))
    ))
 
+;defvar appt-timer nil
+;  "Timer used for diary appointment notifications (`appt-check').")
+
+;(unless appt-timer
+;  (progn
+;    (setq appt-timer (make-itimer))
+;    (set-itimer-fun
+ 
+
 ;;; appt.el ends here