aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Blandy1992-08-12 12:50:10 +0000
committerJim Blandy1992-08-12 12:50:10 +0000
commit7e1dae733a5eda79d5681349ca39bfc36ca27871 (patch)
treeac88eef920fb50a8ece8593ee46a8f46160e6311
parent9f34a2a0c82e7323e825471b10b54fa60ea8859f (diff)
downloademacs-7e1dae733a5eda79d5681349ca39bfc36ca27871.tar.gz
emacs-7e1dae733a5eda79d5681349ca39bfc36ca27871.zip
entered into RCS
-rw-r--r--lisp/byte-run.el16
-rw-r--r--lisp/calendar/appt.el8
-rw-r--r--lisp/calendar/cal-french.el223
-rw-r--r--lisp/calendar/cal-mayan.el409
-rw-r--r--lisp/calendar/calendar.el1160
-rw-r--r--lisp/calendar/holidays.el124
-rw-r--r--lisp/calendar/lunar.el290
-rw-r--r--lisp/cl.el213
-rw-r--r--lisp/cmulisp.el684
-rw-r--r--lisp/diary-ins.el262
-rw-r--r--lisp/emacs-lisp/byte-opt.el9
-rw-r--r--lisp/progmodes/inf-lisp.el6
-rw-r--r--lisp/textmodes/tex-mode.el15
13 files changed, 2800 insertions, 619 deletions
diff --git a/lisp/byte-run.el b/lisp/byte-run.el
index b0bd59b98d1..1a09ec6ac11 100644
--- a/lisp/byte-run.el
+++ b/lisp/byte-run.el
@@ -86,9 +86,23 @@ If NEW is a string, that is the `use instead' message."
86 (put fn 'byte-compile 'byte-compile-obsolete))) 86 (put fn 'byte-compile 'byte-compile-obsolete)))
87 fn) 87 fn)
88 88
89(defun make-obsolete-variable (var new)
90 "Make the byte-compiler warn that VARIABLE is obsolete,
91and NEW should be used instead. If NEW is a string, then that is the
92`use instead' message."
93 (interactive
94 (list
95 (let ((str (completing-read "Make variable obsolete: " obarray 'boundp t)))
96 (if (equal str "") (error ""))
97 (intern str))
98 (car (read-from-string (read-string "Obsoletion replacement: ")))))
99 (put var 'byte-obsolete-variable new)
100 var)
101
89(put 'dont-compile 'lisp-indent-hook 0) 102(put 'dont-compile 'lisp-indent-hook 0)
90(defmacro dont-compile (&rest body) 103(defmacro dont-compile (&rest body)
91 "Like `progn', but the body always runs interpreted (not compiled)." 104 "Like `progn', but the body always runs interpreted (not compiled).
105If you think you need this, you're probably making a mistake somewhere."
92 (list 'eval (list 'quote (if (cdr body) (cons 'progn body) (car body))))) 106 (list 'eval (list 'quote (if (cdr body) (cons 'progn body) (car body)))))
93 107
94 108
diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el
index 30ba686fa37..84a553ed0fe 100644
--- a/lisp/calendar/appt.el
+++ b/lisp/calendar/appt.el
@@ -107,29 +107,37 @@
107 107
108;;; Code: 108;;; Code:
109 109
110;;;###autoload
110(defvar appt-issue-message t 111(defvar appt-issue-message t
111 "*Non-nil means check for appointments in the diary buffer. 112 "*Non-nil means check for appointments in the diary buffer.
112To be detected, the diary entry must have the time 113To be detected, the diary entry must have the time
113as the first thing on a line.") 114as the first thing on a line.")
114 115
116;;;###autoload
115(defvar appt-message-warning-time 10 117(defvar appt-message-warning-time 10
116 "*Time in minutes before an appointment that the warning begins.") 118 "*Time in minutes before an appointment that the warning begins.")
117 119
120;;;###autoload
118(defvar appt-audible t 121(defvar appt-audible t
119 "*Non-nil means beep to indicate appointment.") 122 "*Non-nil means beep to indicate appointment.")
120 123
124;;;###autoload
121(defvar appt-visible t 125(defvar appt-visible t
122 "*Non-nil means display appointment message in echo area.") 126 "*Non-nil means display appointment message in echo area.")
123 127
128;;;###autoload
124(defvar appt-display-mode-line t 129(defvar appt-display-mode-line t
125 "*Non-nil means display minutes to appointment and time on the mode line.") 130 "*Non-nil means display minutes to appointment and time on the mode line.")
126 131
132;;;###autoload
127(defvar appt-msg-window t 133(defvar appt-msg-window t
128 "*Non-nil means display appointment message in another window.") 134 "*Non-nil means display appointment message in another window.")
129 135
136;;;###autoload
130(defvar appt-display-duration 5 137(defvar appt-display-duration 5
131 "*The number of seconds an appointment message is displayed.") 138 "*The number of seconds an appointment message is displayed.")
132 139
140;;;###autoload
133(defvar appt-display-diary t 141(defvar appt-display-diary t
134 "*Non-nil means to display the next days diary on the screen. 142 "*Non-nil means to display the next days diary on the screen.
135This will occur at midnight when the appointment list is updated.") 143This will occur at midnight when the appointment list is updated.")
diff --git a/lisp/calendar/cal-french.el b/lisp/calendar/cal-french.el
new file mode 100644
index 00000000000..5babcdf512a
--- /dev/null
+++ b/lisp/calendar/cal-french.el
@@ -0,0 +1,223 @@
1;;; cal-french.el --- calendar functions for the French Revolutionary calendar.
2
3;; Copyright (C) 1988, 1989, 1992 Free Software Foundation, Inc.
4
5;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
6;; Keywords: French Revolutionary calendar, calendar, diary
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is distributed in the hope that it will be useful,
11;; but WITHOUT ANY WARRANTY. No author or distributor
12;; accepts responsibility to anyone for the consequences of using it
13;; or for whether it serves any particular purpose or works at all,
14;; unless he says so in writing. Refer to the GNU Emacs General Public
15;; License for full details.
16
17;; Everyone is granted permission to copy, modify and redistribute
18;; GNU Emacs, but only under the conditions described in the
19;; GNU Emacs General Public License. A copy of this license is
20;; supposed to have been given to you along with GNU Emacs so you
21;; can know your rights and responsibilities. It should be in a
22;; file named COPYING. Among other things, the copyright notice
23;; and this notice must be preserved on all copies.
24
25;;; Commentary:
26
27;; This collection of functions implements the features of calendar.el and
28;; diary.el that deal with the French Revolutionary calendar.
29
30;; Technical details of the French Revolutionary calendrical calculations can
31;; be found in ``Calendrical Calculations, Part II: Three Historical
32;; Calendars'' by E. M. Reingold, N. Dershowitz, and S. M. Clamen,
33;; Report Number UIUCDCS-R-92-1743, Department of Computer Science,
34;; University of Illinois, April, 1992.
35
36;; Comments, corrections, and improvements should be sent to
37;; Edward M. Reingold Department of Computer Science
38;; (217) 333-6733 University of Illinois at Urbana-Champaign
39;; reingold@cs.uiuc.edu 1304 West Springfield Avenue
40;; Urbana, Illinois 61801
41
42;;; Code:
43
44(require 'calendar)
45
46(defconst french-calendar-month-name-array
47 ["Vende'miaire" "Brumaire" "Frimaire" "Nivo^se" "Pluvio^se" "Vento^se"
48 "Germinal" "Flore'al" "Prairial" "Messidor" "Thermidor" "Fructidor"])
49
50(defconst french-calendar-day-name-array
51 ["Primidi" "Duodi" "Tridi" "Quartidi" "Quintidi" "Sextidi" "Septidi"
52 "Octidi" "Nonidi" "Decadi"])
53
54(defconst french-calendar-special-days-array
55 ["de la Vertu" "du Genie" "du Labour" "de la Raison" "de la Recompense"
56 "de la Revolution"])
57
58(defun french-calendar-leap-year-p (year)
59 "True if YEAR is a leap year on the French Revolutionary calendar.
60For Gregorian years 1793 to 1805, the years of actual operation of the
61calendar, uses historical practice based on equinoxes is followed (years 3, 7,
62and 11 were leap years; 15 and 20 would have been leap years). For later
63years uses the proposed rule of Romme (never adopted)--leap years fall every
64four years except century years not divisible 400 and century years that are
65multiples of 4000."
66 (or (memq year '(3 7 11));; Actual practice--based on equinoxes
67 (memq year '(15 20)) ;; Anticipated practice--based on equinoxes
68 (and (> year 20) ;; Romme's proposal--never adopted
69 (zerop (% year 4))
70 (not (memq (% year 400) '(100 200 300)))
71 (not (zerop (% year 4000))))))
72
73(defun french-calendar-last-day-of-month (month year)
74 "Last day of MONTH, YEAR on the French Revolutionary calendar.
75The 13th month is not really a month, but the 5 (6 in leap years) day period of
76`sansculottides' at the end of the year."
77 (if (< month 13)
78 30
79 (if (french-calendar-leap-year-p year)
80 6
81 5)))
82
83(defun calendar-absolute-from-french (date)
84 "Absolute date of French Revolutionary DATE.
85The absolute date is the number of days elapsed since the (imaginary)
86Gregorian date Sunday, December 31, 1 BC."
87 (let ((month (extract-calendar-month date))
88 (day (extract-calendar-day date))
89 (year (extract-calendar-year date)))
90 (+ (* 365 (1- year));; Days in prior years
91 ;; Leap days in prior years
92 (if (< year 20)
93 (/ year 4);; Actual and anticipated practice (years 3, 7, 11, 15)
94 ;; Romme's proposed rule (using the Principle of Inclusion/Exclusion)
95 (+ (/ (1- year) 4);; Luckily, there were 4 leap years before year 20
96 (- (/ (1- year) 100))
97 (/ (1- year) 400)
98 (- (/ (1- year) 4000))))
99 (* 30 (1- month));; Days in prior months this year
100 day;; Days so far this month
101 654414)));; Days before start of calendar (September 22, 1792).
102
103(defun calendar-french-from-absolute (date)
104 "Compute the French Revolutionary date (month day year) corresponding to
105absolute DATE. The absolute date is the number of days elapsed since the
106(imaginary) Gregorian date Sunday, December 31, 1 BC."
107 (if (< date 654415)
108 (list 0 0 0);; pre-French Revolutionary date
109 (let* ((approx (/ (- date 654414) 366));; Approximation from below.
110 (year ;; Search forward from the approximation.
111 (+ approx
112 (calendar-sum y approx
113 (>= date (calendar-absolute-from-french (list 1 1 (1+ y))))
114 1)))
115 (month ;; Search forward from Vendemiaire.
116 (1+ (calendar-sum m 1
117 (> date
118 (calendar-absolute-from-french
119 (list m
120 (french-calendar-last-day-of-month m year)
121 year)))
122 1)))
123 (day ;; Calculate the day by subtraction.
124 (- date
125 (1- (calendar-absolute-from-french (list month 1 year))))))
126 (list month day year))))
127
128(defun calendar-print-french-date ()
129 "Show the French Revolutionary calendar equivalent of the date under the
130cursor."
131 (interactive)
132 (let* ((french-date (calendar-french-from-absolute
133 (calendar-absolute-from-gregorian
134 (or (calendar-cursor-to-date)
135 (error "Cursor is not on a date!")))))
136 (y (extract-calendar-year french-date))
137 (m (extract-calendar-month french-date))
138 (d (extract-calendar-day french-date)))
139 (if (< y 1)
140 (message "Date is pre-French Revolution")
141 (if (= m 13)
142 (message "Jour %s de l'Anne'e %d de la Revolution"
143 (aref french-calendar-special-days-array (1- d))
144 y)
145 (message "Decade %s, %s de %s de l'Anne'e %d de la Revolution"
146 (make-string (1+ (/ (1- d) 10)) ?I)
147 (aref french-calendar-day-name-array (% (1- d) 10))
148 (aref french-calendar-month-name-array (1- m))
149 y)))))
150
151(defun calendar-goto-french-date (date &optional noecho)
152 "Move cursor to French Revolutionary DATE.
153Echo French Revolutionary date unless NOECHO is t."
154 (interactive
155 (let* ((year (calendar-read
156 "Anne'e de la Revolution (>0): "
157 '(lambda (x) (> x 0))
158 (int-to-string
159 (extract-calendar-year
160 (calendar-french-from-absolute
161 (calendar-absolute-from-gregorian
162 (calendar-current-date)))))))
163 (month-list
164 (mapcar 'list
165 (append french-calendar-month-name-array
166 (if (french-calendar-leap-year-p year)
167 (mapcar
168 '(lambda (x) (concat "Jour " x))
169 french-calendar-special-days-array)
170 (cdr;; we don't want rev. day in a non-leap yr.
171 (nreverse
172 (mapcar
173 '(lambda (x) (concat "Jour " x))
174 french-calendar-special-days-array)))))))
175 (completion-ignore-case t)
176 (month (cdr (assoc
177 (capitalize
178 (completing-read
179 "Mois ou Sansculottide: "
180 month-list
181 nil t))
182 (calendar-make-alist
183 month-list
184 1
185 '(lambda (x) (capitalize (car x)))))))
186 (decade (if (> month 12)
187 1
188 (calendar-read
189 "De'cade (1-3): "
190 '(lambda (x) (memq x '(1 2 3))))))
191 (day (if (> month 12)
192 (- month 12)
193 (calendar-read
194 "Jour (1-10)): "
195 '(lambda (x) (and (<= 1 x) (<= x 10))))))
196 (month (if (> month 12) 13 month))
197 (day (+ day (* 10 (1- decade)))))
198 (list (list month day year))))
199 (calendar-goto-date (calendar-gregorian-from-absolute
200 (calendar-absolute-from-french date)))
201 (or noecho (calendar-print-french-date)))
202
203(defun diary-french-date ()
204 "French calendar equivalent of date diary entry."
205 (let* ((french-date (calendar-french-from-absolute
206 (calendar-absolute-from-gregorian date)))
207 (y (extract-calendar-year french-date))
208 (m (extract-calendar-month french-date))
209 (d (extract-calendar-day french-date)))
210 (if (> y 0)
211 (if (= m 13)
212 (format "Jour %s de l'Anne'e %d de la Revolution"
213 (aref french-calendar-special-days-array (1- d))
214 y)
215 (format "Decade %s, %s de %s de l'Anne'e %d de la Revolution"
216 (make-string (1+ (/ (1- d) 10)) ?I)
217 (aref french-calendar-day-name-array (% (1- d) 10))
218 (aref french-calendar-month-name-array (1- m))
219 y)))))
220
221(provide 'cal-french)
222
223;;; cal-french.el ends here
diff --git a/lisp/calendar/cal-mayan.el b/lisp/calendar/cal-mayan.el
new file mode 100644
index 00000000000..965909a8214
--- /dev/null
+++ b/lisp/calendar/cal-mayan.el
@@ -0,0 +1,409 @@
1;;; cal-mayan.el --- calendar functions for the Mayan calendars.
2
3;; Copyright (C) 1992 Free Software Foundation, Inc.
4
5;; Author: Stewart M. Clamen <clamen@cs.cmu.edu>
6;; Edward M. Reingold <reingold@cs.uiuc.edu>
7;; Keywords: Mayan calendar, Maya, calendar, diary
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is distributed in the hope that it will be useful,
12;; but WITHOUT ANY WARRANTY. No author or distributor
13;; accepts responsibility to anyone for the consequences of using it
14;; or for whether it serves any particular purpose or works at all,
15;; unless he says so in writing. Refer to the GNU Emacs General Public
16;; License for full details.
17
18;; Everyone is granted permission to copy, modify and redistribute
19;; GNU Emacs, but only under the conditions described in the
20;; GNU Emacs General Public License. A copy of this license is
21;; supposed to have been given to you along with GNU Emacs so you
22;; can know your rights and responsibilities. It should be in a
23;; file named COPYING. Among other things, the copyright notice
24;; and this notice must be preserved on all copies.
25
26;;; Commentary:
27
28;; This collection of functions implements the features of calendar.el and
29;; diary.el that deal with the Mayan calendar. It was written jointly by
30
31;; Stewart M. Clamen School of Computer Science
32;; clamen@cs.cmu.edu Carnegie Mellon University
33;; 5000 Forbes Avenue
34;; Pittsburgh, PA 15213
35
36;; and
37
38;; Edward M. Reingold Department of Computer Science
39;; (217) 333-6733 University of Illinois at Urbana-Champaign
40;; reingold@cs.uiuc.edu 1304 West Springfield Avenue
41;; Urbana, Illinois 61801
42
43;; Comments, improvements, and bug reports should be sent to Reingold.
44
45;; Technical details of the Mayan calendrical calculations can be found in
46;; ``Calendrical Calculations, Part II: Three Historical Calendars''
47;; by E. M. Reingold, N. Dershowitz, and S. M. Clamen,
48;; Report Number UIUCDCS-R-92-1743, Department of Computer Science,
49;; University of Illinois, April, 1992.
50
51;;; Code:
52
53(require 'calendar)
54
55(defun mayan-mod (m n)
56 "Returns M mod N; value is *always* non-negative when N>0."
57 (let ((v (% m n)))
58 (if (and (> 0 v) (> n 0))
59 (+ v n)
60 v)))
61
62(defun mayan-adjusted-mod (m n)
63 "Non-negative remainder of M/N with N instead of 0."
64 (1+ (mayan-mod (1- m) n)))
65
66(defconst calendar-mayan-days-before-absolute-zero 1137140
67 "Number of days of the Mayan calendar epoch before absolute day 0 (that is,
68Dec 31, 0 (Gregorian)), according to the Goodman-Martinez-Thompson
69correlation. This correlation is not universally accepted, as it still a
70subject of astro-archeological research. Using 1232041 will give you the
71correlation used by Spinden.")
72
73(defconst calendar-mayan-haab-at-epoch '(8 . 18)
74 "Mayan haab date at the epoch.")
75
76(defconst calendar-mayan-haab-month-name-array
77 ["Pop" "Uo" "Zip" "Zotz" "Tzec" "Xul" "Yaxkin" "Mol" "Chen" "Yax"
78 "Zac" "Ceh" "Mac" "Kankin" "Muan" "Pax" "Kayab" "Cumku"])
79
80(defconst calendar-mayan-tzolkin-at-epoch '(4 . 20)
81 "Mayan tzolkin date at the epoch.")
82
83(defconst calendar-mayan-tzolkin-names-array
84 ["Imix" "Ik" "Akbal" "Kan" "Chicchan" "Cimi" "Manik" "Lamat" "Muluc" "Oc"
85 "Chuen" "Eb" "Ben" "Ix" "Men" "Cib" "Caban" "Etznab" "Cauac" "Ahau"])
86
87(defun calendar-mayan-long-count-from-absolute (date)
88 "Compute the Mayan long count corresponding to the absolute DATE."
89 (let ((long-count (+ date calendar-mayan-days-before-absolute-zero)))
90 (let* ((baktun (/ long-count 144000))
91 (remainder (% long-count 144000))
92 (katun (/ remainder 7200))
93 (remainder (% remainder 7200))
94 (tun (/ remainder 360))
95 (remainder (% remainder 360))
96 (uinal (/ remainder 20))
97 (kin (% remainder 20)))
98 (list baktun katun tun uinal kin))))
99
100(defun calendar-mayan-long-count-to-string (mayan-long-count)
101 "Convert MAYAN-LONG-COUNT into traditional written form."
102 (apply 'format (cons "%s.%s.%s.%s.%s" mayan-long-count)))
103
104(defun calendar-string-to-mayan-long-count (str)
105 "Given STR, a string of format \"%d.%d.%d.%d.%d\", return list of nums."
106 (let ((rlc nil)
107 (c (length str))
108 (cc 0))
109 (condition-case condition
110 (progn
111 (while (< cc c)
112 (let ((datum (read-from-string str cc)))
113 (if (not (integerp (car datum)))
114 (signal 'invalid-read-syntax (car datum))
115 (setq rlc (cons (car datum) rlc))
116 (setq cc (cdr datum)))))
117 (if (not (= (length rlc) 5)) (signal 'invalid-read-syntax nil)))
118 (invalid-read-syntax nil))
119 (reverse rlc)))
120
121(defun calendar-mayan-haab-from-absolute (date)
122 "Convert absolute DATE into a Mayan haab date (a pair)."
123 (let* ((long-count (+ date calendar-mayan-days-before-absolute-zero))
124 (day-of-haab
125 (% (+ long-count
126 (car calendar-mayan-haab-at-epoch)
127 (* 20 (1- (cdr calendar-mayan-haab-at-epoch))))
128 365))
129 (day (% day-of-haab 20))
130 (month (1+ (/ day-of-haab 20))))
131 (cons day month)))
132
133(defun calendar-mayan-haab-difference (date1 date2)
134 "Number of days from Mayan haab date DATE1 to the next occurrence of Mayan
135haab date DATE2."
136 (mayan-mod (+ (* 20 (- (cdr date2) (cdr date1)))
137 (- (car date2) (car date1)))
138 365))
139
140(defun calendar-mayan-haab-on-or-before (haab-date date)
141 "Absolute date of latest HAAB-DATE on or before absolute DATE."
142 (- date
143 (mod (- date
144 (calendar-mayan-haab-difference
145 (calendar-mayan-haab-from-absolute 0) haab-date))
146 365)))
147
148(defun calendar-next-haab-date (haab-date &optional noecho)
149 "Move cursor to next instance of Mayan HAAB-DATE.
150Echo Mayan date if NOECHO is t."
151 (interactive (list (calendar-read-mayan-haab-date)))
152 (calendar-goto-date
153 (calendar-gregorian-from-absolute
154 (calendar-mayan-haab-on-or-before
155 haab-date
156 (+ 365
157 (calendar-absolute-from-gregorian (calendar-cursor-to-date))))))
158 (or noecho (calendar-print-mayan-date)))
159
160(defun calendar-previous-haab-date (haab-date &optional noecho)
161 "Move cursor to previous instance of Mayan HAAB-DATE.
162Echo Mayan date if NOECHO is t."
163 (interactive (list (calendar-read-mayan-haab-date)))
164 (calendar-goto-date
165 (calendar-gregorian-from-absolute
166 (calendar-mayan-haab-on-or-before
167 haab-date
168 (1- (calendar-absolute-from-gregorian (calendar-cursor-to-date))))))
169 (or noecho (calendar-print-mayan-date)))
170
171(defun calendar-mayan-haab-to-string (haab)
172 "Convert Mayan haab date (a pair) into its traditional written form."
173 (let ((month (cdr haab))
174 (day (car haab)))
175 ;; 19th month consists of 5 special days
176 (if (= month 19)
177 (format "%d Uayeb" day)
178 (format "%d %s"
179 day
180 (aref calendar-mayan-haab-month-name-array (1- month))))))
181
182(defun calendar-mayan-tzolkin-from-absolute (date)
183 "Convert absolute DATE into a Mayan tzolkin date (a pair)."
184 (let* ((long-count (+ date calendar-mayan-days-before-absolute-zero))
185 (day (mayan-adjusted-mod
186 (+ long-count (car calendar-mayan-tzolkin-at-epoch))
187 13))
188 (name (mayan-adjusted-mod
189 (+ long-count (cdr calendar-mayan-tzolkin-at-epoch))
190 20)))
191 (cons day name)))
192
193(defun calendar-mayan-tzolkin-difference (date1 date2)
194 "Number of days from Mayan tzolkin date DATE1 to the next occurrence of
195Mayan tzolkin date DATE2."
196 (let ((number-difference (- (car date2) (car date1)))
197 (name-difference (- (cdr date2) (cdr date1))))
198 (mayan-mod (+ number-difference
199 (* 13 (mayan-mod (* 3 (- number-difference name-difference))
200 20)))
201 260)))
202
203(defun calendar-mayan-tzolkin-on-or-before (tzolkin-date date)
204 "Absolute date of latest TZOLKIN-DATE on or before absolute DATE."
205 (- date
206 (mod (- date (calendar-mayan-tzolkin-difference
207 (calendar-mayan-tzolkin-from-absolute 0)
208 tzolkin-date))
209 260)))
210
211(defun calendar-next-tzolkin-date (tzolkin-date &optional noecho)
212 "Move cursor to next instance of Mayan TZOLKIN-DATE.
213Echo Mayan date if NOECHO is t."
214 (interactive (list (calendar-read-mayan-tzolkin-date)))
215 (calendar-goto-date
216 (calendar-gregorian-from-absolute
217 (calendar-mayan-tzolkin-on-or-before
218 tzolkin-date
219 (+ 260
220 (calendar-absolute-from-gregorian (calendar-cursor-to-date))))))
221 (or noecho (calendar-print-mayan-date)))
222
223(defun calendar-previous-tzolkin-date (tzolkin-date &optional noecho)
224 "Move cursor to previous instance of Mayan TZOLKIN-DATE.
225Echo Mayan date if NOECHO is t."
226 (interactive (list (calendar-read-mayan-tzolkin-date)))
227 (calendar-goto-date
228 (calendar-gregorian-from-absolute
229 (calendar-mayan-tzolkin-on-or-before
230 tzolkin-date
231 (1- (calendar-absolute-from-gregorian (calendar-cursor-to-date))))))
232 (or noecho (calendar-print-mayan-date)))
233
234(defun calendar-mayan-tzolkin-to-string (tzolkin)
235 "Convert Mayan tzolkin date (a pair) into its traditional written form."
236 (format "%d %s"
237 (car tzolkin)
238 (aref calendar-mayan-tzolkin-names-array (1- (cdr tzolkin)))))
239
240(defun calendar-mayan-tzolkin-haab-on-or-before (tzolkin-date haab-date date)
241 "Absolute date of latest date on or before date that is Mayan TZOLKIN-DATE
242and HAAB-DATE; returns nil if such a tzolkin-haab combination is impossible."
243 (let* ((haab-difference
244 (calendar-mayan-haab-difference
245 (calendar-mayan-haab-from-absolute 0)
246 haab-date))
247 (tzolkin-difference
248 (calendar-mayan-tzolkin-difference
249 (calendar-mayan-tzolkin-from-absolute 0)
250 tzolkin-date))
251 (difference (- tzolkin-difference haab-difference)))
252 (if (= (% difference 5) 0)
253 (- date
254 (mayan-mod (- date
255 (+ haab-difference (* 365 difference)))
256 18980))
257 nil)))
258
259(defun calendar-read-mayan-haab-date ()
260 "Prompt for a Mayan haab date"
261 (let* ((completion-ignore-case t)
262 (haab-day (calendar-read
263 "Haab kin (0-19): "
264 '(lambda (x) (and (>= x 0) (< x 20)))))
265 (haab-month-list (append calendar-mayan-haab-month-name-array
266 (and (< haab-day 5) '("Uayeb"))))
267 (haab-month (cdr
268 (assoc
269 (capitalize
270 (completing-read "Haab uinal: "
271 (mapcar 'list haab-month-list)
272 nil t))
273 (calendar-make-alist
274 haab-month-list 1 'capitalize)))))
275 (cons haab-day haab-month)))
276
277(defun calendar-read-mayan-tzolkin-date ()
278 "Prompt for a Mayan tzolkin date"
279 (let* ((completion-ignore-case t)
280 (tzolkin-count (calendar-read
281 "Tzolkin kin (1-13): "
282 '(lambda (x) (and (> x 0) (< x 14)))))
283 (tzolkin-name-list (append calendar-mayan-tzolkin-names-array nil))
284 (tzolkin-name (cdr
285 (assoc
286 (capitalize
287 (completing-read "Tzolkin uinal: "
288 (mapcar 'list tzolkin-name-list)
289 nil t))
290 (calendar-make-alist
291 tzolkin-name-list 1 'capitalize)))))
292 (cons tzolkin-count tzolkin-name)))
293
294(defun calendar-next-tzolkin-date (tzolkin-date &optional noecho)
295 "Move cursor to next instance of Mayan TZOLKIN-DATE.
296Echo Mayan date if NOECHO is t."
297 (interactive (list (calendar-read-mayan-tzolkin-date)))
298 (let* ((date (calendar-absolute-from-gregorian (calendar-cursor-to-date)))
299 (tomorrow-tzolkin-date
300 (calendar-mayan-tzolkin-from-absolute (1+ date))))
301 (calendar-goto-date
302 (calendar-gregorian-from-absolute
303 (+ date 1
304 (calendar-mayan-tzolkin-difference
305 tomorrow-tzolkin-date tzolkin-date)))))
306 (or noecho (calendar-print-mayan-date)))
307
308(defun calendar-next-calendar-round-date
309 (tzolkin-date haab-date &optional noecho)
310 "Move cursor to next instance of Mayan HAAB-DATE TZOKLIN-DATE combination.
311Echo Mayan date if NOECHO is t."
312 (interactive (list (calendar-read-mayan-tzolkin-date)
313 (calendar-read-mayan-haab-date)))
314 (let ((date (calendar-mayan-tzolkin-haab-on-or-before
315 tzolkin-date haab-date
316 (+ 18980 (calendar-absolute-from-gregorian
317 (calendar-cursor-to-date))))))
318 (if (not date)
319 (error "%s, %s does not exist in the Mayan calendar round"
320 (calendar-mayan-tzolkin-to-string tzolkin-date)
321 (calendar-mayan-haab-to-string haab-date))
322 (calendar-goto-date (calendar-gregorian-from-absolute date))
323 (or noecho (calendar-print-mayan-date)))))
324
325(defun calendar-previous-calendar-round-date
326 (tzolkin-date haab-date &optional noecho)
327 "Move cursor to previous instance of Mayan TZOKLIN-DATE HAAB-DATE
328combination. Echo Mayan date if NOECHO is t."
329 (interactive (list (calendar-read-mayan-tzolkin-date)
330 (calendar-read-mayan-haab-date)))
331 (let ((date (calendar-mayan-tzolkin-haab-on-or-before
332 tzolkin-date haab-date
333 (1- (calendar-absolute-from-gregorian
334 (calendar-cursor-to-date))))))
335 (if (not date)
336 (error "%s, %s does not exist in the Mayan calendar round"
337 (calendar-mayan-tzolkin-to-string tzolkin-date)
338 (calendar-mayan-haab-to-string haab-date))
339 (calendar-goto-date (calendar-gregorian-from-absolute date))
340 (or noecho (calendar-print-mayan-date)))))
341
342(defun calendar-absolute-from-mayan-long-count (c)
343 "Compute the absolute date corresponding to the Mayan Long
344Count $c$, which is a list (baktun katun tun uinal kin)"
345 (+ (* (nth 0 c) 144000) ; baktun
346 (* (nth 1 c) 7200) ; katun
347 (* (nth 2 c) 360) ; tun
348 (* (nth 3 c) 20) ; uinal
349 (nth 4 c) ; kin (days)
350 (- ; days before absolute date 0
351 calendar-mayan-days-before-absolute-zero)))
352
353(defun calendar-print-mayan-date ()
354 "Show the Mayan long count, tzolkin, and haab equivalents of the date
355under the cursor."
356 (interactive)
357 (let* ((d (calendar-absolute-from-gregorian
358 (or (calendar-cursor-to-date)
359 (error "Cursor is not on a date!"))))
360 (tzolkin (calendar-mayan-tzolkin-from-absolute d))
361 (haab (calendar-mayan-haab-from-absolute d))
362 (long-count (calendar-mayan-long-count-from-absolute d)))
363 (message "Mayan date: Long count = %s; tzolkin = %s; haab = %s"
364 (calendar-mayan-long-count-to-string long-count)
365 (calendar-mayan-tzolkin-to-string haab)
366 (calendar-mayan-haab-to-string tzolkin))))
367
368(defun calendar-goto-mayan-long-count-date (date &optional noecho)
369 "Move cursor to Mayan long count DATE. Echo Mayan date unless NOECHO is t."
370 (interactive
371 (let (lc)
372 (while (not lc)
373 (let ((datum
374 (calendar-string-to-mayan-long-count
375 (read-string "Mayan long count (baktun.katun.tun.uinal.kin): "
376 (calendar-mayan-long-count-to-string
377 (calendar-mayan-long-count-from-absolute
378 (calendar-absolute-from-gregorian
379 (calendar-current-date))))))))
380 (if (calendar-mayan-long-count-common-era datum)
381 (setq lc datum))))
382 (list lc)))
383 (calendar-goto-date
384 (calendar-gregorian-from-absolute
385 (calendar-absolute-from-mayan-long-count date)))
386 (or noecho (calendar-print-mayan-date)))
387
388(defun calendar-mayan-long-count-common-era (lc)
389 "T if long count represents date in the Common Era."
390 (let ((base (calendar-mayan-long-count-from-absolute 1)))
391 (while (and (not (null base)) (= (car lc) (car base)))
392 (setq lc (cdr lc)
393 base (cdr base)))
394 (or (null lc) (> (car lc) (car base)))))
395
396(defun diary-mayan-date ()
397 "Show the Mayan long count, haab, and tzolkin dates as a diary entry."
398 (let* ((d (calendar-absolute-from-gregorian date))
399 (tzolkin (calendar-mayan-tzolkin-from-absolute d))
400 (haab (calendar-mayan-haab-from-absolute d))
401 (long-count (calendar-mayan-long-count-from-absolute d)))
402 (format "Mayan date: Long count = %s; tzolkin = %s; haab = %s"
403 (calendar-mayan-long-count-to-string long-count)
404 (calendar-mayan-tzolkin-to-string haab)
405 (calendar-mayan-haab-to-string tzolkin))))
406
407(provide 'cal-mayan)
408
409;;; cal-mayan.el ends here
diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el
index 001abdce4bf..52bb556a7b1 100644
--- a/lisp/calendar/calendar.el
+++ b/lisp/calendar/calendar.el
@@ -1,11 +1,12 @@
1;;; calendar.el --- Calendar functions. 1;;; calendar.el --- Calendar functions.
2 2
3;;; Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. 3;;; Copyright (C) 1988, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
4 4
5;; Author: Edward M. Reingold <reingold@cs.uiuc.edu> 5;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
6;; Keyword: calendar 6;; Keywords: calendar, Gregorian calendar, Julian calendar, Hebrew calendar,
7;; Islamic calendar, ISO calendar, Julian day number, diary, holidays
7 8
8(defconst calendar-version "Version 4.02, released June 14, 1992") 9(defconst calendar-version "Version 5, released August 10, 1992")
9 10
10;; This file is part of GNU Emacs. 11;; This file is part of GNU Emacs.
11 12
@@ -26,25 +27,37 @@
26 27
27;;; Commentary: 28;;; Commentary:
28 29
29;; This collection of functions implements a calendar window. It generates 30;; This collection of functions implements a calendar window. It
30;; generates a calendar for the current month, together with the previous and 31;; generates a calendar for the current month, together with the previous
31;; coming months, or for any other three-month period. The calendar can be 32;; and coming months, or for any other three-month period. The calendar
32;; scrolled forward and backward in the window to show months in the past or 33;; can be scrolled forward and backward in the window to show months in
33;; future; the cursor can move forward and backward by days, weeks, or months, 34;; the past or future; the cursor can move forward and backward by days,
34;; making it possible, for instance, to jump to the date a specified number of 35;; weeks, or months, making it possible, for instance, to jump to the
35;; days, weeks, or months from the date under the cursor. The user can 36;; date a specified number of days, weeks, or months from the date under
36;; display a list of holidays and other notable days for the period shown; the 37;; the cursor. The user can display a list of holidays and other notable
37;; notable days can be marked on the calendar, if desired. The user can also 38;; days for the period shown; the notable days can be marked on the
38;; specify that dates having corresponding diary entries (in a file that the 39;; calendar, if desired. The user can also specify that dates having
39;; user specifies) be marked; the diary entries for any date can be viewed in 40;; corresponding diary entries (in a file that the user specifies) be
40;; a separate window. The diary and the notable days can be viewed 41;; marked; the diary entries for any date can be viewed in a separate
41;; independently of the calendar. Dates can be translated from the (usual) 42;; window. The diary and the notable days can be viewed independently of
42;; Gregorian calendar to the day of the year/days remaining in year, to the 43;; the calendar. Dates can be translated from the (usual) Gregorian
43;; ISO commercial calendar, to the Julian (old style) calendar, to the Hebrew 44;; calendar to the day of the year/days remaining in year, to the ISO
44;; calendar, to the Islamic calendar, and to the French Revolutionary calendar. 45;; commercial calendar, to the Julian (old style) calendar, to the Hebrew
45 46;; calendar, to the Islamic calendar, to the French Revolutionary calendar,
46;; The diary related functions are in diary.el; the holiday related functions 47;; to the Mayan calendar, and to the astronomical (Julian) day number.
47;; are in holiday.el 48;; When floating point is available, times of sunrise/sunset can be displayed,
49;; as can the phases of the moon. Appointment notication for diary entries
50;; is available.
51
52;; The following files are part of the calendar/diary code:
53
54;; diary.el, diary-insert.el Diary functions
55;; holidays.el Holiday functions
56;; cal-french.el French Revolutionary calendar
57;; cal-mayan.el Mayan calendars
58;; solar.el Sunrise/sunset, equinoxes/solstices
59;; lunar.el Phases of the moon
60;; appt.el Appointment notification
48 61
49;; Comments, corrections, and improvements should be sent to 62;; Comments, corrections, and improvements should be sent to
50;; Edward M. Reingold Department of Computer Science 63;; Edward M. Reingold Department of Computer Science
@@ -70,18 +83,28 @@
70;; Urbana, Illinois 61801 83;; Urbana, Illinois 61801
71 84
72;; Technical details of all the calendrical calculations can be found in 85;; Technical details of all the calendrical calculations can be found in
86
73;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold, 87;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold,
74;; Software--Practice and Experience, Volume 20, Number 9 (September, 1990), 88;; Software--Practice and Experience, Volume 20, Number 9 (September, 1990),
75;; pages 899-928. 89;; pages 899-928. ``Calendrical Calculations, Part II: Three Historical
90;; Calendars'' by E. M. Reingold, N. Dershowitz, and S. M. Clamen,
91;; Report Number UIUCDCS-R-92-1743, Department of Computer Science,
92;; University of Illinois, April, 1992.
93
94;; Hard copies of these two papers can be obtained by sending email to
95;; reingold@cs.uiuc.edu with the SUBJECT "send-paper-cal" (no quotes) and
96;; the message BODY containing your mailing address (snail).
76 97
77;;; Code: 98;;; Code:
78 99
100;;;###autoload
79(defvar view-diary-entries-initially nil 101(defvar view-diary-entries-initially nil
80 "*If T, the diary entries for the current date will be displayed on entry. 102 "*If t, the diary entries for the current date will be displayed on entry.
81The diary is displayed in another window when the calendar is first displayed, 103The diary is displayed in another window when the calendar is first displayed,
82if the current date is visible. The number of days of diary entries displayed 104if the current date is visible. The number of days of diary entries displayed
83is governed by the variable `number-of-diary-entries'.") 105is governed by the variable `number-of-diary-entries'.")
84 106
107;;;###autoload
85(defvar number-of-diary-entries 1 108(defvar number-of-diary-entries 1
86 "*Specifies how many days of diary entries are to be displayed initially. 109 "*Specifies how many days of diary entries are to be displayed initially.
87This variable affects the diary display when the command M-x diary is used, 110This variable affects the diary display when the command M-x diary is used,
@@ -97,13 +120,16 @@ Saturday. This variable does not affect the diary display with the `d'
97command from the calendar; in that case, the prefix argument controls the 120command from the calendar; in that case, the prefix argument controls the
98number of days of diary entries displayed.") 121number of days of diary entries displayed.")
99 122
123;;;###autoload
100(defvar mark-diary-entries-in-calendar nil 124(defvar mark-diary-entries-in-calendar nil
101 "*If t, dates with diary entries will be marked in the calendar window. 125 "*If t, dates with diary entries will be marked in the calendar window.
102The marking symbol is specified by the variable `diary-entry-marker'.") 126The marking symbol is specified by the variable `diary-entry-marker'.")
103 127
128;;;###autoload
104(defvar diary-entry-marker "+" 129(defvar diary-entry-marker "+"
105 "*The symbol used to mark dates that have diary entries.") 130 "*The symbol used to mark dates that have diary entries.")
106 131
132;;;###autoload
107(defvar view-calendar-holidays-initially nil 133(defvar view-calendar-holidays-initially nil
108 "*If t, the holidays for the current three month period will be displayed 134 "*If t, the holidays for the current three month period will be displayed
109on entry. The holidays are displayed in another window when the calendar is 135on entry. The holidays are displayed in another window when the calendar is
@@ -114,6 +140,7 @@ first displayed.")
114 "*If t, dates of holidays will be marked in the calendar window. 140 "*If t, dates of holidays will be marked in the calendar window.
115The marking symbol is specified by the variable `calendar-holiday-marker'.") 141The marking symbol is specified by the variable `calendar-holiday-marker'.")
116 142
143;;;###autoload
117(defvar calendar-holiday-marker "*" 144(defvar calendar-holiday-marker "*"
118 "*The symbol used to mark notable dates in the calendar.") 145 "*The symbol used to mark notable dates in the calendar.")
119 146
@@ -138,12 +165,19 @@ include only those days of such major interest as to appear on secular
138calendars. If t, the holidays shown in the calendar will include all 165calendars. If t, the holidays shown in the calendar will include all
139special days that would be shown on a complete Islamic calendar.") 166special days that would be shown on a complete Islamic calendar.")
140 167
168;;;###autoload
169(defvar calendar-load-hook nil
170 "*List of functions to be called after the calendar is first loaded.
171This is the place to add key bindings to calendar-mode-map.")
172
173;;;###autoload
141(defvar initial-calendar-window-hook nil 174(defvar initial-calendar-window-hook nil
142 "*List of functions to be called when the calendar window is first opened. 175 "*List of functions to be called when the calendar window is first opened.
143The functions invoked are called after the calendar window is opened, but 176The functions invoked are called after the calendar window is opened, but
144once opened is never called again. Leaving the calendar with the `q' command 177once opened is never called again. Leaving the calendar with the `q' command
145and reentering it will cause these functions to be called again.") 178and reentering it will cause these functions to be called again.")
146 179
180;;;###autoload
147(defvar today-visible-calendar-hook nil 181(defvar today-visible-calendar-hook nil
148 "*List of functions called whenever the current date is visible. 182 "*List of functions called whenever the current date is visible.
149This can be used, for example, to replace today's date with asterisks; a 183This can be used, for example, to replace today's date with asterisks; a
@@ -161,6 +195,7 @@ Other than the use of the provided functions, the changing of any
161characters in the calendar buffer by the hooks may cause the failure of the 195characters in the calendar buffer by the hooks may cause the failure of the
162functions that move by days and weeks.") 196functions that move by days and weeks.")
163 197
198;;;###autoload
164(defvar today-invisible-calendar-hook nil 199(defvar today-invisible-calendar-hook nil
165 "*List of functions called whenever the current date is not visible. 200 "*List of functions called whenever the current date is not visible.
166 201
@@ -172,6 +207,7 @@ Other than the use of the provided functions, the changing of any
172characters in the calendar buffer by the hooks may cause the failure of the 207characters in the calendar buffer by the hooks may cause the failure of the
173functions that move by days and weeks.") 208functions that move by days and weeks.")
174 209
210;;;###autoload
175(defvar diary-file "~/diary" 211(defvar diary-file "~/diary"
176 "*Name of the file in which one's personal diary of dates is kept. 212 "*Name of the file in which one's personal diary of dates is kept.
177 213
@@ -251,9 +287,12 @@ Diary entries can be based on Lisp sexps. For example, the diary entry
251 287
252causes the diary entry \"Vacation\" to appear from November 1 through November 288causes the diary entry \"Vacation\" to appear from November 1 through November
25310, 1990. Other functions available are `diary-float', `diary-anniversary', 28910, 1990. Other functions available are `diary-float', `diary-anniversary',
254`diary-cyclic', `day-of-year', `iso-date', `commercial-date', `french-date', 290`diary-cyclic', `diary-day-of-year', `diary-iso-date', `diary-french-date',
255`hebrew-date', `islamic-date', `parasha', `omer', and `rosh-hodesh'. See the 291`diary-hebrew-date', `diary-islamic-date', `diary-mayan-date',
256documentation for the function `list-sexp-diary-entries' for more details. 292`diary-yahrzeit', `diary-sunrise-sunset', `diary-phases-of-moon',
293`diary-parasha', `diary-omer', `diary-rosh-hodesh', and
294`diary-sabbath-candles'. See the documentation for the function
295`list-sexp-diary-entries' for more details.
257 296
258Diary entries based on the Hebrew and/or the Islamic calendar are also 297Diary entries based on the Hebrew and/or the Islamic calendar are also
259possible, but because these are somewhat slow, they are ignored 298possible, but because these are somewhat slow, they are ignored
@@ -264,32 +303,39 @@ for these functions for details.
264Diary files can contain directives to include the contents of other files; for 303Diary files can contain directives to include the contents of other files; for
265details, see the documentation for the variable `list-diary-entries-hook'.") 304details, see the documentation for the variable `list-diary-entries-hook'.")
266 305
306;;;###autoload
267(defvar diary-nonmarking-symbol "&" 307(defvar diary-nonmarking-symbol "&"
268 "*The symbol used to indicate that a diary entry is not to be marked in the 308 "*The symbol used to indicate that a diary entry is not to be marked in the
269calendar window.") 309calendar window.")
270 310
311;;;###autoload
271(defvar hebrew-diary-entry-symbol "H" 312(defvar hebrew-diary-entry-symbol "H"
272 "*The symbol used to indicate that a diary entry is according to the 313 "*The symbol used to indicate that a diary entry is according to the
273Hebrew calendar.") 314Hebrew calendar.")
274 315
316;;;###autoload
275(defvar islamic-diary-entry-symbol "I" 317(defvar islamic-diary-entry-symbol "I"
276 "*The symbol used to indicate that a diary entry is according to the 318 "*The symbol used to indicate that a diary entry is according to the
277Islamic calendar.") 319Islamic calendar.")
278 320
321;;;###autoload
279(defvar diary-include-string "#include" 322(defvar diary-include-string "#include"
280 "*The string used to indicate the inclusion of another file of diary entries 323 "*The string used to indicate the inclusion of another file of diary entries
281in diary-file. See the documentation for the function 324in diary-file. See the documentation for the function
282`include-other-diary-files'.") 325`include-other-diary-files'.")
283 326
327;;;###autoload
284(defvar sexp-diary-entry-symbol "%%" 328(defvar sexp-diary-entry-symbol "%%"
285 "*The string used to indicate a sexp diary entry in diary-file. 329 "*The string used to indicate a sexp diary entry in diary-file.
286See the documentation for the function `list-sexp-diary-entries'.") 330See the documentation for the function `list-sexp-diary-entries'.")
287 331
332;;;###autoload
288(defvar abbreviated-calendar-year t 333(defvar abbreviated-calendar-year t
289 "*Interpret a two-digit year DD in a diary entry as being either 19DD or 334 "*Interpret a two-digit year DD in a diary entry as being either 19DD or
29020DD, as appropriate, for the Gregorian calendar; similarly for the Hebrew and 33520DD, as appropriate, for the Gregorian calendar; similarly for the Hebrew and
291Islamic calendars. If this variable is nil, years must be written in full.") 336Islamic calendars. If this variable is nil, years must be written in full.")
292 337
338;;;###autoload
293(defvar european-calendar-style nil 339(defvar european-calendar-style nil
294 "*Use the European style of dates in the diary and in any displays. If this 340 "*Use the European style of dates in the diary and in any displays. If this
295variable is t, a date 1/2/1990 would be interpreted as February 1, 1990. 341variable is t, a date 1/2/1990 would be interpreted as February 1, 1990.
@@ -304,6 +350,7 @@ The accepted European date styles are
304Names can be capitalized or not, written in full, or abbreviated to three 350Names can be capitalized or not, written in full, or abbreviated to three
305characters with or without a period.") 351characters with or without a period.")
306 352
353;;;###autoload
307(defvar american-date-diary-pattern 354(defvar american-date-diary-pattern
308 '((month "/" day "[^/0-9]") 355 '((month "/" day "[^/0-9]")
309 (month "/" day "/" year "[^0-9]") 356 (month "/" day "/" year "[^0-9]")
@@ -313,6 +360,7 @@ characters with or without a period.")
313 "*List of pseudo-patterns describing the American patterns of date used. 360 "*List of pseudo-patterns describing the American patterns of date used.
314See the documentation of diary-date-forms for an explanantion.") 361See the documentation of diary-date-forms for an explanantion.")
315 362
363;;;###autoload
316(defvar european-date-diary-pattern 364(defvar european-date-diary-pattern
317 '((day "/" month "[^/0-9]") 365 '((day "/" month "[^/0-9]")
318 (day "/" month "/" year "[^0-9]") 366 (day "/" month "/" year "[^0-9]")
@@ -322,6 +370,7 @@ See the documentation of diary-date-forms for an explanantion.")
322 "*List of pseudo-patterns describing the European patterns of date used. 370 "*List of pseudo-patterns describing the European patterns of date used.
323See the documentation of diary-date-forms for an explanantion.") 371See the documentation of diary-date-forms for an explanantion.")
324 372
373;;;###autoload
325(defvar diary-date-forms 374(defvar diary-date-forms
326 (if european-calendar-style 375 (if european-calendar-style
327 european-date-diary-pattern 376 european-date-diary-pattern
@@ -345,22 +394,25 @@ that it is a word constituent.
345 394
346If, to be mutually exclusive, a pseudo-pattern must match a portion of the 395If, to be mutually exclusive, a pseudo-pattern must match a portion of the
347diary entry itself, the first element of the pattern MUST be `backup'. This 396diary entry itself, the first element of the pattern MUST be `backup'. This
348directive causes the the date recognizer to back up to the beginning of the 397directive causes the date recognizer to back up to the beginning of the
349current word of the diary entry, so in no case can the pattern match more 398current word of the diary entry, so in no case can the pattern match more than
350than a portion of the first word of the diary entry.") 399a portion of the first word of the diary entry.")
351 400
401;;;###autoload
352(defvar european-calendar-display-form 402(defvar european-calendar-display-form
353 '(dayname ", " day " " monthname " " year) 403 '((if dayname (concat dayname ", ")) day " " monthname " " year)
354 "*The pseudo-pattern that governs the way a Gregorian date is formatted 404 "*The pseudo-pattern that governs the way a Gregorian date is formatted
355in the European style. See the documentation of calendar-date-display-forms 405in the European style. See the documentation of calendar-date-display-forms
356for an explanantion.") 406for an explanantion.")
357 407
408;;;###autoload
358(defvar american-calendar-display-form 409(defvar american-calendar-display-form
359 '(dayname ", " monthname " " day ", " year) 410 '((if dayname (concat dayname ", ")) monthname " " day ", " year)
360 "*The pseudo-pattern that governs the way a Gregorian date is formatted 411 "*The pseudo-pattern that governs the way a Gregorian date is formatted
361in the American style. See the documentation of calendar-date-display-forms 412in the American style. See the documentation of calendar-date-display-forms
362for an explanantion.") 413for an explanantion.")
363 414
415;;;###autoload
364(defvar calendar-date-display-form 416(defvar calendar-date-display-form
365 (if european-calendar-style 417 (if european-calendar-style
366 european-calendar-display-form 418 european-calendar-display-form
@@ -386,6 +438,96 @@ would give the usual American style in fixed-length fields.
386 438
387See the documentation of the function `calendar-date-string'.") 439See the documentation of the function `calendar-date-string'.")
388 440
441;;;###autoload
442(defvar calendar-time-display-form
443 '(12-hours ":" minutes am-pm
444 (if time-zone " (") time-zone (if time-zone ")"))
445 "*The pseudo-pattern that governs the way a time of day is formatted.
446
447A pseudo-pattern is a list of expressions that can involve the keywords
448`12-hours', `24-hours', and `minutes', all numbers in string form,
449and `am-pm' and `time-zone', both alphabetic strings.
450
451For example, the form
452
453 '(24-hours \":\" minutes
454 (if time-zone \" (\") time-zone (if time-zone \")\"))
455
456would give military-style times like `21:07 (UT)'.")
457
458;;;###autoload
459(defvar calendar-latitude nil
460 "*Latitude of `calendar-location-name' in degrees, + north, - south.
461For example, 40.7 for New York City.")
462
463;;;###autoload
464(defvar calendar-longitude nil
465 "*Longitude of `calendar-location-name' in degrees, + east, - west.
466For example, -74.0 for New York City.")
467
468;;;###autoload
469(defvar calendar-location-name
470 '(let ((float-output-format "%.1f"))
471 (format "%s%s, %s%s"
472 (abs calendar-latitude)
473 (if (> calendar-latitude 0) "N" "S")
474 (abs calendar-longitude)
475 (if (> calendar-longitude 0) "E" "W")))
476 "*An expression that evaluates to the name of the location at
477`calendar-longitude', calendar-latitude'. Default value is just the latitude,
478longitude pair.")
479
480;;;###autoload
481(defvar calendar-time-zone (car (current-time-zone))
482 "*Number of minutes difference between local standard time at
483`calendar-location-name' and Universal (Greenwich) Time. For example, -300
484for New York City, -480 for Los Angeles.")
485
486;;;###autoload
487(defvar calendar-standard-time-zone-name (car (nthcdr 2 (current-time-zone)))
488 "*Abbreviated name of standard time zone at `calendar-location-name'.
489For example, \"EST\" in New York City, \"PST\" for Los Angeles.")
490
491;;;###autoload
492(defvar calendar-daylight-time-zone-name (car (nthcdr 3 (current-time-zone)))
493 "*Abbreviated name of daylight-savings time zone at `calendar-location-name'.
494For example, \"EDT\" in New York City, \"PDT\" for Los Angeles.")
495
496;;;###autoload
497(defvar calendar-daylight-savings-starts
498 '(calendar-nth-named-day 1 0 4 year)
499 "*A sexp in the variable `year' that gives the Gregorian date, in the form
500of a list (month day year), on which daylight savings time starts. This is
501used to determine the starting date of daylight savings time for the holiday
502list and for correcting times of day in the solar and lunar calculations. The
503default value is the American rule of the first Sunday in April.
504
505For example, if daylight savings time is mandated to start on October 1,
506you would set `calendar-daylight-savings-starts' to
507
508 '(10 1 year)
509
510For a more complex example, if daylight savings time begins on the first of
511Nisan on the Hebrew calendar, we would set `calendar-daylight-savings-starts'
512to
513
514 '(calendar-gregorian-from-absolute
515 (calendar-absolute-from-hebrew
516 (list 1 1 (+ year 3760))))
517
518because Nisan is the first month in the Hebrew calendar.")
519
520;;;###autoload
521(defvar calendar-daylight-savings-ends
522 '(calendar-nth-named-day -1 0 10 year)
523 "*An expression in the variable `year' that gives the Gregorian date, in the
524form of a list (month day year), on which daylight savings time ends. This
525is used to determine the ending date of daylight savings time for the holiday
526list and for correcting times of day in the solar and lunar calculations.
527The default value is the American rule of the last Sunday in October.
528See the documentation for `calendar-daylight-savings-starts' for other
529examples.")
530
389(defun european-calendar () 531(defun european-calendar ()
390 "Set the interpretation and display of dates to the European style." 532 "Set the interpretation and display of dates to the European style."
391 (interactive) 533 (interactive)
@@ -402,15 +544,13 @@ See the documentation of the function `calendar-date-string'.")
402 (setq diary-date-forms american-date-diary-pattern) 544 (setq diary-date-forms american-date-diary-pattern)
403 (update-calendar-mode-line)) 545 (update-calendar-mode-line))
404 546
405(defvar print-diary-entries-hook 547;;;###autoload
406 '(add-diary-heading lpr-buffer (lambda nil (kill-buffer temp-buffer))) 548(defvar print-diary-entries-hook 'lpr-buffer
407 "*List of functions to be called after a temporary buffer is prepared 549 "*List of functions to be called after a temporary buffer is prepared with
408with the diary entries currently visible in the diary buffer. The default 550the diary entries currently visible in the diary buffer. The default just
409value adds a heading (formed from the information in the mode line of the 551does the printing. Other uses might include, for example, rearranging the
410diary buffer), does the printing, and kills the buffer. Other uses might 552lines into order by day and time, saving the buffer instead of deleting it, or
411include, for example, rearranging the lines into order by day and time, 553changing the function used to do the printing.")
412saving the buffer instead of deleting it, or changing the function used to
413do the printing.")
414 554
415;;;###autoload 555;;;###autoload
416(defvar list-diary-entries-hook nil 556(defvar list-diary-entries-hook nil
@@ -434,10 +574,7 @@ function `mark-included-diary-files' as part of the mark-diary-entries-hook.
434For example, you could use 574For example, you could use
435 575
436 (setq list-diary-entries-hook 576 (setq list-diary-entries-hook
437 '(include-other-diary-files 577 '(include-other-diary-files sort-diary-entries))
438 (lambda nil
439 (setq diary-entries-list
440 (sort diary-entries-list 'diary-entry-compare)))))
441 (setq diary-display-hook 'fancy-diary-display) 578 (setq diary-display-hook 'fancy-diary-display)
442 579
443in your .emacs file to cause the fancy diary buffer to be displayed with 580in your .emacs file to cause the fancy diary buffer to be displayed with
@@ -470,10 +607,10 @@ diary buffer, set the variable `diary-list-include-blanks' to t.")
470(defvar nongregorian-diary-listing-hook nil 607(defvar nongregorian-diary-listing-hook nil
471 "*List of functions to be called for the diary file and included files as 608 "*List of functions to be called for the diary file and included files as
472they are processed for listing diary entries. You can use any or all of 609they are processed for listing diary entries. You can use any or all of
473`list-hebrew-diary-entries', `yahrzeit-diary-entry', and 610`list-hebrew-diary-entries' and `list-islamic-diary-entries'. The
474`list-islamic-diary-entries'. The documentation for these functions 611documentation for these functions describes the style of such diary entries.")
475describes the style of such diary entries.")
476 612
613;;;###autoload
477(defvar mark-diary-entries-hook nil 614(defvar mark-diary-entries-hook nil
478 "*List of functions called after marking diary entries in the calendar. 615 "*List of functions called after marking diary entries in the calendar.
479 616
@@ -501,22 +638,21 @@ for these functions describes the style of such diary entries.")
501entries. Such days will then not be shown in the the fancy diary buffer, 638entries. Such days will then not be shown in the the fancy diary buffer,
502even if they are holidays.") 639even if they are holidays.")
503 640
641;;;###autoload
504(defvar holidays-in-diary-buffer t 642(defvar holidays-in-diary-buffer t
505 "*If t, the holidays will be indicated in the mode line of the diary buffer 643 "*If t, the holidays will be indicated in the mode line of the diary buffer
506(or in the fancy diary buffer next to the date). This slows down the diary 644(or in the fancy diary buffer next to the date). This slows down the diary
507functions somewhat; setting it to nil will make the diary display faster.") 645functions somewhat; setting it to nil will make the diary display faster.")
508 646
509(defvar calendar-holidays 647;;;###autoload
510 '( 648(defvar general-holidays
511;; General Holidays (American) 649 '((fixed 1 1 "New Year's Day")
512 (fixed 1 1 "New Year's Day")
513 (float 1 1 3 "Martin Luther King Day") 650 (float 1 1 3 "Martin Luther King Day")
514 (fixed 2 2 "Ground Hog Day") 651 (fixed 2 2 "Ground Hog Day")
515 (fixed 2 14 "Valentine's Day") 652 (fixed 2 14 "Valentine's Day")
516 (float 2 1 3 "President's Day") 653 (float 2 1 3 "President's Day")
517 (fixed 3 17 "St. Patrick's Day") 654 (fixed 3 17 "St. Patrick's Day")
518 (fixed 4 1 "April Fool's Day") 655 (fixed 4 1 "April Fool's Day")
519 (float 4 0 1 "Daylight Savings Time Begins")
520 (float 5 0 2 "Mother's Day") 656 (float 5 0 2 "Mother's Day")
521 (float 5 1 -1 "Memorial Day") 657 (float 5 1 -1 "Memorial Day")
522 (fixed 6 14 "Flag Day") 658 (fixed 6 14 "Flag Day")
@@ -524,25 +660,25 @@ functions somewhat; setting it to nil will make the diary display faster.")
524 (fixed 7 4 "Independence Day") 660 (fixed 7 4 "Independence Day")
525 (float 9 1 1 "Labor Day") 661 (float 9 1 1 "Labor Day")
526 (float 10 1 2 "Columbus Day") 662 (float 10 1 2 "Columbus Day")
527 (float 10 0 -1 "Daylight Savings Time Ends")
528 (fixed 10 31 "Halloween") 663 (fixed 10 31 "Halloween")
529 (fixed 11 11 "Veteran's Day") 664 (fixed 11 11 "Veteran's Day")
530 (float 11 4 4 "Thanksgiving") 665 (float 11 4 4 "Thanksgiving"))
666 "*General holidays. Default value is for the United States. See the
667documentation for `calendar-holidays' for details.")
531 668
532;; Christian Holidays 669;;;###autoload
533 (if all-christian-calendar-holidays 670(defvar local-holidays nil
534 (fixed 1 6 "Epiphany")) 671 "*Local holidays.
535 (easter-etc) 672See the documentation for `calendar-holidays' for details.")
536 (if all-christian-calendar-holidays 673
537 (fixed 8 15 "Assumption")) 674;;;###autoload
538 (if all-christian-calendar-holidays 675(defvar other-holidays nil
539 (advent)) 676 "*User defined holidays.
540 (fixed 12 25 "Christmas") 677See the documentation for `calendar-holidays' for details.")
541 (if all-christian-calendar-holidays
542 (julian 12 25 "Eastern Orthodox Christmas"))
543 678
544;; Jewish Holidays 679;;;###autoload
545 (rosh-hashanah-etc) 680(defvar hebrew-holidays
681 '((rosh-hashanah-etc)
546 (if all-hebrew-calendar-holidays 682 (if all-hebrew-calendar-holidays
547 (julian 11 683 (julian 11
548 (let* ((m displayed-month) 684 (let* ((m displayed-month)
@@ -613,10 +749,30 @@ functions somewhat; setting it to nil will make the diary display faster.")
613 (= 21 (% year 28))))) 749 (= 21 (% year 28)))))
614 (julian 3 26 "Kiddush HaHamah")) 750 (julian 3 26 "Kiddush HaHamah"))
615 (if all-hebrew-calendar-holidays 751 (if all-hebrew-calendar-holidays
616 (tisha-b-av-etc)) 752 (tisha-b-av-etc)))
753 "*Jewish holidays.
754See the documentation for `calendar-holidays' for details.")
755
756;;;###autoload
757(defvar christian-holidays
758 '((if all-christian-calendar-holidays
759 (fixed 1 6 "Epiphany"))
760 (easter-etc)
761 (if all-christian-calendar-holidays
762 (greek-orthodox-easter))
763 (if all-christian-calendar-holidays
764 (fixed 8 15 "Assumption"))
765 (if all-christian-calendar-holidays
766 (advent))
767 (fixed 12 25 "Christmas")
768 (if all-christian-calendar-holidays
769 (julian 12 25 "Eastern Orthodox Christmas")))
770 "*Christian holidays.
771See the documentation for `calendar-holidays' for details.")
617 772
618;; Islamic Holidays 773;;;###autoload
619 (islamic 1 1 (format "Islamic New Year %d" 774(defvar islamic-holidays
775 '((islamic 1 1 (format "Islamic New Year %d"
620 (let ((m displayed-month) 776 (let ((m displayed-month)
621 (y displayed-year)) 777 (y displayed-year))
622 (increment-calendar-month m y 1) 778 (increment-calendar-month m y 1)
@@ -639,9 +795,36 @@ functions somewhat; setting it to nil will make the diary display faster.")
639 (islamic 10 1 "Id-al-Fitr")) 795 (islamic 10 1 "Id-al-Fitr"))
640 (if all-islamic-calendar-holidays 796 (if all-islamic-calendar-holidays
641 (islamic 12 10 "Id-al-Adha"))) 797 (islamic 12 10 "Id-al-Adha")))
642 "List of notable days for the command M-x holidays. 798 "*Islamic holidays.
643Additional holidays are easy to add to the list. The possible holiday-forms 799See the documentation for `calendar-holidays' for details.")
644are as follows: 800
801;;;###autoload
802(defvar solar-holidays
803 '((if (fboundp 'atan)
804 (solar-equinoxes-solstices))
805 (sexp (eval calendar-daylight-savings-starts)
806 "Daylight Savings Time Begins")
807 (sexp (eval calendar-daylight-savings-ends)
808 "Daylight Savings Time Ends"))
809 "*Sun-related holidays.
810See the documentation for `calendar-holidays' for details.")
811
812;;;###autoload
813(defvar calendar-holidays
814 (append general-holidays local-holidays other-holidays
815 christian-holidays hebrew-holidays islamic-holidays
816 solar-holidays)
817 "*List of notable days for the command M-x holidays.
818
819Additional holidays are easy to add to the list, just put them in the list
820`other-holidays' in your .emacs file. Similarly, by setting any of
821`general-holidays', `local-holidays' `christian-holidays', `hebrew-holidays',
822`islamic-holidays', or `solar-holidays' to nil in your .emacs file, you can
823eliminate unwanted categories of holidays. The intention is that (in the US)
824`local-holidays' be set in site-init.el and `other-holidays' be set by the
825user.
826
827The possible holiday-forms are as follows:
645 828
646 (fixed MONTH DAY STRING) a fixed date on the Gregorian calendar 829 (fixed MONTH DAY STRING) a fixed date on the Gregorian calendar
647 (float MONTH DAYNAME K STRING) the Kth DAYNAME in MONTH on the Gregorian 830 (float MONTH DAYNAME K STRING) the Kth DAYNAME in MONTH on the Gregorian
@@ -650,6 +833,10 @@ are as follows:
650 (hebrew MONTH DAY STRING) a fixed date on the Hebrew calendar 833 (hebrew MONTH DAY STRING) a fixed date on the Hebrew calendar
651 (islamic MONTH DAY STRING) a fixed date on the Islamic calendar 834 (islamic MONTH DAY STRING) a fixed date on the Islamic calendar
652 (julian MONTH DAY STRING) a fixed date on the Julian calendar 835 (julian MONTH DAY STRING) a fixed date on the Julian calendar
836 (sexp SEXP STRING) SEXP is a Gregorian-date-valued expression
837 in the variable `year'; if it evaluates to
838 a visible date, that's the holiday; if it
839 evaluates to nil, there's no holiday
653 (if BOOLEAN HOLIDAY-FORM &optional HOLIDAY-FORM) gives a choice between 840 (if BOOLEAN HOLIDAY-FORM &optional HOLIDAY-FORM) gives a choice between
654 two holidays based on the value of BOOLEAN 841 two holidays based on the value of BOOLEAN
655 (FUNCTION &optional ARGS) dates requiring special computation; ARGS, 842 (FUNCTION &optional ARGS) dates requiring special computation; ARGS,
@@ -666,9 +853,9 @@ Islands on the fourth Monday in August, add
666 (float 8 1 4 \"Hurricane Supplication Day\") 853 (float 8 1 4 \"Hurricane Supplication Day\")
667 854
668to the list (the last Monday would be specified with `-1' instead of `4'). 855to the list (the last Monday would be specified with `-1' instead of `4').
669To add the last day of Hanukah to the list, use 856To add the last day of Hanukkah to the list, use
670 857
671 (hebrew 10 2 \"Last day of Hanukah\") 858 (hebrew 10 2 \"Last day of Hanukkah\")
672 859
673since the Hebrew months are numbered with 1 starting from Nisan, while to 860since the Hebrew months are numbered with 1 starting from Nisan, while to
674add the Islamic feast celebrating Mohammed's birthday use 861add the Islamic feast celebrating Mohammed's birthday use
@@ -680,10 +867,19 @@ add Thomas Jefferson's birthday, April 2, 1743 (Julian), use
680 867
681 (julian 4 2 \"Jefferson's Birthday\") 868 (julian 4 2 \"Jefferson's Birthday\")
682 869
683To include a holiday conditionally, use the if form. For example, to 870To include a holiday conditionally, use the if or the sexp form. For example,
684include American presidential elections, which occur on the first Tuesday 871to include American presidential elections, which occur on the first Tuesday
685after the first Monday in November of years divisble by 4, add 872after the first Monday in November of years divisble by 4, add
686 873
874 (sexp (if (zerop (% year 4))
875 (calendar-gregorian-from-absolute
876 (1+ (calendar-dayname-on-or-before
877 1 (+ 6 (calendar-absolute-from-gregorian
878 (list 11 1 year)))))))
879 \"US Presidential Election\")
880
881or
882
687 (if (zerop (% displayed-year 4)) 883 (if (zerop (% displayed-year 4))
688 (fixed 11 884 (fixed 11
689 (extract-calendar-day 885 (extract-calendar-day
@@ -703,11 +899,12 @@ the relevant VISIBLE dates with descriptive strings such as
703 899
704 (((2 6 1989) \"New Moon\") ((2 12 1989) \"First Quarter Moon\") ... ) 900 (((2 6 1989) \"New Moon\") ((2 12 1989) \"First Quarter Moon\") ... )
705 901
706The fixed, float, hebrew, islamic, julian and if forms are implemented by 902The fixed, float, hebrew, islamic, julian, sexp, and if forms are implemented
707the inclusion of the functions `calendar-holiday-function-fixed', 903by the inclusion of the functions `calendar-holiday-function-fixed',
708`calendar-holiday-function-float', `calendar-holiday-function-hebrew', 904`calendar-holiday-function-float', `calendar-holiday-function-hebrew',
709`calendar-holiday-function-islamic', `calendar-holiday-function-julian', 905`calendar-holiday-function-islamic', `calendar-holiday-function-julian',
710and `calendar-holiday-function-if', respectively.") 906`calendar-holiday-function-sexp', and `calendar-holiday-function-if',
907respectively.")
711 908
712(defconst calendar-buffer "*Calendar*" 909(defconst calendar-buffer "*Calendar*"
713 "Name of the buffer used for the calendar.") 910 "Name of the buffer used for the calendar.")
@@ -770,19 +967,29 @@ sum EXPRESSION."
770;; . 967;; .
771;; 968;;
772;; The use of these seven macros eliminates the overhead of 92% of the function 969;; The use of these seven macros eliminates the overhead of 92% of the function
773;; calls; it's faster this way. 970;; calls; it's faster this way. For clarity, the defun form of each is given
971;; in comments after the defmacro form.
774 972
775(defmacro extract-calendar-month (date) 973(defmacro extract-calendar-month (date)
776 "Extract the month part of DATE which has the form (month day year)." 974 "Extract the month part of DATE which has the form (month day year)."
777 (` (car (, date)))) 975 (` (car (, date))))
976;;(defun extract-calendar-month (date)
977;; "Extract the month part of DATE which has the form (month day year)."
978;; (car date))
778 979
779(defmacro extract-calendar-day (date) 980(defmacro extract-calendar-day (date)
780 "Extract the day part of DATE which has the form (month day year)." 981 "Extract the day part of DATE which has the form (month day year)."
781 (` (car (cdr (, date))))) 982 (` (car (cdr (, date)))))
983;;(defun extract-calendar-day (date)
984;; "Extract the day part of DATE which has the form (month day year)."
985;; (car (cdr date)))
782 986
783(defmacro extract-calendar-year (date) 987(defmacro extract-calendar-year (date)
784 "Extract the year part of DATE which has the form (month day year)." 988 "Extract the year part of DATE which has the form (month day year)."
785 (` (car (cdr (cdr (, date)))))) 989 (` (car (cdr (cdr (, date))))))
990;;(defun extract-calendar-year (date)
991;; "Extract the year part of DATE which has the form (month day year)."
992;; (car (cdr (cdr date))))
786 993
787(defmacro calendar-leap-year-p (year) 994(defmacro calendar-leap-year-p (year)
788 "Returns t if YEAR is a Gregorian leap year." 995 "Returns t if YEAR is a Gregorian leap year."
@@ -790,6 +997,12 @@ sum EXPRESSION."
790 (and (= (% (, year) 4) 0) 997 (and (= (% (, year) 4) 0)
791 (/= (% (, year) 100) 0)) 998 (/= (% (, year) 100) 0))
792 (= (% (, year) 400) 0)))) 999 (= (% (, year) 400) 0))))
1000;;(defun calendar-leap-year-p (year)
1001;; "Returns t if YEAR is a Gregorian leap year."
1002;; (or
1003;; (and (= (% year 4) 0)
1004;; (/= (% year 100) 0))
1005;; (= (% year 400) 0)))
793 1006
794(defmacro calendar-last-day-of-month (month year) 1007(defmacro calendar-last-day-of-month (month year)
795 "The last day in MONTH during YEAR." 1008 "The last day in MONTH during YEAR."
@@ -798,6 +1011,11 @@ sum EXPRESSION."
798 (= (, month) 2)) 1011 (= (, month) 2))
799 29 1012 29
800 (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- (, month)))))) 1013 (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- (, month))))))
1014;;(defun calendar-last-day-of-month (month year)
1015;; "The last day in MONTH during YEAR."
1016;; (if (and (calendar-leap-year-p year) (= month 2))
1017;; 29
1018;; (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- month))))
801 1019
802(defmacro calendar-day-number (date) 1020(defmacro calendar-day-number (date)
803 "Return the day number within the year of the date DATE. 1021 "Return the day number within the year of the date DATE.
@@ -817,6 +1035,20 @@ while (calendar-day-number '(12 31 1980)) returns 366."
817 (if (, (macroexpand (` (calendar-leap-year-p year)))) 1035 (if (, (macroexpand (` (calendar-leap-year-p year))))
818 (setq day-of-year (1+ day-of-year))))) 1036 (setq day-of-year (1+ day-of-year)))))
819 day-of-year))) 1037 day-of-year)))
1038;;(defun calendar-day-number (date)
1039;; "Return the day number within the year of the date DATE.
1040;;For example, (calendar-day-number '(1 1 1987)) returns the value 1,
1041;;while (calendar-day-number '(12 31 1980)) returns 366."
1042;; (let* ((month (extract-calendar-month date))
1043;; (day (extract-calendar-day date))
1044;; (year (extract-calendar-year date))
1045;; (day-of-year (+ day (* 31 (1- month)))))
1046;; (if (> month 2)
1047;; (progn
1048;; (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10)))
1049;; (if (calendar-leap-year-p year)
1050;; (setq day-of-year (1+ day-of-year)))))
1051;; day-of-year))
820 1052
821(defmacro calendar-absolute-from-gregorian (date) 1053(defmacro calendar-absolute-from-gregorian (date)
822 "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE. 1054 "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE.
@@ -829,6 +1061,17 @@ The Gregorian date Sunday, December 31, 1 BC is imaginary."
829 (/ (1- year) 4);; + Julian leap years 1061 (/ (1- year) 4);; + Julian leap years
830 (- (/ (1- year) 100));; - century years 1062 (- (/ (1- year) 100));; - century years
831 (/ (1- year) 400)))));; + Gregorian leap years 1063 (/ (1- year) 400)))));; + Gregorian leap years
1064;;(defun calendar-absolute-from-gregorian (date)
1065;; "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE.
1066;;The Gregorian date Sunday, December 31, 1 BC is imaginary."
1067;; (let ((month (extract-calendar-month date))
1068;; (day (extract-calendar-day date))
1069;; (year (extract-calendar-year date)))
1070;; (+ (calendar-day-number date);; Days this year
1071;; (* 365 (1- year));; + Days in prior years
1072;; (/ (1- year) 4);; + Julian leap years
1073;; (- (/ (1- year) 100));; - century years
1074;; (/ (1- year) 400))));; + Gregorian leap years
832 1075
833;;;###autoload 1076;;;###autoload
834(defun calendar (&optional arg) 1077(defun calendar (&optional arg)
@@ -836,6 +1079,8 @@ The Gregorian date Sunday, December 31, 1 BC is imaginary."
836The three months appear side by side, with the current month in the middle 1079The three months appear side by side, with the current month in the middle
837surrounded by the previous and next months. The cursor is put on today's date. 1080surrounded by the previous and next months. The cursor is put on today's date.
838 1081
1082If called with an optional prefix argument, prompts for month and year.
1083
839This function is suitable for execution in a .emacs file; appropriate setting 1084This function is suitable for execution in a .emacs file; appropriate setting
840of the variable `view-diary-entries-initially' will cause the diary entries for 1085of the variable `view-diary-entries-initially' will cause the diary entries for
841the current date to be displayed in another window. The value of the variable 1086the current date to be displayed in another window. The value of the variable
@@ -862,6 +1107,10 @@ Use M-x describe-mode for details of the key bindings in the calendar window.
862 1107
863The Gregorian calendar is assumed. 1108The Gregorian calendar is assumed.
864 1109
1110After loading the calendar, the hooks given by the variable
1111`calendar-load-hook' are run. This the place to add key bindings to the
1112calendar-mode-map.
1113
865After preparing the calendar window initially, the hooks given by the variable 1114After preparing the calendar window initially, the hooks given by the variable
866`initial-calendar-window-hook' are run. 1115`initial-calendar-window-hook' are run.
867 1116
@@ -872,25 +1121,42 @@ in the window. If it is not visible, the hooks given by the variable
872`today-visible-calendar-hook' to 'calendar-star-date will cause today's date 1121`today-visible-calendar-hook' to 'calendar-star-date will cause today's date
873to be replaced by asterisks to highlight it whenever it is in the window." 1122to be replaced by asterisks to highlight it whenever it is in the window."
874 (interactive "P") 1123 (interactive "P")
875 (setq arg (if arg (prefix-numeric-value arg) 0))
876 (set-buffer (get-buffer-create calendar-buffer)) 1124 (set-buffer (get-buffer-create calendar-buffer))
877 (calendar-mode) 1125 (calendar-mode)
878 (setq calendar-window-configuration (current-window-configuration)) 1126 (setq calendar-window-configuration (current-window-configuration))
879 (let ((pop-up-windows t) 1127 (let* ((completion-ignore-case t)
880 (split-height-threshold 1000)) 1128 (pop-up-windows t)
1129 (split-height-threshold 1000)
1130 (date (calendar-current-date))
1131 (month
1132 (if arg
1133 (cdr (assoc
1134 (capitalize
1135 (completing-read
1136 "Month name: "
1137 (mapcar 'list (append calendar-month-name-array nil))
1138 nil t))
1139 (calendar-make-alist calendar-month-name-array)))
1140 (extract-calendar-month date)))
1141 (year
1142 (if arg
1143 (calendar-read
1144 "Year (>0): "
1145 '(lambda (x) (> x 0))
1146 (int-to-string (extract-calendar-year date)))
1147 (extract-calendar-year date))))
881 (pop-to-buffer calendar-buffer) 1148 (pop-to-buffer calendar-buffer)
882 (regenerate-calendar-window arg) 1149 (generate-calendar-window month year)
883 (let ((date (list current-month current-day current-year))) 1150 (if (and view-diary-entries-initially (calendar-date-is-visible-p date))
884 (if (and view-diary-entries-initially (calendar-date-is-visible-p date)) 1151 (view-diary-entries
885 (view-diary-entries 1152 (if (vectorp number-of-diary-entries)
886 (if (vectorp number-of-diary-entries) 1153 (aref number-of-diary-entries (calendar-day-of-week date))
887 (aref number-of-diary-entries (calendar-day-of-week date)) 1154 number-of-diary-entries))))
888 number-of-diary-entries)))) 1155 (let* ((diary-buffer (get-file-buffer diary-file))
889 (let* ((diary-buffer (get-file-buffer diary-file)) 1156 (diary-window (if diary-buffer (get-buffer-window diary-buffer)))
890 (diary-window (if diary-buffer (get-buffer-window diary-buffer))) 1157 (split-height-threshold (if diary-window 2 1000)))
891 (split-height-threshold (if diary-window 2 1000))) 1158 (if view-calendar-holidays-initially
892 (if view-calendar-holidays-initially 1159 (list-calendar-holidays)))
893 (list-calendar-holidays))))
894 (run-hooks 'initial-calendar-window-hook)) 1160 (run-hooks 'initial-calendar-window-hook))
895 1161
896(autoload 'view-diary-entries "diary" 1162(autoload 'view-diary-entries "diary"
@@ -900,6 +1166,56 @@ the date indicated by the cursor position in the displayed three-month
900calendar." 1166calendar."
901 t) 1167 t)
902 1168
1169(autoload 'calendar-sunrise-sunset "solar"
1170 "Local time of sunrise and sunset for date under cursor."
1171 t)
1172
1173(autoload 'calendar-phases-of-moon "lunar"
1174 "Create a buffer of the phases of the moon for the current calendar window."
1175 t)
1176
1177(autoload 'calendar-print-french-date "cal-french"
1178 "Show the French Revolutionary calendar equivalent of the date under the
1179cursor."
1180 t)
1181
1182(autoload 'calendar-goto-french-date "cal-french"
1183 "Move cursor to French Revolutionary date."
1184 t)
1185
1186(autoload 'calendar-print-mayan-date "cal-mayan"
1187 "Show the Mayan long count, Tzolkin, and Haab equivalents of the date
1188under the cursor."
1189 t)
1190
1191(autoload 'calendar-goto-mayan-long-count-date "cal-mayan"
1192 "Move cursor to Mayan long count date."
1193 t)
1194
1195(autoload 'calendar-next-haab-date "cal-mayan"
1196 "Move cursor to next instance of Mayan Haab date."
1197 t)
1198
1199(autoload 'calendar-previous-haab-date "cal-mayan"
1200 "Move cursor to previous instance of Mayan Haab date."
1201 t)
1202
1203(autoload 'calendar-next-tzolkin-date "cal-mayan"
1204 "Move cursor to next instance of Mayan Tzolkin date."
1205 t)
1206
1207(autoload 'calendar-previous-tzolkin-date "cal-mayan"
1208 "Move cursor to previous instance of Mayan Tzolkin date."
1209 t)
1210
1211(autoload 'calendar-next-calendar-round-date "cal-mayan"
1212 "Move cursor to next instance of Mayan Haab/Tzoklin combination."
1213 t)
1214
1215(autoload 'calendar-previous-calendar-round-date "cal-mayan"
1216 "Move cursor to previous instance of Mayan Haab/Tzoklin combination."
1217 t)
1218
903(autoload 'show-all-diary-entries "diary" 1219(autoload 'show-all-diary-entries "diary"
904 "Show all of the diary entries in the diary-file. 1220 "Show all of the diary entries in the diary-file.
905This function gets rid of the selective display of the diary-file so that 1221This function gets rid of the selective display of the diary-file so that
@@ -912,60 +1228,60 @@ is created."
912Each entry in diary-file visible in the calendar window is marked." 1228Each entry in diary-file visible in the calendar window is marked."
913 t) 1229 t)
914 1230
915(autoload 'insert-diary-entry "diary" 1231(autoload 'insert-diary-entry "diary-insert"
916 "Insert a diary entry for the date indicated by point." 1232 "Insert a diary entry for the date indicated by point."
917 t) 1233 t)
918 1234
919(autoload 'insert-weekly-diary-entry "diary" 1235(autoload 'insert-weekly-diary-entry "diary-insert"
920 "Insert a weekly diary entry for the day of the week indicated by point." 1236 "Insert a weekly diary entry for the day of the week indicated by point."
921 t) 1237 t)
922 1238
923(autoload 'insert-monthly-diary-entry "diary" 1239(autoload 'insert-monthly-diary-entry "diary-insert"
924 "Insert a monthly diary entry for the day of the month indicated by point." 1240 "Insert a monthly diary entry for the day of the month indicated by point."
925 t) 1241 t)
926 1242
927(autoload 'insert-yearly-diary-entry "diary" 1243(autoload 'insert-yearly-diary-entry "diary-insert"
928 "Insert an annual diary entry for the day of the year indicated by point." 1244 "Insert an annual diary entry for the day of the year indicated by point."
929 t) 1245 t)
930 1246
931(autoload 'insert-anniversary-diary-entry "diary" 1247(autoload 'insert-anniversary-diary-entry "diary-insert"
932 "Insert an anniversary diary entry for the date indicated by point." 1248 "Insert an anniversary diary entry for the date indicated by point."
933 t) 1249 t)
934 1250
935(autoload 'insert-block-diary-entry "diary" 1251(autoload 'insert-block-diary-entry "diary-insert"
936 "Insert a block diary entry for the dates indicated by point and mark." 1252 "Insert a block diary entry for the dates indicated by point and mark."
937 t) 1253 t)
938 1254
939(autoload 'insert-cyclic-diary-entry "diary" 1255(autoload 'insert-cyclic-diary-entry "diary-insert"
940 "Insert a cyclic diary entry starting at the date indicated by point." 1256 "Insert a cyclic diary entry starting at the date indicated by point."
941 t) 1257 t)
942 1258
943(autoload 'insert-hebrew-diary-entry "diary" 1259(autoload 'insert-hebrew-diary-entry "diary-insert"
944 "Insert a diary entry for the Hebrew date corresponding to the date 1260 "Insert a diary entry for the Hebrew date corresponding to the date
945indicated by point." 1261indicated by point."
946 t) 1262 t)
947 1263
948(autoload 'insert-monthly-hebrew-diary-entry "diary" 1264(autoload 'insert-monthly-hebrew-diary-entry "diary-insert"
949 "Insert a monthly diary entry for the day of the Hebrew month corresponding 1265 "Insert a monthly diary entry for the day of the Hebrew month corresponding
950to the date indicated by point." 1266to the date indicated by point."
951 t) 1267 t)
952 1268
953(autoload 'insert-yearly-hebrew-diary-entry "diary" 1269(autoload 'insert-yearly-hebrew-diary-entry "diary-insert"
954 "Insert an annual diary entry for the day of the Hebrew year corresponding 1270 "Insert an annual diary entry for the day of the Hebrew year corresponding
955to the date indicated by point." 1271to the date indicated by point."
956 t) 1272 t)
957 1273
958(autoload 'insert-islamic-diary-entry "diary" 1274(autoload 'insert-islamic-diary-entry "diary-insert"
959 "Insert a diary entry for the Islamic date corresponding to the date 1275 "Insert a diary entry for the Islamic date corresponding to the date
960indicated by point." 1276indicated by point."
961 t) 1277 t)
962 1278
963(autoload 'insert-monthly-islamic-diary-entry "diary" 1279(autoload 'insert-monthly-islamic-diary-entry "diary-insert"
964 "Insert a monthly diary entry for the day of the Islamic month corresponding 1280 "Insert a monthly diary entry for the day of the Islamic month corresponding
965to the date indicated by point." 1281to the date indicated by point."
966 t) 1282 t)
967 1283
968(autoload 'insert-yearly-islamic-diary-entry "diary" 1284(autoload 'insert-yearly-islamic-diary-entry "diary-insert"
969 "Insert an annual diary entry for the day of the Islamic year corresponding 1285 "Insert an annual diary entry for the day of the Islamic year corresponding
970to the date indicated by point." 1286to the date indicated by point."
971 t) 1287 t)
@@ -984,22 +1300,23 @@ holidays are found, nil if not."
984 "Find holidays for the date specified by the cursor in the calendar window." 1300 "Find holidays for the date specified by the cursor in the calendar window."
985 t) 1301 t)
986 1302
987(defun regenerate-calendar-window (&optional arg) 1303(defun generate-calendar-window (&optional mon yr)
988 "Generate the calendar window, offset from the current date by ARG months." 1304 "Generate the calendar window for the current date.
989 (if (not arg) (setq arg 0)) 1305Or, for optional MON, YR."
990 (let* ((buffer-read-only nil) 1306 (let* ((buffer-read-only nil)
991 (today-visible (and (<= arg 1) (>= arg -1)))
992 (today (calendar-current-date)) 1307 (today (calendar-current-date))
993 (month (extract-calendar-month today)) 1308 (month (extract-calendar-month today))
994 (day (extract-calendar-day today)) 1309 (day (extract-calendar-day today))
995 (year (extract-calendar-year today)) 1310 (year (extract-calendar-year today))
1311 (today-visible
1312 (or (not mon)
1313 (let ((offset (calendar-interval mon yr month year)))
1314 (and (<= offset 1) (>= offset -1)))))
996 (day-in-week (calendar-day-of-week today))) 1315 (day-in-week (calendar-day-of-week today)))
997 (update-calendar-mode-line) 1316 (update-calendar-mode-line)
998 (setq current-month month) 1317 (if mon
999 (setq current-day day) 1318 (generate-calendar mon yr)
1000 (setq current-year year) 1319 (generate-calendar month year))
1001 (increment-calendar-month month year arg)
1002 (generate-calendar month year)
1003 (calendar-cursor-to-visible-date 1320 (calendar-cursor-to-visible-date
1004 (if today-visible today (list displayed-month 1 displayed-year))) 1321 (if today-visible today (list displayed-month 1 displayed-year)))
1005 (set-buffer-modified-p nil) 1322 (set-buffer-modified-p nil)
@@ -1078,9 +1395,7 @@ the inserted text. Value is always t."
1078 "Redraw the calendar display." 1395 "Redraw the calendar display."
1079 (interactive) 1396 (interactive)
1080 (let ((cursor-date (calendar-cursor-to-date))) 1397 (let ((cursor-date (calendar-cursor-to-date)))
1081 (regenerate-calendar-window 1398 (generate-calendar-window displayed-month displayed-year)
1082 (calendar-interval current-month current-year
1083 displayed-month displayed-year))
1084 (calendar-cursor-to-visible-date cursor-date))) 1399 (calendar-cursor-to-visible-date cursor-date)))
1085 1400
1086(defvar calendar-mode-map nil) 1401(defvar calendar-mode-map nil)
@@ -1106,11 +1421,11 @@ the inserted text. Value is always t."
1106 (define-key calendar-mode-map "\C-v" 'scroll-calendar-left-three-months) 1421 (define-key calendar-mode-map "\C-v" 'scroll-calendar-left-three-months)
1107 (define-key calendar-mode-map "\C-b" 'calendar-backward-day) 1422 (define-key calendar-mode-map "\C-b" 'calendar-backward-day)
1108 (define-key calendar-mode-map "\C-p" 'calendar-backward-week) 1423 (define-key calendar-mode-map "\C-p" 'calendar-backward-week)
1109 (define-key calendar-mode-map "\e[" 'calendar-backward-month) 1424 (define-key calendar-mode-map "\e{" 'calendar-backward-month)
1110 (define-key calendar-mode-map "\C-x[" 'calendar-backward-year) 1425 (define-key calendar-mode-map "\C-x[" 'calendar-backward-year)
1111 (define-key calendar-mode-map "\C-f" 'calendar-forward-day) 1426 (define-key calendar-mode-map "\C-f" 'calendar-forward-day)
1112 (define-key calendar-mode-map "\C-n" 'calendar-forward-week) 1427 (define-key calendar-mode-map "\C-n" 'calendar-forward-week)
1113 (define-key calendar-mode-map "\e]" 'calendar-forward-month) 1428 (define-key calendar-mode-map "\e}" 'calendar-forward-month)
1114 (define-key calendar-mode-map "\C-x]" 'calendar-forward-year) 1429 (define-key calendar-mode-map "\C-x]" 'calendar-forward-year)
1115 (define-key calendar-mode-map "\C-a" 'calendar-beginning-of-week) 1430 (define-key calendar-mode-map "\C-a" 'calendar-beginning-of-week)
1116 (define-key calendar-mode-map "\C-e" 'calendar-end-of-week) 1431 (define-key calendar-mode-map "\C-e" 'calendar-end-of-week)
@@ -1120,44 +1435,57 @@ the inserted text. Value is always t."
1120 (define-key calendar-mode-map "\e>" 'calendar-end-of-year) 1435 (define-key calendar-mode-map "\e>" 'calendar-end-of-year)
1121 (define-key calendar-mode-map "\C-@" 'calendar-set-mark) 1436 (define-key calendar-mode-map "\C-@" 'calendar-set-mark)
1122 (define-key calendar-mode-map "\C-x\C-x" 'calendar-exchange-point-and-mark) 1437 (define-key calendar-mode-map "\C-x\C-x" 'calendar-exchange-point-and-mark)
1123 (define-key calendar-mode-map "\e=" 'calendar-count-days-region) 1438 (define-key calendar-mode-map "\e=" 'calendar-count-days-region)
1124 (define-key calendar-mode-map "gd" 'calendar-goto-date) 1439 (define-key calendar-mode-map "gd" 'calendar-goto-date)
1125 (define-key calendar-mode-map "gJ" 'calendar-goto-julian-date) 1440 (define-key calendar-mode-map "gj" 'calendar-goto-julian-date)
1126 (define-key calendar-mode-map "gH" 'calendar-goto-hebrew-date) 1441 (define-key calendar-mode-map "ga" 'calendar-goto-astro-day-number)
1127 (define-key calendar-mode-map "gI" 'calendar-goto-islamic-date) 1442 (define-key calendar-mode-map "gh" 'calendar-goto-hebrew-date)
1128 (define-key calendar-mode-map "gC" 'calendar-goto-iso-date) 1443 (define-key calendar-mode-map "gi" 'calendar-goto-islamic-date)
1129 (define-key calendar-mode-map " " 'scroll-other-window) 1444 (define-key calendar-mode-map "gc" 'calendar-goto-iso-date)
1445 (define-key calendar-mode-map "gf" 'calendar-goto-french-date)
1446 (define-key calendar-mode-map "gml" 'calendar-goto-mayan-long-count-date)
1447 (define-key calendar-mode-map "gmpc" 'calendar-previous-calendar-round-date)
1448 (define-key calendar-mode-map "gmnc" 'calendar-next-calendar-round-date)
1449 (define-key calendar-mode-map "gmph" 'calendar-previous-haab-date)
1450 (define-key calendar-mode-map "gmnh" 'calendar-next-haab-date)
1451 (define-key calendar-mode-map "gmpt" 'calendar-previous-tzolkin-date)
1452 (define-key calendar-mode-map "gmnt" 'calendar-next-tzolkin-date)
1453 (define-key calendar-mode-map "S" 'calendar-sunrise-sunset)
1454 (define-key calendar-mode-map "M" 'calendar-phases-of-moon)
1455 (define-key calendar-mode-map " " 'scroll-other-window)
1130 (define-key calendar-mode-map "\C-c\C-l" 'redraw-calendar) 1456 (define-key calendar-mode-map "\C-c\C-l" 'redraw-calendar)
1131 (define-key calendar-mode-map "c" 'calendar-current-month) 1457 (define-key calendar-mode-map "." 'calendar-current-month)
1132 (define-key calendar-mode-map "o" 'calendar-other-month) 1458 (define-key calendar-mode-map "o" 'calendar-other-month)
1133 (define-key calendar-mode-map "q" 'exit-calendar) 1459 (define-key calendar-mode-map "q" 'exit-calendar)
1134 (define-key calendar-mode-map "a" 'list-calendar-holidays) 1460 (define-key calendar-mode-map "a" 'list-calendar-holidays)
1135 (define-key calendar-mode-map "h" 'calendar-cursor-holidays) 1461 (define-key calendar-mode-map "h" 'calendar-cursor-holidays)
1136 (define-key calendar-mode-map "x" 'mark-calendar-holidays) 1462 (define-key calendar-mode-map "x" 'mark-calendar-holidays)
1137 (define-key calendar-mode-map "u" 'calendar-unmark) 1463 (define-key calendar-mode-map "u" 'calendar-unmark)
1138 (define-key calendar-mode-map "m" 'mark-diary-entries) 1464 (define-key calendar-mode-map "m" 'mark-diary-entries)
1139 (define-key calendar-mode-map "d" 'view-diary-entries) 1465 (define-key calendar-mode-map "d" 'view-diary-entries)
1140 (define-key calendar-mode-map "s" 'show-all-diary-entries) 1466 (define-key calendar-mode-map "s" 'show-all-diary-entries)
1141 (define-key calendar-mode-map "D" 'cursor-to-calendar-day-of-year) 1467 (define-key calendar-mode-map "pd" 'calendar-print-day-of-year)
1142 (define-key calendar-mode-map "C" 'cursor-to-iso-calendar-date) 1468 (define-key calendar-mode-map "pc" 'calendar-print-iso-date)
1143 (define-key calendar-mode-map "J" 'cursor-to-julian-calendar-date) 1469 (define-key calendar-mode-map "pj" 'calendar-print-julian-date)
1144 (define-key calendar-mode-map "H" 'cursor-to-hebrew-calendar-date) 1470 (define-key calendar-mode-map "pa" 'calendar-print-astro-day-number)
1145 (define-key calendar-mode-map "I" 'cursor-to-islamic-calendar-date) 1471 (define-key calendar-mode-map "ph" 'calendar-print-hebrew-date)
1146 (define-key calendar-mode-map "F" 'cursor-to-french-calendar-date) 1472 (define-key calendar-mode-map "pi" 'calendar-print-islamic-date)
1147 (define-key calendar-mode-map "\C-cd" 'insert-diary-entry) 1473 (define-key calendar-mode-map "pf" 'calendar-print-french-date)
1148 (define-key calendar-mode-map "\C-cw" 'insert-weekly-diary-entry) 1474 (define-key calendar-mode-map "pm" 'calendar-print-mayan-date)
1149 (define-key calendar-mode-map "\C-cm" 'insert-monthly-diary-entry) 1475 (define-key calendar-mode-map "id" 'insert-diary-entry)
1150 (define-key calendar-mode-map "\C-cy" 'insert-yearly-diary-entry) 1476 (define-key calendar-mode-map "iw" 'insert-weekly-diary-entry)
1151 (define-key calendar-mode-map "\C-ca" 'insert-anniversary-diary-entry) 1477 (define-key calendar-mode-map "im" 'insert-monthly-diary-entry)
1152 (define-key calendar-mode-map "\C-cb" 'insert-block-diary-entry) 1478 (define-key calendar-mode-map "iy" 'insert-yearly-diary-entry)
1153 (define-key calendar-mode-map "\C-cc" 'insert-cyclic-diary-entry) 1479 (define-key calendar-mode-map "ia" 'insert-anniversary-diary-entry)
1154 (define-key calendar-mode-map "\C-cHd" 'insert-hebrew-diary-entry) 1480 (define-key calendar-mode-map "ib" 'insert-block-diary-entry)
1155 (define-key calendar-mode-map "\C-cHm" 'insert-monthly-hebrew-diary-entry) 1481 (define-key calendar-mode-map "ic" 'insert-cyclic-diary-entry)
1156 (define-key calendar-mode-map "\C-cHy" 'insert-yearly-hebrew-diary-entry) 1482 (define-key calendar-mode-map "ihd" 'insert-hebrew-diary-entry)
1157 (define-key calendar-mode-map "\C-cId" 'insert-islamic-diary-entry) 1483 (define-key calendar-mode-map "ihm" 'insert-monthly-hebrew-diary-entry)
1158 (define-key calendar-mode-map "\C-cIm" 'insert-monthly-islamic-diary-entry) 1484 (define-key calendar-mode-map "ihy" 'insert-yearly-hebrew-diary-entry)
1159 (define-key calendar-mode-map "\C-cIy" 'insert-yearly-islamic-diary-entry) 1485 (define-key calendar-mode-map "iid" 'insert-islamic-diary-entry)
1160 (define-key calendar-mode-map "?" 'describe-calendar-mode)) 1486 (define-key calendar-mode-map "iim" 'insert-monthly-islamic-diary-entry)
1487 (define-key calendar-mode-map "iiy" 'insert-yearly-islamic-diary-entry)
1488 (define-key calendar-mode-map "?" 'describe-calendar-mode))
1161 1489
1162(defun describe-calendar-mode () 1490(defun describe-calendar-mode ()
1163 "Create a help buffer with a brief description of the calendar-mode." 1491 "Create a help buffer with a brief description of the calendar-mode."
@@ -1175,12 +1503,16 @@ the inserted text. Value is always t."
1175(put 'calendar-mode 'mode-class 'special) 1503(put 'calendar-mode 'mode-class 'special)
1176 1504
1177(defvar calendar-mode-line-format 1505(defvar calendar-mode-line-format
1178 (substitute-command-keys 1506 (list
1179 "\\<calendar-mode-map>\\[scroll-calendar-left] Calendar \\[describe-calendar-mode] help/\\[calendar-other-month] other/\\[calendar-current-month] current %17s \\[scroll-calendar-right]") 1507 (substitute-command-keys "\\<calendar-mode-map>\\[scroll-calendar-left]")
1508 "Calendar"
1509 (substitute-command-keys "\\<calendar-mode-map>\\[describe-calendar-mode] help/\\[calendar-other-month] other/\\[calendar-current-month] current")
1510 '(calendar-date-string (calendar-current-date) t)
1511 (substitute-command-keys "\\<calendar-mode-map>\\[scroll-calendar-right]"))
1180 "The mode line of the calendar buffer.") 1512 "The mode line of the calendar buffer.")
1181 1513
1182(defun calendar-mode () 1514(defun calendar-mode ()
1183 "A major mode for the sliding calendar window and diary. 1515 "A major mode for the calendar window.
1184 1516
1185The commands for cursor movement are:\\<calendar-mode-map> 1517The commands for cursor movement are:\\<calendar-mode-map>
1186 1518
@@ -1191,13 +1523,27 @@ The commands for cursor movement are:\\<calendar-mode-map>
1191 \\[calendar-beginning-of-week] beginning of week \\[calendar-end-of-week] end of week 1523 \\[calendar-beginning-of-week] beginning of week \\[calendar-end-of-week] end of week
1192 \\[calendar-beginning-of-month] beginning of month \\[calendar-end-of-month] end of month 1524 \\[calendar-beginning-of-month] beginning of month \\[calendar-end-of-month] end of month
1193 \\[calendar-beginning-of-year] beginning of year \\[calendar-end-of-year] end of year 1525 \\[calendar-beginning-of-year] beginning of year \\[calendar-end-of-year] end of year
1194 \\[calendar-goto-date] go to date \\[calendar-goto-julian-date] go to Julian date 1526
1527 \\[calendar-goto-date] go to date
1528
1529 \\[calendar-goto-julian-date] go to Julian date \\[calendar-goto-astro-day-number] go to astronomical (Julian) day number
1195 \\[calendar-goto-hebrew-date] go to Hebrew date \\[calendar-goto-islamic-date] go to Islamic date 1530 \\[calendar-goto-hebrew-date] go to Hebrew date \\[calendar-goto-islamic-date] go to Islamic date
1196 \\[calendar-goto-iso-date] go to ISO date 1531 \\[calendar-goto-iso-date] go to ISO date \\[calendar-goto-french-date] go to French Revolutionary date
1532
1533 \\[calendar-goto-mayan-long-count-date] go to Mayan Long Count date
1534 \\[calendar-next-haab-date] go to next occurrence of Mayan Haab date
1535 \\[calendar-previous-haab-date] go to previous occurrence of Mayan Haab date
1536 \\[calendar-next-tzolkin-date] go to next occurrence of Mayan Tzolkin date
1537 \\[calendar-previous-tzolkin-date] go to previous occurrence of Mayan Tzolkin date
1538 \\[calendar-next-calendar-round-date] go to next occurrence of Mayan Calendar Round date
1539 \\[calendar-previous-calendar-round-date] go to previous occurrence of Mayan Calendar Round date
1197 1540
1198You can mark a date in the calendar and switch the point and mark: 1541You can mark a date in the calendar and switch the point and mark:
1542
1199 \\[calendar-set-mark] mark date \\[calendar-exchange-point-and-mark] exchange point and mark 1543 \\[calendar-set-mark] mark date \\[calendar-exchange-point-and-mark] exchange point and mark
1544
1200You can determine the number of days (inclusive) between the point and mark by 1545You can determine the number of days (inclusive) between the point and mark by
1546
1201 \\[calendar-count-days-region] count days in the region 1547 \\[calendar-count-days-region] count days in the region
1202 1548
1203The commands for calendar movement are: 1549The commands for calendar movement are:
@@ -1292,16 +1638,32 @@ argument; with no prefix argument, the diary entries are marking.
1292The day number in the year and the number of days remaining in the year can be 1638The day number in the year and the number of days remaining in the year can be
1293determined by 1639determined by
1294 1640
1295 \\[cursor-to-calendar-day-of-year] show day number and the number of days remaining in the year 1641 \\[calendar-print-day-of-year] show day number and the number of days remaining in the year
1642
1643Equivalent dates on the ISO commercial, Julian, Hebrew, Islamic, French
1644Revolutionary, and Mayan calendars can be determined by
1296 1645
1297Equivalent dates on the ISO commercial, Julian, Hebrew, Islamic and French 1646 \\[calendar-print-iso-date] show equivalent date on the ISO commercial calendar
1298Revolutionary calendars can be determined by 1647 \\[calendar-print-julian-date] show equivalent date on the Julian calendar
1648 \\[calendar-print-hebrew-date] show equivalent date on the Hebrew calendar
1649 \\[calendar-print-islamic-date] show equivalent date on the Islamic calendar
1650 \\[calendar-print-french-date] show equivalent date on the French Revolutionary calendar
1651 \\[calendar-print-mayan-date] show equivalent date on the Mayan calendar
1299 1652
1300 \\[cursor-to-iso-calendar-date] show equivalent date on the ISO commercial calendar 1653The astromonical (Julian) day number of a date is found with
1301 \\[cursor-to-julian-calendar-date] show equivalent date on the Julian calendar 1654
1302 \\[cursor-to-hebrew-calendar-date] show equivalent date on the Hebrew calendar 1655 \\[calendar-print-astro-day-number] show equivalent astronomical (Julian) day number
1303 \\[cursor-to-islamic-calendar-date] show equivalent date on the Islamic calendar 1656
1304 \\[cursor-to-french-calendar-date] show equivalent date on the French Revolutionary calendar 1657To find the times of sunrise and sunset and lunar phases use
1658
1659 \\[calendar-sunrise-sunset] show times of sunrise and sunset
1660 \\[calendar-phases-of-moon] show times of quarters of the moon
1661
1662The times given will be at latitude `solar-latitude', longitude
1663`solar-longitude' in time zone `solar-time-zone'. These variables, and the
1664variables `solar-location-name', `solar-standard-time-zone-name',
1665`solar-daylight-time-zone-name', `solar-daylight-savings-starts', and
1666`solar-daylight-savings-ends', should be set for your location.
1305 1667
1306To exit from the calendar use 1668To exit from the calendar use
1307 1669
@@ -1321,50 +1683,51 @@ entries will be displayed Monday through Thursday, Friday through Monday's
1321entries will be displayed on Friday, while on Saturday only that day's 1683entries will be displayed on Friday, while on Saturday only that day's
1322entries will be displayed. 1684entries will be displayed.
1323 1685
1324The variable `view-calendar-holidays-initially' can be set to t to cause 1686The variable `view-calendar-holidays-initially' can be set to t to cause the
1325the holidays for the current three month period will be displayed on entry 1687holidays for the current three month period will be displayed on entry to the
1326to the calendar. The holidays are displayed in another window. 1688calendar. The holidays are displayed in another window.
1327 1689
1328The variable `mark-diary-entries-in-calendar' can be set to t to cause any 1690The variable `mark-diary-entries-in-calendar' can be set to t to cause any
1329dates visible with calendar entries to be marked with the symbol specified 1691dates visible with calendar entries to be marked with the symbol specified by
1330by the variable `diary-entry-marker', normally a plus sign. 1692the variable `diary-entry-marker', normally a plus sign.
1331 1693
1332The variable `initial-calendar-window-hook', whose default value is nil, 1694The variable `calendar-load-hook', whose default value is nil, is list of
1333is list of functions to be called when the calendar window is first opened. 1695functions to be called when the calendar is first loaded.
1334The functions invoked are called after the calendar window is opened, but 1696
1335once opened is never called again. Leaving the calendar with the `q' command 1697The variable `initial-calendar-window-hook', whose default value is nil, is
1336and reentering it will cause these functions to be called again. 1698list of functions to be called when the calendar window is first opened. The
1337 1699functions invoked are called after the calendar window is opened, but once
1338The variable `today-visible-calendar-hook', whose default value is nil, 1700opened is never called again. Leaving the calendar with the `q' command and
1339is the list of functions called after the calendar buffer has been prepared 1701reentering it will cause these functions to be called again.
1340with the calendar when the current date is visible in the window. 1702
1341This can be used, for example, to replace today's date with asterisks; a 1703The variable `today-visible-calendar-hook', whose default value is nil, is the
1342function calendar-star-date is included for this purpose: 1704list of functions called after the calendar buffer has been prepared with the
1343 (setq today-visible-calendar-hook 'calendar-star-date) 1705calendar when the current date is visible in the window. This can be used,
1344It could also be used to mark the current date with `*'; a function is also 1706for example, to replace today's date with asterisks; a function
1345provided for this: 1707calendar-star-date is included for this purpose: (setq
1346 (setq today-visible-calendar-hook 'calendar-mark-today) 1708today-visible-calendar-hook 'calendar-star-date) It could also be used to mark
1347 1709the current date with `*'; a function is also provided for this: (setq
1348The variable `today-invisible-calendar-hook', whose default value is nil, 1710today-visible-calendar-hook 'calendar-mark-today)
1349is the list of functions called after the calendar buffer has been prepared 1711
1350with the calendar when the current date is not visible in the window. 1712The variable `today-invisible-calendar-hook', whose default value is nil, is
1351 1713the list of functions called after the calendar buffer has been prepared with
1352The variable `diary-display-hook' is the list of functions called 1714the calendar when the current date is not visible in the window.
1353after the diary buffer is prepared. The default value simply displays the 1715
1354diary file using selective-display to conceal irrelevant diary entries. An 1716The variable `diary-display-hook' is the list of functions called after the
1355alternative function `fancy-diary-display' is provided that, when 1717diary buffer is prepared. The default value simply displays the diary file
1356used as the `diary-display-hook', causes a noneditable buffer to be 1718using selective-display to conceal irrelevant diary entries. An alternative
1357prepared with a neatly organized day-by-day listing of relevant diary 1719function `fancy-diary-display' is provided that, when used as the
1358entries, together with any known holidays. The inclusion of the holidays 1720`diary-display-hook', causes a noneditable buffer to be prepared with a neatly
1359slows this fancy display of the diary; to speed it up, set the variable 1721organized day-by-day listing of relevant diary entries, together with any
1360`holidays-in-diary-buffer' to nil. 1722known holidays. The inclusion of the holidays slows this fancy display of the
1361 1723diary; to speed it up, set the variable `holidays-in-diary-buffer' to nil.
1362The variable `print-diary-entries-hook' is the list of functions called 1724
1363after a temporary buffer is prepared with the diary entries currently 1725The variable `print-diary-entries-hook' is the list of functions called after
1364visible in the diary buffer. The default value of this hook adds a heading 1726a temporary buffer is prepared with the diary entries currently visible in the
1365(composed from the diary buffer's mode line), does the printing with the 1727diary buffer. The default value of this hook adds a heading (composed from
1366command lpr-buffer, and kills the temporary buffer. Other uses might 1728the diary buffer's mode line), does the printing with the command lpr-buffer,
1367include, for example, rearranging the lines into order by day and time. 1729and kills the temporary buffer. Other uses might include, for example,
1730rearranging the lines into order by day and time.
1368 1731
1369The Gregorian calendar is assumed." 1732The Gregorian calendar is assumed."
1370 1733
@@ -1374,25 +1737,47 @@ The Gregorian calendar is assumed."
1374 (use-local-map calendar-mode-map) 1737 (use-local-map calendar-mode-map)
1375 (setq buffer-read-only t) 1738 (setq buffer-read-only t)
1376 (setq indent-tabs-mode nil) 1739 (setq indent-tabs-mode nil)
1740 (update-calendar-mode-line)
1377 (make-local-variable 'calendar-window-configuration);; Windows on entry. 1741 (make-local-variable 'calendar-window-configuration);; Windows on entry.
1378 (make-local-variable 'calendar-mark-ring) 1742 (make-local-variable 'calendar-mark-ring)
1379 (make-local-variable 'current-month) ;; Current month.
1380 (make-local-variable 'current-day) ;; Current day.
1381 (make-local-variable 'current-year) ;; Current year.
1382 (make-local-variable 'displayed-month);; Month in middle of window. 1743 (make-local-variable 'displayed-month);; Month in middle of window.
1383 (make-local-variable 'displayed-year));; Year in middle of window. 1744 (make-local-variable 'displayed-year));; Year in middle of window.
1384 1745
1746(defun calendar-string-spread (strings char length)
1747 "A list of STRINGS is concatenated separated by copies of CHAR so that it
1748fills LENGTH; there must be at least 2 strings. The effect is like mapconcat
1749but the separating pieces are as balanced as possible. Each item of STRINGS
1750is evaluated before concatenation so it can actually be an expression that
1751evaluates to a string. If LENGTH is too short, the STRINGS are just
1752concatenated and the result truncated."
1753;; The algorithm is based on equation (3.25) on page 85 of Concrete
1754;; Mathematics by Ronald L. Graham, Donald E. Knuth, and Oren Patashnik,
1755;; Addison-Wesley, Reading, MA, 1989
1756 (let* ((strings (mapcar 'eval strings))
1757 (n (- length (length (apply 'concat strings))))
1758 (m (1- (length strings)))
1759 (s (car strings))
1760 (strings (cdr strings))
1761 (i 0))
1762 (while strings
1763 (setq s (concat s
1764 (make-string (max 0 (/ (+ n i) m)) char)
1765 (car strings)))
1766 (setq i (1+ i))
1767 (setq strings (cdr strings)))
1768 (substring s 0 length)))
1769
1385(defun update-calendar-mode-line () 1770(defun update-calendar-mode-line ()
1386 "Update the calendar mode line with the current date and date style." 1771 "Update the calendar mode line with the current date and date style."
1387 (if (bufferp (get-buffer calendar-buffer)) 1772 (if (bufferp (get-buffer calendar-buffer))
1388 (save-excursion 1773 (save-excursion
1389 (set-buffer calendar-buffer) 1774 (set-buffer calendar-buffer)
1390 (setq mode-line-format 1775 (setq mode-line-format
1391 (format calendar-mode-line-format 1776 (calendar-string-spread
1392 (calendar-date-string (calendar-current-date) t)))))) 1777 calendar-mode-line-format ? (frame-width))))))
1393 1778
1394(defun exit-calendar () 1779(defun exit-calendar ()
1395 "Get out of the calendar window and destroy it and related buffers." 1780 "Get out of the calendar window and bury it and related buffers."
1396 (interactive) 1781 (interactive)
1397 (let ((diary-buffer (get-file-buffer diary-file)) 1782 (let ((diary-buffer (get-file-buffer diary-file))
1398 (d-buffer (get-buffer fancy-diary-buffer)) 1783 (d-buffer (get-buffer fancy-diary-buffer))
@@ -1400,26 +1785,26 @@ The Gregorian calendar is assumed."
1400 (if (not diary-buffer) 1785 (if (not diary-buffer)
1401 (progn 1786 (progn
1402 (set-window-configuration calendar-window-configuration) 1787 (set-window-configuration calendar-window-configuration)
1403 (kill-buffer calendar-buffer) 1788 (bury-buffer calendar-buffer)
1404 (if d-buffer (kill-buffer d-buffer)) 1789 (if d-buffer (bury-buffer d-buffer))
1405 (if h-buffer (kill-buffer h-buffer))) 1790 (if h-buffer (bury-buffer h-buffer)))
1406 (if (or (not (buffer-modified-p diary-buffer)) 1791 (if (or (not (buffer-modified-p diary-buffer))
1407 (yes-or-no-p "Diary modified; do you really want to exit the calendar? ")) 1792 (yes-or-no-p "Diary modified; do you really want to exit the calendar? "))
1408 (progn 1793 (progn
1409 (set-window-configuration calendar-window-configuration) 1794 (set-window-configuration calendar-window-configuration)
1410 (kill-buffer calendar-buffer) 1795 (bury-buffer calendar-buffer)
1411 (if d-buffer (kill-buffer d-buffer)) 1796 (if d-buffer (bury-buffer d-buffer))
1412 (if h-buffer (kill-buffer h-buffer)) 1797 (if h-buffer (bury-buffer h-buffer))
1413 (set-buffer diary-buffer) 1798 (set-buffer diary-buffer)
1414 (set-buffer-modified-p nil) 1799 (set-buffer-modified-p nil)
1415 (kill-buffer diary-buffer)))))) 1800 (bury-buffer diary-buffer))))))
1416 1801
1417(defun calendar-current-month () 1802(defun calendar-current-month ()
1418 "Reposition the calendar window so the current date is visible." 1803 "Reposition the calendar window so the current date is visible."
1419 (interactive) 1804 (interactive)
1420 (let ((today (calendar-current-date)));; The date might have changed. 1805 (let ((today (calendar-current-date)));; The date might have changed.
1421 (if (not (calendar-date-is-visible-p today)) 1806 (if (not (calendar-date-is-visible-p today))
1422 (regenerate-calendar-window) 1807 (generate-calendar-window)
1423 (update-calendar-mode-line) 1808 (update-calendar-mode-line)
1424 (calendar-cursor-to-visible-date today)))) 1809 (calendar-cursor-to-visible-date today))))
1425 1810
@@ -1471,9 +1856,8 @@ position of the cursor with respect to the calendar as well as possible."
1471 (today (calendar-current-date))) 1856 (today (calendar-current-date)))
1472 (if (/= arg 0) 1857 (if (/= arg 0)
1473 (progn 1858 (progn
1474 (regenerate-calendar-window 1859 (increment-calendar-month displayed-month displayed-year arg)
1475 (+ arg (calendar-interval current-month current-year 1860 (generate-calendar-window displayed-month displayed-year)
1476 displayed-month displayed-year)))
1477 (calendar-cursor-to-visible-date 1861 (calendar-cursor-to-visible-date
1478 (cond 1862 (cond
1479 ((calendar-date-is-visible-p old-date) old-date) 1863 ((calendar-date-is-visible-p old-date) old-date)
@@ -1520,11 +1904,6 @@ If in the calendar buffer, also sets the current date local variables."
1520 (string-to-int (substring date (match-beginning 3) (match-end 3)))) 1904 (string-to-int (substring date (match-beginning 3) (match-end 3))))
1521 (year 1905 (year
1522 (string-to-int (substring date (match-beginning 4) (match-end 4))))) 1906 (string-to-int (substring date (match-beginning 4) (match-end 4)))))
1523 (if (equal (current-buffer) (get-buffer calendar-buffer))
1524 (progn
1525 (setq current-month month)
1526 (setq current-day day)
1527 (setq current-year year)))
1528 (list month day year))) 1907 (list month day year)))
1529 1908
1530(defun calendar-cursor-to-date () 1909(defun calendar-cursor-to-date ()
@@ -1537,7 +1916,7 @@ Returns nil if the cursor is not on a specific day."
1537 (forward-char 1) 1916 (forward-char 1)
1538 (let* 1917 (let*
1539 ((day (string-to-int (buffer-substring (point) (+ 3 (point))))) 1918 ((day (string-to-int (buffer-substring (point) (+ 3 (point)))))
1540 (day (if (= 0 day) current-day day));; Starred date. 1919 (day (if (= 0 day) starred-day day))
1541 (segment (/ (current-column) 25)) 1920 (segment (/ (current-column) 25))
1542 (month (% (+ displayed-month segment -1) 12)) 1921 (month (% (+ displayed-month segment -1) 12))
1543 (month (if (= 0 month) 12 month)) 1922 (month (if (= 0 month) 12 month))
@@ -1746,15 +2125,15 @@ Gregorian date Sunday, December 31, 1 BC."
1746 (year (calendar-read 2125 (year (calendar-read
1747 "Year (>0): " 2126 "Year (>0): "
1748 '(lambda (x) (> x 0)) 2127 '(lambda (x) (> x 0))
1749 (int-to-string current-year)))) 2128 (int-to-string
2129 (extract-calendar-year (calendar-current-date))))))
1750 (list month year))) 2130 (list month year)))
1751 (if (and (= month displayed-month) 2131 (if (and (= month displayed-month)
1752 (= year displayed-year)) 2132 (= year displayed-year))
1753 nil 2133 nil
1754 (let ((old-date (calendar-cursor-to-date)) 2134 (let ((old-date (calendar-cursor-to-date))
1755 (today (calendar-current-date))) 2135 (today (calendar-current-date)))
1756 (regenerate-calendar-window 2136 (generate-calendar-window month year)
1757 (calendar-interval current-month current-year month year))
1758 (calendar-cursor-to-visible-date 2137 (calendar-cursor-to-visible-date
1759 (cond 2138 (cond
1760 ((calendar-date-is-visible-p old-date) old-date) 2139 ((calendar-date-is-visible-p old-date) old-date)
@@ -1823,27 +2202,31 @@ is a string to insert in the minibuffer before reading."
1823 (setq value (read-minibuffer prompt initial-contents))) 2202 (setq value (read-minibuffer prompt initial-contents)))
1824 value)) 2203 value))
1825 2204
2205(defun calendar-read-date ()
2206 "Prompt for Gregorian date. Returns a list (month day year)."
2207 (let* ((year (calendar-read
2208 "Year (>0): "
2209 '(lambda (x) (> x 0))
2210 (int-to-string (extract-calendar-year
2211 (calendar-current-date)))))
2212 (month-array calendar-month-name-array)
2213 (completion-ignore-case t)
2214 (month (cdr (assoc
2215 (capitalize
2216 (completing-read
2217 "Month name: "
2218 (mapcar 'list (append month-array nil))
2219 nil t))
2220 (calendar-make-alist month-array 1 'capitalize))))
2221 (last (calendar-last-day-of-month month year))
2222 (day (calendar-read
2223 (format "Day (1-%d): " last)
2224 '(lambda (x) (and (< 0 x) (<= x last))))))
2225 (list month day year)))
2226
1826(defun calendar-goto-date (date) 2227(defun calendar-goto-date (date)
1827 "Move cursor to DATE." 2228 "Move cursor to DATE."
1828 (interactive 2229 (interactive (list (calendar-read-date)))
1829 (let* ((year (calendar-read
1830 "Year (>0): "
1831 '(lambda (x) (> x 0))
1832 (int-to-string current-year)))
1833 (month-array calendar-month-name-array)
1834 (completion-ignore-case t)
1835 (month (cdr (assoc
1836 (capitalize
1837 (completing-read
1838 "Month name: "
1839 (mapcar 'list (append month-array nil))
1840 nil t))
1841 (calendar-make-alist month-array 1 'capitalize))))
1842 (last (calendar-last-day-of-month month year))
1843 (day (calendar-read
1844 (format "Day (1-%d): " last)
1845 '(lambda (x) (and (< 0 x) (<= x last))))))
1846 (list (list month day year))))
1847 (let ((month (extract-calendar-month date)) 2230 (let ((month (extract-calendar-month date))
1848 (year (extract-calendar-year date))) 2231 (year (extract-calendar-year date)))
1849 (if (not (calendar-date-is-visible-p date)) 2232 (if (not (calendar-date-is-visible-p date))
@@ -1857,14 +2240,15 @@ is a string to insert in the minibuffer before reading."
1857(defun calendar-goto-julian-date (date &optional noecho) 2240(defun calendar-goto-julian-date (date &optional noecho)
1858 "Move cursor to Julian DATE; echo Julian date unless NOECHO is t." 2241 "Move cursor to Julian DATE; echo Julian date unless NOECHO is t."
1859 (interactive 2242 (interactive
1860 (let* ((year (calendar-read 2243 (let* ((today (calendar-current-date))
2244 (year (calendar-read
1861 "Julian calendar year (>0): " 2245 "Julian calendar year (>0): "
1862 '(lambda (x) (> x 0)) 2246 '(lambda (x) (> x 0))
1863 (int-to-string 2247 (int-to-string
1864 (extract-calendar-year 2248 (extract-calendar-year
1865 (calendar-julian-from-absolute 2249 (calendar-julian-from-absolute
1866 (calendar-absolute-from-gregorian 2250 (calendar-absolute-from-gregorian
1867 (list current-month 1 current-year))))))) 2251 today))))))
1868 (month-array calendar-month-name-array) 2252 (month-array calendar-month-name-array)
1869 (completion-ignore-case t) 2253 (completion-ignore-case t)
1870 (month (cdr (assoc 2254 (month (cdr (assoc
@@ -1887,19 +2271,19 @@ is a string to insert in the minibuffer before reading."
1887 (list (list month day year)))) 2271 (list (list month day year))))
1888 (calendar-goto-date (calendar-gregorian-from-absolute 2272 (calendar-goto-date (calendar-gregorian-from-absolute
1889 (calendar-absolute-from-julian date))) 2273 (calendar-absolute-from-julian date)))
1890 (or noecho (cursor-to-julian-calendar-date))) 2274 (or noecho (calendar-print-julian-date)))
1891 2275
1892(defun calendar-goto-hebrew-date (date &optional noecho) 2276(defun calendar-goto-hebrew-date (date &optional noecho)
1893 "Move cursor to Hebrew DATE; echo Hebrew date unless NOECHO is t." 2277 "Move cursor to Hebrew DATE; echo Hebrew date unless NOECHO is t."
1894 (interactive 2278 (interactive
1895 (let* ((year (calendar-read 2279 (let* ((today (calendar-current-date))
2280 (year (calendar-read
1896 "Hebrew calendar year (>3760): " 2281 "Hebrew calendar year (>3760): "
1897 '(lambda (x) (> x 3760)) 2282 '(lambda (x) (> x 3760))
1898 (int-to-string 2283 (int-to-string
1899 (extract-calendar-year 2284 (extract-calendar-year
1900 (calendar-hebrew-from-absolute 2285 (calendar-hebrew-from-absolute
1901 (calendar-absolute-from-gregorian 2286 (calendar-absolute-from-gregorian today))))))
1902 (list current-month 1 current-year)))))))
1903 (month-array (if (hebrew-calendar-leap-year-p year) 2287 (month-array (if (hebrew-calendar-leap-year-p year)
1904 calendar-hebrew-month-name-array-leap-year 2288 calendar-hebrew-month-name-array-leap-year
1905 calendar-hebrew-month-name-array-common-year)) 2289 calendar-hebrew-month-name-array-common-year))
@@ -1935,19 +2319,19 @@ is a string to insert in the minibuffer before reading."
1935 (list (list month day year)))) 2319 (list (list month day year))))
1936 (calendar-goto-date (calendar-gregorian-from-absolute 2320 (calendar-goto-date (calendar-gregorian-from-absolute
1937 (calendar-absolute-from-hebrew date))) 2321 (calendar-absolute-from-hebrew date)))
1938 (or noecho (cursor-to-hebrew-calendar-date))) 2322 (or noecho (calendar-print-hebrew-date)))
1939 2323
1940(defun calendar-goto-islamic-date (date &optional noecho) 2324(defun calendar-goto-islamic-date (date &optional noecho)
1941 "Move cursor to Islamic DATE; echo Islamic date unless NOECHO is t." 2325 "Move cursor to Islamic DATE; echo Islamic date unless NOECHO is t."
1942 (interactive 2326 (interactive
1943 (let* ((year (calendar-read 2327 (let* ((today (calendar-current-date))
2328 (year (calendar-read
1944 "Islamic calendar year (>0): " 2329 "Islamic calendar year (>0): "
1945 '(lambda (x) (> x 0)) 2330 '(lambda (x) (> x 0))
1946 (int-to-string 2331 (int-to-string
1947 (extract-calendar-year 2332 (extract-calendar-year
1948 (calendar-islamic-from-absolute 2333 (calendar-islamic-from-absolute
1949 (calendar-absolute-from-gregorian 2334 (calendar-absolute-from-gregorian today))))))
1950 (list current-month 1 current-year)))))))
1951 (month-array calendar-islamic-month-name-array) 2335 (month-array calendar-islamic-month-name-array)
1952 (completion-ignore-case t) 2336 (completion-ignore-case t)
1953 (month (cdr (assoc 2337 (month (cdr (assoc
@@ -1964,15 +2348,16 @@ is a string to insert in the minibuffer before reading."
1964 (list (list month day year)))) 2348 (list (list month day year))))
1965 (calendar-goto-date (calendar-gregorian-from-absolute 2349 (calendar-goto-date (calendar-gregorian-from-absolute
1966 (calendar-absolute-from-islamic date))) 2350 (calendar-absolute-from-islamic date)))
1967 (or noecho (cursor-to-islamic-calendar-date))) 2351 (or noecho (calendar-print-islamic-date)))
1968 2352
1969(defun calendar-goto-iso-date (date &optional noecho) 2353(defun calendar-goto-iso-date (date &optional noecho)
1970 "Move cursor to ISO DATE; echo ISO date unless NOECHO is t." 2354 "Move cursor to ISO DATE; echo ISO date unless NOECHO is t."
1971 (interactive 2355 (interactive
1972 (let* ((year (calendar-read 2356 (let* ((today (calendar-current-date))
2357 (year (calendar-read
1973 "ISO calendar year (>0): " 2358 "ISO calendar year (>0): "
1974 '(lambda (x) (> x 0)) 2359 '(lambda (x) (> x 0))
1975 (int-to-string current-year))) 2360 (int-to-string (extract-calendar-year today))))
1976 (no-weeks (extract-calendar-month 2361 (no-weeks (extract-calendar-month
1977 (calendar-iso-from-absolute 2362 (calendar-iso-from-absolute
1978 (1- 2363 (1-
@@ -1988,10 +2373,10 @@ is a string to insert in the minibuffer before reading."
1988 (list (list week day year)))) 2373 (list (list week day year))))
1989 (calendar-goto-date (calendar-gregorian-from-absolute 2374 (calendar-goto-date (calendar-gregorian-from-absolute
1990 (calendar-absolute-from-iso date))) 2375 (calendar-absolute-from-iso date)))
1991 (or noecho (cursor-to-iso-calendar-date))) 2376 (or noecho (calendar-print-iso-date)))
1992 2377
1993(defun calendar-interval (mon1 yr1 mon2 yr2) 2378(defun calendar-interval (mon1 yr1 mon2 yr2)
1994 "The number of months difference between the two specified months." 2379 "The number of months difference between MON1, YR1 and MON2, YR2."
1995 (+ (* 12 (- yr2 yr1)) 2380 (+ (* 12 (- yr2 yr1))
1996 (- mon2 mon1))) 2381 (- mon2 mon1)))
1997 2382
@@ -2095,7 +2480,11 @@ If FILTER is provided, apply it to each item in the list."
2095This function can be used with the today-visible-calendar-hook run after the 2480This function can be used with the today-visible-calendar-hook run after the
2096calendar window has been prepared." 2481calendar window has been prepared."
2097 (let ((buffer-read-only nil)) 2482 (let ((buffer-read-only nil))
2483 (make-variable-buffer-local 'starred-day)
2098 (forward-char 1) 2484 (forward-char 1)
2485 (setq starred-day
2486 (string-to-int
2487 (buffer-substring (point) (- (point) 2))))
2099 (delete-char -2) 2488 (delete-char -2)
2100 (insert "**") 2489 (insert "**")
2101 (backward-char 1) 2490 (backward-char 1)
@@ -2125,7 +2514,7 @@ abbreviated to three characters. An optional parameter NODAYNAME, when t,
2125omits the name of the day of the week." 2514omits the name of the day of the week."
2126 (let* ((dayname 2515 (let* ((dayname
2127 (if nodayname 2516 (if nodayname
2128 "" 2517 nil
2129 (if abbreviate 2518 (if abbreviate
2130 (substring (calendar-day-name date) 0 3) 2519 (substring (calendar-day-name date) 0 3)
2131 (calendar-day-name date)))) 2520 (calendar-day-name date))))
@@ -2166,7 +2555,7 @@ the last DAYNAME, -2 is the penultimate DAYNAME, and so on."
2166 (list month (calendar-last-day-of-month month year) year))) 2555 (list month (calendar-last-day-of-month month year) year)))
2167 (* 7 (1+ n)))))) 2556 (* 7 (1+ n))))))
2168 2557
2169(defun cursor-to-calendar-day-of-year () 2558(defun calendar-print-day-of-year ()
2170 "Show the day number in the year and the number of days remaining in the 2559 "Show the day number in the year and the number of days remaining in the
2171year for the date under the cursor." 2560year for the date under the cursor."
2172 (interactive) 2561 (interactive)
@@ -2214,7 +2603,7 @@ date Sunday, December 31, 1 BC."
2214 (% date 7) 2603 (% date 7)
2215 year))) 2604 year)))
2216 2605
2217(defun cursor-to-iso-calendar-date () 2606(defun calendar-print-iso-date ()
2218 "Show the equivalent date on the `ISO commercial calendar' for the date 2607 "Show the equivalent date on the `ISO commercial calendar' for the date
2219under the cursor." 2608under the cursor."
2220 (interactive) 2609 (interactive)
@@ -2269,19 +2658,16 @@ The Gregorian date Sunday, December 31, 1 BC is imaginary."
2269 (/ (1- year) 4) 2658 (/ (1- year) 4)
2270 -2))) 2659 -2)))
2271 2660
2272(defun cursor-to-julian-calendar-date () 2661(defun calendar-print-julian-date ()
2273 "Show the Julian calendar equivalent of the date under the cursor." 2662 "Show the Julian calendar equivalent of the date under the cursor."
2274 (interactive) 2663 (interactive)
2275 (let ((calendar-date-display-form 2664 (message "Julian date: %s"
2276 (if european-calendar-style 2665 (calendar-date-string
2277 '(day " " monthname " " year) 2666 (calendar-julian-from-absolute
2278 '(monthname " " day ", " year)))) 2667 (calendar-absolute-from-gregorian
2279 (message "Julian date: %s" 2668 (or (calendar-cursor-to-date)
2280 (calendar-date-string 2669 (error "Cursor is not on a date!"))))
2281 (calendar-julian-from-absolute 2670 nil t)))
2282 (calendar-absolute-from-gregorian
2283 (or (calendar-cursor-to-date)
2284 (error "Cursor is not on a date!"))))))))
2285 2671
2286(defun islamic-calendar-leap-year-p (year) 2672(defun islamic-calendar-leap-year-p (year)
2287 "Returns t if YEAR is a leap year on the Islamic calendar." 2673 "Returns t if YEAR is a leap year on the Islamic calendar."
@@ -2353,21 +2739,18 @@ Gregorian date Sunday, December 31, 1 BC."
2353 ["Muharram" "Safar" "Rabi I" "Rabi II" "Jumada I" "Jumada II" 2739 ["Muharram" "Safar" "Rabi I" "Rabi II" "Jumada I" "Jumada II"
2354 "Rajab" "Sha'ban" "Ramadan" "Shawwal" "Dhu al-Qada" "Dhu al-Hijjah"]) 2740 "Rajab" "Sha'ban" "Ramadan" "Shawwal" "Dhu al-Qada" "Dhu al-Hijjah"])
2355 2741
2356(defun cursor-to-islamic-calendar-date () 2742(defun calendar-print-islamic-date ()
2357 "Show the Islamic calendar equivalent of the date under the cursor." 2743 "Show the Islamic calendar equivalent of the date under the cursor."
2358 (interactive) 2744 (interactive)
2359 (let ((calendar-date-display-form 2745 (let ((calendar-month-name-array calendar-islamic-month-name-array)
2360 (if european-calendar-style
2361 '(day " " monthname " " year)
2362 '(monthname " " day ", " year)))
2363 (calendar-month-name-array calendar-islamic-month-name-array)
2364 (islamic-date (calendar-islamic-from-absolute 2746 (islamic-date (calendar-islamic-from-absolute
2365 (calendar-absolute-from-gregorian 2747 (calendar-absolute-from-gregorian
2366 (or (calendar-cursor-to-date) 2748 (or (calendar-cursor-to-date)
2367 (error "Cursor is not on a date!")))))) 2749 (error "Cursor is not on a date!"))))))
2368 (if (< (extract-calendar-year islamic-date) 1) 2750 (if (< (extract-calendar-year islamic-date) 1)
2369 (message "Date is pre-Islamic") 2751 (message "Date is pre-Islamic")
2370 (message "Islamic date: %s" (calendar-date-string islamic-date nil t))))) 2752 (message "Islamic date (until sunset): %s"
2753 (calendar-date-string islamic-date nil t)))))
2371 2754
2372(defun calendar-hebrew-from-absolute (date) 2755(defun calendar-hebrew-from-absolute (date)
2373 "Compute the Hebrew date (month day year) corresponding to absolute DATE. 2756 "Compute the Hebrew date (month day year) corresponding to absolute DATE.
@@ -2491,14 +2874,10 @@ Gregorian date Sunday, December 31, 1 BC."
2491 ["Nisan" "Iyar" "Sivan" "Tammuz" "Av" "Elul" "Tishri" 2874 ["Nisan" "Iyar" "Sivan" "Tammuz" "Av" "Elul" "Tishri"
2492 "Heshvan" "Kislev" "Teveth" "Shevat" "Adar I" "Adar II"]) 2875 "Heshvan" "Kislev" "Teveth" "Shevat" "Adar I" "Adar II"])
2493 2876
2494(defun cursor-to-hebrew-calendar-date () 2877(defun calendar-print-hebrew-date ()
2495 "Show the Hebrew calendar equivalent of the date under the cursor." 2878 "Show the Hebrew calendar equivalent of the date under the cursor."
2496 (interactive) 2879 (interactive)
2497 (let* ((calendar-date-display-form 2880 (let* ((hebrew-date (calendar-hebrew-from-absolute
2498 (if european-calendar-style
2499 '(day " " monthname " " year)
2500 '(monthname " " day ", " year)))
2501 (hebrew-date (calendar-hebrew-from-absolute
2502 (calendar-absolute-from-gregorian 2881 (calendar-absolute-from-gregorian
2503 (or (calendar-cursor-to-date) 2882 (or (calendar-cursor-to-date)
2504 (error "Cursor is not on a date!"))))) 2883 (error "Cursor is not on a date!")))))
@@ -2506,7 +2885,8 @@ Gregorian date Sunday, December 31, 1 BC."
2506 (if (hebrew-calendar-leap-year-p (extract-calendar-year hebrew-date)) 2885 (if (hebrew-calendar-leap-year-p (extract-calendar-year hebrew-date))
2507 calendar-hebrew-month-name-array-leap-year 2886 calendar-hebrew-month-name-array-leap-year
2508 calendar-hebrew-month-name-array-common-year))) 2887 calendar-hebrew-month-name-array-common-year)))
2509 (message "Hebrew date: %s" (calendar-date-string hebrew-date nil t)))) 2888 (message "Hebrew date (until sunset): %s"
2889 (calendar-date-string hebrew-date nil t))))
2510 2890
2511(defun hebrew-calendar-yahrzeit (death-date year) 2891(defun hebrew-calendar-yahrzeit (death-date year)
2512 "Absolute date of the anniversary of Hebrew DEATH-DATE in Hebrew YEAR." 2892 "Absolute date of the anniversary of Hebrew DEATH-DATE in Hebrew YEAR."
@@ -2541,12 +2921,40 @@ Gregorian date Sunday, December 31, 1 BC."
2541 (t (calendar-absolute-from-hebrew 2921 (t (calendar-absolute-from-hebrew
2542 (list death-month death-day year)))))) 2922 (list death-month death-day year))))))
2543 2923
2924(defun calendar-set-mode-line (str)
2925 "Set mode line to STR, centered, surrounded by dashes."
2926 (setq mode-line-format
2927 (calendar-string-spread (list "" str "") ?- (frame-width))))
2928
2929;;;###autoload
2544(defun list-yahrzeit-dates (death-date start-year end-year) 2930(defun list-yahrzeit-dates (death-date start-year end-year)
2545 "List of Yahrzeit dates for *Gregorian* DEATH-DATE 2931 "List of Yahrzeit dates for *Gregorian* DEATH-DATE from START-YEAR to
2546from START-YEAR to END-YEAR. When called interactively 2932END-YEAR. When called interactively from the calendar window,
2547the date of death is taken from the cursor in the calendar window." 2933the date of death is taken from the cursor position."
2548 (interactive 2934 (interactive
2549 (let* ((death-date (calendar-cursor-to-date)) 2935 (let* ((death-date
2936 (if (equal (current-buffer) (get-buffer calendar-buffer))
2937 (calendar-cursor-to-date)
2938 (let* ((today (calendar-current-date))
2939 (year (calendar-read
2940 "Year of death (>0): "
2941 '(lambda (x) (> x 0))
2942 (int-to-string (extract-calendar-year today))))
2943 (month-array calendar-month-name-array)
2944 (completion-ignore-case t)
2945 (month (cdr (assoc
2946 (capitalize
2947 (completing-read
2948 "Month of death (name): "
2949 (mapcar 'list (append month-array nil))
2950 nil t))
2951 (calendar-make-alist
2952 month-array 1 'capitalize))))
2953 (last (calendar-last-day-of-month month year))
2954 (day (calendar-read
2955 (format "Day of death (1-%d): " last)
2956 '(lambda (x) (and (< 0 x) (<= x last))))))
2957 (list month day year))))
2550 (death-year (extract-calendar-year death-date)) 2958 (death-year (extract-calendar-year death-date))
2551 (start-year (calendar-read 2959 (start-year (calendar-read
2552 (format "Starting year of Yahrzeit table (>%d): " 2960 (format "Starting year of Yahrzeit table (>%d): "
@@ -2567,17 +2975,13 @@ the date of death is taken from the cursor in the calendar window."
2567 (h-year (extract-calendar-year h-date))) 2975 (h-year (extract-calendar-year h-date)))
2568 (set-buffer (get-buffer-create yahrzeit-buffer)) 2976 (set-buffer (get-buffer-create yahrzeit-buffer))
2569 (setq buffer-read-only nil) 2977 (setq buffer-read-only nil)
2570 (setq mode-line-format 2978 (calendar-set-mode-line
2571 (format "------Yahrzeit dates for %s = %s%%-" 2979 (format "Yahrzeit dates for %s = %s"
2572 (calendar-date-string death-date) 2980 (calendar-date-string death-date)
2573 (let ((calendar-month-name-array 2981 (let ((calendar-month-name-array
2574 (if (hebrew-calendar-leap-year-p h-year) 2982 (if (hebrew-calendar-leap-year-p h-year)
2575 calendar-hebrew-month-name-array-leap-year 2983 calendar-hebrew-month-name-array-leap-year
2576 calendar-hebrew-month-name-array-common-year)) 2984 calendar-hebrew-month-name-array-common-year)))
2577 (calendar-date-display-form
2578 (if european-calendar-style
2579 '(day " " monthname " " year)
2580 '(monthname " " day ", " year))))
2581 (calendar-date-string h-date nil t)))) 2985 (calendar-date-string h-date nil t))))
2582 (erase-buffer) 2986 (erase-buffer)
2583 (goto-char (point-min)) 2987 (goto-char (point-min))
@@ -2596,113 +3000,27 @@ the date of death is taken from the cursor in the calendar window."
2596 (display-buffer yahrzeit-buffer) 3000 (display-buffer yahrzeit-buffer)
2597 (message "Computing yahrzeits...done"))) 3001 (message "Computing yahrzeits...done")))
2598 3002
2599(defun french-calendar-leap-year-p (year) 3003(defun calendar-print-astro-day-number ()
2600 "True if YEAR is a leap year on the French Revolutionary calendar. 3004 "Show the astronomical (Julian) day number of afternoon on date
2601For Gregorian years 1793 to 1805, the years of actual operation of the 3005shown by cursor."
2602calendar, uses historical practice based on equinoxes is followed (years 3, 7,
2603and 11 were leap years; 15 and 20 would have been leap years). For later
2604years uses the proposed rule of Romme (never adopted)--leap years fall every
2605four years except century years not divisible 400 and century years that are
2606multiples of 4000."
2607 (or (memq year '(3 7 11));; Actual practice--based on equinoxes
2608 (memq year '(15 20)) ;; Anticipated practice--based on equinoxes
2609 (and (> year 20) ;; Romme's proposal--never adopted
2610 (zerop (% year 4))
2611 (not (memq (% year 400) '(100 200 300)))
2612 (not (zerop (% year 4000))))))
2613
2614(defun french-calendar-last-day-of-month (month year)
2615 "Last day of MONTH, YEAR on the French Revolutionary calendar.
2616The 13th month is not really a month, but the 5 (6 in leap years) day period of
2617`sansculottides' at the end of the year."
2618 (if (< month 13)
2619 30
2620 (if (french-calendar-leap-year-p year)
2621 6
2622 5)))
2623
2624(defun calendar-absolute-from-french (date)
2625 "Absolute date of French Revolutionary DATE.
2626The absolute date is the number of days elapsed since the (imaginary)
2627Gregorian date Sunday, December 31, 1 BC."
2628 (let ((month (extract-calendar-month date))
2629 (day (extract-calendar-day date))
2630 (year (extract-calendar-year date)))
2631 (+ (* 365 (1- year));; Days in prior years
2632 ;; Leap days in prior years
2633 (if (< year 20)
2634 (/ year 4);; Actual and anticipated practice (years 3, 7, 11, 15)
2635 ;; Romme's proposed rule (using the Principle of Inclusion/Exclusion)
2636 (+ (/ (1- year) 4);; Luckily, there were 4 leap years before year 20
2637 (- (/ (1- year) 100))
2638 (/ (1- year) 400)
2639 (- (/ (1- year) 4000))))
2640 (* 30 (1- month));; Days in prior months this year
2641 day;; Days so far this month
2642 654414)));; Days before start of calendar (September 22, 1792).
2643
2644(defun calendar-french-from-absolute (date)
2645 "Compute the French Revolutionary date (month day year) corresponding to
2646absolute DATE. The absolute date is the number of days elapsed since the
2647(imaginary) Gregorian date Sunday, December 31, 1 BC."
2648 (if (< date 654415)
2649 (list 0 0 0);; pre-French Revolutionary date
2650 (let* ((approx (/ (- date 654414) 366));; Approximation from below.
2651 (year ;; Search forward from the approximation.
2652 (+ approx
2653 (calendar-sum y approx
2654 (>= date (calendar-absolute-from-french (list 1 1 (1+ y))))
2655 1)))
2656 (month ;; Search forward from Vendemiaire.
2657 (1+ (calendar-sum m 1
2658 (> date
2659 (calendar-absolute-from-french
2660 (list m
2661 (french-calendar-last-day-of-month m year)
2662 year)))
2663 1)))
2664 (day ;; Calculate the day by subtraction.
2665 (- date
2666 (1- (calendar-absolute-from-french (list month 1 year))))))
2667 (list month day year))))
2668
2669(defun cursor-to-french-calendar-date ()
2670 "Show the French Revolutionary calendar equivalent of the date under the
2671cursor."
2672 (interactive) 3006 (interactive)
2673 (let* ((french-date (calendar-french-from-absolute 3007 (message
2674 (calendar-absolute-from-gregorian 3008 "Astromonical (Julian) day number after noon Universal Time: %d"
2675 (or (calendar-cursor-to-date) 3009 (+ 1721425
2676 (error "Cursor is not on a date!"))))) 3010 (calendar-absolute-from-gregorian
2677 (y (extract-calendar-year french-date)) 3011 (or (calendar-cursor-to-date)
2678 (m (extract-calendar-month french-date)) 3012 (error "Cursor is not on a date!"))))))
2679 (d (extract-calendar-day french-date))) 3013
2680 (if (< y 1) 3014(defun calendar-goto-astro-day-number (daynumber &optional noecho)
2681 (message "Date is pre-French Revolution") 3015 "Move cursor to astronomical (Julian) DAYNUMBER.
2682 (if (= m 13) 3016Echo astronomical (Julian) day number unless NOECHO is t."
2683 (message "Jour %s de l'Annee %d de la Revolution" 3017 (interactive (list (calendar-read
2684 (aref french-calendar-special-days-array (1- d)) 3018 "Astromonical (Julian) day number (>1721425): "
2685 y) 3019 '(lambda (x) (> x 1721425)))))
2686 (message "Decade %s, %s de %s de l'Annee %d de la Revolution" 3020 (calendar-goto-date (calendar-gregorian-from-absolute (- daynumber 1721425)))
2687 (make-string (1+ (/ (1- d) 10)) ?I) 3021 (or noecho (calendar-print-astro-day-number)))
2688 (aref french-calendar-day-name-array (% (1- d) 10)) 3022
2689 (aref french-calendar-month-name-array (1- m)) 3023(run-hooks 'calendar-load-hook)
2690 y)))))
2691
2692(defconst french-calendar-month-name-array
2693 ["Vendemiaire" "Brumaire" "Frimaire" "Nivose" "Pluviose" "Ventose" "Germinal"
2694 "Floreal" "Prairial" "Messidor" "Thermidor" "Fructidor"])
2695;; Very loosely translated as
2696;; Slippy, Nippy, Drippy, Freezy, Wheezy, Sneezy,
2697;; Showery, Flowery, Bowery, Heaty, Wheaty, Sweety.
2698
2699(defconst french-calendar-day-name-array
2700 ["Primidi" "Duodi" "Tridi" "Quartidi" "Quintidi" "Sextidi" "Septidi"
2701 "Octidi" "Nonidi" "Decadi"])
2702
2703(defconst french-calendar-special-days-array
2704 ["de la Vertu" "du Genie" "du Labour" "de la Raison" "de la Recompense"
2705 "de la Revolution"])
2706 3024
2707(provide 'calendar) 3025(provide 'calendar)
2708 3026
diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el
index 8f6aed27dca..5dd4a537cf1 100644
--- a/lisp/calendar/holidays.el
+++ b/lisp/calendar/holidays.el
@@ -1,9 +1,9 @@
1;;; holidays.el --- holiday functions for the calendar package 1;;; holidays.el --- holiday functions for the calendar package
2 2
3;;; Copyright (C) 1989, 1990 Free Software Foundation, Inc. 3;;; Copyright (C) 1989, 1990, 1992 Free Software Foundation, Inc.
4 4
5;; Author: Edward M. Reingold <reingold@cs.uiuc.edu> 5;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
6;; Keywords: calendar 6;; Keywords: holidays, calendar
7 7
8;; This file is part of GNU Emacs. 8;; This file is part of GNU Emacs.
9 9
@@ -36,21 +36,51 @@
36;; Technical details of all the calendrical calculations can be found in 36;; Technical details of all the calendrical calculations can be found in
37;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold, 37;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold,
38;; Software--Practice and Experience, Volume 20, Number 9 (September, 1990), 38;; Software--Practice and Experience, Volume 20, Number 9 (September, 1990),
39;; pages 899-928. 39;; pages 899-928. ``Calendrical Calculations, Part II: Three Historical
40;; Calendars'' by E. M. Reingold, N. Dershowitz, and S. M. Clamen,
41;; Report Number UIUCDCS-R-92-1743, Department of Computer Science,
42;; University of Illinois, April, 1992.
43
44;; Hard copies of these two papers can be obtained by sending email to
45;; reingold@cs.uiuc.edu with the SUBJECT "send-paper-cal" (no quotes) and
46;; the message BODY containing your mailing address (snail).
40 47
41;;; Code: 48;;; Code:
42 49
43(require 'calendar) 50(require 'calendar)
44 51
45;;;###autoload 52(autoload 'calendar-holiday-function-solar-equinoxes-solstices "solar"
46(defun holidays () 53 "Date and time of equinoxes and solstices, if visible in the calendar window.
54Requires floating point."
55 t)
56
57(defun holidays (&optional arg)
47 "Display the holidays for last month, this month, and next month. 58 "Display the holidays for last month, this month, and next month.
59If called with an optional prefix argument, prompts for month and year.
60
48This function is suitable for execution in a .emacs file." 61This function is suitable for execution in a .emacs file."
49 (interactive) 62 (interactive "P")
50 (save-excursion 63 (save-excursion
51 (let* ((date (calendar-current-date)) 64 (let* ((completion-ignore-case t)
52 (displayed-month (extract-calendar-month date)) 65 (date (calendar-current-date))
53 (displayed-year (extract-calendar-year date))) 66 (displayed-month
67 (if arg
68 (cdr (assoc
69 (capitalize
70 (completing-read
71 "Month name: "
72 (mapcar 'list (append calendar-month-name-array nil))
73 nil t))
74 (calendar-make-alist calendar-month-name-array)))
75 (extract-calendar-month date)))
76 (displayed-year
77 (if arg
78 (calendar-read
79 "Year (>0): "
80 '(lambda (x) (> x 0))
81 (int-to-string
82 (extract-calendar-year (calendar-current-date))))
83 (extract-calendar-year date))))
54 (list-calendar-holidays)))) 84 (list-calendar-holidays))))
55 85
56(defun check-calendar-holidays (date) 86(defun check-calendar-holidays (date)
@@ -79,13 +109,11 @@ The holidays are those in the list calendar-holidays."
79 (msg (format "%s: %s" date-string holiday-string))) 109 (msg (format "%s: %s" date-string holiday-string)))
80 (if (not holiday-list) 110 (if (not holiday-list)
81 (message "No holidays known for %s" date-string) 111 (message "No holidays known for %s" date-string)
82 (if (<= (length msg) (frame-width)) 112 (if (<= (length msg) (screen-width))
83 (message msg) 113 (message msg)
84 (set-buffer (get-buffer-create holiday-buffer)) 114 (set-buffer (get-buffer-create holiday-buffer))
85 (setq buffer-read-only nil) 115 (setq buffer-read-only nil)
86 (setq mode-line-format 116 (calendar-set-mode-line date-string)
87 (format "--------------------------%s%%-"
88 date-string))
89 (erase-buffer) 117 (erase-buffer)
90 (insert (mapconcat 'identity holiday-list "\n")) 118 (insert (mapconcat 'identity holiday-list "\n"))
91 (goto-char (point-min)) 119 (goto-char (point-min))
@@ -125,8 +153,8 @@ holidays are found, nil if not."
125 (setq buffer-read-only nil) 153 (setq buffer-read-only nil)
126 (increment-calendar-month m1 y1 -1) 154 (increment-calendar-month m1 y1 -1)
127 (increment-calendar-month m2 y2 1) 155 (increment-calendar-month m2 y2 1)
128 (setq mode-line-format 156 (calendar-set-mode-line
129 (format "-------------Notable Dates from %s, %d to %s, %d%%-" 157 (format "Notable Dates from %s, %d to %s, %d%%-"
130 (calendar-month-name m1) y1 (calendar-month-name m2) y2)) 158 (calendar-month-name m1) y1 (calendar-month-name m2) y2))
131 (erase-buffer) 159 (erase-buffer)
132 (insert 160 (insert
@@ -150,9 +178,14 @@ The holidays are those in the list calendar-holidays."
150 (let* ((function-name 178 (let* ((function-name
151 (intern (format "calendar-holiday-function-%s" (car (car p))))) 179 (intern (format "calendar-holiday-function-%s" (car (car p)))))
152 (holidays 180 (holidays
153 (if (cdr (car p));; optional arguments 181 (condition-case nil
154 (funcall function-name (cdr (car p))) 182 (if (cdr (car p));; optional arguments
155 (funcall function-name)))) 183 (funcall function-name (cdr (car p)))
184 (funcall function-name))
185 (error
186 (beep)
187 (message "Bad holiday list item: %s" (car p))
188 (sleep-for 2)))))
156 (if holidays 189 (if holidays
157 (setq holiday-list (append holidays holiday-list)))) 190 (setq holiday-list (append holidays holiday-list))))
158 (setq p (cdr p))) 191 (setq p (cdr p)))
@@ -164,13 +197,13 @@ The holidays are those in the list calendar-holidays."
164;; including the evaluation of each element in the list that constitutes 197;; including the evaluation of each element in the list that constitutes
165;; the argument to the function. If you don't do this evaluation, the 198;; the argument to the function. If you don't do this evaluation, the
166;; list calendar-holidays cannot contain expressions (as, for example, in 199;; list calendar-holidays cannot contain expressions (as, for example, in
167;; the entry for the Islamic new year. Also remember that each function 200;; the entry for the Islamic new year.) Also remember that each function
168;; must return a list of items of the form ((month day year) string); 201;; must return a list of items of the form ((month day year) string);
169;; the date (month day year) should be visible in the calendar window. 202;; the date (month day year) should be visible in the calendar window.
170 203
171(defun calendar-holiday-function-fixed (x) 204(defun calendar-holiday-function-fixed (x)
172 "Returns the corresponding Gregorian date, if visible in the window, to 205 "Returns the corresponding Gregorian date, if visible in the window, to
173month, year where month is (car X) and year is (car (cdr X)). If it is 206(month day) where month is (car X) and day is (car (cdr X)). If it is
174visible, the value returned is the list (((month day year) string)) where 207visible, the value returned is the list (((month day year) string)) where
175string is (car (nthcdr 2 X)). Returns nil if it is not visible in the 208string is (car (nthcdr 2 X)). Returns nil if it is not visible in the
176current calendar window." 209current calendar window."
@@ -186,9 +219,9 @@ current calendar window."
186(defun calendar-holiday-function-float (x) 219(defun calendar-holiday-function-float (x)
187 "Returns the corresponding Gregorian date, if visible in the window, to the 220 "Returns the corresponding Gregorian date, if visible in the window, to the
188n-th occurrence (negative counts from the end of the month) of dayname in 221n-th occurrence (negative counts from the end of the month) of dayname in
189month, year where month is (car X), year is (car (cdr X)), n is 222month where month is (car X), dayname is (car (cdr X)), and n is
190\(car \(nthcdr 2 X\)\). If it is visible, the value returned is the list 223(car (nthcdr 2 X)). If it is visible, the value returned is the list
191\(\(\(month day year)\ string\)\) where string is (car (nthcdr 3 X)). 224(((month day year) string)) where string is (car (nthcdr 3 X)).
192Returns nil if it is not visible in the current calendar window." 225Returns nil if it is not visible in the current calendar window."
193 (let* ((month (eval (car x))) 226 (let* ((month (eval (car x)))
194 (dayname (eval (car (cdr x)))) 227 (dayname (eval (car (cdr x))))
@@ -202,7 +235,7 @@ Returns nil if it is not visible in the current calendar window."
202 235
203(defun calendar-holiday-function-julian (x) 236(defun calendar-holiday-function-julian (x)
204 "Returns the corresponding Gregorian date, if visible in the window, to the 237 "Returns the corresponding Gregorian date, if visible in the window, to the
205Julian date month, year where month is (car X) and year is (car (cdr X)). 238Julian date (month day) where month is (car X) and day is (car (cdr X)).
206If it is visible, the value returned is the list (((month day year) string)) 239If it is visible, the value returned is the list (((month day year) string))
207where string is (car (nthcdr 2 X)). Returns nil if it is not visible in the 240where string is (car (nthcdr 2 X)). Returns nil if it is not visible in the
208current calendar window." 241current calendar window."
@@ -233,7 +266,7 @@ current calendar window."
233 266
234(defun calendar-holiday-function-islamic (x) 267(defun calendar-holiday-function-islamic (x)
235 "Returns the corresponding Gregorian date, if visible in the window, to the 268 "Returns the corresponding Gregorian date, if visible in the window, to the
236Islamic date month, day where month is (car X) and day is (car (cdr X)). 269Islamic date (month day) where month is (car X) and day is (car (cdr X)).
237If it is visible, the value returned is the list (((month day year) string)) 270If it is visible, the value returned is the list (((month day year) string))
238where string is (car (nthcdr 2 X)). Returns nil if it is not visible in 271where string is (car (nthcdr 2 X)). Returns nil if it is not visible in
239the current calendar window." 272the current calendar window."
@@ -257,7 +290,7 @@ the current calendar window."
257 290
258(defun calendar-holiday-function-hebrew (x) 291(defun calendar-holiday-function-hebrew (x)
259 "Returns the corresponding Gregorian date, if visible in the window, to the 292 "Returns the corresponding Gregorian date, if visible in the window, to the
260Hebrew date month, day where month is (car X) and day is (car (cdr X)). 293Hebrew date (month day) where month is (car X) and day is (car (cdr X)).
261If it is visible, the value returned is the list (((month day year) string)) 294If it is visible, the value returned is the list (((month day year) string))
262where string is (car (nthcdr 2 X)). Returns nil if it is not visible in 295where string is (car (nthcdr 2 X)). Returns nil if it is not visible in
263the current calendar window." 296the current calendar window."
@@ -308,6 +341,21 @@ checked. If nil, the holiday (car (cdr (cdr X))), if there, is checked."
308 (funcall function-name)))) 341 (funcall function-name))))
309 holidays)))) 342 holidays))))
310 343
344(defun calendar-holiday-function-sexp (x)
345 "Sexp holiday for dates in the calendar window.
346The sexp (in `year') is (car X). If the sexp evals to a date visible in the
347calendar window, the holiday (car (cdr X)) is on that date. If the sexp evals
348to nil, or if the date is not visible, there is no holiday."
349 (let ((m displayed-month)
350 (y displayed-year))
351 (increment-calendar-month m y -1)
352 (filter-visible-calendar-holidays
353 (append
354 (let ((year y))
355 (list (list (eval (car x)) (eval (car (cdr x))))))
356 (let ((year (1+ y)))
357 (list (list (eval (car x)) (eval (car (cdr x))))))))))
358
311(defun calendar-holiday-function-advent () 359(defun calendar-holiday-function-advent ()
312 "Date of Advent, if visible in calendar window." 360 "Date of Advent, if visible in calendar window."
313 (let ((year displayed-year) 361 (let ((year displayed-year)
@@ -389,6 +437,30 @@ checked. If nil, the holiday (car (cdr (cdr X))), if there, is checked."
389 output-list))) 437 output-list)))
390 output-list))) 438 output-list)))
391 439
440(defun calendar-holiday-function-greek-orthodox-easter ()
441 "Date of Easter according to the rule of the Council of Nicaea, if visible
442in the calendar window."
443 (let ((m displayed-month)
444 (y displayed-year))
445 (increment-calendar-month m y 1)
446 (let* ((julian-year
447 (extract-calendar-year
448 (calendar-julian-from-absolute
449 (calendar-absolute-from-gregorian
450 (list m (calendar-last-day-of-month m y) y)))))
451 (shifted-epact ;; Age of moon for April 5.
452 (% (+ 14
453 (* 11 (% julian-year 19)))
454 30))
455 (paschal-moon ;; Day after full moon on or after March 21.
456 (- (calendar-absolute-from-julian (list 4 19 julian-year))
457 shifted-epact))
458 (nicaean-easter;; Sunday following the Paschal moon
459 (calendar-gregorian-from-absolute
460 (calendar-dayname-on-or-before 0 (+ paschal-moon 7)))))
461 (if (calendar-date-is-visible-p nicaean-easter)
462 (list (list nicaean-easter "Pascha (Greek Orthodox Easter)"))))))
463
392(defun calendar-holiday-function-rosh-hashanah-etc () 464(defun calendar-holiday-function-rosh-hashanah-etc ()
393 "List of dates related to Rosh Hashanah, as visible in calendar window." 465 "List of dates related to Rosh Hashanah, as visible in calendar window."
394 (if (or (< displayed-month 8) 466 (if (or (< displayed-month 8)
diff --git a/lisp/calendar/lunar.el b/lisp/calendar/lunar.el
new file mode 100644
index 00000000000..904d99ebfca
--- /dev/null
+++ b/lisp/calendar/lunar.el
@@ -0,0 +1,290 @@
1;;; lunar.el --- calendar functions for phases of the moon.
2
3;; Copyright (C) 1992 Free Software Foundation, Inc.
4
5;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
6;; Keywords: moon, lunar phases, calendar, diary
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is distributed in the hope that it will be useful,
11;; but WITHOUT ANY WARRANTY. No author or distributor
12;; accepts responsibility to anyone for the consequences of using it
13;; or for whether it serves any particular purpose or works at all,
14;; unless he says so in writing. Refer to the GNU Emacs General Public
15;; License for full details.
16
17;; Everyone is granted permission to copy, modify and redistribute
18;; GNU Emacs, but only under the conditions described in the
19;; GNU Emacs General Public License. A copy of this license is
20;; supposed to have been given to you along with GNU Emacs so you
21;; can know your rights and responsibilities. It should be in a
22;; file named COPYING. Among other things, the copyright notice
23;; and this notice must be preserved on all copies.
24
25;;; Commentary:
26
27;; This collection of functions implements lunar phases for calendar.el and
28;; diary.el.
29
30;; Based on ``Astronomical Formulae for Calculators,'' 3rd ed., by Jean Meeus,
31;; Willmann-Bell, Inc., 1985.
32;;
33;; WARNING: The calculations will be accurate only to within a few minutes.
34
35;; The author would be delighted to have an astronomically more sophisticated
36;; person rewrite the code for the lunar calculations in this file!
37
38;; Comments, corrections, and improvements should be sent to
39;; Edward M. Reingold Department of Computer Science
40;; (217) 333-6733 University of Illinois at Urbana-Champaign
41;; reingold@cs.uiuc.edu 1304 West Springfield Avenue
42;; Urbana, Illinois 61801
43
44;;; Code:
45
46(if (fboundp 'atan)
47 (require 'lisp-float-type)
48 (error "Lunar calculations impossible since floating point is unavailable."))
49
50(require 'solar)
51
52(defun lunar-phase-list (month year)
53 "List of lunar phases for three months starting with Gregorian MONTH, YEAR."
54 (let ((end-month month)
55 (end-year year)
56 (start-month month)
57 (start-year year))
58 (increment-calendar-month end-month end-year 3)
59 (increment-calendar-month start-month start-year -1)
60 (let* ((end-date (list (list end-month 1 end-year)))
61 (start-date (list (list start-month
62 (calendar-last-day-of-month
63 start-month start-year)
64 start-year)))
65 (index (* 4
66 (truncate
67 (* 12.3685
68 (+ year
69 ( / (calendar-day-number (list month 1 year))
70 366.0)
71 -1900)))))
72 (new-moon (lunar-phase index))
73 (list))
74 (while (calendar-date-compare new-moon end-date)
75 (if (calendar-date-compare start-date new-moon)
76 (setq list (append list (list new-moon))))
77 (setq index (1+ index))
78 (setq new-moon (lunar-phase index)))
79 list)))
80
81(defun lunar-phase (index)
82 "Local date and time of lunar phase INDEX.
83Integer below INDEX/4 gives the lunation number, counting from Jan 1, 1900;
84remainder mod 4 gives the phase: 0 new moon, 1 first quarter, 2 full moon,
853 last quarter."
86 (let* ((phase (% index 4))
87 (index (/ index 4.0))
88 (time (/ index 1236.85))
89 (date (+ (calendar-absolute-from-gregorian '(1 0.5 1900))
90 0.75933
91 (* 29.53058868 index)
92 (* 0.0001178 time time)
93 (* -0.000000155 time time time)
94 (* 0.00033
95 (solar-sin-degrees (+ 166.56
96 (* 132.87 time)
97 (* -0.009173 time time))))))
98 (sun-anomaly (solar-mod
99 (+ 359.2242
100 (* 29.105356 index)
101 (* -0.0000333 time time)
102 (* -0.00000347 time time time))
103 360.0))
104 (moon-anomaly (solar-mod
105 (+ 306.0253
106 (* 385.81691806 index)
107 (* 0.0107306 time time)
108 (* 0.00001236 time time time))
109 360.0))
110 (moon-lat (solar-mod
111 (+ 21.2964
112 (* 390.67050646 index)
113 (* -0.0016528 time time)
114 (* -0.00000239 time time time))
115 360.0))
116 (adjustment
117 (if (memq phase '(0 2))
118 (+ (* (- 0.1734 (* 0.000393 time))
119 (solar-sin-degrees sun-anomaly))
120 (* 0.0021 (solar-sin-degrees (* 2 sun-anomaly)))
121 (* -0.4068 (solar-sin-degrees moon-anomaly))
122 (* 0.0161 (solar-sin-degrees (* 2 moon-anomaly)))
123 (* -0.0004 (solar-sin-degrees (* 3 moon-anomaly)))
124 (* 0.0104 (solar-sin-degrees (* 2 moon-lat)))
125 (* -0.0051 (solar-sin-degrees (+ sun-anomaly moon-anomaly)))
126 (* -0.0074 (solar-sin-degrees (- sun-anomaly moon-anomaly)))
127 (* 0.0004 (solar-sin-degrees (+ (* 2 moon-lat) sun-anomaly)))
128 (* -0.0004 (solar-sin-degrees (- (* 2 moon-lat) sun-anomaly)))
129 (* -0.0006 (solar-sin-degrees
130 (+ (* 2 moon-lat) moon-anomaly)))
131 (* 0.0010 (solar-sin-degrees (- (* 2 moon-lat) moon-anomaly)))
132 (* 0.0005 (solar-sin-degrees
133 (+ (* 2 moon-anomaly) sun-anomaly))))
134 (+ (* (- 0.1721 (* 0.0004 time))
135 (solar-sin-degrees sun-anomaly))
136 (* 0.0021 (solar-sin-degrees (* 2 sun-anomaly)))
137 (* -0.6280 (solar-sin-degrees moon-anomaly))
138 (* 0.0089 (solar-sin-degrees (* 2 moon-anomaly)))
139 (* -0.0004 (solar-sin-degrees (* 3 moon-anomaly)))
140 (* 0.0079 (solar-sin-degrees (* 2 moon-lat)))
141 (* -0.0119 (solar-sin-degrees (+ sun-anomaly moon-anomaly)))
142 (* -0.0047 (solar-sin-degrees (- sun-anomaly moon-anomaly)))
143 (* 0.0003 (solar-sin-degrees (+ (* 2 moon-lat) sun-anomaly)))
144 (* -0.0004 (solar-sin-degrees (- (* 2 moon-lat) sun-anomaly)))
145 (* -0.0006 (solar-sin-degrees (+ (* 2 moon-lat) moon-anomaly)))
146 (* 0.0021 (solar-sin-degrees (- (* 2 moon-lat) moon-anomaly)))
147 (* 0.0003 (solar-sin-degrees
148 (+ (* 2 moon-anomaly) sun-anomaly)))
149 (* 0.0004 (solar-sin-degrees
150 (- sun-anomaly (* 2 moon-anomaly))))
151 (* -0.0003 (solar-sin-degrees
152 (+ (* 2 sun-anomaly) moon-anomaly))))))
153 (adj (+ 0.0028
154 (* -0.0004 (solar-cosine-degrees
155 sun-anomaly))
156 (* 0.0003 (solar-cosine-degrees
157 moon-anomaly))))
158 (adjustment (cond ((= phase 1) (+ adjustment adj))
159 ((= phase 2) (- adjustment adj))
160 (t adjustment)))
161 (date (+ date adjustment))
162 (calendar-standard-time-zone-name
163 (if calendar-time-zone calendar-standard-time-zone-name "UT"))
164 (calendar-daylight-savings-starts
165 (if calendar-time-zone calendar-daylight-savings-starts))
166 (calendar-daylight-savings-ends
167 (if calendar-time-zone calendar-daylight-savings-ends))
168 (calendar-time-zone (if calendar-time-zone calendar-time-zone 0))
169 (year (extract-calendar-year
170 (calendar-gregorian-from-absolute (truncate date))))
171 (dst (and calendar-daylight-savings-starts
172 calendar-daylight-savings-ends
173 (<= (calendar-absolute-from-gregorian
174 (eval calendar-daylight-savings-starts))
175 date)
176 (< date
177 (calendar-absolute-from-gregorian
178 (eval calendar-daylight-savings-ends)))))
179 (date (+ date
180 (/ (+ (if dst 60 0) calendar-time-zone) 60.0 24.0)
181 (- (/ (solar-ephemeris-correction year) 60.0 24.0))))
182 (time (* 24 (- date (truncate date))))
183 (date (calendar-gregorian-from-absolute (truncate date)))
184 (time-zone calendar-time-zone)
185 (time-zone (if dst
186 calendar-daylight-time-zone-name
187 calendar-standard-time-zone-name))
188 (24-hours (truncate time))
189 (12-hours (format "%d" (if (> 24-hours 12)
190 (- 24-hours 12)
191 (if (= 24-hours 0) 12 24-hours))))
192 (am-pm (if (>= 24-hours 12) "pm" "am"))
193 (minutes (format "%02d" (round (* 60 (- time 24-hours)))))
194 (24-hours (format "%02d" 24-hours))
195 (time (mapconcat 'eval calendar-time-display-form "")))
196 (list date time phase)))
197
198(defun lunar-phase-name (phase)
199 "Name of lunar PHASE.
2000 = new moon, 1 = first quarter, 2 = full moon, 3 = last quarter."
201 (cond ((= 0 phase) "New Moon")
202 ((= 1 phase) "First Quarter Moon")
203 ((= 2 phase) "Full Moon")
204 ((= 3 phase) "Last Quarter Moon")))
205
206(defun calendar-phases-of-moon ()
207 "Create a buffer with the lunar phases for the current calendar window."
208 (interactive)
209 (message "Computing phases of the moon...")
210 (let ((m1 displayed-month)
211 (y1 displayed-year)
212 (m2 displayed-month)
213 (y2 displayed-year)
214 (lunar-phases-buffer "*Phases of Moon*"))
215 (increment-calendar-month m1 y1 -1)
216 (increment-calendar-month m2 y2 1)
217 (set-buffer (get-buffer-create lunar-phases-buffer))
218 (setq buffer-read-only nil)
219 (calendar-set-mode-line
220 (format "Phases of the moon from %s, %d to %s, %d%%-"
221 (calendar-month-name m1) y1 (calendar-month-name m2) y2))
222 (erase-buffer)
223 (insert
224 (mapconcat
225 '(lambda (x)
226 (let ((date (car x))
227 (time (car (cdr x)))
228 (phase (car (cdr (cdr x)))))
229 (concat (calendar-date-string date)
230 ": "
231 (lunar-phase-name phase)
232 " "
233 time)))
234 (lunar-phase-list m1 y1) "\n"))
235 (goto-char (point-min))
236 (set-buffer-modified-p nil)
237 (setq buffer-read-only t)
238 (display-buffer lunar-phases-buffer)
239 (message "Computing phases of the moon...done")))
240
241;;;###autoload
242(defun phases-of-moon (&optional arg)
243 "Display the quarters of the moon for last month, this month, and next month.
244If called with an optional prefix argument, prompts for month and year.
245
246This function is suitable for execution in a .emacs file."
247 (interactive "P")
248 (save-excursion
249 (let* ((completion-ignore-case t)
250 (date (calendar-current-date))
251 (displayed-month
252 (if arg
253 (cdr (assoc
254 (capitalize
255 (completing-read
256 "Month name: "
257 (mapcar 'list (append calendar-month-name-array nil))
258 nil t))
259 (calendar-make-alist calendar-month-name-array)))
260 (extract-calendar-month date)))
261 (displayed-year
262 (if arg
263 (calendar-read
264 "Year (>0): "
265 '(lambda (x) (> x 0))
266 (int-to-string
267 (extract-calendar-year (calendar-current-date))))
268 (extract-calendar-year date))))
269 (calendar-phases-of-moon))))
270
271(defun diary-phases-of-moon ()
272 "Moon phases diary entry."
273 (let* ((index (* 4
274 (truncate
275 (* 12.3685
276 (+ (extract-calendar-year date)
277 ( / (calendar-day-number date)
278 366.0)
279 -1900)))))
280 (phase (lunar-phase index)))
281 (while (calendar-date-compare phase (list date))
282 (setq index (1+ index))
283 (setq phase (lunar-phase index)))
284 (if (calendar-date-equal (car phase) date)
285 (concat (lunar-phase-name (car (cdr (cdr phase)))) " "
286 (car (cdr phase))))))
287
288(provide 'lunar)
289
290;;; lunar.el ends here
diff --git a/lisp/cl.el b/lisp/cl.el
index b675d926fb8..22fda0f4b94 100644
--- a/lisp/cl.el
+++ b/lisp/cl.el
@@ -671,110 +671,55 @@ The forms in BODY should be lists, as non-lists are reserved for new features."
671;;;; Cesar Quiroz @ UofR DofCSc - Dec. 1986 671;;;; Cesar Quiroz @ UofR DofCSc - Dec. 1986
672;;;; (quiroz@cs.rochester.edu) 672;;;; (quiroz@cs.rochester.edu)
673 673
674(defvar *cl-valid-named-list-accessors* 674
675 '(first rest second third fourth fifth sixth seventh eighth ninth tenth)) 675
676(defvar *cl-valid-nth-offsets* 676;;; To make these faster, we define them using defsubst. This directs the
677 '((second . 1) 677;;; compiler to open-code these functions.
678 (third . 2)
679 (fourth . 3)
680 (fifth . 4)
681 (sixth . 5)
682 (seventh . 6)
683 (eighth . 7)
684 (ninth . 8)
685 (tenth . 9)))
686
687(defun byte-compile-named-list-accessors (form)
688 "Generate code for (<accessor> FORM), where <accessor> is one of the named
689list accessors: first, second, ..., tenth, rest."
690 (let* ((fun (car form))
691 (arg (cadr form))
692 (valid *cl-valid-named-list-accessors*)
693 (offsets *cl-valid-nth-offsets*))
694 (cond
695
696 ;; Check that it's a form we're prepared to handle.
697 ((not (memq fun valid))
698 (error
699 "cl.el internal bug: `%s' not in {first, ..., tenth, rest}"
700 fun))
701
702 ;; Check the number of arguments.
703 ((not (= (length form) 2))
704 (byte-compile-subr-wrong-args form 1))
705
706 ;; If the result will simply be tossed, don't generate any code for
707 ;; it, and indicate that we have already discarded the value.
708 (for-effect
709 (setq for-effect nil))
710
711 ;; Generate code for the call.
712 ((eq fun 'first)
713 (byte-compile-form arg)
714 (byte-compile-out 'byte-car 0))
715 ((eq fun 'rest)
716 (byte-compile-form arg)
717 (byte-compile-out 'byte-cdr 0))
718 (t ;one of the others
719 (byte-compile-constant (cdr (assq fun offsets)))
720 (byte-compile-form arg)
721 (byte-compile-out 'byte-nth 0)))))
722 678
723;;; Synonyms for list functions 679;;; Synonyms for list functions
724(defun first (x) 680(defsubst first (x)
725 "Synonym for `car'" 681 "Synonym for `car'"
726 (car x)) 682 (car x))
727(put 'first 'byte-compile 'byte-compile-named-list-accessors)
728 683
729(defun second (x) 684(defsubst second (x)
730 "Return the second element of the list LIST." 685 "Return the second element of the list LIST."
731 (nth 1 x)) 686 (nth 1 x))
732(put 'second 'byte-compile 'byte-compile-named-list-accessors)
733 687
734(defun third (x) 688(defsubst third (x)
735 "Return the third element of the list LIST." 689 "Return the third element of the list LIST."
736 (nth 2 x)) 690 (nth 2 x))
737(put 'third 'byte-compile 'byte-compile-named-list-accessors)
738 691
739(defun fourth (x) 692(defsubst fourth (x)
740 "Return the fourth element of the list LIST." 693 "Return the fourth element of the list LIST."
741 (nth 3 x)) 694 (nth 3 x))
742(put 'fourth 'byte-compile 'byte-compile-named-list-accessors)
743 695
744(defun fifth (x) 696(defsubst fifth (x)
745 "Return the fifth element of the list LIST." 697 "Return the fifth element of the list LIST."
746 (nth 4 x)) 698 (nth 4 x))
747(put 'fifth 'byte-compile 'byte-compile-named-list-accessors)
748 699
749(defun sixth (x) 700(defsubst sixth (x)
750 "Return the sixth element of the list LIST." 701 "Return the sixth element of the list LIST."
751 (nth 5 x)) 702 (nth 5 x))
752(put 'sixth 'byte-compile 'byte-compile-named-list-accessors)
753 703
754(defun seventh (x) 704(defsubst seventh (x)
755 "Return the seventh element of the list LIST." 705 "Return the seventh element of the list LIST."
756 (nth 6 x)) 706 (nth 6 x))
757(put 'seventh 'byte-compile 'byte-compile-named-list-accessors)
758 707
759(defun eighth (x) 708(defsubst eighth (x)
760 "Return the eighth element of the list LIST." 709 "Return the eighth element of the list LIST."
761 (nth 7 x)) 710 (nth 7 x))
762(put 'eighth 'byte-compile 'byte-compile-named-list-accessors)
763 711
764(defun ninth (x) 712(defsubst ninth (x)
765 "Return the ninth element of the list LIST." 713 "Return the ninth element of the list LIST."
766 (nth 8 x)) 714 (nth 8 x))
767(put 'ninth 'byte-compile 'byte-compile-named-list-accessors)
768 715
769(defun tenth (x) 716(defsubst tenth (x)
770 "Return the tenth element of the list LIST." 717 "Return the tenth element of the list LIST."
771 (nth 9 x)) 718 (nth 9 x))
772(put 'tenth 'byte-compile 'byte-compile-named-list-accessors)
773 719
774(defun rest (x) 720(defsubst rest (x)
775 "Synonym for `cdr'" 721 "Synonym for `cdr'"
776 (cdr x)) 722 (cdr x))
777(put 'rest 'byte-compile 'byte-compile-named-list-accessors)
778 723
779(defun endp (x) 724(defun endp (x)
780 "t if X is nil, nil if X is a cons; error otherwise." 725 "t if X is nil, nil if X is a cons; error otherwise."
@@ -845,186 +790,120 @@ SUBLIST must be one of the links in LIST; otherwise the value is LIST itself."
845 790
846;;; The popular c[ad]*r functions and other list accessors. 791;;; The popular c[ad]*r functions and other list accessors.
847 792
848;;; To implement this efficiently, a new byte compile handler is used to 793;;; To implement this efficiently, we define them using defsubst,
849;;; generate the minimal code, saving one function call. 794;;; which directs the compiler to open-code these functions.
850 795
851(defun byte-compile-ca*d*r (form) 796(defsubst caar (X)
852 "Generate code for a (c[ad]+r argument). This realizes the various
853combinations of car and cdr whose names are supported in this implementation.
854To use this functionality for a given function,just give its name a
855'byte-compile property of 'byte-compile-ca*d*r"
856 (let* ((fun (car form))
857 (arg (cadr form))
858 (seq (mapcar (function (lambda (letter)
859 (if (= letter ?a)
860 'byte-car 'byte-cdr)))
861 (cdr (nreverse (cdr (append (symbol-name fun) nil)))))))
862 ;; SEQ is a list of byte-car and byte-cdr in the correct order.
863 (cond
864
865 ;; Is this a function we can handle?
866 ((null seq)
867 (error
868 "cl.el internal bug: `%s' cannot be compiled by byte-compile-ca*d*r"
869 (prin1-to-string form)))
870
871 ;; Are we passing this function the correct number of arguments?
872 ((or (null (cdr form)) (cddr form))
873 (byte-compile-subr-wrong-args form 1))
874
875 ;; Are we evaluating this expression for effect only?
876 (for-effect
877
878 ;; We needn't generate any actual code, as long as we tell the rest
879 ;; of the compiler that we didn't push anything on the stack.
880 (setq for-effect nil))
881
882 ;; Generate code for the function.
883 (t
884 (byte-compile-form arg)
885 (while seq
886 (byte-compile-out (car seq) 0)
887 (setq seq (cdr seq)))))))
888
889(defun caar (X)
890 "Return the car of the car of X." 797 "Return the car of the car of X."
891 (car (car X))) 798 (car (car X)))
892(put 'caar 'byte-compile 'byte-compile-ca*d*r)
893 799
894(defun cadr (X) 800(defsubst cadr (X)
895 "Return the car of the cdr of X." 801 "Return the car of the cdr of X."
896 (car (cdr X))) 802 (car (cdr X)))
897(put 'cadr 'byte-compile 'byte-compile-ca*d*r)
898 803
899(defun cdar (X) 804(defsubst cdar (X)
900 "Return the cdr of the car of X." 805 "Return the cdr of the car of X."
901 (cdr (car X))) 806 (cdr (car X)))
902(put 'cdar 'byte-compile 'byte-compile-ca*d*r)
903 807
904(defun cddr (X) 808(defsubst cddr (X)
905 "Return the cdr of the cdr of X." 809 "Return the cdr of the cdr of X."
906 (cdr (cdr X))) 810 (cdr (cdr X)))
907(put 'cddr 'byte-compile 'byte-compile-ca*d*r)
908 811
909(defun caaar (X) 812(defsubst caaar (X)
910 "Return the car of the car of the car of X." 813 "Return the car of the car of the car of X."
911 (car (car (car X)))) 814 (car (car (car X))))
912(put 'caaar 'byte-compile 'byte-compile-ca*d*r)
913 815
914(defun caadr (X) 816(defsubst caadr (X)
915 "Return the car of the car of the cdr of X." 817 "Return the car of the car of the cdr of X."
916 (car (car (cdr X)))) 818 (car (car (cdr X))))
917(put 'caadr 'byte-compile 'byte-compile-ca*d*r)
918 819
919(defun cadar (X) 820(defsubst cadar (X)
920 "Return the car of the cdr of the car of X." 821 "Return the car of the cdr of the car of X."
921 (car (cdr (car X)))) 822 (car (cdr (car X))))
922(put 'cadar 'byte-compile 'byte-compile-ca*d*r)
923 823
924(defun cdaar (X) 824(defsubst cdaar (X)
925 "Return the cdr of the car of the car of X." 825 "Return the cdr of the car of the car of X."
926 (cdr (car (car X)))) 826 (cdr (car (car X))))
927(put 'cdaar 'byte-compile 'byte-compile-ca*d*r)
928 827
929(defun caddr (X) 828(defsubst caddr (X)
930 "Return the car of the cdr of the cdr of X." 829 "Return the car of the cdr of the cdr of X."
931 (car (cdr (cdr X)))) 830 (car (cdr (cdr X))))
932(put 'caddr 'byte-compile 'byte-compile-ca*d*r)
933 831
934(defun cdadr (X) 832(defsubst cdadr (X)
935 "Return the cdr of the car of the cdr of X." 833 "Return the cdr of the car of the cdr of X."
936 (cdr (car (cdr X)))) 834 (cdr (car (cdr X))))
937(put 'cdadr 'byte-compile 'byte-compile-ca*d*r)
938 835
939(defun cddar (X) 836(defsubst cddar (X)
940 "Return the cdr of the cdr of the car of X." 837 "Return the cdr of the cdr of the car of X."
941 (cdr (cdr (car X)))) 838 (cdr (cdr (car X))))
942(put 'cddar 'byte-compile 'byte-compile-ca*d*r)
943 839
944(defun cdddr (X) 840(defsubst cdddr (X)
945 "Return the cdr of the cdr of the cdr of X." 841 "Return the cdr of the cdr of the cdr of X."
946 (cdr (cdr (cdr X)))) 842 (cdr (cdr (cdr X))))
947(put 'cdddr 'byte-compile 'byte-compile-ca*d*r)
948 843
949(defun caaaar (X) 844(defsubst caaaar (X)
950 "Return the car of the car of the car of the car of X." 845 "Return the car of the car of the car of the car of X."
951 (car (car (car (car X))))) 846 (car (car (car (car X)))))
952(put 'caaaar 'byte-compile 'byte-compile-ca*d*r)
953 847
954(defun caaadr (X) 848(defsubst caaadr (X)
955 "Return the car of the car of the car of the cdr of X." 849 "Return the car of the car of the car of the cdr of X."
956 (car (car (car (cdr X))))) 850 (car (car (car (cdr X)))))
957(put 'caaadr 'byte-compile 'byte-compile-ca*d*r)
958 851
959(defun caadar (X) 852(defsubst caadar (X)
960 "Return the car of the car of the cdr of the car of X." 853 "Return the car of the car of the cdr of the car of X."
961 (car (car (cdr (car X))))) 854 (car (car (cdr (car X)))))
962(put 'caadar 'byte-compile 'byte-compile-ca*d*r)
963 855
964(defun cadaar (X) 856(defsubst cadaar (X)
965 "Return the car of the cdr of the car of the car of X." 857 "Return the car of the cdr of the car of the car of X."
966 (car (cdr (car (car X))))) 858 (car (cdr (car (car X)))))
967(put 'cadaar 'byte-compile 'byte-compile-ca*d*r)
968 859
969(defun cdaaar (X) 860(defsubst cdaaar (X)
970 "Return the cdr of the car of the car of the car of X." 861 "Return the cdr of the car of the car of the car of X."
971 (cdr (car (car (car X))))) 862 (cdr (car (car (car X)))))
972(put 'cdaaar 'byte-compile 'byte-compile-ca*d*r)
973 863
974(defun caaddr (X) 864(defsubst caaddr (X)
975 "Return the car of the car of the cdr of the cdr of X." 865 "Return the car of the car of the cdr of the cdr of X."
976 (car (car (cdr (cdr X))))) 866 (car (car (cdr (cdr X)))))
977(put 'caaddr 'byte-compile 'byte-compile-ca*d*r)
978 867
979(defun cadadr (X) 868(defsubst cadadr (X)
980 "Return the car of the cdr of the car of the cdr of X." 869 "Return the car of the cdr of the car of the cdr of X."
981 (car (cdr (car (cdr X))))) 870 (car (cdr (car (cdr X)))))
982(put 'cadadr 'byte-compile 'byte-compile-ca*d*r)
983 871
984(defun cdaadr (X) 872(defsubst cdaadr (X)
985 "Return the cdr of the car of the car of the cdr of X." 873 "Return the cdr of the car of the car of the cdr of X."
986 (cdr (car (car (cdr X))))) 874 (cdr (car (car (cdr X)))))
987(put 'cdaadr 'byte-compile 'byte-compile-ca*d*r)
988 875
989(defun caddar (X) 876(defsubst caddar (X)
990 "Return the car of the cdr of the cdr of the car of X." 877 "Return the car of the cdr of the cdr of the car of X."
991 (car (cdr (cdr (car X))))) 878 (car (cdr (cdr (car X)))))
992(put 'caddar 'byte-compile 'byte-compile-ca*d*r)
993 879
994(defun cdadar (X) 880(defsubst cdadar (X)
995 "Return the cdr of the car of the cdr of the car of X." 881 "Return the cdr of the car of the cdr of the car of X."
996 (cdr (car (cdr (car X))))) 882 (cdr (car (cdr (car X)))))
997(put 'cdadar 'byte-compile 'byte-compile-ca*d*r)
998 883
999(defun cddaar (X) 884(defsubst cddaar (X)
1000 "Return the cdr of the cdr of the car of the car of X." 885 "Return the cdr of the cdr of the car of the car of X."
1001 (cdr (cdr (car (car X))))) 886 (cdr (cdr (car (car X)))))
1002(put 'cddaar 'byte-compile 'byte-compile-ca*d*r)
1003 887
1004(defun cadddr (X) 888(defsubst cadddr (X)
1005 "Return the car of the cdr of the cdr of the cdr of X." 889 "Return the car of the cdr of the cdr of the cdr of X."
1006 (car (cdr (cdr (cdr X))))) 890 (car (cdr (cdr (cdr X)))))
1007(put 'cadddr 'byte-compile 'byte-compile-ca*d*r)
1008 891
1009(defun cddadr (X) 892(defsubst cddadr (X)
1010 "Return the cdr of the cdr of the car of the cdr of X." 893 "Return the cdr of the cdr of the car of the cdr of X."
1011 (cdr (cdr (car (cdr X))))) 894 (cdr (cdr (car (cdr X)))))
1012(put 'cddadr 'byte-compile 'byte-compile-ca*d*r)
1013 895
1014(defun cdaddr (X) 896(defsubst cdaddr (X)
1015 "Return the cdr of the car of the cdr of the cdr of X." 897 "Return the cdr of the car of the cdr of the cdr of X."
1016 (cdr (car (cdr (cdr X))))) 898 (cdr (car (cdr (cdr X)))))
1017(put 'cdaddr 'byte-compile 'byte-compile-ca*d*r)
1018 899
1019(defun cdddar (X) 900(defsubst cdddar (X)
1020 "Return the cdr of the cdr of the cdr of the car of X." 901 "Return the cdr of the cdr of the cdr of the car of X."
1021 (cdr (cdr (cdr (car X))))) 902 (cdr (cdr (cdr (car X)))))
1022(put 'cdddar 'byte-compile 'byte-compile-ca*d*r)
1023 903
1024(defun cddddr (X) 904(defsubst cddddr (X)
1025 "Return the cdr of the cdr of the cdr of the cdr of X." 905 "Return the cdr of the cdr of the cdr of the cdr of X."
1026 (cdr (cdr (cdr (cdr X))))) 906 (cdr (cdr (cdr (cdr X)))))
1027(put 'cddddr 'byte-compile 'byte-compile-ca*d*r)
1028 907
1029;;; some inverses of the accessors are needed for setf purposes 908;;; some inverses of the accessors are needed for setf purposes
1030 909
diff --git a/lisp/cmulisp.el b/lisp/cmulisp.el
new file mode 100644
index 00000000000..11fc14af064
--- /dev/null
+++ b/lisp/cmulisp.el
@@ -0,0 +1,684 @@
1;;; cmulisp.el --- improved version of standard inferior-lisp mode
2
3;;; Copyright Olin Shivers (1988).
4;;; Please imagine a long, tedious, legalistic 5-page gnu-style copyright
5;;; notice appearing here to the effect that you may use this code any
6;;; way you like, as long as you don't charge money for it, remove this
7;;; notice, or hold me liable for its results.
8
9;;; This replaces the standard inferior-lisp mode.
10;;; Hacked from tea.el by Olin Shivers (shivers@cs.cmu.edu). 8/88
11;;; Please send me bug reports, bug fixes, and extensions, so that I can
12;;; merge them into the master source.
13;;;
14;;; Change log at end of file.
15
16;;; This file defines a a lisp-in-a-buffer package (cmulisp mode) built on top
17;;; of comint mode. Cmulisp mode is similar to, and intended to replace, its
18;;; counterpart in the standard gnu emacs release. This replacements is more
19;;; featureful, robust, and uniform than the released version. The key
20;;; bindings are also more compatible with the bindings of Hemlock and Zwei
21;;; (the Lisp Machine emacs).
22
23;;; Since this mode is built on top of the general command-interpreter-in-
24;;; a-buffer mode (comint mode), it shares a common base functionality,
25;;; and a common set of bindings, with all modes derived from comint mode.
26;;; This makes these modes easier to use.
27
28;;; For documentation on the functionality provided by comint mode, and
29;;; the hooks available for customising it, see the file comint.el.
30;;; For further information on cmulisp mode, see the comments below.
31
32;;; Needs fixin:
33;;; The load-file/compile-file default mechanism could be smarter -- it
34;;; doesn't know about the relationship between filename extensions and
35;;; whether the file is source or executable. If you compile foo.lisp
36;;; with compile-file, then the next load-file should use foo.bin for
37;;; the default, not foo.lisp. This is tricky to do right, particularly
38;;; because the extension for executable files varies so much (.o, .bin,
39;;; .lbin, .mo, .vo, .ao, ...).
40;;;
41;;; It would be nice if cmulisp (and inferior scheme, T, ...) modes
42;;; had a verbose minor mode wherein sending or compiling defuns, etc.
43;;; would be reflected in the transcript with suitable comments, e.g.
44;;; ";;; redefining fact". Several ways to do this. Which is right?
45;;;
46;;; When sending text from a source file to a subprocess, the process-mark can
47;;; move off the window, so you can lose sight of the process interactions.
48;;; Maybe I should ensure the process mark is in the window when I send
49;;; text to the process? Switch selectable?
50
51(require 'comint)
52;; YOUR .EMACS FILE
53;;=============================================================================
54;; Some suggestions for your .emacs file.
55;;
56;; ; If cmulisp lives in some non-standard directory, you must tell emacs
57;; ; where to get it. This may or may not be necessary.
58;; (setq load-path (cons (expand-file-name "~jones/lib/emacs") load-path))
59;;
60;; ; Autoload cmulisp from file cmulisp.el
61;; (autoload 'cmulisp "cmulisp"
62;; "Run an inferior Lisp process."
63;; t)
64;;
65;; ; Define C-c t to run my favorite command in cmulisp mode:
66;; (setq cmulisp-load-hook
67;; '((lambda ()
68;; (define-key cmulisp-mode-map "\C-ct" 'favorite-cmd))))
69
70
71;;; Brief Command Documentation:
72;;;============================================================================
73;;; Comint Mode Commands: (common to cmulisp and all comint-derived modes)
74;;;
75;;; m-p comint-previous-input Cycle backwards in input history
76;;; m-n comint-next-input Cycle forwards
77;;; m-c-r comint-previous-input-matching Search backwards in input history
78;;; return comint-send-input
79;;; c-a comint-bol Beginning of line; skip prompt.
80;;; c-d comint-delchar-or-maybe-eof Delete char unless at end of buff.
81;;; c-c c-u comint-kill-input ^u
82;;; c-c c-w backward-kill-word ^w
83;;; c-c c-c comint-interrupt-subjob ^c
84;;; c-c c-z comint-stop-subjob ^z
85;;; c-c c-\ comint-quit-subjob ^\
86;;; c-c c-o comint-kill-output Delete last batch of process output
87;;; c-c c-r comint-show-output Show last batch of process output
88;;; send-invisible Read line w/o echo & send to proc
89;;; comint-continue-subjob Useful if you accidentally suspend
90;;; top-level job.
91;;; comint-mode-hook is the comint mode hook.
92
93;;; CMU Lisp Mode Commands:
94;;; c-m-x lisp-send-defun This binding is a gnu convention.
95;;; c-c c-l lisp-load-file Prompt for file name; tell Lisp to load it.
96;;; c-c c-k lisp-compile-file Prompt for file name; tell Lisp to kompile it.
97;;; Filename completion is available, of course.
98;;;
99;;; Additionally, these commands are added to the key bindings of Lisp mode:
100;;; c-m-x lisp-eval-defun This binding is a gnu convention.
101;;; c-c c-e lisp-eval-defun Send the current defun to Lisp process.
102;;; c-x c-e lisp-eval-last-sexp Send the previous sexp to Lisp process.
103;;; c-c c-r lisp-eval-region Send the current region to Lisp process.
104;;; c-c c-c lisp-compile-defun Compile the current defun in Lisp process.
105;;; c-c c-z switch-to-lisp Switch to the Lisp process buffer.
106;;; c-c c-l lisp-load-file (See above. In a Lisp file buffer, default
107;;; c-c c-k lisp-compile-file is to load/compile the current file.)
108;;; c-c c-d lisp-describe-sym Query Lisp for a symbol's description.
109;;; c-c c-a lisp-show-arglist Query Lisp for function's arglist.
110;;; c-c c-f lisp-show-function-documentation Query Lisp for a function's doc.
111;;; c-c c-v lisp-show-variable-documentation Query Lisp for a variable's doc.
112
113;;; cmulisp Fires up the Lisp process.
114;;; lisp-compile-region Compile all forms in the current region.
115;;;
116;;; CMU Lisp Mode Variables:
117;;; cmulisp-filter-regexp Match this => don't get saved on input hist
118;;; inferior-lisp-program Name of Lisp program run-lisp executes
119;;; inferior-lisp-load-command Customises lisp-load-file
120;;; cmulisp-mode-hook
121;;; inferior-lisp-prompt Initialises comint-prompt-regexp.
122;;; Backwards compatibility.
123;;; lisp-source-modes Anything loaded into a buffer that's in
124;;; one of these modes is considered Lisp
125;;; source by lisp-load/compile-file.
126
127;;; Read the rest of this file for more information.
128
129(defvar cmulisp-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)\\)?\\s *\\'"
130 "*What not to save on inferior Lisp's input history
131Input matching this regexp is not saved on the input history in cmulisp
132mode. Default is whitespace followed by 0 or 1 single-letter :keyword
133(as in :a, :c, etc.)")
134
135(defvar cmulisp-mode-map nil)
136(cond ((not cmulisp-mode-map)
137 (setq cmulisp-mode-map
138 (full-copy-sparse-keymap comint-mode-map))
139 (lisp-mode-commands cmulisp-mode-map)
140 (define-key cmulisp-mode-map "\C-x\C-e" 'lisp-eval-last-sexp)
141 (define-key cmulisp-mode-map "\C-c\C-l" 'lisp-load-file)
142 (define-key cmulisp-mode-map "\C-c\C-k" 'lisp-compile-file)
143 (define-key cmulisp-mode-map "\C-c\C-a" 'lisp-show-arglist)
144 (define-key cmulisp-mode-map "\C-c\C-d" 'lisp-describe-sym)
145 (define-key cmulisp-mode-map "\C-c\C-f" 'lisp-show-function-documentation)
146 (define-key cmulisp-mode-map "\C-c\C-v" 'lisp-show-variable-documentation)))
147
148;;; These commands augment Lisp mode, so you can process Lisp code in
149;;; the source files.
150(define-key lisp-mode-map "\M-\C-x" 'lisp-eval-defun) ; Gnu convention
151(define-key lisp-mode-map "\C-x\C-e" 'lisp-eval-last-sexp) ; Gnu convention
152(define-key lisp-mode-map "\C-c\C-e" 'lisp-eval-defun)
153(define-key lisp-mode-map "\C-c\C-r" 'lisp-eval-region)
154(define-key lisp-mode-map "\C-c\C-c" 'lisp-compile-defun)
155(define-key lisp-mode-map "\C-c\C-z" 'switch-to-lisp)
156(define-key lisp-mode-map "\C-c\C-l" 'lisp-load-file)
157(define-key lisp-mode-map "\C-c\C-k" 'lisp-compile-file) ; "kompile" file
158(define-key lisp-mode-map "\C-c\C-a" 'lisp-show-arglist)
159(define-key lisp-mode-map "\C-c\C-d" 'lisp-describe-sym)
160(define-key lisp-mode-map "\C-c\C-f" 'lisp-show-function-documentation)
161(define-key lisp-mode-map "\C-c\C-v" 'lisp-show-variable-documentation)
162
163
164;;; This function exists for backwards compatibility.
165;;; Previous versions of this package bound commands to C-c <letter>
166;;; bindings, which is not allowed by the gnumacs standard.
167
168(defun cmulisp-install-letter-bindings ()
169 "This function binds many cmulisp commands to C-c <letter> bindings,
170where they are more accessible. C-c <letter> bindings are reserved for the
171user, so these bindings are non-standard. If you want them, you should
172have this function called by the cmulisp-load-hook:
173 (setq cmulisp-load-hook '(cmulisp-install-letter-bindings))
174You can modify this function to install just the bindings you want."
175
176 (define-key lisp-mode-map "\C-ce" 'lisp-eval-defun-and-go)
177 (define-key lisp-mode-map "\C-cr" 'lisp-eval-region-and-go)
178 (define-key lisp-mode-map "\C-cc" 'lisp-compile-defun-and-go)
179 (define-key lisp-mode-map "\C-cz" 'switch-to-lisp)
180 (define-key lisp-mode-map "\C-cl" 'lisp-load-file)
181 (define-key lisp-mode-map "\C-ck" 'lisp-compile-file)
182 (define-key lisp-mode-map "\C-ca" 'lisp-show-arglist)
183 (define-key lisp-mode-map "\C-cd" 'lisp-describe-sym)
184 (define-key lisp-mode-map "\C-cf" 'lisp-show-function-documentation)
185 (define-key lisp-mode-map "\C-cv" 'lisp-show-variable-documentation)
186
187 (define-key cmulisp-mode-map "\C-cl" 'lisp-load-file)
188 (define-key cmulisp-mode-map "\C-ck" 'lisp-compile-file)
189 (define-key cmulisp-mode-map "\C-ca" 'lisp-show-arglist)
190 (define-key cmulisp-mode-map "\C-cd" 'lisp-describe-sym)
191 (define-key cmulisp-mode-map "\C-cf" 'lisp-show-function-documentation)
192 (define-key cmulisp-mode-map "\C-cv" 'lisp-show-variable-documentation))
193
194
195(defvar inferior-lisp-program "lisp"
196 "*Program name for invoking an inferior Lisp with `cmulisp'.")
197
198(defvar inferior-lisp-load-command "(load \"%s\")\n"
199 "*Format-string for building a Lisp expression to load a file.
200This format string should use %s to substitute a file name
201and should result in a Lisp expression that will command the inferior Lisp
202to load that file. The default works acceptably on most Lisps.
203The string \"(progn (load \\\"%s\\\" :verbose nil :print t) (values))\\\n\"
204produces cosmetically superior output for this application,
205but it works only in Common Lisp.")
206
207(defvar inferior-lisp-prompt "^[^> ]*>+:? *"
208 "Regexp to recognise prompts in the inferior Lisp.
209Defaults to \"^[^> ]*>+:? *\", which works pretty good for Lucid, kcl,
210and franz. This variable is used to initialise comint-prompt-regexp in the
211cmulisp buffer.
212
213More precise choices:
214Lucid Common Lisp: \"^\\(>\\|\\(->\\)+\\) *\"
215franz: \"^\\(->\\|<[0-9]*>:\\) *\"
216kcl: \"^>+ *\"
217
218This is a fine thing to set in your .emacs file.")
219
220(defvar cmulisp-mode-hook '()
221 "*Hook for customising cmulisp mode")
222
223(defun cmulisp-mode ()
224 "Major mode for interacting with an inferior Lisp process.
225Runs a Lisp interpreter as a subprocess of Emacs, with Lisp I/O through an
226Emacs buffer. Variable inferior-lisp-program controls which Lisp interpreter
227is run. Variables inferior-lisp-prompt, cmulisp-filter-regexp and
228inferior-lisp-load-command can customize this mode for different Lisp
229interpreters.
230
231For information on running multiple processes in multiple buffers, see
232documentation for variable cmulisp-buffer.
233
234\\{cmulisp-mode-map}
235
236Customisation: Entry to this mode runs the hooks on comint-mode-hook and
237cmulisp-mode-hook (in that order).
238
239You can send text to the inferior Lisp process from other buffers containing
240Lisp source.
241 switch-to-lisp switches the current buffer to the Lisp process buffer.
242 lisp-eval-defun sends the current defun to the Lisp process.
243 lisp-compile-defun compiles the current defun.
244 lisp-eval-region sends the current region to the Lisp process.
245 lisp-compile-region compiles the current region.
246
247 Prefixing the lisp-eval/compile-defun/region commands with
248 a \\[universal-argument] causes a switch to the Lisp process buffer after sending
249 the text.
250
251Commands:
252Return after the end of the process' output sends the text from the
253 end of process to point.
254Return before the end of the process' output copies the sexp ending at point
255 to the end of the process' output, and sends it.
256Delete converts tabs to spaces as it moves back.
257Tab indents for Lisp; with argument, shifts rest
258 of expression rigidly with the current line.
259C-M-q does Tab on each line starting within following expression.
260Paragraphs are separated only by blank lines. Semicolons start comments.
261If you accidentally suspend your process, use \\[comint-continue-subjob]
262to continue it."
263 (interactive)
264 (comint-mode)
265 (setq comint-prompt-regexp inferior-lisp-prompt)
266 (setq major-mode 'cmulisp-mode)
267 (setq mode-name "CMU Lisp")
268 (setq mode-line-process '(": %s"))
269 (if (string-match "^18.4" emacs-version) ; hack.
270 (lisp-mode-variables) ; This is right for 18.49
271 (lisp-mode-variables t)) ; This is right for 18.50
272 (use-local-map cmulisp-mode-map) ;c-c c-k for "kompile" file
273 (setq comint-get-old-input (function lisp-get-old-input))
274 (setq comint-input-filter (function lisp-input-filter))
275 (setq comint-input-sentinel 'ignore)
276 (run-hooks 'cmulisp-mode-hook))
277
278(defun lisp-get-old-input ()
279 "Snarf the sexp ending at point"
280 (save-excursion
281 (let ((end (point)))
282 (backward-sexp)
283 (buffer-substring (point) end))))
284
285(defun lisp-input-filter (str)
286 "Don't save anything matching cmulisp-filter-regexp"
287 (not (string-match cmulisp-filter-regexp str)))
288
289(defun cmulisp (cmd)
290 "Run an inferior Lisp process, input and output via buffer *cmulisp*.
291If there is a process already running in *cmulisp*, just switch to that buffer.
292With argument, allows you to edit the command line (default is value
293of inferior-lisp-program). Runs the hooks from cmulisp-mode-hook (after the
294comint-mode-hook is run).
295\(Type \\[describe-mode] in the process buffer for a list of commands.)"
296 (interactive (list (if current-prefix-arg
297 (read-string "Run lisp: " inferior-lisp-program)
298 inferior-lisp-program)))
299 (if (not (comint-check-proc "*cmulisp*"))
300 (let ((cmdlist (cmulisp-args-to-list cmd)))
301 (set-buffer (apply (function make-comint) "cmulisp" (car cmdlist) nil
302 (cdr cmdlist)))
303 (cmulisp-mode)))
304 (setq cmulisp-buffer "*cmulisp*")
305 (switch-to-buffer "*cmulisp*"))
306
307;;; Break a string up into a list of arguments.
308;;; This will break if you have an argument with whitespace, as in
309;;; string = "-ab +c -x 'you lose'".
310(defun cmulisp-args-to-list (string)
311 (let ((where (string-match "[ \t]" string)))
312 (cond ((null where) (list string))
313 ((not (= where 0))
314 (cons (substring string 0 where)
315 (tea-args-to-list (substring string (+ 1 where)
316 (length string)))))
317 (t (let ((pos (string-match "[^ \t]" string)))
318 (if (null pos)
319 nil
320 (cmulsip-args-to-list (substring string pos
321 (length string)))))))))
322
323(defun lisp-eval-region (start end &optional and-go)
324 "Send the current region to the inferior Lisp process.
325Prefix argument means switch-to-lisp afterwards."
326 (interactive "r\nP")
327 (comint-send-region (cmulisp-proc) start end)
328 (comint-send-string (cmulisp-proc) "\n")
329 (if and-go (switch-to-lisp t)))
330
331(defun lisp-eval-defun (&optional and-go)
332 "Send the current defun to the inferior Lisp process.
333Prefix argument means switch-to-lisp afterwards."
334 (interactive "P")
335 (save-excursion
336 (end-of-defun)
337 (skip-chars-backward " \t\n\r\f") ; Makes allegro happy
338 (let ((end (point)))
339 (beginning-of-defun)
340 (lisp-eval-region (point) end)))
341 (if and-go (switch-to-lisp t)))
342
343(defun lisp-eval-last-sexp (&optional and-go)
344 "Send the previous sexp to the inferior Lisp process.
345Prefix argument means switch-to-lisp afterwards."
346 (interactive "P")
347 (lisp-eval-region (save-excursion (backward-sexp) (point)) (point) and-go))
348
349;;; Common Lisp COMPILE sux.
350(defun lisp-compile-region (start end &optional and-go)
351 "Compile the current region in the inferior Lisp process.
352Prefix argument means switch-to-lisp afterwards."
353 (interactive "r\nP")
354 (comint-send-string (cmulisp-proc)
355 (format "(funcall (compile nil `(lambda () (progn 'compile %s))))\n"
356 (buffer-substring start end)))
357 (if and-go (switch-to-lisp t)))
358
359(defun lisp-compile-defun (&optional and-go)
360 "Compile the current defun in the inferior Lisp process.
361Prefix argument means switch-to-lisp afterwards."
362 (interactive "P")
363 (save-excursion
364 (end-of-defun)
365 (skip-chars-backward " \t\n\r\f") ; Makes allegro happy
366 (let ((e (point)))
367 (beginning-of-defun)
368 (lisp-compile-region (point) e)))
369 (if and-go (switch-to-lisp t)))
370
371(defun switch-to-lisp (eob-p)
372 "Switch to the inferior Lisp process buffer.
373With argument, positions cursor at end of buffer."
374 (interactive "P")
375 (if (get-buffer cmulisp-buffer)
376 (pop-to-buffer cmulisp-buffer)
377 (error "No current process buffer. See variable cmulisp-buffer."))
378 (cond (eob-p
379 (push-mark)
380 (goto-char (point-max)))))
381
382
383;;; Now that lisp-compile/eval-defun/region takes an optional prefix arg,
384;;; these commands are redundant. But they are kept around for the user
385;;; to bind if he wishes, for backwards functionality, and because it's
386;;; easier to type C-c e than C-u C-c C-e.
387
388(defun lisp-eval-region-and-go (start end)
389 "Send the current region to the inferior Lisp,
390and switch to the process buffer."
391 (interactive "r")
392 (lisp-eval-region start end t))
393
394(defun lisp-eval-defun-and-go ()
395 "Send the current defun to the inferior Lisp,
396and switch to the process buffer."
397 (interactive)
398 (lisp-eval-defun t))
399
400(defun lisp-compile-region-and-go (start end)
401 "Compile the current region in the inferior Lisp,
402and switch to the process buffer."
403 (interactive "r")
404 (lisp-compile-region start end t))
405
406(defun lisp-compile-defun-and-go ()
407 "Compile the current defun in the inferior Lisp,
408and switch to the process buffer."
409 (interactive)
410 (lisp-compile-defun t))
411
412;;; A version of the form in H. Shevis' soar-mode.el package. Less robust.
413;(defun lisp-compile-sexp (start end)
414; "Compile the s-expression bounded by START and END in the inferior lisp.
415;If the sexp isn't a DEFUN form, it is evaluated instead."
416; (cond ((looking-at "(defun\\s +")
417; (goto-char (match-end 0))
418; (let ((name-start (point)))
419; (forward-sexp 1)
420; (process-send-string "cmulisp" (format "(compile '%s #'(lambda "
421; (buffer-substring name-start
422; (point)))))
423; (let ((body-start (point)))
424; (goto-char start) (forward-sexp 1) ; Can't use end-of-defun.
425; (process-send-region "cmulisp" (buffer-substring body-start (point))))
426; (process-send-string "cmulisp" ")\n"))
427; (t (lisp-eval-region start end)))))
428;
429;(defun lisp-compile-region (start end)
430; "Each s-expression in the current region is compiled (if a DEFUN)
431;or evaluated (if not) in the inferior lisp."
432; (interactive "r")
433; (save-excursion
434; (goto-char start) (end-of-defun) (beginning-of-defun) ; error check
435; (if (< (point) start) (error "region begins in middle of defun"))
436; (goto-char start)
437; (let ((s start))
438; (end-of-defun)
439; (while (<= (point) end) ; Zip through
440; (lisp-compile-sexp s (point)) ; compiling up defun-sized chunks.
441; (setq s (point))
442; (end-of-defun))
443; (if (< s end) (lisp-compile-sexp s end)))))
444;;;
445;;; End of HS-style code
446
447
448(defvar lisp-prev-l/c-dir/file nil
449 "Saves the (directory . file) pair used in the last lisp-load-file or
450lisp-compile-file command. Used for determining the default in the
451next one.")
452
453(defvar lisp-source-modes '(lisp-mode)
454 "*Used to determine if a buffer contains Lisp source code.
455If it's loaded into a buffer that is in one of these major modes, it's
456considered a Lisp source file by lisp-load-file and lisp-compile-file.
457Used by these commands to determine defaults.")
458
459(defun lisp-load-file (file-name)
460 "Load a Lisp file into the inferior Lisp process."
461 (interactive (comint-get-source "Load Lisp file: " lisp-prev-l/c-dir/file
462 lisp-source-modes nil)) ; NIL because LOAD
463 ; doesn't need an exact name
464 (comint-check-source file-name) ; Check to see if buffer needs saved.
465 (setq lisp-prev-l/c-dir/file (cons (file-name-directory file-name)
466 (file-name-nondirectory file-name)))
467 (comint-send-string (cmulisp-proc)
468 (format inferior-lisp-load-command file-name))
469 (switch-to-lisp t))
470
471
472(defun lisp-compile-file (file-name)
473 "Compile a Lisp file in the inferior Lisp process."
474 (interactive (comint-get-source "Compile Lisp file: " lisp-prev-l/c-dir/file
475 lisp-source-modes nil)) ; NIL = don't need
476 ; suffix .lisp
477 (comint-check-source file-name) ; Check to see if buffer needs saved.
478 (setq lisp-prev-l/c-dir/file (cons (file-name-directory file-name)
479 (file-name-nondirectory file-name)))
480 (comint-send-string (cmulisp-proc) (concat "(compile-file \""
481 file-name
482 "\"\)\n"))
483 (switch-to-lisp t))
484
485
486
487;;; Documentation functions: function doc, var doc, arglist, and
488;;; describe symbol.
489;;; ===========================================================================
490
491;;; Command strings
492;;; ===============
493
494(defvar lisp-function-doc-command
495 "(let ((fn '%s))
496 (format t \"Documentation for ~a:~&~a\"
497 fn (documentation fn 'function))
498 (values))\n"
499 "Command to query inferior Lisp for a function's documentation.")
500
501(defvar lisp-var-doc-command
502 "(let ((v '%s))
503 (format t \"Documentation for ~a:~&~a\"
504 v (documentation v 'variable))
505 (values))\n"
506 "Command to query inferior Lisp for a variable's documentation.")
507
508(defvar lisp-arglist-command
509 "(let ((fn '%s))
510 (format t \"Arglist for ~a: ~a\" fn (arglist fn))
511 (values))\n"
512 "Command to query inferior Lisp for a function's arglist.")
513
514(defvar lisp-describe-sym-command
515 "(describe '%s)\n"
516 "Command to query inferior Lisp for a variable's documentation.")
517
518
519;;; Ancillary functions
520;;; ===================
521
522;;; Reads a string from the user.
523(defun lisp-symprompt (prompt default)
524 (list (let* ((prompt (if default
525 (format "%s (default %s): " prompt default)
526 (concat prompt ": ")))
527 (ans (read-string prompt)))
528 (if (zerop (length ans)) default ans))))
529
530
531;;; Adapted from function-called-at-point in help.el.
532(defun lisp-fn-called-at-pt ()
533 "Returns the name of the function called in the current call.
534Nil if it can't find one."
535 (condition-case nil
536 (save-excursion
537 (save-restriction
538 (narrow-to-region (max (point-min) (- (point) 1000)) (point-max))
539 (backward-up-list 1)
540 (forward-char 1)
541 (let ((obj (read (current-buffer))))
542 (and (symbolp obj) obj))))
543 (error nil)))
544
545
546;;; Adapted from variable-at-point in help.el.
547(defun lisp-var-at-pt ()
548 (condition-case ()
549 (save-excursion
550 (forward-sexp -1)
551 (skip-chars-forward "'")
552 (let ((obj (read (current-buffer))))
553 (and (symbolp obj) obj)))
554 (error nil)))
555
556
557;;; Documentation functions: fn and var doc, arglist, and symbol describe.
558;;; ======================================================================
559
560(defun lisp-show-function-documentation (fn)
561 "Send a command to the inferior Lisp to give documentation for function FN.
562See variable lisp-function-doc-command."
563 (interactive (lisp-symprompt "Function doc" (lisp-fn-called-at-pt)))
564 (comint-proc-query (cmulisp-proc) (format lisp-function-doc-command fn)))
565
566(defun lisp-show-variable-documentation (var)
567 "Send a command to the inferior Lisp to give documentation for function FN.
568See variable lisp-var-doc-command."
569 (interactive (lisp-symprompt "Variable doc" (lisp-var-at-pt)))
570 (comint-proc-query (cmulisp-proc) (format lisp-var-doc-command var)))
571
572(defun lisp-show-arglist (fn)
573 "Sends an query to the inferior Lisp for the arglist for function FN.
574See variable lisp-arglist-command."
575 (interactive (lisp-symprompt "Arglist" (lisp-fn-called-at-pt)))
576 (comint-proc-query (cmulisp-proc) (format lisp-arglist-command fn)))
577
578(defun lisp-describe-sym (sym)
579 "Send a command to the inferior Lisp to describe symbol SYM.
580See variable lisp-describe-sym-command."
581 (interactive (lisp-symprompt "Describe" (lisp-var-at-pt)))
582 (comint-proc-query (cmulisp-proc) (format lisp-describe-sym-command sym)))
583
584
585(defvar cmulisp-buffer nil "*The current cmulisp process buffer.
586
587MULTIPLE PROCESS SUPPORT
588===========================================================================
589Cmulisp.el supports, in a fairly simple fashion, running multiple Lisp
590processes. To run multiple Lisp processes, you start the first up with
591\\[cmulisp]. It will be in a buffer named *cmulisp*. Rename this buffer
592with \\[rename-buffer]. You may now start up a new process with another
593\\[cmulisp]. It will be in a new buffer, named *cmulisp*. You can
594switch between the different process buffers with \\[switch-to-buffer].
595
596Commands that send text from source buffers to Lisp processes --
597like lisp-eval-defun or lisp-show-arglist -- have to choose a process
598to send to, when you have more than one Lisp process around. This
599is determined by the global variable cmulisp-buffer. Suppose you
600have three inferior lisps running:
601 Buffer Process
602 foo cmulisp
603 bar cmulisp<2>
604 *cmulisp* cmulisp<3>
605If you do a \\[lisp-eval-defun] command on some Lisp source code,
606what process do you send it to?
607
608- If you're in a process buffer (foo, bar, or *cmulisp*),
609 you send it to that process.
610- If you're in some other buffer (e.g., a source file), you
611 send it to the process attached to buffer cmulisp-buffer.
612This process selection is performed by function cmulisp-proc.
613
614Whenever \\[cmulisp] fires up a new process, it resets cmulisp-buffer
615to be the new process's buffer. If you only run one process, this will
616do the right thing. If you run multiple processes, you can change
617cmulisp-buffer to another process buffer with \\[set-variable].
618
619More sophisticated approaches are, of course, possible. If you find youself
620needing to switch back and forth between multiple processes frequently,
621you may wish to consider ilisp.el, a larger, more sophisticated package
622for running inferior Lisp processes. The approach taken here is for a
623minimal, simple implementation. Feel free to extend it.")
624
625(defun cmulisp-proc ()
626 "Returns the current cmulisp process. See variable cmulisp-buffer."
627 (let ((proc (get-buffer-process (if (eq major-mode 'inferior-lisp-mode)
628 (current-buffer)
629 cmulisp-buffer))))
630 (or proc
631 (error "No current process. See variable cmulisp-buffer"))))
632
633
634;;; Do the user's customisation...
635;;;===============================
636(defvar cmulisp-load-hook nil
637 "This hook is run when cmulisp is loaded in.
638This is a good place to put keybindings.")
639
640(run-hooks 'cmulisp-load-hook)
641
642;;; CHANGE LOG
643;;; ===========================================================================
644;;; 5/24/90 Olin
645;;; - Split cmulisp and cmushell modes into separate files.
646;;; Not only is this a good idea, it's apparently the way it'll be rel 19.
647;;; - Upgraded process sends to use comint-send-string instead of
648;;; process-send-string.
649;;; - Explicit references to process "cmulisp" have been replaced with
650;;; (cmulisp-proc). This allows better handling of multiple process bufs.
651;;; - Added process query and var/function/symbol documentation
652;;; commands. Based on code written by Douglas Roberts.
653;;; - Added lisp-eval-last-sexp, bound to C-x C-e.
654;;;
655;;; 9/20/90 Olin
656;;; Added a save-restriction to lisp-fn-called-at-pt. This bug and fix
657;;; reported by Lennart Staflin.
658;;;
659;;; 3/12/90 Olin
660;;; - lisp-load-file and lisp-compile-file no longer switch-to-lisp.
661;;; Tale suggested this.
662;;; - Reversed this decision 7/15/91. You need the visual feedback.
663;;;
664;;; 7/25/91 Olin
665;;; Changed all keybindings of the form C-c <letter>. These are
666;;; supposed to be reserved for the user to bind. This affected
667;;; mainly the compile/eval-defun/region[-and-go] commands.
668;;; This was painful, but necessary to adhere to the gnumacs standard.
669;;; For some backwards compatibility, see the
670;;; cmulisp-install-letter-bindings
671;;; function.
672;;;
673;;; 8/2/91 Olin
674;;; - The lisp-compile/eval-defun/region commands now take a prefix arg,
675;;; which means switch-to-lisp after sending the text to the Lisp process.
676;;; This obsoletes all the -and-go commands. The -and-go commands are
677;;; kept around for historical reasons, and because the user can bind
678;;; them to key sequences shorter than C-u C-c C-<letter>.
679;;; - If M-x cmulisp is invoked with a prefix arg, it allows you to
680;;; edit the command line.
681
682(provide 'cmulisp)
683
684;;; cmulisp.el ends here
diff --git a/lisp/diary-ins.el b/lisp/diary-ins.el
new file mode 100644
index 00000000000..1ac2c0bfc0c
--- /dev/null
+++ b/lisp/diary-ins.el
@@ -0,0 +1,262 @@
1;;; diary-insert.el --- calendar functions for adding diary entries.
2
3;; Copyright (C) 1990 Free Software Foundation, Inc.
4
5;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
6;; Keywords: diary, calendar
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is distributed in the hope that it will be useful,
11;; but WITHOUT ANY WARRANTY. No author or distributor
12;; accepts responsibility to anyone for the consequences of using it
13;; or for whether it serves any particular purpose or works at all,
14;; unless he says so in writing. Refer to the GNU Emacs General Public
15;; License for full details.
16
17;; Everyone is granted permission to copy, modify and redistribute
18;; GNU Emacs, but only under the conditions described in the
19;; GNU Emacs General Public License. A copy of this license is
20;; supposed to have been given to you along with GNU Emacs so you
21;; can know your rights and responsibilities. It should be in a
22;; file named COPYING. Among other things, the copyright notice
23;; and this notice must be preserved on all copies.
24
25;;; Commentary:
26
27;; This collection of functions implements the diary insertion features as
28;; described in calendar.el.
29
30;; Comments, corrections, and improvements should be sent to
31;; Edward M. Reingold Department of Computer Science
32;; (217) 333-6733 University of Illinois at Urbana-Champaign
33;; reingold@cs.uiuc.edu 1304 West Springfield Avenue
34;; Urbana, Illinois 61801
35
36;;; Code:
37
38(require 'diary)
39
40(defun make-diary-entry (string &optional nonmarking file)
41 "Insert a diary entry STRING which may be NONMARKING in FILE.
42If omitted, NONMARKING defaults to nil and FILE defaults to diary-file."
43 (find-file-other-window
44 (substitute-in-file-name (if file file diary-file)))
45 (goto-char (point-max))
46 (insert
47 (if (bolp) "" "\n")
48 (if nonmarking diary-nonmarking-symbol "")
49 string " "))
50
51(defun insert-diary-entry (arg)
52 "Insert a diary entry for the date indicated by point.
53Prefix arg will make the entry nonmarking."
54 (interactive "P")
55 (make-diary-entry
56 (calendar-date-string
57 (or (calendar-cursor-to-date)
58 (error "Cursor is not on a date!"))
59 t t)
60 arg))
61
62(defun insert-weekly-diary-entry (arg)
63 "Insert a weekly diary entry for the day of the week indicated by point.
64Prefix arg will make the entry nonmarking."
65 (interactive "P")
66 (make-diary-entry
67 (calendar-day-name
68 (or (calendar-cursor-to-date)
69 (error "Cursor is not on a date!")))
70 arg))
71
72(defun insert-monthly-diary-entry (arg)
73 "Insert a monthly diary entry for the day of the month indicated by point.
74Prefix arg will make the entry nonmarking."
75 (interactive "P")
76 (let* ((calendar-date-display-form
77 (if european-calendar-style
78 '(day " * ")
79 '("* " day))))
80 (make-diary-entry
81 (calendar-date-string
82 (or (calendar-cursor-to-date)
83 (error "Cursor is not on a date!"))
84 t)
85 arg)))
86
87(defun insert-yearly-diary-entry (arg)
88 "Insert an annual diary entry for the day of the year indicated by point.
89Prefix arg will make the entry nonmarking."
90 (interactive "P")
91 (let* ((calendar-date-display-form
92 (if european-calendar-style
93 '(day " " monthname)
94 '(monthname " " day))))
95 (make-diary-entry
96 (calendar-date-string
97 (or (calendar-cursor-to-date)
98 (error "Cursor is not on a date!"))
99 t)
100 arg)))
101
102(defun insert-anniversary-diary-entry (arg)
103 "Insert an anniversary diary entry for the date given by point.
104Prefix arg will make the entry nonmarking."
105 (interactive "P")
106 (make-diary-entry
107 (format "%s(diary-anniversary %s)"
108 sexp-diary-entry-symbol
109 (calendar-date-string
110 (or (calendar-cursor-to-date)
111 (error "Cursor is not on a date!"))
112 nil t))
113 arg))
114
115(defun insert-block-diary-entry (arg)
116 "Insert a block diary entry for the days between the point and marked date.
117Prefix arg will make the entry nonmarking."
118 (interactive "P")
119 (let* ((cursor (or (calendar-cursor-to-date)
120 (error "Cursor is not on a date!")))
121 (mark (or (car calendar-mark-ring)
122 (error "No mark set in this buffer")))
123 (start)
124 (end))
125 (if (< (calendar-absolute-from-gregorian mark)
126 (calendar-absolute-from-gregorian cursor))
127 (setq start mark
128 end cursor)
129 (setq start cursor
130 end mark))
131 (make-diary-entry
132 (format "%s(diary-block %s %s)"
133 sexp-diary-entry-symbol
134 (calendar-date-string start nil t)
135 (calendar-date-string end nil t))
136 arg)))
137
138(defun insert-cyclic-diary-entry (arg)
139 "Insert a cyclic diary entry starting at the date given by point.
140Prefix arg will make the entry nonmarking."
141 (interactive "P")
142 (make-diary-entry
143 (format "%s(diary-cyclic %d %s)"
144 sexp-diary-entry-symbol
145 (calendar-read "Repeat every how many days: "
146 '(lambda (x) (> x 0)))
147 (calendar-date-string
148 (or (calendar-cursor-to-date)
149 (error "Cursor is not on a date!"))
150 nil t))
151 arg))
152
153(defun insert-hebrew-diary-entry (arg)
154 "Insert a diary entry for the Hebrew date corresponding to the date
155indicated by point. Prefix arg will make the entry nonmarking."
156 (interactive "P")
157 (let* ((calendar-month-name-array
158 calendar-hebrew-month-name-array-leap-year))
159 (make-diary-entry
160 (concat
161 hebrew-diary-entry-symbol
162 (calendar-date-string
163 (calendar-hebrew-from-absolute
164 (calendar-absolute-from-gregorian
165 (or (calendar-cursor-to-date)
166 (error "Cursor is not on a date!"))))
167 nil t))
168 arg)))
169
170(defun insert-monthly-hebrew-diary-entry (arg)
171 "Insert a monthly diary entry for the day of the Hebrew month corresponding
172to the date indicated by point. Prefix arg will make the entry nonmarking."
173 (interactive "P")
174 (let* ((calendar-date-display-form
175 (if european-calendar-style '(day " * ") '("* " day )))
176 (calendar-month-name-array
177 calendar-hebrew-month-name-array-leap-year))
178 (make-diary-entry
179 (concat
180 hebrew-diary-entry-symbol
181 (calendar-date-string
182 (calendar-hebrew-from-absolute
183 (calendar-absolute-from-gregorian
184 (or (calendar-cursor-to-date)
185 (error "Cursor is not on a date!"))))))
186 arg)))
187
188(defun insert-yearly-hebrew-diary-entry (arg)
189 "Insert an annual diary entry for the day of the Hebrew year corresponding
190to the date indicated by point. Prefix arg will make the entry nonmarking."
191 (interactive "P")
192 (let* ((calendar-date-display-form
193 (if european-calendar-style
194 '(day " " monthname)
195 '(monthname " " day)))
196 (calendar-month-name-array
197 calendar-hebrew-month-name-array-leap-year))
198 (make-diary-entry
199 (concat
200 hebrew-diary-entry-symbol
201 (calendar-date-string
202 (calendar-hebrew-from-absolute
203 (calendar-absolute-from-gregorian
204 (or (calendar-cursor-to-date)
205 (error "Cursor is not on a date!"))))))
206 arg)))
207
208(defun insert-islamic-diary-entry (arg)
209 "Insert a diary entry for the Islamic date corresponding to the date
210indicated by point. Prefix arg will make the entry nonmarking."
211 (interactive "P")
212 (let* ((calendar-month-name-array calendar-islamic-month-name-array))
213 (make-diary-entry
214 (concat
215 islamic-diary-entry-symbol
216 (calendar-date-string
217 (calendar-islamic-from-absolute
218 (calendar-absolute-from-gregorian
219 (or (calendar-cursor-to-date)
220 (error "Cursor is not on a date!"))))
221 nil t))
222 arg)))
223
224(defun insert-monthly-islamic-diary-entry (arg)
225 "Insert a monthly diary entry for the day of the Islamic month corresponding
226to the date indicated by point. Prefix arg will make the entry nonmarking."
227 (interactive "P")
228 (let* ((calendar-date-display-form
229 (if european-calendar-style '(day " * ") '("* " day )))
230 (calendar-month-name-array calendar-islamic-month-name-array))
231 (make-diary-entry
232 (concat
233 islamic-diary-entry-symbol
234 (calendar-date-string
235 (calendar-islamic-from-absolute
236 (calendar-absolute-from-gregorian
237 (or (calendar-cursor-to-date)
238 (error "Cursor is not on a date!"))))))
239 arg)))
240
241(defun insert-yearly-islamic-diary-entry (arg)
242 "Insert an annual diary entry for the day of the Islamic year corresponding
243to the date indicated by point. Prefix arg will make the entry nonmarking."
244 (interactive "P")
245 (let* ((calendar-date-display-form
246 (if european-calendar-style
247 '(day " " monthname)
248 '(monthname " " day)))
249 (calendar-month-name-array calendar-islamic-month-name-array))
250 (make-diary-entry
251 (concat
252 islamic-diary-entry-symbol
253 (calendar-date-string
254 (calendar-islamic-from-absolute
255 (calendar-absolute-from-gregorian
256 (or (calendar-cursor-to-date)
257 (error "Cursor is not on a date!"))))))
258 arg)))
259
260(provide 'diary-insert)
261
262;;; diary-insert.el ends here
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 008a9967322..d4789564f5f 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -234,9 +234,9 @@
234 (let ((lambda (car form)) 234 (let ((lambda (car form))
235 (values (cdr form))) 235 (values (cdr form)))
236 (if (compiled-function-p lambda) 236 (if (compiled-function-p lambda)
237 (setq lambda (list 'lambda (nth 0 form) 237 (setq lambda (list 'lambda (aref lambda 0)
238 (list 'byte-code 238 (list 'byte-code (aref lambda 1)
239 (nth 1 form) (nth 2 form) (nth 3 form))))) 239 (aref lambda 2) (aref lambda 3)))))
240 (let ((arglist (nth 1 lambda)) 240 (let ((arglist (nth 1 lambda))
241 (body (cdr (cdr lambda))) 241 (body (cdr (cdr lambda)))
242 optionalp restp 242 optionalp restp
@@ -913,7 +913,8 @@
913 (eq (car-safe last) 'quote)) 913 (eq (car-safe last) 'quote))
914 (if (listp (nth 1 last)) 914 (if (listp (nth 1 last))
915 (let ((butlast (nreverse (cdr (reverse (cdr (cdr form))))))) 915 (let ((butlast (nreverse (cdr (reverse (cdr (cdr form)))))))
916 (nconc (list 'funcall fn) butlast (nth 1 last))) 916 (nconc (list 'funcall fn) butlast
917 (mapcar '(lambda (x) (list 'quote x)) (nth 1 last))))
917 (byte-compile-warn 918 (byte-compile-warn
918 "last arg to apply can't be a literal atom: %s" 919 "last arg to apply can't be a literal atom: %s"
919 (prin1-to-string last)) 920 (prin1-to-string last))
diff --git a/lisp/progmodes/inf-lisp.el b/lisp/progmodes/inf-lisp.el
index 820ae27389e..5706990ea56 100644
--- a/lisp/progmodes/inf-lisp.el
+++ b/lisp/progmodes/inf-lisp.el
@@ -142,6 +142,7 @@
142(require 'lisp-mode) 142(require 'lisp-mode)
143 143
144 144
145;;;###autoload
145(defvar inferior-lisp-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)\\)?\\s *\\'" 146(defvar inferior-lisp-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)\\)?\\s *\\'"
146 "*What not to save on inferior Lisp's input history 147 "*What not to save on inferior Lisp's input history
147Input matching this regexp is not saved on the input history in inferior-lisp 148Input matching this regexp is not saved on the input history in inferior-lisp
@@ -212,9 +213,11 @@ You can modify this function to install just the bindings you want."
212 'lisp-show-variable-documentation)) 213 'lisp-show-variable-documentation))
213 214
214 215
216;;;###autoload
215(defvar inferior-lisp-program "lisp" 217(defvar inferior-lisp-program "lisp"
216 "*Program name for invoking an inferior Lisp with `inferior-lisp'.") 218 "*Program name for invoking an inferior Lisp with `inferior-lisp'.")
217 219
220;;;###autoload
218(defvar inferior-lisp-load-command "(load \"%s\")\n" 221(defvar inferior-lisp-load-command "(load \"%s\")\n"
219 "*Format-string for building a Lisp expression to load a file. 222 "*Format-string for building a Lisp expression to load a file.
220This format string should use %s to substitute a file name 223This format string should use %s to substitute a file name
@@ -224,6 +227,7 @@ The string \"(progn (load \\\"%s\\\" :verbose nil :print t) (values))\\\n\"
224produces cosmetically superior output for this application, 227produces cosmetically superior output for this application,
225but it works only in Common Lisp.") 228but it works only in Common Lisp.")
226 229
230;;;###autoload
227(defvar inferior-lisp-prompt "^[^> ]*>+:? *" 231(defvar inferior-lisp-prompt "^[^> ]*>+:? *"
228 "Regexp to recognise prompts in the inferior Lisp. 232 "Regexp to recognise prompts in the inferior Lisp.
229Defaults to \"^[^> ]*>+:? *\", which works pretty good for Lucid, kcl, 233Defaults to \"^[^> ]*>+:? *\", which works pretty good for Lucid, kcl,
@@ -237,6 +241,7 @@ kcl: \"^>+ *\"
237 241
238This is a fine thing to set in your .emacs file.") 242This is a fine thing to set in your .emacs file.")
239 243
244;;;###autoload
240(defvar inferior-lisp-mode-hook '() 245(defvar inferior-lisp-mode-hook '()
241 "*Hook for customising inferior-lisp mode") 246 "*Hook for customising inferior-lisp mode")
242 247
@@ -304,6 +309,7 @@ to continue it."
304 "Don't save anything matching inferior-lisp-filter-regexp" 309 "Don't save anything matching inferior-lisp-filter-regexp"
305 (not (string-match inferior-lisp-filter-regexp str))) 310 (not (string-match inferior-lisp-filter-regexp str)))
306 311
312;;;###autoload
307(defun inferior-lisp (cmd) 313(defun inferior-lisp (cmd)
308 "Run an inferior Lisp process, input and output via buffer *inferior-lisp*. 314 "Run an inferior Lisp process, input and output via buffer *inferior-lisp*.
309If there is a process already running in *inferior-lisp*, just switch 315If there is a process already running in *inferior-lisp*, just switch
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index 18b0782b92d..02277d796d6 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -29,24 +29,29 @@
29;; This was a pain. Now, make-comint should autoload comint. 29;; This was a pain. Now, make-comint should autoload comint.
30;; (require 'comint) 30;; (require 'comint)
31 31
32;;;###autoload
32(defvar tex-shell-file-name nil 33(defvar tex-shell-file-name nil
33 "*If non-nil, is file name to use for the subshell in which TeX is run.") 34 "*If non-nil, is file name to use for the subshell in which TeX is run.")
34 35
36;;;###autoload
35(defvar tex-directory "." 37(defvar tex-directory "."
36 "*Directory in which temporary files are left. 38 "*Directory in which temporary files are left.
37You can make this /tmp if your TEXINPUTS has no relative directories in it 39You can make this /tmp if your TEXINPUTS has no relative directories in it
38and you don't try to apply \\[tex-region] or \\[tex-buffer] when there are 40and you don't try to apply \\[tex-region] or \\[tex-buffer] when there are
39\\input commands with relative directories.") 41\\input commands with relative directories.")
40 42
43;;;###autoload
41(defvar tex-offer-save t 44(defvar tex-offer-save t
42 "*If non-nil, ask about saving modified buffers before \\[tex-file] is run.") 45 "*If non-nil, ask about saving modified buffers before \\[tex-file] is run.")
43 46
47;;;###autoload
44(defvar tex-run-command "tex" 48(defvar tex-run-command "tex"
45 "*Command used to run TeX subjob. 49 "*Command used to run TeX subjob.
46If this string contains an asterisk (*), it will be replaced by the 50If this string contains an asterisk (*), it will be replaced by the
47filename; if not, the name of the file, preceded by blank, will be added to 51filename; if not, the name of the file, preceded by blank, will be added to
48this string.") 52this string.")
49 53
54;;;###autoload
50(defvar latex-run-command "latex" 55(defvar latex-run-command "latex"
51 "*Command used to run LaTeX subjob. 56 "*Command used to run LaTeX subjob.
52If this string contains an asterisk (*), it will be replaced by the 57If this string contains an asterisk (*), it will be replaced by the
@@ -65,28 +70,33 @@ this string.")
65 "verbatim" "verbatim*" "verse") 70 "verbatim" "verbatim*" "verse")
66 "Standard LaTeX block names.") 71 "Standard LaTeX block names.")
67 72
73;;;###autoload
68(defvar latex-block-names nil 74(defvar latex-block-names nil
69 "*User defined LaTeX block names. 75 "*User defined LaTeX block names.
70Combined with `standard-latex-block-names' for minibuffer completion.") 76Combined with `standard-latex-block-names' for minibuffer completion.")
71 77
78;;;###autoload
72(defvar slitex-run-command "slitex" 79(defvar slitex-run-command "slitex"
73 "*Command used to run SliTeX subjob. 80 "*Command used to run SliTeX subjob.
74If this string contains an asterisk (*), it will be replaced by the 81If this string contains an asterisk (*), it will be replaced by the
75filename; if not, the name of the file, preceded by blank, will be added to 82filename; if not, the name of the file, preceded by blank, will be added to
76this string.") 83this string.")
77 84
85;;;###autoload
78(defvar tex-bibtex-command "bibtex" 86(defvar tex-bibtex-command "bibtex"
79 "*Command used by `tex-bibtex-file' to gather bibliographic data. 87 "*Command used by `tex-bibtex-file' to gather bibliographic data.
80If this string contains an asterisk (*), it will be replaced by the 88If this string contains an asterisk (*), it will be replaced by the
81filename; if not, the name of the file, preceded by blank, will be added to 89filename; if not, the name of the file, preceded by blank, will be added to
82this string.") 90this string.")
83 91
92;;;###autoload
84(defvar tex-dvi-print-command "lpr -d" 93(defvar tex-dvi-print-command "lpr -d"
85 "*Command used by \\[tex-print] to print a .dvi file. 94 "*Command used by \\[tex-print] to print a .dvi file.
86If this string contains an asterisk (*), it will be replaced by the 95If this string contains an asterisk (*), it will be replaced by the
87filename; if not, the name of the file, preceded by blank, will be added to 96filename; if not, the name of the file, preceded by blank, will be added to
88this string.") 97this string.")
89 98
99;;;###autoload
90(defvar tex-alt-dvi-print-command "lpr -d" 100(defvar tex-alt-dvi-print-command "lpr -d"
91 "*Command used by \\[tex-print] with a prefix arg to print a .dvi file. 101 "*Command used by \\[tex-print] with a prefix arg to print a .dvi file.
92If this string contains an asterisk (*), it will be replaced by the 102If this string contains an asterisk (*), it will be replaced by the
@@ -103,6 +113,7 @@ for example,
103would tell \\[tex-print] with a prefix argument to ask you which printer to 113would tell \\[tex-print] with a prefix argument to ask you which printer to
104use.") 114use.")
105 115
116;;;###autoload
106(defvar tex-dvi-view-command nil 117(defvar tex-dvi-view-command nil
107 "*Command used by \\[tex-view] to display a .dvi file. 118 "*Command used by \\[tex-view] to display a .dvi file.
108If this string contains an asterisk (*), it will be replaced by the 119If this string contains an asterisk (*), it will be replaced by the
@@ -118,19 +129,23 @@ window system being used. For example,
118would tell \\[tex-view] use xdvi under X windows and to use dvi2tty 129would tell \\[tex-view] use xdvi under X windows and to use dvi2tty
119otherwise.") 130otherwise.")
120 131
132;;;###autoload
121(defvar tex-show-queue-command "lpq" 133(defvar tex-show-queue-command "lpq"
122 "*Command used by \\[tex-show-print-queue] to show the print queue. 134 "*Command used by \\[tex-show-print-queue] to show the print queue.
123Should show the queue(s) that \\[tex-print] puts jobs on.") 135Should show the queue(s) that \\[tex-print] puts jobs on.")
124 136
137;;;###autoload
125(defvar tex-default-mode 'plain-tex-mode 138(defvar tex-default-mode 'plain-tex-mode
126 "*Mode to enter for a new file that might be either TeX or LaTeX. 139 "*Mode to enter for a new file that might be either TeX or LaTeX.
127This variable is used when it can't be determined whether the file 140This variable is used when it can't be determined whether the file
128is plain TeX or LaTeX or what because the file contains no commands. 141is plain TeX or LaTeX or what because the file contains no commands.
129Normally set to either 'plain-tex-mode or 'latex-mode.") 142Normally set to either 'plain-tex-mode or 'latex-mode.")
130 143
144;;;###autoload
131(defvar tex-open-quote "``" 145(defvar tex-open-quote "``"
132 "*String inserted by typing \\[tex-insert-quote] to open a quotation.") 146 "*String inserted by typing \\[tex-insert-quote] to open a quotation.")
133 147
148;;;###autoload
134(defvar tex-close-quote "''" 149(defvar tex-close-quote "''"
135 "*String inserted by typing \\[tex-insert-quote] to close a quotation.") 150 "*String inserted by typing \\[tex-insert-quote] to close a quotation.")
136 151