]> code.delx.au - gnu-emacs/blobdiff - lisp/calendar/diary-lib.el
(diary-list-entries): Replace superfluous save-excursion with
[gnu-emacs] / lisp / calendar / diary-lib.el
index 9ece770f3241f053550b71536ffa3cc096a81d63..0cb52cfb805eb0cc15b2f565f0c9a5dc49a31909 100644 (file)
@@ -1,7 +1,7 @@
 ;;; diary-lib.el --- diary functions
 
 ;; Copyright (C) 1989, 1990, 1992, 1993, 1994, 1995, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+;;   2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
 
 ;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
 ;; Maintainer: Glenn Morris <rgm@gnu.org>
@@ -29,7 +29,7 @@
 ;;; Code:
 
 (require 'calendar)
-(require 'diary-loaddefs)
+(eval-and-compile (load "diary-loaddefs" nil t))
 
 (defgroup diary nil
   "Emacs diary."
@@ -71,8 +71,8 @@ are holidays."
   "Face used for buttons in the fancy diary display."
   :version "22.1"
   :group 'calendar-faces)
-;; Backward-compatibility alias. FIXME make obsolete.
-(put 'diary-button-face 'face-alias 'diary-button)
+
+(define-obsolete-face-alias 'diary-button-face 'diary-button "22.1")
 
 ;; Face markup of calendar and diary displays: Any entry line that
 ;; ends with [foo:value] where foo is a face attribute (except :box
@@ -106,7 +106,7 @@ is pre-pended to REGEXP for file-wide specifiers.  ATTRIBUTE
 specifies which face attribute (e.g. `:foreground') to modify, or
 that this is a face (`:face') to apply.  TYPE is the type of
 attribute being applied.  Available TYPES (see `diary-attrtype-convert')
-are: `string', `symbol', `int', `tnil',`stringtnil.'"
+are: `string', `symbol', `int', `tnil', `stringtnil.'"
   :type '(repeat (list (string :tag "Regular expression")
                        (integer :tag "Sub-expression")
                        (symbol :tag "Attribute (e.g. :foreground)")
@@ -151,10 +151,9 @@ Used for example by the appointment package - see `appt-activate'."
 (define-obsolete-variable-alias 'diary-display-hook 'diary-display-function
   "23.1")
 
-(defcustom diary-display-function 'diary-simple-display
+(defcustom diary-display-function 'diary-fancy-display
   "Function used to display the diary.
-The default is `diary-simple-display'; `diary-fancy-display' is
-an alternative.
+The two standard options are `diary-fancy-display' and `diary-simple-display'.
 
 For historical reasons, `nil' is the same as `diary-simple-display'
 \(so you must use `ignore' for no display).  Also for historical
@@ -167,14 +166,14 @@ form of ((MONTH DAY YEAR) STRING), where string is the diary
 entry for the given date.  This can be used, for example, to
 produce a different buffer for display (perhaps combined with
 holidays), or hard copy output."
-  :type '(choice (const diary-simple-display :tag "Basic display")
-                 (const diary-fancy-display :tag "Fancy display")
+  :type '(choice (const diary-fancy-display :tag "Fancy display")
+                 (const diary-simple-display :tag "Basic display")
                  (const ignore :tag "No display")
                  (const nil :tag "Obsolete way to choose basic display")
                  (hook :tag "Obsolete form with list of display functions"))
   :initialize 'custom-initialize-default
   :set 'diary-set-maybe-redraw
-  :version "23.1"
+  :version "23.2"                       ; simple->fancy
   :group 'diary)
 
 (define-obsolete-variable-alias 'list-diary-entries-hook
@@ -286,8 +285,8 @@ with no recognizable time after those with times."
   "Pseudo-pattern giving form of reminder messages in the fancy diary display.
 
 Used by the function `diary-remind', a pseudo-pattern is a list of
-expressions that can involve the keywords `days' (a number), `date' (a list of
-month, day, year), and `diary-entry' (a string)."
+expressions that can involve the keywords `days' (a number), `date'
+\(a list of month, day, year), and `diary-entry' (a string)."
   :type 'sexp
   :group 'diary)
 
@@ -355,9 +354,7 @@ template following the rules above."
 (defun diary-set-header (symbol value)
   "Set SYMBOL's value to VALUE, and redraw the diary header if necessary."
   (let ((oldvalue (symbol-value symbol))
-        (dbuff (and diary-file
-                    (find-buffer-visiting
-                     (substitute-in-file-name diary-file)))))
+        (dbuff (and diary-file (find-buffer-visiting diary-file))))
     (custom-set-default symbol value)
     (and dbuff
          (not (equal value oldvalue))
@@ -410,8 +407,7 @@ Only used if `diary-header-line-flag' is non-nil."
 (defun diary-live-p ()
   "Return non-nil if the diary is being displayed."
   (or (get-buffer diary-fancy-buffer)
-      (and diary-file
-           (find-buffer-visiting (substitute-in-file-name diary-file)))))
+      (and diary-file (find-buffer-visiting diary-file))))
 
 ;;;###cal-autoload
 (defun diary-set-maybe-redraw (symbol value)
@@ -430,21 +426,20 @@ just visiting the `diary-file'), and SYMBOL's value is to be changed."
 
 (defcustom diary-number-of-entries 1
   "Specifies how many days of diary entries are to be displayed initially.
-This variable affects the diary display when the command \\[diary] is used,
-or if the value of the variable `calendar-view-diary-initially-flag' is non-nil.
-For example, if the default value 1 is used, then only the current day's diary
-entries will be displayed.  If the value 2 is used, then both the current
-day's and the next day's entries will be displayed.
-
-The value can also be a vector such as [0 2 2 2 2 4 1]; this value
-says to display no diary entries on Sunday, the entries for
-the current date and the day after on Monday through Thursday,
-Friday through Monday's entries on Friday, and only Saturday's
-entries on Saturday.
+This variable affects the diary display when the command \\[diary] is
+used, or if the value of the variable `calendar-view-diary-initially-flag'
+is non-nil.  For example, if the default value 1 is used, then only the
+current day's diary entries will be displayed.  If the value 2 is used,
+then both the current day's and the next day's entries will be displayed.
+
+The value can also be a vector such as [0 2 2 2 2 4 1]; this value says
+to display no diary entries on Sunday, the entries for the current date
+and the day after on Monday through Thursday, Friday through Monday's
+entries on Friday, and only Saturday's entries on Saturday.
 
 This variable does not affect the diary display with the `d' command
-from the calendar; in that case, the prefix argument controls the
-number of days of diary entries displayed."
+from the calendar; in that case, the prefix argument controls the number
+of days of diary entries displayed."
   :type '(choice (integer :tag "Entries")
                  (vector :value [0 0 0 0 0 0 0]
                          (integer :tag "Sunday")
@@ -464,12 +459,11 @@ number of days of diary entries displayed."
 (defun diary-check-diary-file ()
   "Check that the file specified by `diary-file' exists and is readable.
 If so, return the expanded file name, otherwise signal an error."
-  (let ((d-file (substitute-in-file-name diary-file)))
-    (if (and d-file (file-exists-p d-file))
-        (if (file-readable-p d-file)
-            d-file
-          (error "Diary file `%s' is not readable" diary-file))
-      (error "Diary file `%s' does not exist" diary-file))))
+  (if (and diary-file (file-exists-p diary-file))
+      (if (file-readable-p diary-file)
+          diary-file
+        (error "Diary file `%s' is not readable" diary-file))
+    (error "Diary file `%s' does not exist" diary-file)))
 
 ;;;###autoload
 (defun diary (&optional arg)
@@ -485,8 +479,8 @@ does nothing.  This function is suitable for execution in a `.emacs' file."
 ;;;###cal-autoload
 (defun diary-view-entries (&optional arg)
   "Prepare and display a buffer with diary entries.
-Searches the file named in `diary-file' for entries that
-match ARG days starting with the date indicated by the cursor position
+Searches the file named in `diary-file' for entries that match
+ARG days starting with the date indicated by the cursor position
 in the displayed three-month calendar."
   (interactive "p")
   (diary-check-diary-file)
@@ -587,13 +581,13 @@ The function takes a string argument and must return a string.")
 (defun diary-add-to-list (date string specifier &optional marker
                                globcolor literal)
   "Add an entry to `diary-entries-list'.
-Do nothing if DATE or STRING is nil.  DATE is the (MONTH DAY
+Do nothing if DATE or STRING are nil.  DATE is the (MONTH DAY
 YEAR) for which the entry applies; STRING is the text of the
 entry as it will appear in the diary (i.e. with any format
 strings such as \"%d\" expanded); SPECIFIER is the date part of
 the entry as it appears in the diary-file; LITERAL is the entry
-as it appears in the diary-file (i.e. before expansion).  If
-LITERAL is nil, it is taken to be the same as STRING.
+as it appears in the diary-file (i.e. before expansion).
+If LITERAL is nil, it is taken to be the same as STRING.
 
 The entry is added to the list as (DATE STRING SPECIFIER LOCATOR
 GLOBCOLOR), where LOCATOR has the form (MARKER FILENAME LITERAL),
@@ -616,7 +610,7 @@ FILENAME being the file containing the diary entry."
 (define-obsolete-function-alias 'add-to-diary-list 'diary-add-to-list "23.1")
 
 (defun diary-list-entries-2 (date mark globattr list-only
-                                  &optional months symbol)
+                                  &optional months symbol gdate)
   "Internal subroutine of `diary-list-entries'.
 Find diary entries applying to DATE, by searching from point-min for
 each element of `diary-date-forms'.  MARK indicates an entry is non-marking.
@@ -624,7 +618,9 @@ GLOBATTR is the list of global file attributes.  If LIST-ONLY is
 non-nil, don't change the buffer, only return a list of entries.
 Optional array MONTHS replaces `calendar-month-name-array', and
 means months cannot be abbreviated.  Optional string SYMBOL marks diary
-entries of the desired type.  Returns non-nil if any entries were found."
+entries of the desired type.  If DATE is not Gregorian, then the
+Gregorian equivalent should be provided via GDATE.  Returns non-nil if
+any entries were found."
   (let* ((month (calendar-extract-month date))
          (day (calendar-extract-day date))
          (year (calendar-extract-year date))
@@ -658,7 +654,7 @@ entries of the desired type.  Returns non-nil if any entries were found."
           ;; regexp moves us past the end of date, onto the next line.
           ;; Trailing whitespace after date not allowed (see diary-file).
           (if (and (bolp) (not (looking-at "[ \t]")))
-              ;;  Diary entry that consists only of date.
+              ;; Diary entry that consists only of date.
               (backward-char 1)
             ;; Found a nonempty diary entry--make it
             ;; visible and add it to the list.
@@ -678,7 +674,7 @@ entries of the desired type.  Returns non-nil if any entries were found."
                         (buffer-substring-no-properties
                          entry-start (point)) globattr))
             (diary-add-to-list
-             date (car temp)
+             (or gdate date) (car temp)
              (buffer-substring-no-properties (1+ date-start) (1- entry-start))
              (copy-marker entry-start) (cadr temp))))))
     entry-found))
@@ -697,7 +693,7 @@ of the appropriate type."
     (dotimes (idummy number)
       (diary-list-entries-2
        (funcall absfunc (calendar-absolute-from-gregorian gdate))
-       diary-nonmarking-symbol file-glob-attrs list-only months symbol)
+       diary-nonmarking-symbol file-glob-attrs list-only months symbol gdate)
       (setq gdate
             (calendar-gregorian-from-absolute
              (1+ (calendar-absolute-from-gregorian gdate))))))
@@ -745,18 +741,17 @@ LIST-ONLY is non-nil, in which case it just returns the list."
   (when (> number 0)
     (let* ((original-date date)    ; save for possible use in the hooks
            (date-string (calendar-date-string date))
-           (d-file (substitute-in-file-name diary-file))
-           (diary-buffer (find-buffer-visiting d-file))
+           (diary-buffer (find-buffer-visiting diary-file))
            diary-entries-list file-glob-attrs)
       (message "Preparing diary...")
-      (save-excursion
+      (save-current-buffer
         (if (not diary-buffer)
-            (set-buffer (find-file-noselect d-file t))
+            (set-buffer (find-file-noselect diary-file t))
           (set-buffer diary-buffer)
           (or (verify-visited-file-modtime diary-buffer)
               (revert-buffer t t)))
         ;; Setup things like the header-line-format and invisibility-spec.
-        (if (eq major-mode default-major-mode)
+        (if (eq major-mode (default-value 'major-mode))
             (diary-mode)
           ;; This kludge is to make customizations to
           ;; diary-header-line-flag after diary has been displayed
@@ -770,37 +765,39 @@ LIST-ONLY is non-nil, in which case it just returns the list."
         ;; d-s-p is passed to the diary display function.
         (let ((diary-saved-point (point)))
           (save-excursion
-            (setq file-glob-attrs (cadr (diary-pull-attrs nil "")))
-            (with-syntax-table diary-syntax-table
+            (save-restriction
+              (widen)                   ; bug#5093
+              (setq file-glob-attrs (cadr (diary-pull-attrs nil "")))
+              (with-syntax-table diary-syntax-table
+                (goto-char (point-min))
+                (unless list-only
+                  (let ((ol (make-overlay (point-min) (point-max) nil t nil)))
+                    (set (make-local-variable 'diary-selective-display) t)
+                    (overlay-put ol 'invisible 'diary)
+                    (overlay-put ol 'evaporate t)))
+                (dotimes (idummy number)
+                  (let ((sexp-found (diary-list-sexp-entries date))
+                        (entry-found (diary-list-entries-2
+                                      date diary-nonmarking-symbol
+                                      file-glob-attrs list-only)))
+                    (if diary-list-include-blanks
+                        (or sexp-found entry-found
+                            (diary-add-to-list date "" "" "" "")))
+                    (setq date
+                          (calendar-gregorian-from-absolute
+                           (1+ (calendar-absolute-from-gregorian date)))))))
               (goto-char (point-min))
+              (run-hooks 'diary-nongregorian-listing-hook
+                         'diary-list-entries-hook)
               (unless list-only
-                (let ((ol (make-overlay (point-min) (point-max) nil t nil)))
-                  (set (make-local-variable 'diary-selective-display) t)
-                  (overlay-put ol 'invisible 'diary)
-                  (overlay-put ol 'evaporate t)))
-              (dotimes (idummy number)
-                (let ((sexp-found (diary-list-sexp-entries date))
-                      (entry-found (diary-list-entries-2
-                                    date diary-nonmarking-symbol
-                                    file-glob-attrs list-only)))
-                  (if diary-list-include-blanks
-                      (or sexp-found entry-found
-                          (diary-add-to-list date "" "" "" "")))
-                  (setq date
-                        (calendar-gregorian-from-absolute
-                         (1+ (calendar-absolute-from-gregorian date)))))))
-            (goto-char (point-min))
-            (run-hooks 'diary-nongregorian-listing-hook
-                       'diary-list-entries-hook)
-            (unless list-only
-              (if (and diary-display-function
-                       (listp diary-display-function))
-                  ;; Backwards compatability.
-                  (run-hooks 'diary-display-function)
-                (funcall (or diary-display-function
-                             'diary-simple-display))))
-            (run-hooks 'diary-hook)
-            diary-entries-list))))))
+                (if (and diary-display-function
+                         (listp diary-display-function))
+                    ;; Backwards compatibility.
+                    (run-hooks 'diary-display-function)
+                  (funcall (or diary-display-function
+                               'diary-simple-display))))
+              (run-hooks 'diary-hook)
+              diary-entries-list)))))))
 
 (define-obsolete-function-alias 'list-diary-entries 'diary-list-entries "22.1")
 
@@ -820,18 +817,16 @@ it enables you to use shared diary files together with your own.
 The files included are specified in the `diary-file' by lines of this form:
         #include \"filename\"
 This is recursive; that is, #include directives in diary files thus included
-are obeyed.  You can change the `#include' to some other string by
-changing the variable `diary-include-string'."
+are obeyed.  You can change the `#include' to some other string by changing
+the variable `diary-include-string'."
   (goto-char (point-min))
   (while (re-search-forward
           (format "^%s \"\\([^\"]*\\)\"" (regexp-quote diary-include-string))
           nil t)
-    (let ((diary-file (substitute-in-file-name
-                       (match-string-no-properties 1)))
-          (diary-list-include-blanks nil)
+    (let ((diary-file (match-string-no-properties 1))
           (diary-list-entries-hook 'diary-include-other-diary-files)
           (diary-display-function 'ignore)
-          (diary-hook nil))
+          diary-hook diary-list-include-blanks)
       (if (file-exists-p diary-file)
           (if (file-readable-p diary-file)
               (unwind-protect
@@ -894,7 +889,7 @@ in the mode line.  This is an option for `diary-display-function'."
   ;; to display the diary.
   (let* ((pop-up-frames (or pop-up-frames
                             (window-dedicated-p (selected-window))))
-         (dbuff (find-buffer-visiting (substitute-in-file-name diary-file)))
+         (dbuff (find-buffer-visiting diary-file))
          (empty (diary-display-no-entries)))
     ;; This may be too wide, but when simple diary is used there is
     ;; nowhere else for the holidays to go.  Also, it is documented in
@@ -914,9 +909,9 @@ in the mode line.  This is an option for `diary-display-function'."
 (define-obsolete-function-alias 'simple-diary-display
   'diary-simple-display "23.1")
 
-(define-button-type 'diary-entry
-  'action #'diary-goto-entry
-  'face 'diary-button)
+(define-button-type 'diary-entry 'action #'diary-goto-entry
+  'face 'diary-button 'help-echo "Find this diary entry"
+  'follow-link t)
 
 (defun diary-goto-entry (button)
   "Jump to the diary entry for the BUTTON at point."
@@ -933,7 +928,7 @@ in the mode line.  This is an option for `diary-display-function'."
                (file-exists-p file)
                (find-file-other-window file)
                (progn
-                 (when (eq major-mode default-major-mode) (diary-mode))
+                 (when (eq major-mode (default-value 'major-mode)) (diary-mode))
                  (goto-char (point-min))
                  (if (re-search-forward (format "%s.*\\(%s\\)"
                                                 (regexp-quote (nth 2 locator))
@@ -950,8 +945,7 @@ holiday), unless `diary-list-include-blanks' is non-nil.
 
 This is an option for `diary-display-function'."
   ;; Turn off selective-display in the diary file's buffer.
-  (with-current-buffer
-      (find-buffer-visiting (substitute-in-file-name diary-file))
+  (with-current-buffer (find-buffer-visiting diary-file)
     (diary-unhide-everything))
   (unless (car (diary-display-no-entries)) ; no entries
     ;; Prepare the fancy diary buffer.
@@ -1007,7 +1001,7 @@ This is an option for `diary-display-function'."
                 this-loc marks temp-face)
             (unless (zerop (length this-entry))
               (if (setq this-loc (nth 3 entry))
-                  (insert-button (concat this-entry "\n")
+                  (insert-button this-entry
                                  ;; (MARKER FILENAME SPECIFIER LITERAL)
                                  'locator (list (car this-loc)
                                                 (cadr this-loc)
@@ -1015,8 +1009,11 @@ This is an option for `diary-display-function'."
                                                 (or (nth 2 this-loc)
                                                     (nth 1 entry)))
                                  :type 'diary-entry)
-                (insert this-entry ?\n))
-              (and font-lock-mode
+                (insert this-entry))
+              (insert ?\n)
+              ;; Doesn't make sense to check font-lock-mode - see
+              ;; comments above diary-entry-marker in calendar.el.
+              (and ; font-lock-mode
                    (setq marks (nth 4 entry))
                    (save-excursion
                      (setq temp-face (calendar-make-temp-face marks))
@@ -1024,7 +1021,11 @@ This is an option for `diary-display-function'."
                      (overlay-put
                       (make-overlay (match-beginning 0) (match-end 0))
                       'face temp-face)))))))
-      (diary-fancy-display-mode)
+      ;; FIXME can't remember what this check was for.
+      ;; To prevent something looping, or a minor optimization?
+      (if (eq major-mode 'diary-fancy-display-mode)
+          (run-hooks 'diary-fancy-display-mode-hook)
+        (diary-fancy-display-mode))
       (calendar-set-mode-line date-string)
       (message "Preparing diary...done"))))
 
@@ -1049,8 +1050,7 @@ the actual printing."
     (if diary-buffer
         (with-current-buffer diary-buffer
           (run-hooks 'diary-print-entries-hook))
-      (or (setq diary-buffer
-                (find-buffer-visiting (substitute-in-file-name diary-file)))
+      (or (setq diary-buffer (find-buffer-visiting diary-file))
           (error "You don't have a diary buffer!"))
       ;; Name affects printing?
       (setq temp-buffer (get-buffer-create " *Printable Diary Entries*"))
@@ -1086,14 +1086,20 @@ This function gets rid of the selective display of the diary file so that
 all entries, not just some, are visible.  If there is no diary buffer, one
 is created."
   (interactive)
-  (let ((d-file (diary-check-diary-file))
-        (pop-up-frames (or pop-up-frames
-                           (window-dedicated-p (selected-window)))))
+  (let* ((d-file (diary-check-diary-file))
+         (pop-up-frames (or pop-up-frames
+                            (window-dedicated-p (selected-window))))
+         (win (selected-window))
+         (height (window-height)))
     (with-current-buffer (or (find-buffer-visiting d-file)
                              (find-file-noselect d-file t))
-      (when (eq major-mode default-major-mode) (diary-mode))
+      (when (eq major-mode (default-value 'major-mode)) (diary-mode))
       (diary-unhide-everything)
-      (display-buffer (current-buffer)))))
+      (display-buffer (current-buffer))
+      (when (and (/= height (window-height win))
+                 (with-current-buffer (window-buffer win)
+                   (derived-mode-p 'calendar-mode)))
+        (fit-window-to-buffer win)))))
 
 (define-obsolete-function-alias 'show-all-diary-entries
   'diary-show-all-entries "22.1")
@@ -1243,7 +1249,9 @@ function that converts absolute dates to dates of the appropriate type.  "
                                (buffer-substring-no-properties
                                 (point) (line-end-position))
                                file-glob-attrs)))
-            (if dd-name
+            ;; Only mark all days of a given name if the pattern
+            ;; contains no more specific elements.
+            (if (and dd-name (not (or d-pos m-pos y-pos)))
                 (calendar-mark-days-named
                  (cdr (assoc-string dd-name
                                     (calendar-make-alist
@@ -1284,7 +1292,7 @@ diary entries."
         file-glob-attrs)
     (with-current-buffer (find-file-noselect (diary-check-diary-file) t)
       (save-excursion
-        (when (eq major-mode default-major-mode) (diary-mode))
+        (when (eq major-mode (default-value 'major-mode)) (diary-mode))
         (setq calendar-mark-diary-entries-flag t)
         (message "Marking diary entries...")
         (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '())))
@@ -1382,14 +1390,13 @@ you to use shared diary files together with your own.  The files included are
 specified in the `diary-file' by lines of this form:
         #include \"filename\"
 This is recursive; that is, #include directives in diary files thus included
-are obeyed.  You can change the `#include' to some other string by
-changing the variable `diary-include-string'."
+are obeyed.  You can change the `#include' to some other string by changing
+the variable `diary-include-string'."
   (goto-char (point-min))
   (while (re-search-forward
           (format "^%s \"\\([^\"]*\\)\"" (regexp-quote diary-include-string))
           nil t)
-    (let* ((diary-file (substitute-in-file-name
-                        (match-string-no-properties 1)))
+    (let* ((diary-file (match-string-no-properties 1))
            (diary-mark-entries-hook 'diary-mark-included-diary-files)
            (dbuff (find-buffer-visiting diary-file)))
       (if (file-exists-p diary-file)
@@ -1499,10 +1506,9 @@ Optional argument COLOR is passed to `calendar-mark-visible-date' as MARK."
 (defun calendar-mark-1 (month day year fromabs toabs &optional color)
   "Mark dates in the calendar conforming to MONTH DAY YEAR of some system.
 The function FROMABS converts absolute dates to the appropriate date system.
-The function TOABDS carries out the inverse operation.  Optional argument
+The function TOABS carries out the inverse operation.  Optional argument
 COLOR is passed to `calendar-mark-visible-date' as MARK."
-  (save-excursion
-    (set-buffer calendar-buffer)
+  (with-current-buffer calendar-buffer
     (if (and (not (zerop month)) (not (zerop day)))
         (if (not (zerop year))
             ;; Fully specified date.
@@ -1534,7 +1540,7 @@ For example, returns 1325 for 1:25pm.
 
 Returns `diary-unknown-time' (default value -9999) if no time is recognized.
 The recognized forms are XXXX, X:XX, or XX:XX (military time), and XXam,
-XXAM, XXpm, XXPM, XX:XXam, XX:XXAM XX:XXpm, or XX:XXPM.  A period (.) can
+XXAM, XXpm, XXPM, XX:XXam, XX:XXAM, XX:XXpm, or XX:XXPM.  A period (.) can
 be used instead of a colon (:) to separate the hour and minute parts."
   (let (case-fold-search)
     (cond ((string-match                ; military time
@@ -1675,7 +1681,7 @@ These functions give the date in alternative calendrical systems:
 
 Theses functions only produce output on certain dates:
 
-`diary-phases-of-moon'         - phases of moon (on the appropriate days)
+`diary-lunar-phases'           - phases of moon (on the appropriate days)
 `diary-hebrew-omer'            - Omer count, within 50 days after Passover
 `diary-hebrew-parasha'         - weekly parasha, every Saturday
 `diary-hebrew-rosh-hodesh'     - Rosh Hodesh, or the day or Saturday before
@@ -1690,8 +1696,7 @@ best if they are non-marking."
         sexp-start sexp entry specifier entry-start line-start
         diary-entry temp literal)
     (goto-char (point-min))
-    (save-excursion
-      (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '()))))
+    (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '())))
     (while (re-search-forward s-entry nil t)
       (backward-char 1)
       (setq sexp-start (point))
@@ -1737,7 +1742,7 @@ best if they are non-marking."
   "Convert A B C into the internal calendar date form.
 The expected order of the inputs depends on `calendar-date-style',
 e.g. in the European case, A = day, B = month, C = year.  Returns
-a list\(MONTH DAY YEAR), i.e. the American style, which is the
+a list (MONTH DAY YEAR), i.e. the American style, which is the
 form used internally by the calendar and diary."
   (cond ((eq calendar-date-style 'iso)  ; YMD
          (list b c a))
@@ -1754,13 +1759,13 @@ form used internally by the calendar and diary."
 ;; To be called from diary-sexp-entry, where DATE, ENTRY are bound.
 (defun diary-date (month day year &optional mark)
   "Specific date(s) diary entry.
-Entry applies if date is MONTH, DAY, YEAR.  Each parameter can be
-a list of integers, `t' (meaning all values), or an integer.  The
-order of the input parameters changes according to `calendar-date-style'
+Entry applies if date is MONTH, DAY, YEAR.  Each parameter can be a
+list of integers, `t' (meaning all values), or an integer.  The order
+of the input parameters changes according to `calendar-date-style'
 \(e.g. to DAY MONTH YEAR in the European style).
 
-An optional parameter MARK specifies a face or single-character string to
-use when highlighting the day in the calendar."
+An optional parameter MARK specifies a face or single-character string
+to use when highlighting the day in the calendar."
   (let* ((ddate (diary-make-date month day year))
          (dd (calendar-extract-day ddate))
          (mm (calendar-extract-month ddate))
@@ -1783,12 +1788,12 @@ use when highlighting the day in the calendar."
 ;; To be called from diary-sexp-entry, where DATE, ENTRY are bound.
 (defun diary-block (m1 d1 y1 m2 d2 y2 &optional mark)
   "Block diary entry.
-Entry applies if date is between, or on one of, two dates.  The
-order of the input parameters changes according to
-`calendar-date-style' (e.g. to D1, M1, Y1, D2, M2, Y2 in the European style).
+Entry applies if date is between, or on one of, two dates.  The order
+of the input parameters changes according to `calendar-date-style'
+\(e.g. to D1, M1, Y1, D2, M2, Y2 in the European style).
 
-An optional parameter MARK specifies a face or single-character string to
-use when highlighting the day in the calendar."
+An optional parameter MARK specifies a face or single-character string
+to use when highlighting the day in the calendar."
   (let ((date1 (calendar-absolute-from-gregorian
                 (diary-make-date m1 d1 y1)))
         (date2 (calendar-absolute-from-gregorian
@@ -1877,11 +1882,11 @@ Entry applies if date is the anniversary of MONTH, DAY, YEAR.
 The order of the input parameters changes according to
 `calendar-date-style' (e.g. to DAY MONTH YEAR in the European style).
 
-The diary entry can contain `%d' or `%d%s'; the %d will be
-replaced by the number of years since the MONTH, DAY, YEAR, and the
-%s will be replaced by the ordinal ending of that number (that
-is, `st', `nd', `rd' or `th', as appropriate.  The anniversary of
-February 29 is considered to be March 1 in non-leap years.
+The diary entry can contain `%d' or `%d%s'; the %d will be replaced
+by the number of years since the MONTH, DAY, YEAR, and the %s will
+be replaced by the ordinal ending of that number (that is, `st',
+`nd', `rd' or `th', as appropriate).  The anniversary of February 29
+is considered to be March 1 in non-leap years.
 
 An optional parameter MARK specifies a face or single-character
 string to use when highlighting the day in the calendar."
@@ -1902,13 +1907,15 @@ string to use when highlighting the day in the calendar."
   "Cycle diary entry--entry applies every N days starting at MONTH, DAY, YEAR.
 The order of the input parameters changes according to
 `calendar-date-style' (e.g. to N DAY MONTH YEAR in the European
-style).  ENTRY can contain `%d' or `%d%s'; the %d will be
+style).  The entry can contain `%d' or `%d%s'; the %d will be
 replaced by the number of repetitions since the MONTH DAY YEAR,
 and %s by the ordinal ending of that number (that is, `st', `nd',
-`rd' or `th', as appropriate.
+`rd' or `th', as appropriate).
 
 An optional parameter MARK specifies a face or single-character
 string to use when highlighting the day in the calendar."
+  (or (> n 0)
+      (error "Day count must be positive"))
   (let* ((diff (- (calendar-absolute-from-gregorian date)
                   (calendar-absolute-from-gregorian
                    (diary-make-date month day year))))
@@ -1975,8 +1982,8 @@ If omitted, NONMARKING defaults to nil and FILE defaults to
 `diary-file'."
   (let ((pop-up-frames (or pop-up-frames
                            (window-dedicated-p (selected-window)))))
-    (find-file-other-window (substitute-in-file-name (or file diary-file))))
-  (when (eq major-mode default-major-mode) (diary-mode))
+    (find-file-other-window (or file diary-file)))
+  (when (eq major-mode (default-value 'major-mode)) (diary-mode))
   (widen)
   (diary-unhide-everything)
   (goto-char (point-max))
@@ -1996,11 +2003,12 @@ If omitted, NONMARKING defaults to nil and FILE defaults to
 (define-obsolete-function-alias 'make-diary-entry 'diary-make-entry "23.1")
 
 ;;;###cal-autoload
-(defun diary-insert-entry (arg)
+(defun diary-insert-entry (arg &optional event)
   "Insert a diary entry for the date indicated by point.
 Prefix argument ARG makes the entry nonmarking."
-  (interactive "P")
-  (diary-make-entry (calendar-date-string (calendar-cursor-to-date t) t t)
+  (interactive
+   (list current-prefix-arg last-nonmenu-event))
+  (diary-make-entry (calendar-date-string (calendar-cursor-to-date t event) t t)
                     arg))
 
 ;;;###cal-autoload
@@ -2019,7 +2027,7 @@ Prefix argument ARG makes the entry nonmarking."
   'diary-insert-weekly-entry "23.1")
 
 (defun diary-date-display-form (&optional type)
-  "Return value for `calendar-date-display-form' using `calendar-date-style.'
+  "Return value for `calendar-date-display-form' using `calendar-date-style'.
 Optional symbol TYPE is either `monthly' or `yearly'."
   (cond ((eq type 'monthly) (cond ((eq calendar-date-style 'iso)
                                    '((format "*-*-%.2d"
@@ -2045,11 +2053,11 @@ Optional symbol TYPE is either `monthly' or `yearly'."
 
 (defun diary-insert-entry-1 (&optional type nomark months symbol absfunc)
   "Subroutine to insert a diary entry related to the date at point.
-TYPE is the type of entry (`monthly' or `yearly').  NOMARK
-non-nil means make the entry non-marking.  Array MONTHS is used
-in place of `calendar-month-name-array'.  String SYMBOL marks the
-type of diary entry.  Function ABSFUNC converts absolute dates to
-dates of the appropriate type."
+TYPE is the type of entry (`monthly' or `yearly').  NOMARK non-nil
+means make the entry non-marking.  Array MONTHS is used in place
+of `calendar-month-name-array'.  String SYMBOL marks the type of
+diary entry.  Function ABSFUNC converts absolute dates to dates of
+the appropriate type."
   (let ((calendar-date-display-form (if type
                                         (diary-date-display-form type)
                                       calendar-date-display-form))
@@ -2215,8 +2223,8 @@ names."
 (defmacro diary-font-lock-keywords-1 (markfunc listfunc feature months symbol)
   "Subroutine of the function `diary-font-lock-keywords'.
 If MARKFUNC is a member of `diary-nongregorian-marking-hook', or
-LISTFUNC of `diary-nongregorian-listing-hook', then require FEATURE
-and return a font-lock pattern matching array of MONTHS and marking SYMBOL."
+LISTFUNC of `diary-nongregorian-listing-hook', then require FEATURE and
+return a font-lock pattern matching array of MONTHS and marking SYMBOL."
   `(when (or (memq ',markfunc diary-nongregorian-marking-hook)
              (memq ',listfunc diary-nongregorian-listing-hook))
      (require ',feature)
@@ -2350,6 +2358,11 @@ Fontify the region between BEG and END, quietly unless VERBOSE is non-nil."
       (setq end (line-beginning-position 2)))
   (font-lock-default-fontify-region beg end verbose))
 
+(defvar diary-fancy-overriding-map (let ((map (make-sparse-keymap)))
+                                     (define-key map "q" 'quit-window)
+                                     map)
+  "Keymap overriding minor-mode maps in `diary-fancy-display-mode'.")
+
 (define-derived-mode diary-fancy-display-mode fundamental-mode
   "Diary"
   "Major mode used while displaying diary entries using Fancy Display."
@@ -2358,7 +2371,10 @@ Fontify the region between BEG and END, quietly unless VERBOSE is non-nil."
          t nil nil nil
          (font-lock-fontify-region-function
           . diary-fancy-font-lock-fontify-region-function)))
-  (local-set-key "q" 'quit-window))
+  (local-set-key "q" 'quit-window)
+  (set (make-local-variable 'minor-mode-overriding-map-alist)
+       (list (cons t diary-fancy-overriding-map)))
+  (view-mode 1))
 
 (define-obsolete-function-alias 'fancy-diary-display-mode
   'diary-fancy-display-mode "23.1")
@@ -2373,6 +2389,7 @@ Fontify the region between BEG and END, quietly unless VERBOSE is non-nil."
 ;; `diary-outlook-formats'.
 
 (defvar subject)                        ; bound in diary-from-outlook-gnus
+(defvar body)
 
 (defun diary-from-outlook-internal (&optional test-only)
   "Snarf a diary entry from a message assumed to be from MS Outlook.