aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2004-01-11 22:24:57 +0000
committerGlenn Morris2004-01-11 22:24:57 +0000
commit8d638c1b96575ebf30b66a54e249ce09eac59a47 (patch)
treea50b1480c88e21e999d58ade55110b1ba92b1eda
parentde7515d6b8aef2312120f3749d2423cb1f8f332f (diff)
downloademacs-8d638c1b96575ebf30b66a54e249ce09eac59a47.tar.gz
emacs-8d638c1b96575ebf30b66a54e249ce09eac59a47.zip
Update copyright and commentary.
(appt-issue-message): Delete (see appt-activate). (appt-visible, appt-msg-window): Make obsolete, in favour of appt-display-format. (appt-display-mode-line, appt-display-duration) (appt-display-diary, appt-time-msg-list, appt-mode-string) (appt-prev-comp-time, appt-display-count, appt-timer) (appt-convert-time): Doc change. (appt-disp-window-function, appt-delete-window-function): Use defcustom rather than defvar. (appt-display-format): New variable. (appt-display-message): New function with display code from appt-check. (appt-check): Add optional FORCE argument. Doc change. Add appt-make-list to diary-hook if displaying diary. Remove checking of view-diary-entries-initially. Message display section removed to new function appt-display-message. (appt-display-window): Doc change. Remove unused internal var this-buffer. Do not beep, since appt-display-message does that. (appt-make-list): Doc change. Use caar. (appt-sort-list): Simplify by using builtin sort function. (appt-update-list): New function for updating appts when diary is saved. (appt-activate): New autoloaded function to toggle package functionality.
-rw-r--r--lisp/calendar/appt.el415
1 files changed, 219 insertions, 196 deletions
diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el
index 8c1562385c9..825bd936475 100644
--- a/lisp/calendar/appt.el
+++ b/lisp/calendar/appt.el
@@ -1,6 +1,6 @@
1;;; appt.el --- appointment notification functions 1;;; appt.el --- appointment notification functions
2 2
3;; Copyright (C) 1989, 1990, 1994, 1998 Free Software Foundation, Inc. 3;; Copyright (C) 1989, 1990, 1994, 1998, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Neil Mager <neilm@juliet.ll.mit.edu> 5;; Author: Neil Mager <neilm@juliet.ll.mit.edu>
6;; Maintainer: FSF 6;; Maintainer: FSF
@@ -27,7 +27,7 @@
27 27
28;; 28;;
29;; appt.el - visible and/or audible notification of 29;; appt.el - visible and/or audible notification of
30;; appointments from ~/diary file. 30;; appointments from diary file.
31;; 31;;
32;;; 32;;;
33;;; Thanks to Edward M. Reingold for much help and many suggestions, 33;;; Thanks to Edward M. Reingold for much help and many suggestions,
@@ -35,62 +35,41 @@
35;;; 35;;;
36;;; 36;;;
37;;; This functions in this file will alert the user of a 37;;; This functions in this file will alert the user of a
38;;; pending appointment based on their diary file. 38;;; pending appointment based on his/her diary file. This package
39;;; is documented in the Emacs manual.
39;;; 40;;;
40;;; A message will be displayed in the mode line of the Emacs buffer 41;;; To activate this package, simply use (appt-activate 1).
41;;; and (if you request) the terminal will beep and display a message 42;;; A `diary-file' with appointments of the format described in the
42;;; from the diary in the mini-buffer, or you can choose to 43;;; documentation of the function `appt-check' is required.
43;;; have a message displayed in a new buffer. 44;;; Relevant customizable variables are also listed in the
45;;; documentation of that function.
46;;;
47;;; Today's appointment list is initialized from the diary when this
48;;; package is activated. Additionally, the appointments list is
49;;; recreated automatically at 12:01am for those who do not logout
50;;; every day or are programming late. It is also updated when the
51;;; `diary-file' is saved. Calling `appt-check' with an argument forces
52;;; a re-initialization at any time.
44;;; 53;;;
45;;; The variable `appt-message-warning-time' allows the 54;;; In order to add or delete items from today's list, without
46;;; user to specify how much notice they want before the appointment. The 55;;; changing the diary file, use `appt-add' and `appt-delete'.
47;;; variable `appt-issue-message' specifies whether the user wants
48;;; to be notified of a pending appointment.
49;;;
50;;; In order to use the appt package, you only need
51;;; to load it---provided you have appointments.
52;;;
53;;; Before that, you can also set some options if you want
54;;; (setq view-diary-entries-initially t)
55;;; (setq appt-issue-message t)
56;;;
57;;; This is an example of what can be in your diary file:
58;;; Monday
59;;; 9:30am Coffee break
60;;; 12:00pm Lunch
61;;;
62;;; Based upon the above lines in your .emacs and diary files,
63;;; the calendar and diary will be displayed when you enter
64;;; Emacs and your appointments list will automatically be created.
65;;; You will then be reminded at 9:20am about your coffee break
66;;; and at 11:50am to go to lunch.
67;;;
68;;; Use describe-function on appt-check for a description of other variables
69;;; that can be used to personalize the notification system.
70;;;
71;;; In order to add or delete items from todays list, use appt-add
72;;; and appt-delete.
73;;;
74;;; Additionally, the appointments list is recreated automatically
75;;; at 12:01am for those who do not logout every day or are programming
76;;; late.
77;;; 56;;;
57
78;;; Brief internal description - Skip this if you are not interested! 58;;; Brief internal description - Skip this if you are not interested!
79;;; 59;;;
80;;; The function appt-make-list creates the appointments list which appt-check 60;;; The function `appt-make-list' creates the appointments list which
81;;; reads. This is all done automatically. 61;;; `appt-check' reads.
82;;; It is invoked from the function list-diary-entries.
83;;; 62;;;
84;;; You can change the way the appointment window is created/deleted by 63;;; You can change the way the appointment window is created/deleted by
85;;; setting the variables 64;;; setting the variables
86;;; 65;;;
87;;; appt-disp-window-function 66;;; appt-disp-window-function
88;;; and 67;;; and
89;;; appt-delete-window-function 68;;; appt-delete-window-function
90;;; 69;;;
91;;; For instance, these variables can be set to functions that display 70;;; For instance, these variables could be set to functions that display
92;;; appointments in pop-up frames, which are lowered or iconified after 71;;; appointments in pop-up frames, which are lowered or iconified after
93;;; appt-display-interval minutes. 72;;; `appt-display-interval' minutes.
94;;; 73;;;
95 74
96;;; Code: 75;;; Code:
@@ -98,15 +77,6 @@
98;; Make sure calendar is loaded when we compile this. 77;; Make sure calendar is loaded when we compile this.
99(require 'calendar) 78(require 'calendar)
100 79
101(provide 'appt)
102
103;;;###autoload
104(defcustom appt-issue-message t
105 "*Non-nil means check for appointments in the diary buffer.
106To be detected, the diary entry must have the time
107as the first thing on a line."
108 :type 'boolean
109 :group 'appt)
110 80
111;;;###autoload 81;;;###autoload
112(defcustom appt-message-warning-time 12 82(defcustom appt-message-warning-time 12
@@ -122,80 +92,149 @@ as the first thing on a line."
122 92
123;;;###autoload 93;;;###autoload
124(defcustom appt-visible t 94(defcustom appt-visible t
125 "*Non-nil means display appointment message in echo area." 95 "*Non-nil means display appointment message in echo area.
96This variable is only relevant if `appt-msg-window' is nil."
126 :type 'boolean 97 :type 'boolean
127 :group 'appt) 98 :group 'appt)
128 99
100(make-obsolete-variable 'appt-visible 'appt-display-format "21.4")
101
129;;;###autoload 102;;;###autoload
130(defcustom appt-display-mode-line t 103(defcustom appt-msg-window t
131 "*Non-nil means display minutes to appointment and time on the mode line." 104 "*Non-nil means display appointment message in another window.
105If non-nil, this variable overrides `appt-visible'."
132 :type 'boolean 106 :type 'boolean
133 :group 'appt) 107 :group 'appt)
134 108
109(make-obsolete-variable 'appt-msg-window 'appt-display-format "21.4")
110
111;; TODO - add popup.
112(defcustom appt-display-format (cond (appt-msg-window 'window)
113 (appt-visible 'echo)
114 (t nil))
115 "How appointment reminders should be displayed.
116The options are:
117 window - use a separate window
118 echo - use the echo area
119 nil - no visible reminder.
120See also `appt-audible' and `appt-display-mode-line'."
121 :type '(choice
122 (const :tag "Separate window" window)
123 (const :tag "Echo-area" echo)
124 (const :tag "No visible display" nil))
125 :group 'appt
126 :version "21.4")
127
135;;;###autoload 128;;;###autoload
136(defcustom appt-msg-window t 129(defcustom appt-display-mode-line t
137 "*Non-nil means display appointment message in another window." 130 "*Non-nil means display minutes to appointment and time on the mode line.
131This is in addition to any other display of appointment messages."
138 :type 'boolean 132 :type 'boolean
139 :group 'appt) 133 :group 'appt)
140 134
141;;;###autoload 135;;;###autoload
142(defcustom appt-display-duration 10 136(defcustom appt-display-duration 10
143 "*The number of seconds an appointment message is displayed." 137 "*The number of seconds an appointment message is displayed.
138Only relevant if reminders are to be displayed in their own window."
144 :type 'integer 139 :type 'integer
145 :group 'appt) 140 :group 'appt)
146 141
147;;;###autoload 142;;;###autoload
148(defcustom appt-display-diary t 143(defcustom appt-display-diary t
149 "*Non-nil means to display the next days diary on the screen. 144 "*Non-nil displays the diary when the appointment list is first initialized.
150This will occur at midnight when the appointment list is updated." 145This will occur at midnight when the appointment list is updated."
151 :type 'boolean 146 :type 'boolean
152 :group 'appt) 147 :group 'appt)
153 148
154(defvar appt-time-msg-list nil
155 "The list of appointments for today.
156Use `appt-add' and `appt-delete' to add and delete appointments from list.
157The original list is generated from the today's `diary-entries-list'.
158The number before each time/message is the time in minutes from midnight.")
159
160(defconst appt-max-time 1439
161 "11:59pm in minutes - number of minutes in a day minus 1.")
162
163(defcustom appt-display-interval 3 149(defcustom appt-display-interval 3
164 "*Number of minutes to wait between checking the appointment list." 150 "*Number of minutes to wait between checking the appointment list."
165 :type 'integer 151 :type 'integer
166 :group 'appt) 152 :group 'appt)
167 153
154(defcustom appt-disp-window-function 'appt-disp-window
155 "Function called to display appointment window.
156Only relevant if reminders are being displayed in a window."
157 :type '(choice (const appt-disp-window)
158 function)
159 :group 'appt)
160
161(defcustom appt-delete-window-function 'appt-delete-window
162 "Function called to remove appointment window and buffer.
163Only relevant if reminders are being displayed in a window."
164 :type '(choice (const appt-delete-window)
165 function)
166 :group 'appt)
167
168
169;;; Internal variables below this point.
170
168(defvar appt-buffer-name " *appt-buf*" 171(defvar appt-buffer-name " *appt-buf*"
169 "Name of the appointments buffer.") 172 "Name of the appointments buffer.")
170 173
171(defvar appt-disp-window-function 'appt-disp-window 174(defvar appt-time-msg-list nil
172 "Function called to display appointment window.") 175 "The list of appointments for today.
176Use `appt-add' and `appt-delete' to add and delete appointments.
177The original list is generated from today's `diary-entries-list', and
178can be regenerated using the function `appt-check'.
179Each element of the generated list has the form (MINUTES) STRING; where
180MINUTES is the time in minutes of the appointment after midnight, and
181STRING is the description of the appointment.")
173 182
174(defvar appt-delete-window-function 'appt-delete-window 183(defconst appt-max-time 1439
175 "Function called to remove appointment window and buffer.") 184 "11:59pm in minutes - number of minutes in a day minus 1.")
176 185
177(defvar appt-mode-string nil 186(defvar appt-mode-string nil
178 "String being displayed in the mode line saying you have an appointment. 187 "String being displayed in the mode line saying you have an appointment.
179The actual string includes the amount of time till the appointment.") 188The actual string includes the amount of time till the appointment.
189Only used if `appt-display-mode-line' is non-nil.")
180 190
181(defvar appt-prev-comp-time nil 191(defvar appt-prev-comp-time nil
182 "Time of day (mins since midnight) at which we last checked appointments.") 192 "Time of day (mins since midnight) at which we last checked appointments.
193A nil value forces the diary file to be (re-)checked for appointments.")
183 194
184(defvar appt-now-displayed nil 195(defvar appt-now-displayed nil
185 "Non-nil when we have started notifying about a appointment that is near.") 196 "Non-nil when we have started notifying about a appointment that is near.")
186 197
187(defvar appt-display-count nil) 198(defvar appt-display-count nil
199 "Internal variable used to count number of consecutive reminders.")
188 200
189(defun appt-check () 201(defvar appt-timer nil
190 "Check for an appointment and update the mode line. 202 "Timer used for diary appointment notifications (`appt-check').
191Note: the time must be the first thing in the line in the diary 203If this is non-nil, appointment checking is active.")
192for a warning to be issued. 204
205
206;;; Functions.
207
208(defun appt-display-message (string mins)
209 "Display a reminder about an appointment.
210The string STRING describes the appointment, due in integer MINS minutes.
211The format of the visible reminder is controlled by `appt-display-format'.
212The variable `appt-audible' controls the audible reminder."
213 (cond ((eq appt-display-format 'window)
214 (funcall appt-disp-window-function
215 (number-to-string mins)
216 (format-time-string "%a %b %e " (current-time))
217 string)
218 (run-at-time (format "%d sec" appt-display-duration)
219 nil
220 appt-delete-window-function))
221 ((eq appt-display-format 'echo)
222 (message "%s" string)))
223 (if appt-audible (beep 1)))
224
225
226(defun appt-check (&optional force)
227 "Check for an appointment and update any reminder display.
228If optional argument FORCE is non-nil, reparse the diary file for
229appointments. Otherwise the diary file is only parsed once per day,
230and when saved.
193 231
194The format of the time can be either 24 hour or am/pm. 232Note: the time must be the first thing in the line in the diary
195Example: 233for a warning to be issued. The format of the time can be either
23424 hour or am/pm. For example:
196 235
197 02/23/89 236 02/23/89
198 18:00 Dinner 237 18:00 Dinner
199 238
200 Thursday 239 Thursday
201 11:45am Lunch meeting. 240 11:45am Lunch meeting.
@@ -203,42 +242,41 @@ Example:
203Appointments are checked every `appt-display-interval' minutes. 242Appointments are checked every `appt-display-interval' minutes.
204The following variables control appointment notification: 243The following variables control appointment notification:
205 244
206`appt-issue-message' 245`appt-display-format'
207 If t, the diary buffer is checked for appointments. 246 Controls the format in which reminders are displayed.
208
209`appt-message-warning-time'
210 Variable used to determine if appointment message
211 should be displayed.
212 247
213`appt-audible' 248`appt-audible'
214 Variable used to determine if appointment is audible. 249 Variable used to determine if reminder is audible.
215 Default is t. 250 Default is t.
216 251
217`appt-visible' 252`appt-message-warning-time'
218 Variable used to determine if appointment message should be 253 Variable used to determine when appointment message
219 displayed in the mini-buffer. Default is t. 254 should first be displayed.
255
256`appt-display-mode-line'
257 If non-nil, a generic message giving the time remaining
258 is shown in the mode-line when an appointment is due.
259
260`appt-display-interval'
261 Interval in minutes at which to check for pending appointments.
220 262
221`appt-msg-window' 263`appt-display-diary'
222 Variable used to determine if appointment message 264 Display the diary buffer when the appointment list is
223 should temporarily appear in another window. Mutually exclusive 265 initialized for the first time in a day.
224 to `appt-visible'. 266
267The following variables are only relevant if reminders are being
268displayed in a window:
225 269
226`appt-display-duration' 270`appt-display-duration'
227 The number of seconds an appointment message 271 The number of seconds an appointment message is displayed.
228 is displayed in another window.
229 272
230`appt-disp-window-function' 273`appt-disp-window-function'
231 Function called to display appointment window. You can customize 274 Function called to display appointment window.
232 appt.el by setting this variable to a function different from the
233 one provided with this package.
234 275
235`appt-delete-window-function' 276`appt-delete-window-function'
236 Function called to remove appointment window and buffer. You can 277 Function called to remove appointment window and buffer."
237 customize appt.el by setting this variable to a function different
238 from the one provided with this package."
239 278
240 (let* ((min-to-app -1) 279 (let* ((min-to-app -1)
241 (new-time "")
242 (prev-appt-mode-string appt-mode-string) 280 (prev-appt-mode-string appt-mode-string)
243 (prev-appt-display-count (or appt-display-count 0)) 281 (prev-appt-display-count (or appt-display-count 0))
244 ;; Non-nil means do a full check for pending appointments 282 ;; Non-nil means do a full check for pending appointments
@@ -248,7 +286,7 @@ The following variables control appointment notification:
248 (full-check 286 (full-check
249 (or (not appt-now-displayed) 287 (or (not appt-now-displayed)
250 ;; This is true every appt-display-interval minutes. 288 ;; This is true every appt-display-interval minutes.
251 (= 0 (mod prev-appt-display-count appt-display-interval)))) 289 (zerop (mod prev-appt-display-count appt-display-interval))))
252 ;; Non-nil means only update the interval displayed in the mode line. 290 ;; Non-nil means only update the interval displayed in the mode line.
253 (mode-line-only 291 (mode-line-only
254 (and (not full-check) appt-now-displayed))) 292 (and (not full-check) appt-now-displayed)))
@@ -267,26 +305,31 @@ The following variables control appointment notification:
267 ;; At the first check in any given day, update our 305 ;; At the first check in any given day, update our
268 ;; appointments to today's list. 306 ;; appointments to today's list.
269 307
270 (if (or (null appt-prev-comp-time) 308 (if (or force
271 (< cur-comp-time appt-prev-comp-time)) 309 (null appt-prev-comp-time) ; first check
310 (< cur-comp-time appt-prev-comp-time)) ; new day
272 (condition-case nil 311 (condition-case nil
273 (progn 312 (progn
274 (if (and view-diary-entries-initially appt-display-diary) 313 (if appt-display-diary
275 (diary) 314 (let ((diary-hook
315 (if (assoc 'appt-make-list diary-hook)
316 diary-hook
317 (cons 'appt-make-list diary-hook))))
318 (diary))
276 (let ((diary-display-hook 'appt-make-list)) 319 (let ((diary-display-hook 'appt-make-list))
277 (diary)))) 320 (diary))))
278 (error nil))) 321 (error nil)))
279 (setq appt-prev-comp-time cur-comp-time)
280 322
281 (setq appt-mode-string nil) 323 (setq appt-prev-comp-time cur-comp-time
282 (setq appt-display-count nil) 324 appt-mode-string nil
325 appt-display-count nil)
283 326
284 ;; If there are entries in the list, and the 327 ;; If there are entries in the list, and the
285 ;; user wants a message issued, 328 ;; user wants a message issued,
286 ;; get the first time off of the list 329 ;; get the first time off of the list
287 ;; and calculate the number of minutes until the appointment. 330 ;; and calculate the number of minutes until the appointment.
288 331
289 (if (and appt-issue-message appt-time-msg-list) 332 (if appt-time-msg-list
290 (let ((appt-comp-time (car (car (car appt-time-msg-list))))) 333 (let ((appt-comp-time (car (car (car appt-time-msg-list)))))
291 (setq min-to-app (- appt-comp-time cur-comp-time)) 334 (setq min-to-app (- appt-comp-time cur-comp-time))
292 335
@@ -317,45 +360,21 @@ The following variables control appointment notification:
317 360
318 (when (and (<= min-to-app appt-message-warning-time) 361 (when (and (<= min-to-app appt-message-warning-time)
319 (>= min-to-app 0)) 362 (>= min-to-app 0))
320 (setq appt-now-displayed t) 363 (setq appt-now-displayed t
321 (setq appt-display-count 364 appt-display-count (1+ prev-appt-display-count))
322 (1+ prev-appt-display-count))
323 (unless mode-line-only 365 (unless mode-line-only
324 (if appt-msg-window 366 (appt-display-message (cadr (car appt-time-msg-list))
325 (progn 367 min-to-app))
326 (setq new-time (format-time-string "%a %b %e "
327 (current-time)))
328 (funcall
329 appt-disp-window-function
330 (number-to-string min-to-app) new-time
331 (car (cdr (car appt-time-msg-list))))
332
333 (run-at-time
334 (format "%d sec" appt-display-duration)
335 nil
336 appt-delete-window-function))
337 ;;; else
338
339 (if appt-visible
340 (message "%s"
341 (car (cdr (car appt-time-msg-list)))))
342
343 (if appt-audible
344 (beep 1))))
345
346 (when appt-display-mode-line 368 (when appt-display-mode-line
347 (setq appt-mode-string 369 (setq appt-mode-string
348 (concat " App't in " 370 (format " App't in %s min." min-to-app)))
349 (number-to-string min-to-app)
350 " min. ")))
351 371
352 ;; When an appointment is reached, 372 ;; When an appointment is reached,
353 ;; delete it from the list. 373 ;; delete it from the list.
354 ;; Reset the count to 0 in case we display another 374 ;; Reset the count to 0 in case we display another
355 ;; appointment on the next cycle. 375 ;; appointment on the next cycle.
356 (if (= min-to-app 0) 376 (if (zerop min-to-app)
357 (setq appt-time-msg-list 377 (setq appt-time-msg-list (cdr appt-time-msg-list)
358 (cdr appt-time-msg-list)
359 appt-display-count nil))))) 378 appt-display-count nil)))))
360 379
361 ;; If we have changed the mode line string, 380 ;; If we have changed the mode line string,
@@ -372,7 +391,9 @@ The following variables control appointment notification:
372 391
373 392
374(defun appt-disp-window (min-to-app new-time appt-msg) 393(defun appt-disp-window (min-to-app new-time appt-msg)
375 "Display appointment message APPT-MSG in a separate buffer." 394 "Display appointment message APPT-MSG in a separate buffer.
395The appointment is due in MIN-TO-APP (a string) minutes.
396NEW-TIME is a string giving the date."
376 (require 'electric) 397 (require 'electric)
377 398
378 ;; Make sure we're not in the minibuffer 399 ;; Make sure we're not in the minibuffer
@@ -384,9 +405,8 @@ The following variables control appointment notification:
384 (if (display-multi-frame-p) 405 (if (display-multi-frame-p)
385 (select-frame (other-frame 1))))) 406 (select-frame (other-frame 1)))))
386 407
387 (let* ((this-buffer (current-buffer)) 408 (let ((this-window (selected-window))
388 (this-window (selected-window)) 409 (appt-disp-buf (set-buffer (get-buffer-create appt-buffer-name))))
389 (appt-disp-buf (set-buffer (get-buffer-create appt-buffer-name))))
390 410
391 (if (cdr (assq 'unsplittable (frame-parameters))) 411 (if (cdr (assq 'unsplittable (frame-parameters)))
392 ;; In an unsplittable frame, use something somewhere else. 412 ;; In an unsplittable frame, use something somewhere else.
@@ -405,9 +425,7 @@ The following variables control appointment notification:
405 (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf t)) 425 (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf t))
406 (set-buffer-modified-p nil) 426 (set-buffer-modified-p nil)
407 (raise-frame (selected-frame)) 427 (raise-frame (selected-frame))
408 (select-window this-window) 428 (select-window this-window)))
409 (if appt-audible
410 (beep 1))))
411 429
412(defun appt-delete-window () 430(defun appt-delete-window ()
413 "Function called to undisplay appointment messages. 431 "Function called to undisplay appointment messages.
@@ -437,11 +455,9 @@ Usually just deletes the appointment buffer."
437The time should be in either 24 hour format or am/pm format." 455The time should be in either 24 hour format or am/pm format."
438 456
439 (interactive "sTime (hh:mm[am/pm]): \nsMessage: ") 457 (interactive "sTime (hh:mm[am/pm]): \nsMessage: ")
440 (if (string-match "[0-9]?[0-9][:.][0-9][0-9]\\(am\\|pm\\)?" 458 (unless (string-match "[0-9]?[0-9][:.][0-9][0-9]\\(am\\|pm\\)?"
441 new-appt-time) 459 new-appt-time)
442 nil
443 (error "Unacceptable time-string")) 460 (error "Unacceptable time-string"))
444
445 (let* ((appt-time-string (concat new-appt-time " " new-appt-msg)) 461 (let* ((appt-time-string (concat new-appt-time " " new-appt-msg))
446 (appt-time (list (appt-convert-time new-appt-time))) 462 (appt-time (list (appt-convert-time new-appt-time)))
447 (time-msg (cons appt-time (list appt-time-string)))) 463 (time-msg (cons appt-time (list appt-time-string))))
@@ -452,7 +468,7 @@ The time should be in either 24 hour format or am/pm format."
452(defun appt-delete () 468(defun appt-delete ()
453 "Delete an appointment from the list of appointments." 469 "Delete an appointment from the list of appointments."
454 (interactive) 470 (interactive)
455 (let* ((tmp-msg-list appt-time-msg-list)) 471 (let ((tmp-msg-list appt-time-msg-list))
456 (while tmp-msg-list 472 (while tmp-msg-list
457 (let* ((element (car tmp-msg-list)) 473 (let* ((element (car tmp-msg-list))
458 (prompt-string (concat "Delete " 474 (prompt-string (concat "Delete "
@@ -476,15 +492,11 @@ The time should be in either 24 hour format or am/pm format."
476 (defvar diary-entries-list)) 492 (defvar diary-entries-list))
477;;;###autoload 493;;;###autoload
478(defun appt-make-list () 494(defun appt-make-list ()
479 "Create the appointments list from todays diary buffer. 495 "Create the appointments list from today's diary buffer.
480The time must be at the beginning of a line for it to be 496The time must be at the beginning of a line for it to be
481put in the appointments list. 497put in the appointments list (see examples in documentation of
482 02/23/89 498the function `appt-check'). We assume that the variables DATE and
483 12:00pm lunch 499NUMBER hold the arguments that `list-diary-entries' received.
484 Wednesday
485 10:00am group meeting
486We assume that the variables DATE and NUMBER
487hold the arguments that `list-diary-entries' received.
488They specify the range of dates that the diary is being processed for." 500They specify the range of dates that the diary is being processed for."
489 501
490 ;; We have something to do if the range of dates that the diary is 502 ;; We have something to do if the range of dates that the diary is
@@ -557,38 +569,24 @@ They specify the range of dates that the diary is being processed for."
557 (cur-hour (nth 2 now)) 569 (cur-hour (nth 2 now))
558 (cur-min (nth 1 now)) 570 (cur-min (nth 1 now))
559 (cur-comp-time (+ (* cur-hour 60) cur-min)) 571 (cur-comp-time (+ (* cur-hour 60) cur-min))
560 (appt-comp-time (car (car (car appt-time-msg-list))))) 572 (appt-comp-time (car (caar appt-time-msg-list))))
561 573
562 (while (and appt-time-msg-list (< appt-comp-time cur-comp-time)) 574 (while (and appt-time-msg-list (< appt-comp-time cur-comp-time))
563 (setq appt-time-msg-list (cdr appt-time-msg-list)) 575 (setq appt-time-msg-list (cdr appt-time-msg-list))
564 (if appt-time-msg-list 576 (if appt-time-msg-list
565 (setq appt-comp-time (car (car (car appt-time-msg-list)))))))))) 577 (setq appt-comp-time (car (caar appt-time-msg-list)))))))))
566 578
567 579
568(defun appt-sort-list (appt-list) 580(defun appt-sort-list (appt-list)
569 "Simple sort to put the appointments list APPT-LIST in order. 581 "Sort an appointment list, putting earlier items at the front.
570Scan the list for the smallest element left in the list. 582APPT-LIST is a list of the same format as `appt-time-msg-list'."
571Append the smallest element left into the new list, and remove 583(sort appt-list (lambda (e1 e2) (< (caar e1) (caar e2)))))
572it from the original list."
573 (let ((order-list nil))
574 (while appt-list
575 (let* ((element (car appt-list))
576 (element-time (car (car element)))
577 (tmp-list (cdr appt-list)))
578 (while tmp-list
579 (if (< element-time (car (car (car tmp-list))))
580 nil
581 (setq element (car tmp-list))
582 (setq element-time (car (car element))))
583 (setq tmp-list (cdr tmp-list)))
584 (setq order-list (nconc order-list (list element)))
585 (setq appt-list (delq element appt-list))))
586 order-list))
587 584
588 585
589(defun appt-convert-time (time2conv) 586(defun appt-convert-time (time2conv)
590 "Convert hour:min[am/pm] format to minutes from midnight. 587 "Convert hour:min[am/pm] format to minutes from midnight.
591Also try to accept the hour.min[am/pm] format." 588A period (.) can be used instead of a colon (:) to separate the
589hour and minute parts."
592 (let ((conv-time 0) 590 (let ((conv-time 0)
593 (hr 0) 591 (hr 0)
594 (min 0)) 592 (min 0))
@@ -615,16 +613,41 @@ Also try to accept the hour.min[am/pm] format."
615 (setq conv-time (+ (* hr 60) min)) 613 (setq conv-time (+ (* hr 60) min))
616 conv-time)) 614 conv-time))
617 615
618(defvar appt-timer nil
619 "Timer used for diary appointment notifications (`appt-check').")
620 616
621(unless appt-timer 617(defun appt-update-list ()
622 (setq appt-timer (run-at-time t 60 'appt-check))) 618 "If the current buffer is visiting the diary, update appointments.
619This function is intended for use with `write-file-functions'."
620 (and (equal buffer-file-name (expand-file-name diary-file))
621 appt-timer
622 (let ((appt-display-diary nil))
623 (appt-check t)))
624 nil)
625
626
627;;;###autoload
628(defun appt-activate (&optional arg)
629"Toggle checking of appointments.
630With optional numeric argument ARG, turn appointment checking on if
631ARG is positive, otherwise off."
632 (interactive "P")
633 (let ((appt-active appt-timer))
634 (setq appt-active (if arg (> (prefix-numeric-value arg) 0)
635 (not appt-active)))
636 (remove-hook 'write-file-functions 'appt-update-list)
637 (or global-mode-string (setq global-mode-string '("")))
638 (delq 'appt-mode-string global-mode-string)
639 (and appt-timer
640 (cancel-timer appt-timer)
641 (setq appt-timer nil))
642 (when appt-active
643 (add-hook 'write-file-functions 'appt-update-list)
644 (setq appt-timer (run-at-time t 60 'appt-check)
645 global-mode-string
646 (append global-mode-string '(appt-mode-string)))
647 (appt-check t))))
648
623 649
624(or global-mode-string (setq global-mode-string '(""))) 650(provide 'appt)
625(or (memq 'appt-mode-string global-mode-string)
626 (setq global-mode-string
627 (append global-mode-string '(appt-mode-string))))
628 651
629;;; arch-tag: bf5791c4-8921-499e-a26f-772b1788d347 652;;; arch-tag: bf5791c4-8921-499e-a26f-772b1788d347
630;;; appt.el ends here 653;;; appt.el ends here