comparison lisp/calendar/diary-lib.el @ 93270:639cd5027418

(diary-face-attrs): Fix type of `width'. (list-diary-entries-hook, mark-diary-entries-hook) (include-other-diary-files, mark-included-diary-files): Doc fixes. (diary-set-header): New function. (diary-header-line-flag, diary-header-line-format): Use diary-set-header for custom :set function. (diary-set-maybe-redraw): Use symbol-value rather than eval. (diary-attrtype-convert): Use intern-soft rather than read. (diary-display-no-entries): New function. (simple-diary-display, fancy-diary-display): Use it. (fancy-diary-display): Doc fix. Remove unneeded local entry-list.
author Glenn Morris <rgm@gnu.org>
date Thu, 27 Mar 2008 02:50:38 +0000
parents 32f5a7f03231
children 177806bc3b1b
comparison
equal deleted inserted replaced
93269:da37495d5c85 93270:639cd5027418
82 ;; follows: the first line matching "^# [tag:value]" defines the value 82 ;; follows: the first line matching "^# [tag:value]" defines the value
83 ;; for that particular tag. 83 ;; for that particular tag.
84 (defcustom diary-face-attrs 84 (defcustom diary-face-attrs
85 '((" *\\[foreground:\\([-a-z]+\\)\\]$" 1 :foreground string) 85 '((" *\\[foreground:\\([-a-z]+\\)\\]$" 1 :foreground string)
86 (" *\\[background:\\([-a-z]+\\)\\]$" 1 :background string) 86 (" *\\[background:\\([-a-z]+\\)\\]$" 1 :background string)
87 (" *\\[width:\\([-a-z]+\\)\\]$" 1 :width symbol) 87 (" *\\[width:\\([-a-z]+\\)\\]$" 1 :width int)
88 (" *\\[height:\\([-0-9a-z]+\\)\\]$" 1 :height int) 88 (" *\\[height:\\([-0-9a-z]+\\)\\]$" 1 :height int)
89 (" *\\[weight:\\([-a-z]+\\)\\]$" 1 :weight symbol) 89 (" *\\[weight:\\([-a-z]+\\)\\]$" 1 :weight symbol)
90 (" *\\[slant:\\([-a-z]+\\)\\]$" 1 :slant symbol) 90 (" *\\[slant:\\([-a-z]+\\)\\]$" 1 :slant symbol)
91 (" *\\[underline:\\([-a-z]+\\)\\]$" 1 :underline stringtnil) 91 (" *\\[underline:\\([-a-z]+\\)\\]$" 1 :underline stringtnil)
92 (" *\\[overline:\\([-a-z]+\\)\\]$" 1 :overline stringtnil) 92 (" *\\[overline:\\([-a-z]+\\)\\]$" 1 :overline stringtnil)
137 "The string used to indicate a sexp diary entry in `diary-file'. 137 "The string used to indicate a sexp diary entry in `diary-file'.
138 See the documentation for the function `list-sexp-diary-entries'." 138 See the documentation for the function `list-sexp-diary-entries'."
139 :type 'string 139 :type 'string
140 :group 'diary) 140 :group 'diary)
141 141
142 ;; FIXME
143 (defcustom list-diary-entries-hook nil 142 (defcustom list-diary-entries-hook nil
144 "List of functions called after diary file is culled for relevant entries. 143 "List of functions called after diary file is culled for relevant entries.
145 It is to be used for diary entries that are not found in the diary file. 144 You might wish to add `include-other-diary-files', in which case
146 145 you will probably also want to add `mark-included-diary-files' to
147 A function `include-other-diary-files' is provided for use as the value of 146 `mark-diary-entries-hook'. For example, you could use
148 this hook. This function enables you to use shared diary files together
149 with your own. The files included are specified in the diary file by lines
150 of the form
151
152 #include \"filename\"
153
154 This is recursive; that is, #include directives in files thus included are
155 obeyed. You can change the \"#include\" to some other string by changing
156 the variable `diary-include-string'. When you use `include-other-diary-files'
157 as part of the list-diary-entries-hook, you will probably also want to use the
158 function `mark-included-diary-files' as part of `mark-diary-entries-hook'.
159
160 For example, you could use
161 147
162 (add-hook 'list-diary-entries-hook 'include-other-diary-files) 148 (add-hook 'list-diary-entries-hook 'include-other-diary-files)
163 (add-hook 'list-diary-entries-hook 'sort-diary-entries) 149 (add-hook 'list-diary-entries-hook 'sort-diary-entries)
164 (add-hook 'diary-display-hook 'fancy-diary-display) 150 (add-hook 'diary-display-hook 'fancy-diary-display)
165 151
168 lexicographic order." 154 lexicographic order."
169 :type 'hook 155 :type 'hook
170 :options '(include-other-diary-files sort-diary-entries) 156 :options '(include-other-diary-files sort-diary-entries)
171 :group 'diary) 157 :group 'diary)
172 158
173 ;; FIXME
174 (defcustom mark-diary-entries-hook nil 159 (defcustom mark-diary-entries-hook nil
175 "List of functions called after marking diary entries in the calendar. 160 "List of functions called after marking diary entries in the calendar.
176 161 You might wish to add `mark-included-diary-files', in which case
177 A function `mark-included-diary-files' is also provided for use as the 162 you will probably also want to add `include-other-diary-files' to
178 `mark-diary-entries-hook'; it enables you to use shared diary files together 163 `list-diary-entries-hook'."
179 with your own. The files included are specified in the diary file by lines
180 of the form
181 #include \"filename\"
182 This is recursive; that is, #include directives in files thus included are
183 obeyed. You can change the \"#include\" to some other string by changing the
184 variable `diary-include-string'. When you use `mark-included-diary-files' as
185 part of the mark-diary-entries-hook, you will probably also want to use the
186 function `include-other-diary-files' as part of `list-diary-entries-hook'."
187 :type 'hook 164 :type 'hook
188 :options '(mark-included-diary-files) 165 :options '(mark-included-diary-files)
189 :group 'diary) 166 :group 'diary)
190 167
191 (defcustom nongregorian-diary-listing-hook nil 168 (defcustom nongregorian-diary-listing-hook nil
304 "Unary function providing template"))) 281 "Unary function providing template")))
305 :version "22.1" 282 :version "22.1"
306 :group 'diary) 283 :group 'diary)
307 284
308 285
286 (defun diary-set-header (symbol value)
287 "Set SYMBOL's value to VALUE, and redraw the diary header if necessary."
288 (let ((oldvalue (symbol-value symbol))
289 (dbuff (and diary-file
290 (find-buffer-visiting
291 (substitute-in-file-name diary-file)))))
292 (custom-set-default symbol value)
293 (and dbuff
294 (not (equal value oldvalue))
295 (with-current-buffer dbuff
296 (if (eq major-mode 'diary-mode)
297 (setq header-line-format (and diary-header-line-flag
298 diary-header-line-format)))))))
299
300 ;; This can be removed once the kill/yank treatment of invisible text
301 ;; (see etc/TODO) is fixed. -- gm
302 (defcustom diary-header-line-flag t
303 "Non-nil means `simple-diary-display' will show a header line.
304 The format of the header is specified by `diary-header-line-format'."
305 :group 'diary
306 :type 'boolean
307 :initialize 'custom-initialize-default
308 :set 'diary-set-header
309 :version "22.1")
310
311 (defvar diary-selective-display nil
312 "Internal diary variable; non-nil if some diary text is hidden.")
313
314 (defcustom diary-header-line-format
315 '(:eval (calendar-string-spread
316 (list (if diary-selective-display
317 "Some text is hidden - press \"s\" in calendar \
318 before edit/copy"
319 "Diary"))
320 ?\s (frame-width)))
321 "Format of the header line displayed by `simple-diary-display'.
322 Only used if `diary-header-line-flag' is non-nil."
323 :group 'diary
324 :type 'sexp
325 :initialize 'custom-initialize-default
326 :set 'diary-set-header
327 :version "22.1")
328
309 ;; The first version of this also checked for diary-selective-display 329 ;; The first version of this also checked for diary-selective-display
310 ;; in the non-fancy case. This was an attempt to distinguish between 330 ;; in the non-fancy case. This was an attempt to distinguish between
311 ;; displaying the diary and just visiting the diary file. However, 331 ;; displaying the diary and just visiting the diary file. However,
312 ;; when using fancy diary, calling diary when there are no entries to 332 ;; when using fancy diary, calling diary when there are no entries to
313 ;; display does not create the fancy buffer, nor does it set 333 ;; display does not create the fancy buffer, nor does it set
327 ;;;###cal-autoload 347 ;;;###cal-autoload
328 (defun diary-set-maybe-redraw (symbol value) 348 (defun diary-set-maybe-redraw (symbol value)
329 "Set SYMBOL's value to VALUE, and redraw the diary if necessary. 349 "Set SYMBOL's value to VALUE, and redraw the diary if necessary.
330 Redraws the diary if it is being displayed (note this is not the same as 350 Redraws the diary if it is being displayed (note this is not the same as
331 just visiting the `diary-file'), and SYMBOL's value is to be changed." 351 just visiting the `diary-file'), and SYMBOL's value is to be changed."
332 (let ((oldvalue (eval symbol))) ; FIXME symbol-value? 352 (let ((oldvalue (symbol-value symbol)))
333 (custom-set-default symbol value) 353 (custom-set-default symbol value)
334 (and (not (equal value oldvalue)) 354 (and (not (equal value oldvalue))
335 (diary-live-p) 355 (diary-live-p)
336 ;; Note this assumes diary was called without prefix arg. 356 ;; Note this assumes diary was called without prefix arg.
337 (diary)))) 357 (diary))))
338
339 (defvar diary-selective-display nil
340 "Internal diary variable; non-nil if some diary text is hidden.")
341
342
343 ;; This can be removed once the kill/yank treatment of invisible text
344 ;; (see etc/TODO) is fixed. -- gm
345 (defcustom diary-header-line-flag t
346 "Non-nil means `simple-diary-display' will show a header line.
347 The format of the header is specified by `diary-header-line-format'."
348 :group 'diary
349 :type 'boolean
350 :initialize 'custom-initialize-default
351 ;; FIXME overkill.
352 :set 'diary-set-maybe-redraw
353 :version "22.1")
354
355 (defcustom diary-header-line-format
356 '(:eval (calendar-string-spread
357 (list (if diary-selective-display
358 "Some text is hidden - press \"s\" in calendar \
359 before edit/copy"
360 "Diary"))
361 ?\s (frame-width)))
362 "Format of the header line displayed by `simple-diary-display'.
363 Only used if `diary-header-line-flag' is non-nil."
364 :group 'diary
365 :type 'sexp
366 :initialize 'custom-initialize-default
367 ;; FIXME overkill.
368 :set 'diary-set-maybe-redraw
369 :version "22.1")
370 358
371 (defcustom number-of-diary-entries 1 359 (defcustom number-of-diary-entries 1
372 "Specifies how many days of diary entries are to be displayed initially. 360 "Specifies how many days of diary entries are to be displayed initially.
373 This variable affects the diary display when the command \\[diary] is used, 361 This variable affects the diary display when the command \\[diary] is used,
374 or if the value of the variable `view-diary-entries-initially' is non-nil. 362 or if the value of the variable `view-diary-entries-initially' is non-nil.
458 446
459 (defun diary-attrtype-convert (attrvalue type) 447 (defun diary-attrtype-convert (attrvalue type)
460 "Convert string ATTRVALUE to TYPE appropriate for a face description. 448 "Convert string ATTRVALUE to TYPE appropriate for a face description.
461 Valid TYPEs are: string, symbol, int, stringtnil, tnil." 449 Valid TYPEs are: string, symbol, int, stringtnil, tnil."
462 (cond ((eq type 'string) attrvalue) 450 (cond ((eq type 'string) attrvalue)
463 ((eq type 'symbol) (read attrvalue)) ; FIXME intern-soft? 451 ((eq type 'symbol) (intern-soft attrvalue))
464 ((eq type 'int) (string-to-number attrvalue)) 452 ((eq type 'int) (string-to-number attrvalue))
465 ((eq type 'stringtnil) 453 ((eq type 'stringtnil)
466 (cond ((string-equal "t" attrvalue) t) 454 (cond ((string-equal "t" attrvalue) t)
467 ((string-equal "nil" attrvalue) nil) 455 ((string-equal "nil" attrvalue) nil)
468 (t attrvalue))) 456 (t attrvalue)))
711 (setq header-line-format (and diary-header-line-flag 699 (setq header-line-format (and diary-header-line-flag
712 diary-header-line-format)))) 700 diary-header-line-format))))
713 ;; d-s-p is passed to the diary display function. 701 ;; d-s-p is passed to the diary display function.
714 (let ((diary-saved-point (point))) 702 (let ((diary-saved-point (point)))
715 (save-excursion 703 (save-excursion
716 ;; FIXME move after goto? 704 ;; FIXME move after goto? Syntax?
717 (setq file-glob-attrs (cadr (diary-pull-attrs nil ""))) 705 (setq file-glob-attrs (cadr (diary-pull-attrs nil "")))
718 (with-syntax-table diary-syntax-table 706 (with-syntax-table diary-syntax-table
719 (goto-char (point-min)) 707 (goto-char (point-min))
720 (unless list-only 708 (unless list-only
721 (let ((ol (make-overlay (point-min) (point-max) nil t nil))) 709 (let ((ol (make-overlay (point-min) (point-max) nil t nil)))
752 (defvar original-date) ; bound in diary-list-entries 740 (defvar original-date) ; bound in diary-list-entries
753 (defvar number) 741 (defvar number)
754 742
755 (defun include-other-diary-files () 743 (defun include-other-diary-files ()
756 "Include the diary entries from other diary files with those of `diary-file'. 744 "Include the diary entries from other diary files with those of `diary-file'.
757 This function is suitable for use in `list-diary-entries-hook'; 745 This function is suitable for use with `list-diary-entries-hook';
758 it enables you to use shared diary files together with your own. 746 it enables you to use shared diary files together with your own.
759 The files included are specified in the `diary-file' by lines of this form: 747 The files included are specified in the `diary-file' by lines of this form:
760 #include \"filename\" 748 #include \"filename\"
761 This is recursive; that is, #include directives in diary files thus included 749 This is recursive; that is, #include directives in diary files thus included
762 are obeyed. You can change the `#include' to some other string by 750 are obeyed. You can change the `#include' to some other string by
785 (beep) 773 (beep)
786 (message "Can't find included diary file %s" diary-file) 774 (message "Can't find included diary file %s" diary-file)
787 (sleep-for 2)))) 775 (sleep-for 2))))
788 (goto-char (point-min))) 776 (goto-char (point-min)))
789 777
790 ;; Bound in diary-list-entries. 778 (defvar date-string) ; bound in diary-list-entries
791 (defvar date-string) 779
792 (defvar diary-saved-point) 780 (defun diary-display-no-entries ()
793 781 "Common subroutine of `simple-diary-display' and `fancy-diary-display'.
794 ;; FIXME common code with fancy-diary-display. 782 Handles the case where there are no diary entries.
783 Returns a cons (NOENTRIES . HOLIDAY-STRING)."
784 (let* ((holiday-list (if holidays-in-diary-buffer
785 (calendar-check-holidays original-date)))
786 (hol-string (format "%s%s%s"
787 date-string
788 (if holiday-list ": " "")
789 (mapconcat 'identity holiday-list "; ")))
790 (msg (format "No diary entries for %s" hol-string))
791 ;; Empty list, or single item with no text.
792 ;; FIXME multiple items with no text?
793 (noentries (or (not diary-entries-list)
794 (and (not (cdr diary-entries-list))
795 (string-equal "" (cadr
796 (car diary-entries-list)))))))
797 ;; Inconsistency: whether or not the holidays are displayed in a
798 ;; separate buffer depends on if there are diary entries.
799 (when noentries
800 (if (or (< (length msg) (frame-width))
801 (not holiday-list))
802 (message "%s" msg)
803 ;; holiday-list which is too wide for a message gets a buffer.
804 (calendar-in-read-only-buffer holiday-buffer
805 (calendar-set-mode-line (format "Holidays for %s" date-string))
806 (insert (mapconcat 'identity holiday-list "\n")))
807 (message "No diary entries for %s" date-string)))
808 (cons noentries hol-string)))
809
810
811 (defvar diary-saved-point) ; bound in diary-list-entries
812
795 (defun simple-diary-display () 813 (defun simple-diary-display ()
796 "Display the diary buffer if there are any relevant entries or holidays." 814 "Display the diary buffer if there are any relevant entries or holidays."
797 (let* ((holiday-list (if holidays-in-diary-buffer 815 ;; If selected window is dedicated (to the calendar), need a new one
798 (calendar-check-holidays original-date))) 816 ;; to display the diary.
799 (hol-string (format "%s%s%s" 817 (let* ((pop-up-frames (or pop-up-frames
800 date-string 818 (window-dedicated-p (selected-window))))
801 (if holiday-list ": " "") 819 (dbuff (find-buffer-visiting (substitute-in-file-name diary-file)))
802 (mapconcat 'identity holiday-list "; "))) 820 (empty (diary-display-no-entries)))
803 (msg (format "No diary entries for %s" hol-string)) 821 ;; This may be too wide, but when simple diary is used there is
804 ;; If selected window is dedicated (to the calendar), 822 ;; nowhere else for the holidays to go. Also, it is documented in
805 ;; need a new one to display the diary. 823 ;; holidays-in-diary-buffer that the holidays go in the mode-line.
806 (pop-up-frames (or pop-up-frames 824 ;; FIXME however if there are no diary entries a separate buffer
807 (window-dedicated-p (selected-window))))) 825 ;; is displayed - this is inconsistent.
808 (calendar-set-mode-line (format "Diary for %s" hol-string)) 826 (with-current-buffer dbuff
809 (if (or (not diary-entries-list) 827 (calendar-set-mode-line (format "Diary for %s" (cdr empty))))
810 (and (not (cdr diary-entries-list)) 828 (unless (car empty) ; no entries
811 (string-equal (cadr (car diary-entries-list)) ""))) 829 (with-current-buffer dbuff
812 (if (< (length msg) (frame-width))
813 (message "%s" msg)
814 (calendar-in-read-only-buffer holiday-buffer
815 (calendar-set-mode-line date-string)
816 (insert (mapconcat 'identity holiday-list "\n")))
817 (message "No diary entries for %s" date-string))
818 (with-current-buffer
819 (find-buffer-visiting (substitute-in-file-name diary-file))
820 (let ((window (display-buffer (current-buffer)))) 830 (let ((window (display-buffer (current-buffer))))
821 ;; d-s-p is passed from diary-list-entries. 831 ;; d-s-p is passed from diary-list-entries.
822 (set-window-point window diary-saved-point) 832 (set-window-point window diary-saved-point)
823 (set-window-start window (point-min)))) 833 (set-window-start window (point-min))))
824 (message "Preparing diary...done")))) 834 (message "Preparing diary...done"))))
851 (goto-char (match-beginning 1))))) 861 (goto-char (match-beginning 1)))))
852 (message "Unable to locate this diary entry"))))) 862 (message "Unable to locate this diary entry")))))
853 863
854 (defun fancy-diary-display () 864 (defun fancy-diary-display ()
855 "Prepare a diary buffer with relevant entries in a fancy, noneditable form. 865 "Prepare a diary buffer with relevant entries in a fancy, noneditable form.
856 This function is provided for optional use as the `diary-display-hook'." 866 To use this function, add it to `diary-display-hook'."
857 ;; Turn off selective-display in the diary file's buffer. 867 ;; Turn off selective-display in the diary file's buffer.
858 (with-current-buffer 868 (with-current-buffer
859 (find-buffer-visiting (substitute-in-file-name diary-file)) 869 (find-buffer-visiting (substitute-in-file-name diary-file))
860 (diary-unhide-everything)) 870 (diary-unhide-everything))
861 (if (or (not diary-entries-list) 871 (unless (car (diary-display-no-entries)) ; no entries
862 (and (not (cdr diary-entries-list))
863 (string-equal (cadr (car diary-entries-list)) "")))
864 (let* ((holiday-list (if holidays-in-diary-buffer
865 (calendar-check-holidays original-date)))
866 (msg (format "No diary entries for %s %s"
867 (concat date-string (if holiday-list ":" ""))
868 (mapconcat 'identity holiday-list "; "))))
869 (if (<= (length msg) (frame-width))
870 (message "%s" msg)
871 (calendar-in-read-only-buffer holiday-buffer
872 (insert (mapconcat 'identity holiday-list "\n")))
873 (message "No diary entries for %s" date-string)))
874 ;; Prepare the fancy diary buffer. 872 ;; Prepare the fancy diary buffer.
875 (calendar-in-read-only-buffer fancy-diary-buffer 873 (calendar-in-read-only-buffer fancy-diary-buffer
876 (calendar-set-mode-line "Diary Entries") 874 (calendar-set-mode-line "Diary Entries")
877 (let ((entry-list diary-entries-list) 875 (let ((holiday-list-last-month 1)
878 (holiday-list)
879 (holiday-list-last-month 1)
880 (holiday-list-last-year 1) 876 (holiday-list-last-year 1)
881 (date (list 0 0 0))) 877 (date (list 0 0 0))
882 (dolist (entry entry-list) 878 holiday-list)
879 (dolist (entry diary-entries-list)
883 (unless (calendar-date-equal date (car entry)) 880 (unless (calendar-date-equal date (car entry))
884 (setq date (car entry)) 881 (setq date (car entry))
885 (and holidays-in-diary-buffer 882 (and holidays-in-diary-buffer
886 (calendar-date-compare 883 (calendar-date-compare
887 (list (list holiday-list-last-month 884 (list (list holiday-list-last-month
1303 marks 1300 marks
1304 (if (consp mark) (car mark)))))))))) 1301 (if (consp mark) (car mark))))))))))
1305 1302
1306 (defun mark-included-diary-files () 1303 (defun mark-included-diary-files ()
1307 "Mark the diary entries from other diary files with those of the diary file. 1304 "Mark the diary entries from other diary files with those of the diary file.
1308 This function is suitable for use as the `mark-diary-entries-hook'; it enables 1305 This function is suitable for use with `mark-diary-entries-hook'; it enables
1309 you to use shared diary files together with your own. The files included are 1306 you to use shared diary files together with your own. The files included are
1310 specified in the `diary-file' by lines of this form: 1307 specified in the `diary-file' by lines of this form:
1311 #include \"filename\" 1308 #include \"filename\"
1312 This is recursive; that is, #include directives in diary files thus included 1309 This is recursive; that is, #include directives in diary files thus included
1313 are obeyed. You can change the `#include' to some other string by 1310 are obeyed. You can change the `#include' to some other string by