diff options
| author | Karl Heuer | 1998-09-21 19:45:14 +0000 |
|---|---|---|
| committer | Karl Heuer | 1998-09-21 19:45:14 +0000 |
| commit | f3e7c0dc58b24bf2d3ad356ab7c193a7acf1809a (patch) | |
| tree | 7a13a813433f516e274d313bf18ef28a8ed0d71e | |
| parent | 691d39b7b45cc47f609dabb72ee1d09bbc6a0377 (diff) | |
| download | emacs-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.el | 263 |
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. |
| 185 | Use `appt-add' and `appt-delete' to add and delete appointments from list. | 161 | Use `appt-add' and `appt-delete' to add and delete appointments from list. |
| 186 | The original list is generated from the today's `diary-entries-list'. | 162 | The original list is generated from the today's `diary-entries-list'. |
| 187 | The number before each time/message is the time in minutes from midnight.") | 163 | The 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. |
| 184 | The 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 | ||
| 223 | The following variables control the action of the notification: | 208 | Appointments are checked every `appt-display-interval' minutes. |
| 209 | The 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. |
| 433 | The time should be in either 24 hour format or am/pm format." | 450 | The 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) |