aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward M. Reingold1994-10-26 15:26:22 +0000
committerEdward M. Reingold1994-10-26 15:26:22 +0000
commitcba0c2538d0e0c69d6f8944e99bb2a7bd43ced12 (patch)
tree7ad56acd1af97d6ff225361660e8e99e552e08f3
parent38971c41570bb0cfe12156c2227e4be295b12803 (diff)
downloademacs-cba0c2538d0e0c69d6f8944e99bb2a7bd43ced12.tar.gz
emacs-cba0c2538d0e0c69d6f8944e99bb2a7bd43ced12.zip
Lots of minor fixes and code polishing. Exit-calendar code rewritten.
-rw-r--r--lisp/calendar/calendar.el555
1 files changed, 151 insertions, 404 deletions
diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el
index 07e4ca52c72..db7413599d5 100644
--- a/lisp/calendar/calendar.el
+++ b/lisp/calendar/calendar.el
@@ -109,6 +109,13 @@
1090 means Sunday (default), 1 means Monday, and so on.") 1090 means Sunday (default), 1 means Monday, and so on.")
110 110
111;;;###autoload 111;;;###autoload
112(defvar calendar-offset 0
113 "*The offset of the principal month from the center of the calendar window.
1140 means the principal month is in the center (default), -1 means on the left,
115+1 means on the right. Larger (or smaller) values push the principal month off
116the screen.")
117
118;;;###autoload
112(defvar view-diary-entries-initially nil 119(defvar view-diary-entries-initially nil
113 "*Non-nil means display current date's diary entries on entry. 120 "*Non-nil means display current date's diary entries on entry.
114The diary is displayed in another window when the calendar is first displayed, 121The diary is displayed in another window when the calendar is first displayed,
@@ -923,6 +930,9 @@ with descriptive strings such as
923(defconst fancy-diary-buffer "*Fancy Diary Entries*" 930(defconst fancy-diary-buffer "*Fancy Diary Entries*"
924 "Name of the buffer used for the optional fancy display of the diary.") 931 "Name of the buffer used for the optional fancy display of the diary.")
925 932
933(defconst lunar-phases-buffer "*Phases of Moon*"
934 "Name of the buffer used for the lunar phases.")
935
926(defmacro increment-calendar-month (mon yr n) 936(defmacro increment-calendar-month (mon yr n)
927 "Move the variables MON and YR to the month and year by N months. 937 "Move the variables MON and YR to the month and year by N months.
928Forward if N is positive or backward if N is negative." 938Forward if N is positive or backward if N is negative."
@@ -945,10 +955,9 @@ Forward if N is positive or backward if N is negative."
945 (setq (, index) (1+ (, index)))) 955 (setq (, index) (1+ (, index))))
946 sum))) 956 sum)))
947 957
948;; The following macros are for speed; the code would be clearer if they 958;; The following are in-line for speed; they can be called thousands of times
949;; were functions, but they can be called thousands of times when 959;; when looking up holidays or processing the diary. Here, for example, are
950;; looking up holidays or processing the diary. Here, for example, are the 960;; the numbers of calls to calendar/diary/holiday functions in preparing the
951;; numbers of calls to calendar/diary/holiday functions in preparing the
952;; fancy diary display, for a moderately complex diary file, with functions 961;; fancy diary display, for a moderately complex diary file, with functions
953;; used instead of macros. There were a total of 10000 such calls: 962;; used instead of macros. There were a total of 10000 such calls:
954;; 963;;
@@ -974,123 +983,68 @@ Forward if N is positive or backward if N is negative."
974;; . 983;; .
975;; 984;;
976;; The use of these seven macros eliminates the overhead of 92% of the function 985;; The use of these seven macros eliminates the overhead of 92% of the function
977;; calls; it's faster this way. For clarity, the defun form of each is given 986;; calls; it's faster this way.
978;; in comments after the defmacro form.
979 987
980(defmacro extract-calendar-month (date) 988(defsubst extract-calendar-month (date)
981 "Extract the month part of DATE which has the form (month day year)." 989 "Extract the month part of DATE which has the form (month day year)."
982 (` (car (, date)))) 990 (car date))
983;;(defun extract-calendar-month (date)
984;; "Extract the month part of DATE which has the form (month day year)."
985;; (car date))
986 991
987(defmacro extract-calendar-day (date) 992(defsubst extract-calendar-day (date)
988 "Extract the day part of DATE which has the form (month day year)." 993 "Extract the day part of DATE which has the form (month day year)."
989 (` (car (cdr (, date))))) 994 (car (cdr date)))
990;;(defun extract-calendar-day (date)
991;; "Extract the day part of DATE which has the form (month day year)."
992;; (car (cdr date)))
993 995
994(defmacro extract-calendar-year (date) 996(defsubst extract-calendar-year (date)
995 "Extract the year part of DATE which has the form (month day year)." 997 "Extract the year part of DATE which has the form (month day year)."
996 (` (car (cdr (cdr (, date)))))) 998 (car (cdr (cdr date))))
997;;(defun extract-calendar-year (date)
998;; "Extract the year part of DATE which has the form (month day year)."
999;; (car (cdr (cdr date))))
1000 999
1001(defmacro calendar-leap-year-p (year) 1000(defsubst calendar-leap-year-p (year)
1002 "Returns t if YEAR is a Gregorian leap year." 1001 "Returns t if YEAR is a Gregorian leap year."
1003 (` (and 1002 (and (zerop (% year 4))
1004 (zerop (% (, year) 4)) 1003 (or (not (zerop (% year 100)))
1005 (or (not (zerop (% (, year) 100))) 1004 (zerop (% year 400)))))
1006 (zerop (% (, year) 400)))))) 1005
1007;;(defun calendar-leap-year-p (year)
1008;; "Returns t if YEAR is a Gregorian leap year."
1009;; (and
1010;; (zerop (% year 4))
1011;; (or ((not (zerop (% year 100))))
1012;; (zerop (% year 400)))))
1013;;
1014;; The foregoing is a bit faster, but not as clear as the following: 1006;; The foregoing is a bit faster, but not as clear as the following:
1015;; 1007;;
1016;;(defmacro calendar-leap-year-p (year) 1008;;(defsubst calendar-leap-year-p (year)
1017;; "Returns t if YEAR is a Gregorian leap year."
1018;; (` (or
1019;; (and (= (% (, year) 4) 0)
1020;; (/= (% (, year) 100) 0))
1021;; (= (% (, year) 400) 0))))
1022;;(defun calendar-leap-year-p (year)
1023;; "Returns t if YEAR is a Gregorian leap year." 1009;; "Returns t if YEAR is a Gregorian leap year."
1024;; (or 1010;; (or
1025;; (and (= (% year 4) 0) 1011;; (and (= (% year 4) 0)
1026;; (/= (% year 100) 0)) 1012;; (/= (% year 100) 0))
1027;; (= (% year 400) 0))) 1013;; (= (% year 400) 0)))
1028 1014
1029(defmacro calendar-last-day-of-month (month year) 1015(defsubst calendar-last-day-of-month (month year)
1030 "The last day in MONTH during YEAR." 1016 "The last day in MONTH during YEAR."
1031 (` (if (and 1017 (if (and (= month 2) (calendar-leap-year-p year))
1032 (= (, month) 2) 1018 29
1033 (, (macroexpand (` (calendar-leap-year-p (, year)))))) 1019 (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- month))))
1034 29 1020
1035 (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- (, month)))))) 1021;; An explanation of the calculation can be found in PascAlgorithms by
1036;;(defun calendar-last-day-of-month (month year) 1022;; Edward and Ruth Reingold, Scott-Foresman/Little, Brown, 1988.
1037;; "The last day in MONTH during YEAR." 1023
1038;; (if (and (= month 2) (calendar-leap-year-p year)) 1024(defsubst calendar-day-number (date)
1039;; 29
1040;; (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- month))))
1041
1042(defmacro calendar-day-number (date)
1043 "Return the day number within the year of the date DATE. 1025 "Return the day number within the year of the date DATE.
1044For example, (calendar-day-number '(1 1 1987)) returns the value 1, 1026For example, (calendar-day-number '(1 1 1987)) returns the value 1,
1045while (calendar-day-number '(12 31 1980)) returns 366." 1027while (calendar-day-number '(12 31 1980)) returns 366."
1046;; 1028 (let* ((month (extract-calendar-month date))
1047;; An explanation of the calculation can be found in PascAlgorithms by 1029 (day (extract-calendar-day date))
1048;; Edward and Ruth Reingold, Scott-Foresman/Little, Brown, 1988. 1030 (year (extract-calendar-year date))
1049;; 1031 (day-of-year (+ day (* 31 (1- month)))))
1050 (` (let* ((month (, (macroexpand (` (extract-calendar-month (, date)))))) 1032 (if (> month 2)
1051 (day (, (macroexpand (` (extract-calendar-day (, date)))))) 1033 (progn
1052 (year (, (macroexpand (` (extract-calendar-year (, date)))))) 1034 (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10)))
1053 (day-of-year (+ day (* 31 (1- month))))) 1035 (if (calendar-leap-year-p year)
1054 (if (> month 2)
1055 (progn
1056 (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10)))
1057 (if (, (macroexpand (` (calendar-leap-year-p year))))
1058 (setq day-of-year (1+ day-of-year))))) 1036 (setq day-of-year (1+ day-of-year)))))
1059 day-of-year))) 1037 day-of-year))
1060;;(defun calendar-day-number (date) 1038
1061;; "Return the day number within the year of the date DATE. 1039(defsubst calendar-absolute-from-gregorian (date)
1062;;For example, (calendar-day-number '(1 1 1987)) returns the value 1,
1063;;while (calendar-day-number '(12 31 1980)) returns 366."
1064;; (let* ((month (extract-calendar-month date))
1065;; (day (extract-calendar-day date))
1066;; (year (extract-calendar-year date))
1067;; (day-of-year (+ day (* 31 (1- month)))))
1068;; (if (> month 2)
1069;; (progn
1070;; (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10)))
1071;; (if (calendar-leap-year-p year)
1072;; (setq day-of-year (1+ day-of-year)))))
1073;; day-of-year))
1074
1075(defmacro calendar-absolute-from-gregorian (date)
1076 "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE. 1040 "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE.
1077The Gregorian date Sunday, December 31, 1 BC is imaginary." 1041The Gregorian date Sunday, December 31, 1 BC is imaginary."
1078 (` (let ((prior-years 1042 (let ((prior-years (1- (extract-calendar-year date))))
1079 (1- (, (macroexpand (` (extract-calendar-year (, date)))))))) 1043 (+ (calendar-day-number date);; Days this year
1080 (+ (, (macroexpand (` (calendar-day-number (, date)))));; Days this year 1044 (* 365 prior-years);; + Days in prior years
1081 (* 365 prior-years);; + Days in prior years 1045 (/ prior-years 4);; + Julian leap years
1082 (/ prior-years 4);; + Julian leap years 1046 (- (/ prior-years 100));; - century years
1083 (- (/ prior-years 100));; - century years 1047 (/ prior-years 400))));; + Gregorian leap years
1084 (/ prior-years 400)))));; + Gregorian leap years
1085;;(defun calendar-absolute-from-gregorian (date)
1086;; "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE.
1087;;The Gregorian date Sunday, December 31, 1 BC is imaginary."
1088;; (let ((prior-years (1- (extract-calendar-year date))))
1089;; (+ (calendar-day-number date);; Days this year
1090;; (* 365 prior-years);; + Days in prior years
1091;; (/ prior-years 4);; + Julian leap years
1092;; (- (/ prior-years 100));; - century years
1093;; (/ prior-years 400))));; + Gregorian leap years
1094 1048
1095;;;###autoload 1049;;;###autoload
1096(defun calendar (&optional arg) 1050(defun calendar (&optional arg)
@@ -1142,29 +1096,16 @@ to be replaced by asterisks to highlight it whenever it is in the window."
1142 (interactive "P") 1096 (interactive "P")
1143 (set-buffer (get-buffer-create calendar-buffer)) 1097 (set-buffer (get-buffer-create calendar-buffer))
1144 (calendar-mode) 1098 (calendar-mode)
1145;;; (setq calendar-window-configuration (current-window-configuration))
1146 (let* ((completion-ignore-case t) 1099 (let* ((completion-ignore-case t)
1147 (pop-up-windows t) 1100 (pop-up-windows t)
1148 (split-height-threshold 1000) 1101 (split-height-threshold 1000)
1149 (date (calendar-current-date)) 1102 (date (if arg
1150 (month 1103 (calendar-read-date t)
1151 (if arg 1104 (calendar-current-date)))
1152 (cdr (assoc 1105 (month (extract-calendar-month date))
1153 (capitalize 1106 (year (extract-calendar-year date)))
1154 (completing-read
1155 "Month name: "
1156 (mapcar 'list (append calendar-month-name-array nil))
1157 nil t))
1158 (calendar-make-alist calendar-month-name-array)))
1159 (extract-calendar-month date)))
1160 (year
1161 (if arg
1162 (calendar-read
1163 "Year (>0): "
1164 '(lambda (x) (> x 0))
1165 (int-to-string (extract-calendar-year date)))
1166 (extract-calendar-year date))))
1167 (pop-to-buffer calendar-buffer) 1107 (pop-to-buffer calendar-buffer)
1108 (increment-calendar-month month year (- calendar-offset))
1168 (generate-calendar-window month year) 1109 (generate-calendar-window month year)
1169 (if (and view-diary-entries-initially (calendar-date-is-visible-p date)) 1110 (if (and view-diary-entries-initially (calendar-date-is-visible-p date))
1170 (view-diary-entries 1111 (view-diary-entries
@@ -1535,7 +1476,7 @@ the inserted text. Value is always t."
1535 (define-key calendar-mode-map "iid" 'insert-islamic-diary-entry) 1476 (define-key calendar-mode-map "iid" 'insert-islamic-diary-entry)
1536 (define-key calendar-mode-map "iim" 'insert-monthly-islamic-diary-entry) 1477 (define-key calendar-mode-map "iim" 'insert-monthly-islamic-diary-entry)
1537 (define-key calendar-mode-map "iiy" 'insert-yearly-islamic-diary-entry) 1478 (define-key calendar-mode-map "iiy" 'insert-yearly-islamic-diary-entry)
1538 (define-key calendar-mode-map "?" 'describe-calendar-mode)) 1479 (define-key calendar-mode-map "?" 'calendar-goto-info-node))
1539 1480
1540(defun describe-calendar-mode () 1481(defun describe-calendar-mode ()
1541 "Create a help buffer with a brief description of the calendar-mode." 1482 "Create a help buffer with a brief description of the calendar-mode."
@@ -1556,234 +1497,29 @@ the inserted text. Value is always t."
1556 (list 1497 (list
1557 (substitute-command-keys "\\<calendar-mode-map>\\[scroll-calendar-left]") 1498 (substitute-command-keys "\\<calendar-mode-map>\\[scroll-calendar-left]")
1558 "Calendar" 1499 "Calendar"
1559 (substitute-command-keys "\\<calendar-mode-map>\\[describe-calendar-mode] help/\\[calendar-other-month] other/\\[calendar-goto-today] today") 1500 (substitute-command-keys "\\<calendar-mode-map>\\[calendar-goto-info-node] info/\\[calendar-other-month] other/\\[calendar-goto-today] today")
1560 '(calendar-date-string (calendar-current-date) t) 1501 '(calendar-date-string (calendar-current-date) t)
1561 (substitute-command-keys "\\<calendar-mode-map>\\[scroll-calendar-right]")) 1502 (substitute-command-keys "\\<calendar-mode-map>\\[scroll-calendar-right]"))
1562 "The mode line of the calendar buffer.") 1503 "The mode line of the calendar buffer.")
1563 1504
1505(defun calendar-goto-info-node ()
1506 "Go to the info node for the calendar."
1507 (interactive)
1508 (require 'info)
1509 (let ((where (Info-find-emacs-command-nodes 'calendar)))
1510 (if (not where)
1511 (error "Couldn't find documentation for the calendar.")
1512 (save-window-excursion (info))
1513 (pop-to-buffer "*info*")
1514 (Info-find-node (car (car where)) (car (cdr (car where)))))))
1515
1564(defun calendar-mode () 1516(defun calendar-mode ()
1565 "A major mode for the calendar window. 1517 "A major mode for the calendar window.
1566 1518
1567The commands for cursor movement are:\\<calendar-mode-map> 1519For a complete description, type \
1568 1520\\<calendar-mode-map>\\[calendar-goto-info-node] from within the calendar.
1569 \\[calendar-forward-day] one day forward \\[calendar-backward-day] one day backward
1570 \\[calendar-forward-week] one week forward \\[calendar-backward-week] one week backward
1571 \\[calendar-forward-month] one month forward \\[calendar-backward-month] one month backward
1572 \\[calendar-forward-year] one year forward \\[calendar-backward-year] one year backward
1573 \\[calendar-beginning-of-week] beginning of week \\[calendar-end-of-week] end of week
1574 \\[calendar-beginning-of-month] beginning of month \\[calendar-end-of-month] end of month
1575 \\[calendar-beginning-of-year] beginning of year \\[calendar-end-of-year] end of year
1576
1577 \\[calendar-goto-date] go to date
1578
1579 \\[calendar-goto-julian-date] go to Julian date \\[calendar-goto-astro-day-number] go to astronomical (Julian) day number
1580 \\[calendar-goto-hebrew-date] go to Hebrew date \\[calendar-goto-islamic-date] go to Islamic date
1581 \\[calendar-goto-iso-date] go to ISO date \\[calendar-goto-french-date] go to French Revolutionary date
1582
1583 \\[calendar-goto-mayan-long-count-date] go to Mayan Long Count date
1584 \\[calendar-next-haab-date] go to next occurrence of Mayan Haab date
1585 \\[calendar-previous-haab-date] go to previous occurrence of Mayan Haab date
1586 \\[calendar-next-tzolkin-date] go to next occurrence of Mayan Tzolkin date
1587 \\[calendar-previous-tzolkin-date] go to previous occurrence of Mayan Tzolkin date
1588 \\[calendar-next-calendar-round-date] go to next occurrence of Mayan Calendar Round date
1589 \\[calendar-previous-calendar-round-date] go to previous occurrence of Mayan Calendar Round date
1590
1591You can mark a date in the calendar and switch the point and mark:
1592
1593 \\[calendar-set-mark] mark date \\[calendar-exchange-point-and-mark] exchange point and mark
1594
1595You can determine the number of days (inclusive) between the point and mark by
1596
1597 \\[calendar-count-days-region] count days in the region
1598
1599The commands for calendar movement are:
1600
1601 \\[scroll-calendar-right] scroll one month right \\[scroll-calendar-left] scroll one month left
1602 \\[scroll-calendar-right-three-months] scroll 3 months right \\[scroll-calendar-left-three-months] scroll 3 months left
1603 \\[calendar-goto-today] display current month \\[calendar-other-month] display another month
1604
1605Whenever it makes sense, the above commands take prefix arguments that
1606multiply their affect. For convenience, the digit keys and the minus sign
1607are bound to digit-argument, so they need not be prefixed with ESC.
1608
1609If the calendar window somehow becomes corrupted, it can be regenerated with
1610
1611 \\[redraw-calendar] redraw the calendar
1612
1613The following commands deal with holidays and other notable days:
1614
1615 \\[calendar-cursor-holidays] give holidays for the date specified by the cursor
1616 \\[mark-calendar-holidays] mark notable days
1617 \\[calendar-unmark] unmark dates
1618 \\[list-calendar-holidays] display notable days
1619 1521
1620The command M-x holidays causes the notable dates for the current month, and 1522\\<calendar-mode-map>\\{calendar-mode-map}"
1621the preceding and succeeding months, to be displayed, independently of the
1622calendar.
1623
1624The following commands control the diary:
1625
1626 \\[mark-diary-entries] mark diary entries \\[calendar-unmark] unmark dates
1627 \\[view-diary-entries] display diary entries \\[show-all-diary-entries] show all diary entries
1628 \\[print-diary-entries] print diary entries
1629
1630Displaying the diary entries causes the diary entries from the diary file
1631\(for the date indicated by the cursor in the calendar window) to be
1632displayed in another window. This function takes an integer argument that
1633specifies the number of days of calendar entries to be displayed, starting
1634with the date indicated by the cursor.
1635
1636The command \\[print-diary-entries] prints the diary buffer (as it appears)
1637on the line printer.
1638
1639The command M-x diary causes the diary entries for the current date to be
1640displayed, independently of the calendar. The number of days of entries is
1641governed by number-of-diary-entries.
1642
1643The format of the entries in the diary file is described in the
1644documentation string for the variable `diary-file'.
1645
1646When diary entries are in view in the window, they can be edited. It is
1647important to keep in mind that the buffer displayed contains the entire
1648diary file, but with portions of it concealed from view. This means, for
1649instance, that the forward-char command can put the cursor at what appears
1650to be the end of the line, but what is in reality the middle of some
1651concealed line. BE CAREFUL WHEN EDITING THE DIARY ENTRIES! (Inserting
1652additional lines or adding/deleting characters in the middle of a visible
1653line will not cause problems; watch out for end-of-line, however--it may
1654put you at the end of a concealed line far from where the cursor appears to
1655be!) BEFORE EDITING THE DIARY IT IS BEST TO DISPLAY THE ENTIRE FILE WITH
1656show-all-diary-entries. BE SURE TO WRITE THE FILE BEFORE EXITING FROM THE
1657CALENDAR.
1658
1659The following commands assist in making diary entries:
1660
1661 \\[insert-diary-entry] insert a diary entry for the selected date
1662 \\[insert-weekly-diary-entry] insert a diary entry for the selected day of the week
1663 \\[insert-monthly-diary-entry] insert a diary entry for the selected day of the month
1664 \\[insert-yearly-diary-entry] insert a diary entry for the selected day of the year
1665 \\[insert-block-diary-entry] insert a diary entry for the block days between point and mark
1666 \\[insert-anniversary-diary-entry] insert an anniversary diary entry for the selected date
1667 \\[insert-cyclic-diary-entry] insert a cyclic diary entry
1668
1669There are corresponding commands to assist in making Hebrew- or Islamic-date
1670diary entries:
1671
1672 \\[insert-hebrew-diary-entry] insert a diary entry for the Hebrew date corresponding
1673 to the selected date
1674 \\[insert-monthly-hebrew-diary-entry] insert a diary entry for the day of the Hebrew month
1675 corresponding to the selected day
1676 \\[insert-yearly-hebrew-diary-entry] insert a diary entry for the day of the Hebrew year
1677 corresponding to the selected day
1678 \\[insert-islamic-diary-entry] insert a diary entry for the Islamic date corresponding
1679 to the selected date
1680 \\[insert-monthly-islamic-diary-entry] insert a diary entry for the day of the Islamic month
1681 corresponding to the selected day
1682 \\[insert-yearly-islamic-diary-entry] insert a diary entry for the day of the Islamic year
1683 corresponding to the selected day
1684
1685All of the diary entry commands make nonmarking entries when given a prefix
1686argument; with no prefix argument, the diary entries are marking.
1687
1688The day number in the year and the number of days remaining in the year can be
1689determined by
1690
1691 \\[calendar-print-day-of-year] show day number and the number of days remaining in the year
1692
1693Equivalent dates on the ISO commercial, Julian, Hebrew, Islamic, French
1694Revolutionary, and Mayan calendars can be determined by
1695
1696 \\[calendar-print-iso-date] show equivalent date on the ISO commercial calendar
1697 \\[calendar-print-julian-date] show equivalent date on the Julian calendar
1698 \\[calendar-print-hebrew-date] show equivalent date on the Hebrew calendar
1699 \\[calendar-print-islamic-date] show equivalent date on the Islamic calendar
1700 \\[calendar-print-french-date] show equivalent date on the French Revolutionary calendar
1701 \\[calendar-print-mayan-date] show equivalent date on the Mayan calendar
1702
1703The astronomical (Julian) day number of a date is found with
1704
1705 \\[calendar-print-astro-day-number] show equivalent astronomical (Julian) day number
1706
1707To find the times of sunrise and sunset and lunar phases use
1708
1709 \\[calendar-sunrise-sunset] show times of sunrise and sunset
1710 \\[calendar-phases-of-moon] show times of quarters of the moon
1711
1712The times given apply to location `calendar-location-name' at latitude
1713`calendar-latitude', longitude `calendar-longitude'; set these variables for
1714your location. The following variables are also consulted, and you must set
1715them if your system does not initialize them properly: `calendar-time-zone',
1716`calendar-daylight-time-offset', `calendar-standard-time-zone-name',
1717`calendar-daylight-time-zone-name', `calendar-daylight-savings-starts',
1718`calendar-daylight-savings-ends', `calendar-daylight-savings-starts-time',
1719`calendar-daylight-savings-ends-time'.
1720
1721To exit from the calendar use
1722
1723 \\[exit-calendar] exit from calendar
1724
1725Set `view-diary-entries-initially' to a non-nil value to display
1726diary entries for the current date in
1727another window when the calendar is first displayed, if the current date is
1728visible. The variable `number-of-diary-entries' controls number of days of
1729diary entries that to display initially or with the command M-x
1730diary. For example, the default value 1 says to display only the current
1731day's diary entries. The value 2 says to display both the
1732current day's and the next day's entries.
1733
1734The value can also be a vector such as [0 2 2 2 2 4 1]; this value
1735says to display no diary entries on Sunday, the display the entries
1736for the current date and the day after on Monday through Thursday,
1737display Friday through Monday's entries on Friday, and display only
1738Saturday's entries on Saturday.
1739
1740Set `view-calendar-holidays-initially' to a non-nil value to display
1741holidays for the current three month period on entry to the calendar.
1742
1743Set `mark-diary-entries-in-calendar' to a non-nil value to mark in the
1744calendar all the dates that have diary entries. The variable
1745`diary-entry-marker' controls how to mark them.
1746
1747The variable `calendar-load-hook', whose default value is nil, is list of
1748functions to be called when the calendar is first loaded.
1749
1750The variable `initial-calendar-window-hook', whose default value is nil, is
1751list of functions to be called when the calendar window is first opened. The
1752functions invoked are called after the calendar window is opened, but once
1753opened is never called again. Leaving the calendar with the `q' command and
1754reentering it will cause these functions to be called again.
1755
1756The variable `today-visible-calendar-hook', whose default value is nil, is the
1757list of functions called after the calendar buffer has been prepared with the
1758calendar when the current date is visible in the window. This can be used,
1759for example, to replace today's date with asterisks; a function
1760calendar-star-date is included for this purpose:
1761 (setq today-visible-calendar-hook 'calendar-star-date)
1762It could also be used to mark the current date; a function is also provided
1763for this:
1764 (setq today-visible-calendar-hook 'calendar-mark-today)
1765
1766The variable `today-invisible-calendar-hook', whose default value is nil, is
1767the list of functions called after the calendar buffer has been prepared with
1768the calendar when the current date is not visible in the window.
1769
1770The variable `diary-display-hook' is the list of functions called after the
1771diary buffer is prepared. The default value simply displays the diary file
1772using selective-display to conceal irrelevant diary entries. An alternative
1773function `fancy-diary-display' is provided that, when used as the
1774`diary-display-hook', causes a noneditable buffer to be prepared with a neatly
1775organized day-by-day listing of relevant diary entries, together with any
1776known holidays. The inclusion of the holidays slows this fancy display of the
1777diary; to speed it up, set the variable `holidays-in-diary-buffer' to nil.
1778
1779The variable `print-diary-entries-hook' is the list of functions called after
1780a temporary buffer is prepared with the diary entries currently visible in the
1781diary buffer. The default value of this hook adds a heading (composed from
1782the diary buffer's mode line), does the printing with the command lpr-buffer,
1783and kills the temporary buffer. Other uses might include, for example,
1784rearranging the lines into order by day and time.
1785
1786The Gregorian calendar is assumed."
1787 1523
1788 (kill-all-local-variables) 1524 (kill-all-local-variables)
1789 (setq major-mode 'calendar-mode) 1525 (setq major-mode 'calendar-mode)
@@ -1830,34 +1566,63 @@ concatenated and the result truncated."
1830 (calendar-string-spread 1566 (calendar-string-spread
1831 calendar-mode-line-format ? (frame-width)))))) 1567 calendar-mode-line-format ? (frame-width))))))
1832 1568
1569(defun calendar-window-list ()
1570 "List of all calendar-related windows."
1571 (let ((calendar-buffers (calendar-buffer-list))
1572 list)
1573 (walk-windows '(lambda (w)
1574 (if (memq (window-buffer w) calendar-buffers)
1575 (setq list (cons w list))))
1576 nil t)
1577 list))
1578
1579(defun calendar-buffer-list ()
1580 "List of all calendar-related buffers."
1581 (let* ((diary-buffer (get-file-buffer diary-file))
1582 (buffers (list "*Yahrzeits*" lunar-phases-buffer holiday-buffer
1583 fancy-diary-buffer diary-buffer calendar-buffer))
1584 (buffer-list nil)
1585 b)
1586 (while buffers
1587 (setq b (car buffers))
1588 (setq b (cond ((stringp b) (get-buffer b))
1589 ((bufferp b) b)
1590 (t nil)))
1591 (if b (setq buffer-list (cons b buffer-list)))
1592 (setq buffers (cdr buffers)))
1593 buffer-list))
1594
1833(defun exit-calendar () 1595(defun exit-calendar ()
1834 "Delete the calendar window, and bury the calendar and related buffers." 1596 "Get out of the calendar window and hide it and related buffers."
1835 (interactive) 1597 (interactive)
1836 (let ((diary-buffer (get-file-buffer diary-file)) 1598 (let* ((diary-buffer (get-file-buffer diary-file)))
1837 (d-buffer (get-buffer fancy-diary-buffer)) 1599 (if (and diary-buffer (buffer-modified-p diary-buffer)
1838 (h-buffer (get-buffer holiday-buffer))) 1600 (not
1839 (if (not diary-buffer) 1601 (yes-or-no-p
1840 (progn 1602 "Diary modified; do you really want to exit the calendar? ")))
1841 ;; Restoring the configuration is undesirable because 1603 (error)
1842 ;; it restores the value of point in other windows. 1604 ;; Need to do this multiple times because one time can replace some
1843;;; (set-window-configuration calendar-window-configuration) 1605 ;; calendar-related buffers with other calendar-related buffers
1844 (or (one-window-p t) 1606 (mapcar (lambda (x)
1845 (delete-window)) 1607 (mapcar 'calendar-hide-window (calendar-window-list)))
1846 (bury-buffer calendar-buffer) 1608 (calendar-window-list)))))
1847 (if d-buffer (bury-buffer d-buffer)) 1609
1848 (if h-buffer (bury-buffer h-buffer))) 1610(defun calendar-hide-window (window)
1849 (if (or (not (buffer-modified-p diary-buffer)) 1611 "Hide WINDOW if it is calendar-related."
1850 (yes-or-no-p "Diary modified; do you really want to exit the calendar? ")) 1612 (let ((buffer (if (window-live-p window) (window-buffer window))))
1851 (progn 1613 (if (memq buffer (calendar-buffer-list))
1852;;; (set-window-configuration calendar-window-configuration) 1614 (cond
1853 (or (one-window-p t) 1615 ((and window-system
1854 (delete-window)) 1616 (eq 'icon (cdr (assoc 'visibility
1855 (bury-buffer calendar-buffer) 1617 (frame-parameters
1856 (if d-buffer (bury-buffer d-buffer)) 1618 (window-frame window))))))
1857 (if h-buffer (bury-buffer h-buffer)) 1619 nil)
1858 (set-buffer diary-buffer) 1620 ((and window-system (window-dedicated-p window))
1859 (set-buffer-modified-p nil) 1621 (iconify-frame (window-frame window)))
1860 (bury-buffer diary-buffer)))))) 1622 ((not (and (select-window window) (one-window-p window)))
1623 (delete-window window))
1624 (t (set-buffer buffer)
1625 (bury-buffer))))))
1861 1626
1862(defun calendar-goto-today () 1627(defun calendar-goto-today ()
1863 "Reposition the calendar window so the current date is visible." 1628 "Reposition the calendar window so the current date is visible."
@@ -1945,27 +1710,16 @@ position of the cursor with respect to the calendar as well as possible."
1945 (scroll-calendar-left (* -3 arg))) 1710 (scroll-calendar-left (* -3 arg)))
1946 1711
1947(defun calendar-current-date () 1712(defun calendar-current-date ()
1948 "Returns the current date in a list (month day year). 1713 "Returns the current date in a list (month day year)."
1949If in the calendar buffer, also sets the current date local variables." 1714 (let ((s (current-time-string)))
1950 (let* ((date (current-time-string)) 1715 (list (length (member (substring s 4 7)
1951 (garbage 1716 '("Dec" "Nov" "Oct" "Sep" "Aug" "Jul"
1952 (string-match 1717 "Jun" "May" "Apr" "Mar" "Feb" "Jan")))
1953 "^\\([A-Z][a-z]*\\) *\\([A-Z][a-z]*\\) *\\([0-9]*\\) .* \\([0-9]*\\)$" 1718 (string-to-number (substring s 8 10))
1954 date)) 1719 (string-to-number (substring s 20 24)))))
1955 (month
1956 (cdr (assoc
1957 (substring date (match-beginning 2) (match-end 2))
1958 '(("Jan" . 1) ("Feb" . 2) ("Mar" . 3) ("Apr" . 4)
1959 ("May" . 5) ("Jun" . 6) ("Jul" . 7) ("Aug" . 8)
1960 ("Sep" . 9) ("Oct" . 10) ("Nov" . 11) ("Dec" . 12)))))
1961 (day
1962 (string-to-int (substring date (match-beginning 3) (match-end 3))))
1963 (year
1964 (string-to-int (substring date (match-beginning 4) (match-end 4)))))
1965 (list month day year)))
1966 1720
1967(defun calendar-cursor-to-date (&optional error) 1721(defun calendar-cursor-to-date (&optional error)
1968 "Returns a list of the month, day, and year of current cursor position. 1722 "Returns a list (month day year) of current cursor position.
1969If cursor is not on a specific date, signals an error if optional parameter 1723If cursor is not on a specific date, signals an error if optional parameter
1970ERROR is t, otherwise just returns nil." 1724ERROR is t, otherwise just returns nil."
1971 (let* ((segment (/ (current-column) 25)) 1725 (let* ((segment (/ (current-column) 25))
@@ -2222,20 +1976,8 @@ Gregorian date Sunday, December 31, 1 BC."
2222(defun calendar-other-month (month year) 1976(defun calendar-other-month (month year)
2223 "Display a three-month calendar centered around MONTH and YEAR." 1977 "Display a three-month calendar centered around MONTH and YEAR."
2224 (interactive 1978 (interactive
2225 (let* ((completion-ignore-case t) 1979 (let* ((completion-ignore-case t))
2226 (month (cdr (assoc 1980 (calendar-read-date t)))
2227 (capitalize
2228 (completing-read
2229 "Month name: "
2230 (mapcar 'list (append calendar-month-name-array nil))
2231 nil t))
2232 (calendar-make-alist calendar-month-name-array))))
2233 (year (calendar-read
2234 "Year (>0): "
2235 '(lambda (x) (> x 0))
2236 (int-to-string
2237 (extract-calendar-year (calendar-current-date))))))
2238 (list month year)))
2239 (if (and (= month displayed-month) 1981 (if (and (= month displayed-month)
2240 (= year displayed-year)) 1982 (= year displayed-year))
2241 nil 1983 nil
@@ -2307,8 +2049,10 @@ is a string to insert in the minibuffer before reading."
2307 (setq value (read-minibuffer prompt initial-contents))) 2049 (setq value (read-minibuffer prompt initial-contents)))
2308 value)) 2050 value))
2309 2051
2310(defun calendar-read-date () 2052(defun calendar-read-date (&optional noday)
2311 "Prompt for Gregorian date. Returns a list (month day year)." 2053 "Prompt for Gregorian date. Returns a list (month day year).
2054If optional NODAY is t, does not ask for day, but just returns
2055(month nil year)."
2312 (let* ((year (calendar-read 2056 (let* ((year (calendar-read
2313 "Year (>0): " 2057 "Year (>0): "
2314 '(lambda (x) (> x 0)) 2058 '(lambda (x) (> x 0))
@@ -2323,11 +2067,14 @@ is a string to insert in the minibuffer before reading."
2323 (mapcar 'list (append month-array nil)) 2067 (mapcar 'list (append month-array nil))
2324 nil t)) 2068 nil t))
2325 (calendar-make-alist month-array 1 'capitalize)))) 2069 (calendar-make-alist month-array 1 'capitalize))))
2326 (last (calendar-last-day-of-month month year)) 2070 (last (calendar-last-day-of-month month year)))
2327 (day (calendar-read 2071 (list month
2328 (format "Day (1-%d): " last) 2072 (if noday
2329 '(lambda (x) (and (< 0 x) (<= x last)))))) 2073 nil
2330 (list month day year))) 2074 (day (calendar-read
2075 (format "Day (1-%d): " last)
2076 '(lambda (x) (and (< 0 x) (<= x last))))))
2077 year)))
2331 2078
2332(defun calendar-goto-date (date) 2079(defun calendar-goto-date (date)
2333 "Move cursor to DATE." 2080 "Move cursor to DATE."