# HG changeset patch # User Edward M. Reingold # Date 783185182 0 # Node ID 3ece524b8ea3564b60eefb20037253fed26ad1f9 # Parent 33dcf295f62a70f8c46a4ac944d4400c9cda85cd Lots of minor fixes and code polishing. Exit-calendar code rewritten. diff -r 33dcf295f62a -r 3ece524b8ea3 lisp/calendar/calendar.el --- a/lisp/calendar/calendar.el Wed Oct 26 12:57:46 1994 +0000 +++ b/lisp/calendar/calendar.el Wed Oct 26 15:26:22 1994 +0000 @@ -109,6 +109,13 @@ 0 means Sunday (default), 1 means Monday, and so on.") ;;;###autoload +(defvar calendar-offset 0 + "*The offset of the principal month from the center of the calendar window. +0 means the principal month is in the center (default), -1 means on the left, ++1 means on the right. Larger (or smaller) values push the principal month off +the screen.") + +;;;###autoload (defvar view-diary-entries-initially nil "*Non-nil means display current date's diary entries on entry. The diary is displayed in another window when the calendar is first displayed, @@ -923,6 +930,9 @@ (defconst fancy-diary-buffer "*Fancy Diary Entries*" "Name of the buffer used for the optional fancy display of the diary.") +(defconst lunar-phases-buffer "*Phases of Moon*" + "Name of the buffer used for the lunar phases.") + (defmacro increment-calendar-month (mon yr n) "Move the variables MON and YR to the month and year by N months. Forward if N is positive or backward if N is negative." @@ -945,10 +955,9 @@ (setq (, index) (1+ (, index)))) sum))) -;; The following macros are for speed; the code would be clearer if they -;; were functions, but they can be called thousands of times when -;; looking up holidays or processing the diary. Here, for example, are the -;; numbers of calls to calendar/diary/holiday functions in preparing the +;; The following are in-line for speed; they can be called thousands of times +;; when looking up holidays or processing the diary. Here, for example, are +;; the numbers of calls to calendar/diary/holiday functions in preparing the ;; fancy diary display, for a moderately complex diary file, with functions ;; used instead of macros. There were a total of 10000 such calls: ;; @@ -974,123 +983,68 @@ ;; . ;; ;; The use of these seven macros eliminates the overhead of 92% of the function -;; calls; it's faster this way. For clarity, the defun form of each is given -;; in comments after the defmacro form. +;; calls; it's faster this way. -(defmacro extract-calendar-month (date) +(defsubst extract-calendar-month (date) "Extract the month part of DATE which has the form (month day year)." - (` (car (, date)))) -;;(defun extract-calendar-month (date) -;; "Extract the month part of DATE which has the form (month day year)." -;; (car date)) + (car date)) -(defmacro extract-calendar-day (date) +(defsubst extract-calendar-day (date) "Extract the day part of DATE which has the form (month day year)." - (` (car (cdr (, date))))) -;;(defun extract-calendar-day (date) -;; "Extract the day part of DATE which has the form (month day year)." -;; (car (cdr date))) + (car (cdr date))) -(defmacro extract-calendar-year (date) +(defsubst extract-calendar-year (date) "Extract the year part of DATE which has the form (month day year)." - (` (car (cdr (cdr (, date)))))) -;;(defun extract-calendar-year (date) -;; "Extract the year part of DATE which has the form (month day year)." -;; (car (cdr (cdr date)))) + (car (cdr (cdr date)))) -(defmacro calendar-leap-year-p (year) +(defsubst calendar-leap-year-p (year) "Returns t if YEAR is a Gregorian leap year." - (` (and - (zerop (% (, year) 4)) - (or (not (zerop (% (, year) 100))) - (zerop (% (, year) 400)))))) -;;(defun calendar-leap-year-p (year) -;; "Returns t if YEAR is a Gregorian leap year." -;; (and -;; (zerop (% year 4)) -;; (or ((not (zerop (% year 100)))) -;; (zerop (% year 400))))) -;; + (and (zerop (% year 4)) + (or (not (zerop (% year 100))) + (zerop (% year 400))))) + ;; The foregoing is a bit faster, but not as clear as the following: ;; -;;(defmacro calendar-leap-year-p (year) -;; "Returns t if YEAR is a Gregorian leap year." -;; (` (or -;; (and (= (% (, year) 4) 0) -;; (/= (% (, year) 100) 0)) -;; (= (% (, year) 400) 0)))) -;;(defun calendar-leap-year-p (year) +;;(defsubst calendar-leap-year-p (year) ;; "Returns t if YEAR is a Gregorian leap year." ;; (or ;; (and (= (% year 4) 0) ;; (/= (% year 100) 0)) ;; (= (% year 400) 0))) -(defmacro calendar-last-day-of-month (month year) +(defsubst calendar-last-day-of-month (month year) "The last day in MONTH during YEAR." - (` (if (and - (= (, month) 2) - (, (macroexpand (` (calendar-leap-year-p (, year)))))) - 29 - (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- (, month)))))) -;;(defun calendar-last-day-of-month (month year) -;; "The last day in MONTH during YEAR." -;; (if (and (= month 2) (calendar-leap-year-p year)) -;; 29 -;; (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- month)))) + (if (and (= month 2) (calendar-leap-year-p year)) + 29 + (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- month)))) -(defmacro calendar-day-number (date) +;; An explanation of the calculation can be found in PascAlgorithms by +;; Edward and Ruth Reingold, Scott-Foresman/Little, Brown, 1988. + +(defsubst calendar-day-number (date) "Return the day number within the year of the date DATE. For example, (calendar-day-number '(1 1 1987)) returns the value 1, while (calendar-day-number '(12 31 1980)) returns 366." -;; -;; An explanation of the calculation can be found in PascAlgorithms by -;; Edward and Ruth Reingold, Scott-Foresman/Little, Brown, 1988. -;; - (` (let* ((month (, (macroexpand (` (extract-calendar-month (, date)))))) - (day (, (macroexpand (` (extract-calendar-day (, date)))))) - (year (, (macroexpand (` (extract-calendar-year (, date)))))) - (day-of-year (+ day (* 31 (1- month))))) - (if (> month 2) - (progn - (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10))) - (if (, (macroexpand (` (calendar-leap-year-p year)))) + (let* ((month (extract-calendar-month date)) + (day (extract-calendar-day date)) + (year (extract-calendar-year date)) + (day-of-year (+ day (* 31 (1- month))))) + (if (> month 2) + (progn + (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10))) + (if (calendar-leap-year-p year) (setq day-of-year (1+ day-of-year))))) - day-of-year))) -;;(defun calendar-day-number (date) -;; "Return the day number within the year of the date DATE. -;;For example, (calendar-day-number '(1 1 1987)) returns the value 1, -;;while (calendar-day-number '(12 31 1980)) returns 366." -;; (let* ((month (extract-calendar-month date)) -;; (day (extract-calendar-day date)) -;; (year (extract-calendar-year date)) -;; (day-of-year (+ day (* 31 (1- month))))) -;; (if (> month 2) -;; (progn -;; (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10))) -;; (if (calendar-leap-year-p year) -;; (setq day-of-year (1+ day-of-year))))) -;; day-of-year)) + day-of-year)) -(defmacro calendar-absolute-from-gregorian (date) +(defsubst calendar-absolute-from-gregorian (date) "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE. The Gregorian date Sunday, December 31, 1 BC is imaginary." - (` (let ((prior-years - (1- (, (macroexpand (` (extract-calendar-year (, date)))))))) - (+ (, (macroexpand (` (calendar-day-number (, date)))));; Days this year - (* 365 prior-years);; + Days in prior years - (/ prior-years 4);; + Julian leap years - (- (/ prior-years 100));; - century years - (/ prior-years 400)))));; + Gregorian leap years -;;(defun calendar-absolute-from-gregorian (date) -;; "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE. -;;The Gregorian date Sunday, December 31, 1 BC is imaginary." -;; (let ((prior-years (1- (extract-calendar-year date)))) -;; (+ (calendar-day-number date);; Days this year -;; (* 365 prior-years);; + Days in prior years -;; (/ prior-years 4);; + Julian leap years -;; (- (/ prior-years 100));; - century years -;; (/ prior-years 400))));; + Gregorian leap years + (let ((prior-years (1- (extract-calendar-year date)))) + (+ (calendar-day-number date);; Days this year + (* 365 prior-years);; + Days in prior years + (/ prior-years 4);; + Julian leap years + (- (/ prior-years 100));; - century years + (/ prior-years 400))));; + Gregorian leap years ;;;###autoload (defun calendar (&optional arg) @@ -1142,29 +1096,16 @@ (interactive "P") (set-buffer (get-buffer-create calendar-buffer)) (calendar-mode) -;;; (setq calendar-window-configuration (current-window-configuration)) (let* ((completion-ignore-case t) (pop-up-windows t) (split-height-threshold 1000) - (date (calendar-current-date)) - (month - (if arg - (cdr (assoc - (capitalize - (completing-read - "Month name: " - (mapcar 'list (append calendar-month-name-array nil)) - nil t)) - (calendar-make-alist calendar-month-name-array))) - (extract-calendar-month date))) - (year - (if arg - (calendar-read - "Year (>0): " - '(lambda (x) (> x 0)) - (int-to-string (extract-calendar-year date))) - (extract-calendar-year date)))) + (date (if arg + (calendar-read-date t) + (calendar-current-date))) + (month (extract-calendar-month date)) + (year (extract-calendar-year date))) (pop-to-buffer calendar-buffer) + (increment-calendar-month month year (- calendar-offset)) (generate-calendar-window month year) (if (and view-diary-entries-initially (calendar-date-is-visible-p date)) (view-diary-entries @@ -1535,7 +1476,7 @@ (define-key calendar-mode-map "iid" 'insert-islamic-diary-entry) (define-key calendar-mode-map "iim" 'insert-monthly-islamic-diary-entry) (define-key calendar-mode-map "iiy" 'insert-yearly-islamic-diary-entry) - (define-key calendar-mode-map "?" 'describe-calendar-mode)) + (define-key calendar-mode-map "?" 'calendar-goto-info-node)) (defun describe-calendar-mode () "Create a help buffer with a brief description of the calendar-mode." @@ -1556,234 +1497,29 @@ (list (substitute-command-keys "\\\\[scroll-calendar-left]") "Calendar" - (substitute-command-keys "\\\\[describe-calendar-mode] help/\\[calendar-other-month] other/\\[calendar-goto-today] today") + (substitute-command-keys "\\\\[calendar-goto-info-node] info/\\[calendar-other-month] other/\\[calendar-goto-today] today") '(calendar-date-string (calendar-current-date) t) (substitute-command-keys "\\\\[scroll-calendar-right]")) "The mode line of the calendar buffer.") +(defun calendar-goto-info-node () + "Go to the info node for the calendar." + (interactive) + (require 'info) + (let ((where (Info-find-emacs-command-nodes 'calendar))) + (if (not where) + (error "Couldn't find documentation for the calendar.") + (save-window-excursion (info)) + (pop-to-buffer "*info*") + (Info-find-node (car (car where)) (car (cdr (car where))))))) + (defun calendar-mode () "A major mode for the calendar window. -The commands for cursor movement are:\\ - - \\[calendar-forward-day] one day forward \\[calendar-backward-day] one day backward - \\[calendar-forward-week] one week forward \\[calendar-backward-week] one week backward - \\[calendar-forward-month] one month forward \\[calendar-backward-month] one month backward - \\[calendar-forward-year] one year forward \\[calendar-backward-year] one year backward - \\[calendar-beginning-of-week] beginning of week \\[calendar-end-of-week] end of week - \\[calendar-beginning-of-month] beginning of month \\[calendar-end-of-month] end of month - \\[calendar-beginning-of-year] beginning of year \\[calendar-end-of-year] end of year - - \\[calendar-goto-date] go to date - - \\[calendar-goto-julian-date] go to Julian date \\[calendar-goto-astro-day-number] go to astronomical (Julian) day number - \\[calendar-goto-hebrew-date] go to Hebrew date \\[calendar-goto-islamic-date] go to Islamic date - \\[calendar-goto-iso-date] go to ISO date \\[calendar-goto-french-date] go to French Revolutionary date - - \\[calendar-goto-mayan-long-count-date] go to Mayan Long Count date - \\[calendar-next-haab-date] go to next occurrence of Mayan Haab date - \\[calendar-previous-haab-date] go to previous occurrence of Mayan Haab date - \\[calendar-next-tzolkin-date] go to next occurrence of Mayan Tzolkin date - \\[calendar-previous-tzolkin-date] go to previous occurrence of Mayan Tzolkin date - \\[calendar-next-calendar-round-date] go to next occurrence of Mayan Calendar Round date - \\[calendar-previous-calendar-round-date] go to previous occurrence of Mayan Calendar Round date - -You can mark a date in the calendar and switch the point and mark: - - \\[calendar-set-mark] mark date \\[calendar-exchange-point-and-mark] exchange point and mark - -You can determine the number of days (inclusive) between the point and mark by - - \\[calendar-count-days-region] count days in the region - -The commands for calendar movement are: - - \\[scroll-calendar-right] scroll one month right \\[scroll-calendar-left] scroll one month left - \\[scroll-calendar-right-three-months] scroll 3 months right \\[scroll-calendar-left-three-months] scroll 3 months left - \\[calendar-goto-today] display current month \\[calendar-other-month] display another month - -Whenever it makes sense, the above commands take prefix arguments that -multiply their affect. For convenience, the digit keys and the minus sign -are bound to digit-argument, so they need not be prefixed with ESC. - -If the calendar window somehow becomes corrupted, it can be regenerated with - - \\[redraw-calendar] redraw the calendar - -The following commands deal with holidays and other notable days: - - \\[calendar-cursor-holidays] give holidays for the date specified by the cursor - \\[mark-calendar-holidays] mark notable days - \\[calendar-unmark] unmark dates - \\[list-calendar-holidays] display notable days - -The command M-x holidays causes the notable dates for the current month, and -the preceding and succeeding months, to be displayed, independently of the -calendar. - -The following commands control the diary: - - \\[mark-diary-entries] mark diary entries \\[calendar-unmark] unmark dates - \\[view-diary-entries] display diary entries \\[show-all-diary-entries] show all diary entries - \\[print-diary-entries] print diary entries - -Displaying the diary entries causes the diary entries from the diary file -\(for the date indicated by the cursor in the calendar window) to be -displayed in another window. This function takes an integer argument that -specifies the number of days of calendar entries to be displayed, starting -with the date indicated by the cursor. - -The command \\[print-diary-entries] prints the diary buffer (as it appears) -on the line printer. - -The command M-x diary causes the diary entries for the current date to be -displayed, independently of the calendar. The number of days of entries is -governed by number-of-diary-entries. - -The format of the entries in the diary file is described in the -documentation string for the variable `diary-file'. - -When diary entries are in view in the window, they can be edited. It is -important to keep in mind that the buffer displayed contains the entire -diary file, but with portions of it concealed from view. This means, for -instance, that the forward-char command can put the cursor at what appears -to be the end of the line, but what is in reality the middle of some -concealed line. BE CAREFUL WHEN EDITING THE DIARY ENTRIES! (Inserting -additional lines or adding/deleting characters in the middle of a visible -line will not cause problems; watch out for end-of-line, however--it may -put you at the end of a concealed line far from where the cursor appears to -be!) BEFORE EDITING THE DIARY IT IS BEST TO DISPLAY THE ENTIRE FILE WITH -show-all-diary-entries. BE SURE TO WRITE THE FILE BEFORE EXITING FROM THE -CALENDAR. - -The following commands assist in making diary entries: - - \\[insert-diary-entry] insert a diary entry for the selected date - \\[insert-weekly-diary-entry] insert a diary entry for the selected day of the week - \\[insert-monthly-diary-entry] insert a diary entry for the selected day of the month - \\[insert-yearly-diary-entry] insert a diary entry for the selected day of the year - \\[insert-block-diary-entry] insert a diary entry for the block days between point and mark - \\[insert-anniversary-diary-entry] insert an anniversary diary entry for the selected date - \\[insert-cyclic-diary-entry] insert a cyclic diary entry - -There are corresponding commands to assist in making Hebrew- or Islamic-date -diary entries: +For a complete description, type \ +\\\\[calendar-goto-info-node] from within the calendar. - \\[insert-hebrew-diary-entry] insert a diary entry for the Hebrew date corresponding - to the selected date - \\[insert-monthly-hebrew-diary-entry] insert a diary entry for the day of the Hebrew month - corresponding to the selected day - \\[insert-yearly-hebrew-diary-entry] insert a diary entry for the day of the Hebrew year - corresponding to the selected day - \\[insert-islamic-diary-entry] insert a diary entry for the Islamic date corresponding - to the selected date - \\[insert-monthly-islamic-diary-entry] insert a diary entry for the day of the Islamic month - corresponding to the selected day - \\[insert-yearly-islamic-diary-entry] insert a diary entry for the day of the Islamic year - corresponding to the selected day - -All of the diary entry commands make nonmarking entries when given a prefix -argument; with no prefix argument, the diary entries are marking. - -The day number in the year and the number of days remaining in the year can be -determined by - - \\[calendar-print-day-of-year] show day number and the number of days remaining in the year - -Equivalent dates on the ISO commercial, Julian, Hebrew, Islamic, French -Revolutionary, and Mayan calendars can be determined by - - \\[calendar-print-iso-date] show equivalent date on the ISO commercial calendar - \\[calendar-print-julian-date] show equivalent date on the Julian calendar - \\[calendar-print-hebrew-date] show equivalent date on the Hebrew calendar - \\[calendar-print-islamic-date] show equivalent date on the Islamic calendar - \\[calendar-print-french-date] show equivalent date on the French Revolutionary calendar - \\[calendar-print-mayan-date] show equivalent date on the Mayan calendar - -The astronomical (Julian) day number of a date is found with - - \\[calendar-print-astro-day-number] show equivalent astronomical (Julian) day number - -To find the times of sunrise and sunset and lunar phases use - - \\[calendar-sunrise-sunset] show times of sunrise and sunset - \\[calendar-phases-of-moon] show times of quarters of the moon - -The times given apply to location `calendar-location-name' at latitude -`calendar-latitude', longitude `calendar-longitude'; set these variables for -your location. The following variables are also consulted, and you must set -them if your system does not initialize them properly: `calendar-time-zone', -`calendar-daylight-time-offset', `calendar-standard-time-zone-name', -`calendar-daylight-time-zone-name', `calendar-daylight-savings-starts', -`calendar-daylight-savings-ends', `calendar-daylight-savings-starts-time', -`calendar-daylight-savings-ends-time'. - -To exit from the calendar use - - \\[exit-calendar] exit from calendar - -Set `view-diary-entries-initially' to a non-nil value to display -diary entries for the current date in -another window when the calendar is first displayed, if the current date is -visible. The variable `number-of-diary-entries' controls number of days of -diary entries that to display initially or with the command M-x -diary. For example, the default value 1 says to display only the current -day's diary entries. The value 2 says to display both the -current day's and the next day's entries. - -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 display the entries -for the current date and the day after on Monday through Thursday, -display Friday through Monday's entries on Friday, and display only -Saturday's entries on Saturday. - -Set `view-calendar-holidays-initially' to a non-nil value to display -holidays for the current three month period on entry to the calendar. - -Set `mark-diary-entries-in-calendar' to a non-nil value to mark in the -calendar all the dates that have diary entries. The variable -`diary-entry-marker' controls how to mark them. - -The variable `calendar-load-hook', whose default value is nil, is list of -functions to be called when the calendar is first loaded. - -The variable `initial-calendar-window-hook', whose default value is nil, is -list of functions to be called when the calendar window is first opened. The -functions invoked are called after the calendar window is opened, but once -opened is never called again. Leaving the calendar with the `q' command and -reentering it will cause these functions to be called again. - -The variable `today-visible-calendar-hook', whose default value is nil, is the -list of functions called after the calendar buffer has been prepared with the -calendar when the current date is visible in the window. This can be used, -for example, to replace today's date with asterisks; a function -calendar-star-date is included for this purpose: - (setq today-visible-calendar-hook 'calendar-star-date) -It could also be used to mark the current date; a function is also provided -for this: - (setq today-visible-calendar-hook 'calendar-mark-today) - -The variable `today-invisible-calendar-hook', whose default value is nil, is -the list of functions called after the calendar buffer has been prepared with -the calendar when the current date is not visible in the window. - -The variable `diary-display-hook' is the list of functions called after the -diary buffer is prepared. The default value simply displays the diary file -using selective-display to conceal irrelevant diary entries. An alternative -function `fancy-diary-display' is provided that, when used as the -`diary-display-hook', causes a noneditable buffer to be prepared with a neatly -organized day-by-day listing of relevant diary entries, together with any -known holidays. The inclusion of the holidays slows this fancy display of the -diary; to speed it up, set the variable `holidays-in-diary-buffer' to nil. - -The variable `print-diary-entries-hook' is the list of functions called after -a temporary buffer is prepared with the diary entries currently visible in the -diary buffer. The default value of this hook adds a heading (composed from -the diary buffer's mode line), does the printing with the command lpr-buffer, -and kills the temporary buffer. Other uses might include, for example, -rearranging the lines into order by day and time. - -The Gregorian calendar is assumed." +\\\\{calendar-mode-map}" (kill-all-local-variables) (setq major-mode 'calendar-mode) @@ -1830,34 +1566,63 @@ (calendar-string-spread calendar-mode-line-format ? (frame-width)))))) +(defun calendar-window-list () + "List of all calendar-related windows." + (let ((calendar-buffers (calendar-buffer-list)) + list) + (walk-windows '(lambda (w) + (if (memq (window-buffer w) calendar-buffers) + (setq list (cons w list)))) + nil t) + list)) + +(defun calendar-buffer-list () + "List of all calendar-related buffers." + (let* ((diary-buffer (get-file-buffer diary-file)) + (buffers (list "*Yahrzeits*" lunar-phases-buffer holiday-buffer + fancy-diary-buffer diary-buffer calendar-buffer)) + (buffer-list nil) + b) + (while buffers + (setq b (car buffers)) + (setq b (cond ((stringp b) (get-buffer b)) + ((bufferp b) b) + (t nil))) + (if b (setq buffer-list (cons b buffer-list))) + (setq buffers (cdr buffers))) + buffer-list)) + (defun exit-calendar () - "Delete the calendar window, and bury the calendar and related buffers." + "Get out of the calendar window and hide it and related buffers." (interactive) - (let ((diary-buffer (get-file-buffer diary-file)) - (d-buffer (get-buffer fancy-diary-buffer)) - (h-buffer (get-buffer holiday-buffer))) - (if (not diary-buffer) - (progn - ;; Restoring the configuration is undesirable because - ;; it restores the value of point in other windows. -;;; (set-window-configuration calendar-window-configuration) - (or (one-window-p t) - (delete-window)) - (bury-buffer calendar-buffer) - (if d-buffer (bury-buffer d-buffer)) - (if h-buffer (bury-buffer h-buffer))) - (if (or (not (buffer-modified-p diary-buffer)) - (yes-or-no-p "Diary modified; do you really want to exit the calendar? ")) - (progn -;;; (set-window-configuration calendar-window-configuration) - (or (one-window-p t) - (delete-window)) - (bury-buffer calendar-buffer) - (if d-buffer (bury-buffer d-buffer)) - (if h-buffer (bury-buffer h-buffer)) - (set-buffer diary-buffer) - (set-buffer-modified-p nil) - (bury-buffer diary-buffer)))))) + (let* ((diary-buffer (get-file-buffer diary-file))) + (if (and diary-buffer (buffer-modified-p diary-buffer) + (not + (yes-or-no-p + "Diary modified; do you really want to exit the calendar? "))) + (error) + ;; Need to do this multiple times because one time can replace some + ;; calendar-related buffers with other calendar-related buffers + (mapcar (lambda (x) + (mapcar 'calendar-hide-window (calendar-window-list))) + (calendar-window-list))))) + +(defun calendar-hide-window (window) + "Hide WINDOW if it is calendar-related." + (let ((buffer (if (window-live-p window) (window-buffer window)))) + (if (memq buffer (calendar-buffer-list)) + (cond + ((and window-system + (eq 'icon (cdr (assoc 'visibility + (frame-parameters + (window-frame window)))))) + nil) + ((and window-system (window-dedicated-p window)) + (iconify-frame (window-frame window))) + ((not (and (select-window window) (one-window-p window))) + (delete-window window)) + (t (set-buffer buffer) + (bury-buffer)))))) (defun calendar-goto-today () "Reposition the calendar window so the current date is visible." @@ -1945,27 +1710,16 @@ (scroll-calendar-left (* -3 arg))) (defun calendar-current-date () - "Returns the current date in a list (month day year). -If in the calendar buffer, also sets the current date local variables." - (let* ((date (current-time-string)) - (garbage - (string-match - "^\\([A-Z][a-z]*\\) *\\([A-Z][a-z]*\\) *\\([0-9]*\\) .* \\([0-9]*\\)$" - date)) - (month - (cdr (assoc - (substring date (match-beginning 2) (match-end 2)) - '(("Jan" . 1) ("Feb" . 2) ("Mar" . 3) ("Apr" . 4) - ("May" . 5) ("Jun" . 6) ("Jul" . 7) ("Aug" . 8) - ("Sep" . 9) ("Oct" . 10) ("Nov" . 11) ("Dec" . 12))))) - (day - (string-to-int (substring date (match-beginning 3) (match-end 3)))) - (year - (string-to-int (substring date (match-beginning 4) (match-end 4))))) - (list month day year))) + "Returns the current date in a list (month day year)." + (let ((s (current-time-string))) + (list (length (member (substring s 4 7) + '("Dec" "Nov" "Oct" "Sep" "Aug" "Jul" + "Jun" "May" "Apr" "Mar" "Feb" "Jan"))) + (string-to-number (substring s 8 10)) + (string-to-number (substring s 20 24))))) (defun calendar-cursor-to-date (&optional error) - "Returns a list of the month, day, and year of current cursor position. + "Returns a list (month day year) of current cursor position. If cursor is not on a specific date, signals an error if optional parameter ERROR is t, otherwise just returns nil." (let* ((segment (/ (current-column) 25)) @@ -2222,20 +1976,8 @@ (defun calendar-other-month (month year) "Display a three-month calendar centered around MONTH and YEAR." (interactive - (let* ((completion-ignore-case t) - (month (cdr (assoc - (capitalize - (completing-read - "Month name: " - (mapcar 'list (append calendar-month-name-array nil)) - nil t)) - (calendar-make-alist calendar-month-name-array)))) - (year (calendar-read - "Year (>0): " - '(lambda (x) (> x 0)) - (int-to-string - (extract-calendar-year (calendar-current-date)))))) - (list month year))) + (let* ((completion-ignore-case t)) + (calendar-read-date t))) (if (and (= month displayed-month) (= year displayed-year)) nil @@ -2307,8 +2049,10 @@ (setq value (read-minibuffer prompt initial-contents))) value)) -(defun calendar-read-date () - "Prompt for Gregorian date. Returns a list (month day year)." +(defun calendar-read-date (&optional noday) + "Prompt for Gregorian date. Returns a list (month day year). +If optional NODAY is t, does not ask for day, but just returns +(month nil year)." (let* ((year (calendar-read "Year (>0): " '(lambda (x) (> x 0)) @@ -2323,11 +2067,14 @@ (mapcar 'list (append month-array nil)) nil t)) (calendar-make-alist month-array 1 'capitalize)))) - (last (calendar-last-day-of-month month year)) - (day (calendar-read - (format "Day (1-%d): " last) - '(lambda (x) (and (< 0 x) (<= x last)))))) - (list month day year))) + (last (calendar-last-day-of-month month year))) + (list month + (if noday + nil + (day (calendar-read + (format "Day (1-%d): " last) + '(lambda (x) (and (< 0 x) (<= x last)))))) + year))) (defun calendar-goto-date (date) "Move cursor to DATE."