aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarl Heuer1998-09-21 19:45:14 +0000
committerKarl Heuer1998-09-21 19:45:14 +0000
commitf3e7c0dc58b24bf2d3ad356ab7c193a7acf1809a (patch)
tree7a13a813433f516e274d313bf18ef28a8ed0d71e
parent691d39b7b45cc47f609dabb72ee1d09bbc6a0377 (diff)
downloademacs-f3e7c0dc58b24bf2d3ad356ab7c193a7acf1809a.tar.gz
emacs-f3e7c0dc58b24bf2d3ad356ab7c193a7acf1809a.zip
(appt-interval): Variable deleted.
(appt-check): For minutes in between appt-display-interval times, do check, but don't display anything except an updated mode line. Count against appt-display-interval based on minutes since first display of this appointment, not based on time of day. If appt-display-mode-line, force mode line redisplay whenever appt-mode-string has changed. (appt-add, appt-delete): Add autoload cookies. (appt-check): Catch errors from calling `diary'. (appt-max-time): Renamed from max-time. (appt-now-displayed, appt-display-count): New variables. (appt-timer): Don't create one if we already have one.
-rw-r--r--lisp/calendar/appt.el263
1 files changed, 141 insertions, 122 deletions
diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el
index 9368c1b4265..d9e4fd0e328 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 Free Software Foundation, Inc. 3;; Copyright (C) 1989, 1990, 1994, 1998 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,8 +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 generated from 30;; appointments from ~/diary file.
31;; Edward M. Reingold's calendar.el.
32;; 31;;
33;; 32;;
34;; Comments, corrections, and improvements should be sent to 33;; Comments, corrections, and improvements should be sent to
@@ -43,28 +42,18 @@
43;;; This functions in this file will alert the user of a 42;;; This functions in this file will alert the user of a
44;;; pending appointment based on their diary file. 43;;; pending appointment based on their diary file.
45;;; 44;;;
46;;; 45;;; A message will be displayed in the mode line of the Emacs buffer
47;;; ******* It is necessary to invoke 'diary' for this to work properly. **** 46;;; and (if you request) the terminal will beep and display a message
48;;; 47;;; from the diary in the mini-buffer, or you can choose to
49;;; A message will be displayed in the mode line of the emacs buffer
50;;; and (if the user desires) the terminal will beep and display a message
51;;; from the diary in the mini-buffer, or the user may select to
52;;; have a message displayed in a new buffer. 48;;; have a message displayed in a new buffer.
53;;; 49;;;
54;;; The variable 'appt-message-warning-time' allows the 50;;; The variable `appt-message-warning-time' allows the
55;;; user to specify how much notice they want before the appointment. The 51;;; user to specify how much notice they want before the appointment. The
56;;; variable 'appt-issue-message' specifies whether the user wants 52;;; variable `appt-issue-message' specifies whether the user wants
57;;; to to be notified of a pending appointment. 53;;; to to be notified of a pending appointment.
58;;; 54;;;
59;;; In order to use, the following should be in your .emacs file in addition to 55;;; In order to use the appt package, you only need
60;;; creating a diary file and invoking calendar: 56;;; to load it---provided you have appointments.
61;;;
62;;; To enable appointment reminders, the following lines are required:
63;;; (add-hook 'diary-hook 'appt-make-list)
64;;; (let ((diary-display-hook 'ignore))
65;;; (diary))
66;;; You can replace the last two with just (diary)
67;;; if you want to display the diary as well.
68;;; 57;;;
69;;; Before that, you can also set some options if you want 58;;; Before that, you can also set some options if you want
70;;; (setq view-diary-entries-initially t) 59;;; (setq view-diary-entries-initially t)
@@ -77,7 +66,7 @@
77;;; 66;;;
78;;; Based upon the above lines in your .emacs and diary files, 67;;; Based upon the above lines in your .emacs and diary files,
79;;; the calendar and diary will be displayed when you enter 68;;; the calendar and diary will be displayed when you enter
80;;; emacs and your appointments list will automatically be created. 69;;; Emacs and your appointments list will automatically be created.
81;;; You will then be reminded at 9:20am about your coffee break 70;;; You will then be reminded at 9:20am about your coffee break
82;;; and at 11:50am to go to lunch. 71;;; and at 11:50am to go to lunch.
83;;; 72;;;
@@ -93,13 +82,6 @@
93;;; 82;;;
94;;; Brief internal description - Skip this if your not interested! 83;;; Brief internal description - Skip this if your not interested!
95;;; 84;;;
96;;; The function appt-check is run from the 'loadst' process which is started
97;;; by invoking (display-time). A temporary function below modifies
98;;; display-time-filter
99;;; (from original time.el) to include a hook which will invoke appt-check.
100;;; This will not be necessary in the next version of gnuemacs.
101;;;
102;;;
103;;; The function appt-make-list creates the appointments list which appt-check 85;;; The function appt-make-list creates the appointments list which appt-check
104;;; reads. This is all done automatically. 86;;; reads. This is all done automatically.
105;;; It is invoked from the function list-diary-entries. 87;;; It is invoked from the function list-diary-entries.
@@ -113,7 +95,7 @@
113;;; 95;;;
114;;; For instance, these variables can be set to functions that display 96;;; For instance, these variables can be set to functions that display
115;;; appointments in pop-up frames, which are lowered or iconified after 97;;; appointments in pop-up frames, which are lowered or iconified after
116;;; appt-display-interval seconds. 98;;; appt-display-interval minutes.
117;;; 99;;;
118 100
119;;; Code: 101;;; Code:
@@ -174,19 +156,13 @@ This will occur at midnight when the appointment list is updated."
174 :type 'boolean 156 :type 'boolean
175 :group 'appt) 157 :group 'appt)
176 158
177(defcustom appt-interval 60
178 "*Interval in seconds between checking for appointments."
179 :type 'integer
180 :group 'appt
181 :version "20.3")
182
183(defvar appt-time-msg-list nil 159(defvar appt-time-msg-list nil
184 "The list of appointments for today. 160 "The list of appointments for today.
185Use `appt-add' and `appt-delete' to add and delete appointments from list. 161Use `appt-add' and `appt-delete' to add and delete appointments from list.
186The original list is generated from the today's `diary-entries-list'. 162The original list is generated from the today's `diary-entries-list'.
187The number before each time/message is the time in minutes from midnight.") 163The number before each time/message is the time in minutes from midnight.")
188 164
189(defconst max-time 1439 165(defconst appt-max-time 1439
190 "11:59pm in minutes - number of minutes in a day minus 1.") 166 "11:59pm in minutes - number of minutes in a day minus 1.")
191 167
192(defcustom appt-display-interval 3 168(defcustom appt-display-interval 3
@@ -204,7 +180,16 @@ The number before each time/message is the time in minutes from midnight.")
204 "Function called to remove appointment window and buffer.") 180 "Function called to remove appointment window and buffer.")
205 181
206(defvar appt-mode-string nil 182(defvar appt-mode-string nil
207 "String to display in the mode line for an appointment.") 183 "String being displayed in the mode line saying you have an appointment.
184The actual string includes the amount of time till the appointment.")
185
186(defvar appt-prev-comp-time nil
187 "Time of day (mins since midnight) at which we last checked appointments.")
188
189(defvar appt-now-displayed nil
190 "Non-nil when we have started notifying about a appointment that is near.")
191
192(defvar appt-display-count nil)
208 193
209(defun appt-check () 194(defun appt-check ()
210 "Check for an appointment and update the mode line. 195 "Check for an appointment and update the mode line.
@@ -220,7 +205,8 @@ Example:
220 Thursday 205 Thursday
221 11:45am Lunch meeting. 206 11:45am Lunch meeting.
222 207
223The following variables control the action of the notification: 208Appointments are checked every `appt-display-interval' minutes.
209The following variables control appointment notification:
224 210
225`appt-issue-message' 211`appt-issue-message'
226 If t, the diary buffer is checked for appointments. 212 If t, the diary buffer is checked for appointments.
@@ -246,85 +232,100 @@ The following variables control the action of the notification:
246 The number of seconds an appointment message 232 The number of seconds an appointment message
247 is displayed in another window. 233 is displayed in another window.
248 234
249`appt-display-interval' 235`appt-disp-window-function'
250 The number of minutes to wait between checking the appointments
251 list.
252
253`appt-disp-window-function '
254 Function called to display appointment window. You can customize 236 Function called to display appointment window. You can customize
255 appt.el by setting this variable to a function different from the 237 appt.el by setting this variable to a function different from the
256 one provided with this package. 238 one provided with this package.
257 239
258`appt-delete-window-function ' 240`appt-delete-window-function'
259 Function called to remove appointment window and buffer. You can 241 Function called to remove appointment window and buffer. You can
260 customize appt.el by setting this variable to a function different 242 customize appt.el by setting this variable to a function different
261 from the one provided with this package." 243 from the one provided with this package."
262 244
245 (let* ((min-to-app -1)
246 (new-time "")
247 (prev-appt-mode-string appt-mode-string)
248 (prev-appt-display-count (or appt-display-count 0))
249 ;; Non-nil means do a full check for pending appointments
250 ;; and display in whatever ways the user has selected.
251 ;; When no appointment is being displayed,
252 ;; we always do a full check.
253 (full-check
254 (or (not appt-now-displayed)
255 ;; This is true every appt-display-interval minutes.
256 (= 0 (mod prev-appt-display-count appt-display-interval))))
257 ;; Non-nil means only update the interval displayed in the mode line.
258 (mode-line-only
259 (and (not full-check) appt-now-displayed)))
260
261 (when (or full-check mode-line-only)
262 (save-excursion
263
264 ;; Get the current time and convert it to minutes
265 ;; from midnight. ie. 12:01am = 1, midnight = 0.
263 266
264 (if (or (= appt-display-interval 1) 267 (let* ((now (decode-time))
265 ;; This is true every appt-display-interval minutes. 268 (cur-hour (nth 2 now))
266 (= 0 (mod (/ (nth 1 (current-time)) 60) appt-display-interval))) 269 (cur-min (nth 1 now))
267 (let ((min-to-app -1) 270 (cur-comp-time (+ (* cur-hour 60) cur-min)))
268 (new-time "")) 271
269 (save-excursion 272 ;; At the first check in any given day, update our
270 273 ;; appointments to today's list.
271 ;; Get the current time and convert it to minutes 274
272 ;; from midnight. ie. 12:01am = 1, midnight = 0. 275 (if (or (null appt-prev-comp-time)
273 276 (< cur-comp-time appt-prev-comp-time))
274 (let* ((now (decode-time)) 277 (condition-case nil
275 (cur-hour (nth 2 now)) 278 (progn
276 (cur-min (nth 1 now)) 279 (if (and view-diary-entries-initially appt-display-diary)
277 (cur-comp-time (+ (* cur-hour 60) cur-min))) 280 (diary)
278 281 (let ((diary-display-hook 'appt-make-list))
279 ;; At the first check after 12:01am, we should update our 282 (diary))))
280 ;; appointments to today's list. 283 (error nil)))
281 284 (setq appt-prev-comp-time cur-comp-time)
282 (if (and (>= cur-comp-time 1) 285
283 (<= cur-comp-time appt-display-interval)) 286 (setq appt-mode-string nil)
284 (if (and view-diary-entries-initially appt-display-diary) 287 (setq appt-display-count nil)
285 (diary) 288
286 (let ((diary-display-hook 'appt-make-list)) 289 ;; If there are entries in the list, and the
287 (diary)))) 290 ;; user wants a message issued,
288 291 ;; get the first time off of the list
289 (setq appt-mode-string nil) 292 ;; and calculate the number of minutes until the appointment.
290 293
291 ;; If there are entries in the list, and the 294 (if (and appt-issue-message appt-time-msg-list)
292 ;; user wants a message issued 295 (let ((appt-comp-time (car (car (car appt-time-msg-list)))))
293 ;; get the first time off of the list 296 (setq min-to-app (- appt-comp-time cur-comp-time))
294 ;; and calculate the number of minutes until 297
295 ;; the appointment. 298 (while (and appt-time-msg-list
296 299 (< appt-comp-time cur-comp-time))
297 (if (and appt-issue-message appt-time-msg-list) 300 (setq appt-time-msg-list (cdr appt-time-msg-list))
298 (let ((appt-comp-time (car (car (car appt-time-msg-list))))) 301 (if appt-time-msg-list
299 (setq min-to-app (- appt-comp-time cur-comp-time)) 302 (setq appt-comp-time
300 303 (car (car (car appt-time-msg-list))))))
301 (while (and appt-time-msg-list 304
302 (< appt-comp-time cur-comp-time)) 305 ;; If we have an appointment between midnight and
303 (setq appt-time-msg-list (cdr appt-time-msg-list)) 306 ;; 'appt-message-warning-time' minutes after midnight,
304 (if appt-time-msg-list 307 ;; we must begin to issue a message before midnight.
305 (setq appt-comp-time 308 ;; Midnight is considered 0 minutes and 11:59pm is
306 (car (car (car appt-time-msg-list)))))) 309 ;; 1439 minutes. Therefore we must recalculate the minutes
307 310 ;; to appointment variable. It is equal to the number of
308 ;; If we have an appointment between midnight and 311 ;; minutes before midnight plus the number of
309 ;; 'appt-message-warning-time' minutes after midnight, 312 ;; minutes after midnight our appointment is.
310 ;; we must begin to issue a message before midnight. 313
311 ;; Midnight is considered 0 minutes and 11:59pm is 314 (if (and (< appt-comp-time appt-message-warning-time)
312 ;; 1439 minutes. Therefore we must recalculate the minutes 315 (> (+ cur-comp-time appt-message-warning-time)
313 ;; to appointment variable. It is equal to the number of 316 appt-max-time))
314 ;; minutes before midnight plus the number of 317 (setq min-to-app (+ (- (1+ appt-max-time) cur-comp-time))
315 ;; minutes after midnight our appointment is. 318 appt-comp-time))
316 319
317 (if (and (< appt-comp-time appt-message-warning-time) 320 ;; issue warning if the appointment time is
318 (> (+ cur-comp-time appt-message-warning-time) 321 ;; within appt-message-warning time
319 max-time)) 322
320 (setq min-to-app (+ (- (1+ max-time) cur-comp-time)) 323 (when (and (<= min-to-app appt-message-warning-time)
321 appt-comp-time)) 324 (>= min-to-app 0))
322 325 (setq appt-now-displayed t)
323 ;; issue warning if the appointment time is 326 (setq appt-display-count
324 ;; within appt-message-warning time 327 (1+ prev-appt-display-count))
325 328 (unless mode-line-only
326 (when (and (<= min-to-app appt-message-warning-time)
327 (>= min-to-app 0))
328 (if appt-msg-window 329 (if appt-msg-window
329 (progn 330 (progn
330 (setq new-time (format-time-string "%a %b %e " 331 (setq new-time (format-time-string "%a %b %e "
@@ -333,29 +334,44 @@ The following variables control the action of the notification:
333 appt-disp-window-function 334 appt-disp-window-function
334 min-to-app new-time 335 min-to-app new-time
335 (car (cdr (car appt-time-msg-list)))) 336 (car (cdr (car appt-time-msg-list))))
336 337
337 (run-at-time 338 (run-at-time
338 (format "%d sec" appt-display-duration) 339 (format "%d sec" appt-display-duration)
339 nil 340 nil
340 appt-delete-window-function)) 341 appt-delete-window-function))
341 ;;; else 342 ;;; else
342 343
343 (if appt-visible 344 (if appt-visible
344 (message "%s" 345 (message "%s"
345 (car (cdr (car appt-time-msg-list))))) 346 (car (cdr (car appt-time-msg-list)))))
346 347
347 (if appt-audible 348 (if appt-audible
348 (beep 1))) 349 (beep 1))))
349 350
350 (when appt-display-mode-line 351 (when appt-display-mode-line
351 (setq appt-mode-string 352 (setq appt-mode-string
352 (concat " App't in " min-to-app " min. ")) 353 (concat " App't in " min-to-app " min. ")))
353 (force-mode-line-update t) 354
354 (sit-for 0)) 355 ;; When an appointment is reached,
355 356 ;; delete it from the list.
356 (if (= min-to-app 0) 357 ;; Reset the count to 0 in case we display another
357 (setq appt-time-msg-list 358 ;; appointment on the next cycle.
358 (cdr appt-time-msg-list))))))))))) 359 (if (= min-to-app 0)
360 (setq appt-time-msg-list
361 (cdr appt-time-msg-list)
362 appt-display-count nil)))))
363
364 ;; If we have changed the mode line string,
365 ;; redisplay all mode lines.
366 (and appt-display-mode-line
367 (not (equal appt-mode-string
368 prev-appt-mode-string))
369 (progn
370 (force-mode-line-update t)
371 ;; If the string now has a notification,
372 ;; redisplay right now.
373 (if appt-mode-string
374 (sit-for 0)))))))))
359 375
360 376
361;; Display appointment message in a separate buffer. 377;; Display appointment message in a separate buffer.
@@ -428,6 +444,7 @@ Usually just deletes the appointment buffer."
428 (setq window-search nil))))))) 444 (setq window-search nil)))))))
429 445
430 446
447;;;###autoload
431(defun appt-add (new-appt-time new-appt-msg) 448(defun appt-add (new-appt-time new-appt-msg)
432 "Add an appointment for the day at TIME and issue MESSAGE. 449 "Add an appointment for the day at TIME and issue MESSAGE.
433The time should be in either 24 hour format or am/pm format." 450The time should be in either 24 hour format or am/pm format."
@@ -444,6 +461,7 @@ The time should be in either 24 hour format or am/pm format."
444 (list time-msg))) 461 (list time-msg)))
445 (setq appt-time-msg-list (appt-sort-list appt-time-msg-list)))) 462 (setq appt-time-msg-list (appt-sort-list appt-time-msg-list))))
446 463
464;;;###autoload
447(defun appt-delete () 465(defun appt-delete ()
448 "Delete an appointment from the list of appointments." 466 "Delete an appointment from the list of appointments."
449 (interactive) 467 (interactive)
@@ -609,7 +627,8 @@ The time should be in either 24 hour format or am/pm format."
609(defvar appt-timer nil 627(defvar appt-timer nil
610 "Timer used for diary appointment notifications (`appt-check').") 628 "Timer used for diary appointment notifications (`appt-check').")
611 629
612(setq appt-timer (run-at-time t appt-interval 'appt-check)) 630(unless appt-timer
631 (setq appt-timer (run-at-time t 60 'appt-check)))
613 632
614(or global-mode-string (setq global-mode-string '(""))) 633(or global-mode-string (setq global-mode-string '("")))
615(or (memq 'appt-mode-string global-mode-string) 634(or (memq 'appt-mode-string global-mode-string)