Mercurial > emacs
comparison lisp/calendar/calendar.el @ 92969:bb4fc128d00d
(european-calendar-style, calendar-for-loop)
(calendar-sum, calendar-insert-indented, mouse-calendar-other-month)
(calendar-cursor-to-date): Doc fix.
(hebrew-holidays-1, hebrew-holidays-4): Simplify.
(extract-calendar-day, extract-calendar-year): Use cadr, nth.
(calendar-day-number): Use when.
(generate-calendar-month): Use dotimes.
(exit-calendar, calendar-print-other-dates): Use let rather than let*.
(calendar-set-mark): Reverse conditional.
(calendar-make-alist): Move definition before use.
author | Glenn Morris <rgm@gnu.org> |
---|---|
date | Sat, 15 Mar 2008 03:00:17 +0000 |
parents | d0fa9dff8d20 |
children | 189ca7ef805d |
comparison
equal
deleted
inserted
replaced
92968:e2f0046a8cb4 | 92969:bb4fc128d00d |
---|---|
89 | 89 |
90 ;; Hard copies of these two papers can be obtained by sending email to | 90 ;; Hard copies of these two papers can be obtained by sending email to |
91 ;; reingold@cs.uiuc.edu with the SUBJECT "send-paper-cal" (no quotes) and | 91 ;; reingold@cs.uiuc.edu with the SUBJECT "send-paper-cal" (no quotes) and |
92 ;; the message BODY containing your mailing address (snail). | 92 ;; the message BODY containing your mailing address (snail). |
93 | 93 |
94 | |
95 ;; A note on free variables: | |
96 | |
97 ;; The calendar passes around a few dynamically bound variables, which | |
98 ;; unfortunately have rather common names. They are meant to be | |
99 ;; available for external functions, so the names can't be changed. | |
100 | |
101 ;; displayed-month, displayed-year: bound in generate-calendar, the | |
102 ;; central month of the 3 month calendar window | |
103 ;; original-date, number: bound in diary-list-entries, the arguments | |
104 ;; with which that function was called. | |
105 ;; date, entry: bound in list-sexp-diary-entries (qv) | |
106 | |
107 ;; Bound in diary-list-entries: | |
108 ;; diary-entries-list: use in d-l, appt.el, and by add-to-diary-list | |
109 ;; diary-saved-point: only used in diary-lib.el, passed to the display func | |
110 ;; date-string: only used in diary-lib.el FIXME could be removed? | |
111 | |
94 ;;; Code: | 112 ;;; Code: |
95 | 113 |
96 ;; (elisp) Eval During Compile: "Effectively `require' is | 114 ;; (elisp) Eval During Compile: "Effectively `require' is |
97 ;; automatically `eval-and-compile'" [but `load' is not] | 115 ;; automatically `eval-and-compile'" [but `load' is not] |
98 (eval-and-compile | 116 (eval-and-compile |
455 :group 'diary) | 473 :group 'diary) |
456 | 474 |
457 ;;;###autoload | 475 ;;;###autoload |
458 (defcustom european-calendar-style nil | 476 (defcustom european-calendar-style nil |
459 "Use the European style of dates in the diary and in any displays. | 477 "Use the European style of dates in the diary and in any displays. |
460 If this variable is t, a date 1/2/1990 would be interpreted as February 1, | 478 If this variable is non-nil, a date 1/2/1990 would be interpreted as |
461 1990. The default European date styles (see `european-date-diary-pattern') | 479 February 1, 1990. The default European date styles (see |
462 are | 480 `european-date-diary-pattern') are |
463 | 481 |
464 DAY/MONTH | 482 DAY/MONTH |
465 DAY/MONTH/YEAR | 483 DAY/MONTH/YEAR |
466 DAY MONTHNAME | 484 DAY MONTHNAME |
467 DAY MONTHNAME YEAR | 485 DAY MONTHNAME YEAR |
744 (defvar hebrew-holidays-1 | 762 (defvar hebrew-holidays-1 |
745 '((holiday-rosh-hashanah-etc) | 763 '((holiday-rosh-hashanah-etc) |
746 (if all-hebrew-calendar-holidays | 764 (if all-hebrew-calendar-holidays |
747 (holiday-julian | 765 (holiday-julian |
748 11 | 766 11 |
749 (let* ((m displayed-month) | 767 (let ((m displayed-month) |
750 (y displayed-year) | 768 (y displayed-year) |
751 (year)) | 769 year) |
752 (increment-calendar-month m y -1) | 770 (increment-calendar-month m y -1) |
753 (let ((year (extract-calendar-year | 771 (setq year (extract-calendar-year |
754 (calendar-julian-from-absolute | 772 (calendar-julian-from-absolute |
755 (calendar-absolute-from-gregorian | 773 (calendar-absolute-from-gregorian (list m 1 y))))) |
756 (list m 1 y)))))) | 774 (if (zerop (% (1+ year) 4)) |
757 (if (zerop (% (1+ year) 4)) | 775 22 |
758 22 | 776 21)) "\"Tal Umatar\" (evening)"))) |
759 21))) "\"Tal Umatar\" (evening)"))) | |
760 "Component of the default value of `hebrew-holidays'.") | 777 "Component of the default value of `hebrew-holidays'.") |
761 ;;;###autoload | 778 ;;;###autoload |
762 (put 'hebrew-holidays-1 'risky-local-variable t) | 779 (put 'hebrew-holidays-1 'risky-local-variable t) |
763 | 780 |
764 ;;;###autoload | 781 ;;;###autoload |
771 10 | 788 10 |
772 (let ((h-year (extract-calendar-year | 789 (let ((h-year (extract-calendar-year |
773 (calendar-hebrew-from-absolute | 790 (calendar-hebrew-from-absolute |
774 (calendar-absolute-from-gregorian | 791 (calendar-absolute-from-gregorian |
775 (list displayed-month 28 displayed-year)))))) | 792 (list displayed-month 28 displayed-year)))))) |
776 (if (= (% (calendar-absolute-from-hebrew (list 10 10 h-year)) | 793 (if (= 6 (% (calendar-absolute-from-hebrew (list 10 10 h-year)) |
777 7) | 794 7)) |
778 6) | |
779 11 10)) | 795 11 10)) |
780 "Tzom Teveth")) | 796 "Tzom Teveth")) |
781 (if all-hebrew-calendar-holidays | 797 (if all-hebrew-calendar-holidays |
782 (holiday-hebrew 11 15 "Tu B'Shevat"))) | 798 (holiday-hebrew 11 15 "Tu B'Shevat"))) |
783 "Component of the default value of `hebrew-holidays'.") | 799 "Component of the default value of `hebrew-holidays'.") |
798 (list m | 814 (list m |
799 (calendar-last-day-of-month m y) | 815 (calendar-last-day-of-month m y) |
800 y))))) | 816 y))))) |
801 (s-s | 817 (s-s |
802 (calendar-hebrew-from-absolute | 818 (calendar-hebrew-from-absolute |
803 (if (= | 819 (if (= 6 |
804 (% (calendar-absolute-from-hebrew | 820 (% (calendar-absolute-from-hebrew |
805 (list 7 1 h-year)) | 821 (list 7 1 h-year)) |
806 7) | 822 7)) |
807 6) | |
808 (calendar-dayname-on-or-before | 823 (calendar-dayname-on-or-before |
809 6 (calendar-absolute-from-hebrew | 824 6 (calendar-absolute-from-hebrew |
810 (list 11 17 h-year))) | 825 (list 11 17 h-year))) |
811 (calendar-dayname-on-or-before | 826 (calendar-dayname-on-or-before |
812 6 (calendar-absolute-from-hebrew | 827 6 (calendar-absolute-from-hebrew |
820 | 835 |
821 ;;;###autoload | 836 ;;;###autoload |
822 (defvar hebrew-holidays-4 | 837 (defvar hebrew-holidays-4 |
823 '((holiday-passover-etc) | 838 '((holiday-passover-etc) |
824 (if (and all-hebrew-calendar-holidays | 839 (if (and all-hebrew-calendar-holidays |
825 (let* ((m displayed-month) | 840 (let ((m displayed-month) |
826 (y displayed-year) | 841 (y displayed-year) |
827 (year)) | 842 year) |
828 (increment-calendar-month m y -1) | 843 (increment-calendar-month m y -1) |
829 (let ((year (extract-calendar-year | 844 (setq year (extract-calendar-year |
830 (calendar-julian-from-absolute | 845 (calendar-julian-from-absolute |
831 (calendar-absolute-from-gregorian | 846 (calendar-absolute-from-gregorian |
832 (list m 1 y)))))) | 847 (list m 1 y))))) |
833 (= 21 (% year 28))))) | 848 (= 21 (% year 28)))) |
834 (holiday-julian 3 26 "Kiddush HaHamah")) | 849 (holiday-julian 3 26 "Kiddush HaHamah")) |
835 (if all-hebrew-calendar-holidays | 850 (if all-hebrew-calendar-holidays |
836 (holiday-tisha-b-av-etc))) | 851 (holiday-tisha-b-av-etc))) |
837 "Component of the default value of `hebrew-holidays'.") | 852 "Component of the default value of `hebrew-holidays'.") |
838 ;;;###autoload | 853 ;;;###autoload |
1189 (cons mon yr)) | 1204 (cons mon yr)) |
1190 | 1205 |
1191 (defmacro calendar-for-loop (var from init to final do &rest body) | 1206 (defmacro calendar-for-loop (var from init to final do &rest body) |
1192 "Execute a for loop. | 1207 "Execute a for loop. |
1193 Evaluate BODY with VAR bound to successive integers from INIT to FINAL, | 1208 Evaluate BODY with VAR bound to successive integers from INIT to FINAL, |
1194 inclusive." | 1209 inclusive. The standard macro `dotimes' is preferable in most cases." |
1195 (declare (debug (symbolp "from" form "to" form "do" body))) | 1210 (declare (debug (symbolp "from" form "to" form "do" body))) |
1196 `(let ((,var (1- ,init))) | 1211 `(let ((,var (1- ,init))) |
1197 (while (>= ,final (setq ,var (1+ ,var))) | 1212 (while (>= ,final (setq ,var (1+ ,var))) |
1198 ,@body))) | 1213 ,@body))) |
1199 | 1214 |
1200 (defmacro calendar-sum (index initial condition expression) | 1215 (defmacro calendar-sum (index initial condition expression) |
1201 "For INDEX = INITIAL et seq, as long as CONDITION holds, sum EXPRESSION." | 1216 "For INDEX = INITIAL, +1, ... (as long as CONDITION holds), sum EXPRESSION." |
1202 (declare (debug (symbolp form form form))) | 1217 (declare (debug (symbolp form form form))) |
1203 `(let ((,index ,initial) | 1218 `(let ((,index ,initial) |
1204 (sum 0)) | 1219 (sum 0)) |
1205 (while ,condition | 1220 (while ,condition |
1206 (setq sum (+ sum ,expression)) | 1221 (setq sum (+ sum ,expression) |
1207 (setq ,index (1+ ,index))) | 1222 ,index (1+ ,index))) |
1208 sum)) | 1223 sum)) |
1209 | 1224 |
1210 ;; The following are in-line for speed; they can be called thousands of times | 1225 ;; The following are in-line for speed; they can be called thousands of times |
1211 ;; when looking up holidays or processing the diary. Here, for example, are | 1226 ;; when looking up holidays or processing the diary. Here, for example, are |
1212 ;; the numbers of calls to calendar/diary/holiday functions in preparing the | 1227 ;; the numbers of calls to calendar/diary/holiday functions in preparing the |
1240 (car date)) | 1255 (car date)) |
1241 | 1256 |
1242 ;; Note gives wrong answer for result of (calendar-read-date 'noday). | 1257 ;; Note gives wrong answer for result of (calendar-read-date 'noday). |
1243 (defsubst extract-calendar-day (date) | 1258 (defsubst extract-calendar-day (date) |
1244 "Extract the day part of DATE which has the form (month day year)." | 1259 "Extract the day part of DATE which has the form (month day year)." |
1245 (car (cdr date))) | 1260 (cadr date)) |
1246 | 1261 |
1247 (defsubst extract-calendar-year (date) | 1262 (defsubst extract-calendar-year (date) |
1248 "Extract the year part of DATE which has the form (month day year)." | 1263 "Extract the year part of DATE which has the form (month day year)." |
1249 (car (cdr (cdr date)))) | 1264 (nth 2 date)) |
1250 | 1265 |
1251 (defsubst calendar-leap-year-p (year) | 1266 (defsubst calendar-leap-year-p (year) |
1252 "Return t if YEAR is a Gregorian leap year. | 1267 "Return t if YEAR is a Gregorian leap year. |
1253 A negative year is interpreted as BC; -1 being 1 BC, and so on." | 1268 A negative year is interpreted as BC; -1 being 1 BC, and so on." |
1254 ;; 1 BC = 0 AD, 2 BC acts like 1 AD, etc. | 1269 ;; 1 BC = 0 AD, 2 BC acts like 1 AD, etc. |
1277 | 1292 |
1278 (defsubst calendar-day-number (date) | 1293 (defsubst calendar-day-number (date) |
1279 "Return the day number within the year of the date DATE. | 1294 "Return the day number within the year of the date DATE. |
1280 For example, (calendar-day-number '(1 1 1987)) returns the value 1, | 1295 For example, (calendar-day-number '(1 1 1987)) returns the value 1, |
1281 while (calendar-day-number '(12 31 1980)) returns 366." | 1296 while (calendar-day-number '(12 31 1980)) returns 366." |
1282 (let* ((month (extract-calendar-month date)) | 1297 (let* ((month (extract-calendar-month date)) |
1283 (day (extract-calendar-day date)) | 1298 (day (extract-calendar-day date)) |
1284 (year (extract-calendar-year date)) | 1299 (year (extract-calendar-year date)) |
1285 (day-of-year (+ day (* 31 (1- month))))) | 1300 (day-of-year (+ day (* 31 (1- month))))) |
1286 (if (> month 2) | 1301 (when (> month 2) |
1287 (progn | 1302 (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10))) |
1288 (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10))) | 1303 (if (calendar-leap-year-p year) |
1289 (if (calendar-leap-year-p year) | 1304 (setq day-of-year (1+ day-of-year)))) |
1290 (setq day-of-year (1+ day-of-year))))) | 1305 day-of-year)) |
1291 day-of-year)) | |
1292 | 1306 |
1293 (defsubst calendar-absolute-from-gregorian (date) | 1307 (defsubst calendar-absolute-from-gregorian (date) |
1294 "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE. | 1308 "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE. |
1295 The Gregorian date Sunday, December 31, 1 BC is imaginary. | 1309 The Gregorian date Sunday, December 31, 1 BC is imaginary. |
1296 DATE is a list of the form (month day year). A negative year is | 1310 DATE is a list of the form (month day year). A negative year is |
1376 (interactive "P") | 1390 (interactive "P") |
1377 (set-buffer (get-buffer-create calendar-buffer)) | 1391 (set-buffer (get-buffer-create calendar-buffer)) |
1378 (calendar-mode) | 1392 (calendar-mode) |
1379 (let* ((pop-up-windows t) | 1393 (let* ((pop-up-windows t) |
1380 (split-height-threshold 1000) | 1394 (split-height-threshold 1000) |
1381 (date (if arg | 1395 (date (if arg (calendar-read-date t) |
1382 (calendar-read-date t) | |
1383 (calendar-current-date))) | 1396 (calendar-current-date))) |
1384 (month (extract-calendar-month date)) | 1397 (month (extract-calendar-month date)) |
1385 (year (extract-calendar-year date))) | 1398 (year (extract-calendar-year date))) |
1386 ;; (calendar-read-date t) returns a date with day = nil, which is | 1399 ;; (calendar-read-date t) returns a date with day = nil, which is |
1387 ;; not a valid date for the visible test in the diary section. | 1400 ;; not a valid date for the visible test in the diary section. |
1463 "Produce a calendar for MONTH, YEAR on the Gregorian calendar. | 1476 "Produce a calendar for MONTH, YEAR on the Gregorian calendar. |
1464 The calendar is inserted at the top of the buffer in which point is currently | 1477 The calendar is inserted at the top of the buffer in which point is currently |
1465 located, but indented INDENT spaces. The indentation is done from the first | 1478 located, but indented INDENT spaces. The indentation is done from the first |
1466 character on the line and does not disturb the first INDENT characters on the | 1479 character on the line and does not disturb the first INDENT characters on the |
1467 line." | 1480 line." |
1468 (let* ((blank-days ; at start of month | 1481 (let ((blank-days ; at start of month |
1469 (mod | 1482 (mod |
1470 (- (calendar-day-of-week (list month 1 year)) | 1483 (- (calendar-day-of-week (list month 1 year)) |
1471 calendar-week-start-day) | 1484 calendar-week-start-day) |
1472 7)) | 1485 7)) |
1473 (last (calendar-last-day-of-month month year))) | 1486 (last (calendar-last-day-of-month month year))) |
1474 (goto-char (point-min)) | 1487 (goto-char (point-min)) |
1475 (calendar-insert-indented | 1488 (calendar-insert-indented |
1476 (calendar-string-spread | 1489 (calendar-string-spread |
1477 (list (format "%s %d" (calendar-month-name month) year)) ? 20) | 1490 (list (format "%s %d" (calendar-month-name month) year)) ? 20) |
1489 (calendar-insert-indented "" 0 t) ; force onto following line | 1502 (calendar-insert-indented "" 0 t) ; force onto following line |
1490 (calendar-insert-indented "" indent) ; go to proper spot | 1503 (calendar-insert-indented "" indent) ; go to proper spot |
1491 ;; Add blank days before the first of the month. | 1504 ;; Add blank days before the first of the month. |
1492 (dotimes (idummy blank-days) (insert " ")) | 1505 (dotimes (idummy blank-days) (insert " ")) |
1493 ;; Put in the days of the month. | 1506 ;; Put in the days of the month. |
1494 (calendar-for-loop i from 1 to last do | 1507 (dotimes (i last) |
1495 (insert (format "%2d " i)) | 1508 (insert (format "%2d " (1+ i))) |
1496 (add-text-properties | 1509 (add-text-properties |
1497 (- (point) 3) (1- (point)) | 1510 (- (point) 3) (1- (point)) |
1498 '(mouse-face highlight | 1511 '(mouse-face highlight |
1499 help-echo "mouse-2: menu of operations for this date")) | 1512 help-echo "mouse-2: menu of operations for this date")) |
1500 (and (zerop (mod (+ i blank-days) 7)) | 1513 (and (zerop (mod (+ i 1 blank-days) 7)) |
1501 (/= i last) | 1514 (/= i (1- last)) |
1502 (calendar-insert-indented "" 0 t) ; force onto following line | 1515 (calendar-insert-indented "" 0 t) ; force onto following line |
1503 (calendar-insert-indented "" indent))))) ; go to proper spot | 1516 (calendar-insert-indented "" indent))))) ; go to proper spot |
1504 | 1517 |
1505 (defun calendar-insert-indented (string indent &optional newline) | 1518 (defun calendar-insert-indented (string indent &optional newline) |
1506 "Insert STRING at column INDENT. | 1519 "Insert STRING at column INDENT. |
1507 If the optional parameter NEWLINE is t, leave point at start of next line, | 1520 If the optional parameter NEWLINE is non-nil, leave point at start of next |
1508 inserting a newline if there was no next line; otherwise, leave point after | 1521 line, inserting a newline if there was no next line; otherwise, leave point |
1509 the inserted text. Returns t." | 1522 after the inserted text. Returns t." |
1510 ;; Try to move to that column. | 1523 ;; Try to move to that column. |
1511 (move-to-column indent) | 1524 (move-to-column indent) |
1512 ;; If line is too short, indent out to that column. | 1525 ;; If line is too short, indent out to that column. |
1513 (if (< (current-column) indent) | 1526 (if (< (current-column) indent) |
1514 (indent-to indent)) | 1527 (indent-to indent)) |
1756 \"\"))" | 1769 \"\"))" |
1757 :type 'sexp | 1770 :type 'sexp |
1758 :group 'calendar) | 1771 :group 'calendar) |
1759 | 1772 |
1760 (defun mouse-calendar-other-month (event) | 1773 (defun mouse-calendar-other-month (event) |
1761 "Display a three-month calendar centered around a specified month and year." | 1774 "Display a three-month calendar centered around a specified month and year. |
1775 EVENT is the last mouse event." | |
1762 (interactive "e") | 1776 (interactive "e") |
1763 (save-selected-window | 1777 (save-selected-window |
1764 (select-window (posn-window (event-start event))) | 1778 (select-window (posn-window (event-start event))) |
1765 (call-interactively 'calendar-other-month))) | 1779 (call-interactively 'calendar-other-month))) |
1766 | 1780 |
1862 buffs)) | 1876 buffs)) |
1863 | 1877 |
1864 (defun exit-calendar () | 1878 (defun exit-calendar () |
1865 "Get out of the calendar window and hide it and related buffers." | 1879 "Get out of the calendar window and hide it and related buffers." |
1866 (interactive) | 1880 (interactive) |
1867 (let* ((diary-buffer (get-file-buffer diary-file))) | 1881 (let ((diary-buffer (get-file-buffer diary-file))) |
1868 (if (or (not diary-buffer) | 1882 (if (or (not diary-buffer) |
1869 (not (buffer-modified-p diary-buffer)) | 1883 (not (buffer-modified-p diary-buffer)) |
1870 (yes-or-no-p | 1884 (yes-or-no-p |
1871 "Diary modified; do you really want to exit the calendar? ")) | 1885 "Diary modified; do you really want to exit the calendar? ")) |
1872 ;; Need to do this multiple times because one time can replace some | 1886 ;; Need to do this multiple times because one time can replace some |
1900 (list (nth 4 now) (nth 3 now) (nth 5 now)))) | 1914 (list (nth 4 now) (nth 3 now) (nth 5 now)))) |
1901 | 1915 |
1902 (defun calendar-cursor-to-date (&optional error) | 1916 (defun calendar-cursor-to-date (&optional error) |
1903 "Return a list (month day year) of current cursor position. | 1917 "Return a list (month day year) of current cursor position. |
1904 If cursor is not on a specific date, signals an error if optional parameter | 1918 If cursor is not on a specific date, signals an error if optional parameter |
1905 ERROR is t, otherwise just returns nil." | 1919 ERROR is non-nil, otherwise just returns nil." |
1906 (let* ((segment (/ (current-column) 25)) | 1920 (let* ((segment (/ (current-column) 25)) |
1907 (month (% (+ displayed-month segment -1) 12)) | 1921 (month (% (+ displayed-month segment -1) 12)) |
1908 (month (if (zerop month) 12 month)) | 1922 (month (if (zerop month) 12 month)) |
1909 (year | 1923 (year |
1910 (cond | 1924 (cond |
2000 "Mark the date under the cursor, or jump to marked date. | 2014 "Mark the date under the cursor, or jump to marked date. |
2001 With no prefix argument, push current date onto marked date ring. | 2015 With no prefix argument, push current date onto marked date ring. |
2002 With argument ARG, jump to mark, pop it, and put point at end of ring." | 2016 With argument ARG, jump to mark, pop it, and put point at end of ring." |
2003 (interactive "P") | 2017 (interactive "P") |
2004 (let ((date (calendar-cursor-to-date t))) | 2018 (let ((date (calendar-cursor-to-date t))) |
2005 (if (null arg) | 2019 (if arg |
2006 (progn | 2020 (if (null calendar-mark-ring) |
2007 (push date calendar-mark-ring) | 2021 (error "No mark set in this buffer") |
2008 ;; Since the top of the mark ring is the marked date in the | 2022 (calendar-goto-date (car calendar-mark-ring)) |
2009 ;; calendar, the mark ring in the calendar is one longer than | 2023 (setq calendar-mark-ring |
2010 ;; in other buffers to get the same effect. | 2024 (cdr (nconc calendar-mark-ring (list date))))) |
2011 (if (> (length calendar-mark-ring) (1+ mark-ring-max)) | 2025 (push date calendar-mark-ring) |
2012 (setcdr (nthcdr mark-ring-max calendar-mark-ring) nil)) | 2026 ;; Since the top of the mark ring is the marked date in the |
2013 (message "Mark set")) | 2027 ;; calendar, the mark ring in the calendar is one longer than |
2014 (if (null calendar-mark-ring) | 2028 ;; in other buffers to get the same effect. |
2015 (error "No mark set in this buffer") | 2029 (if (> (length calendar-mark-ring) (1+ mark-ring-max)) |
2016 (calendar-goto-date (car calendar-mark-ring)) | 2030 (setcdr (nthcdr mark-ring-max calendar-mark-ring) nil)) |
2017 (setq calendar-mark-ring | 2031 (message "Mark set")))) |
2018 (cdr (nconc calendar-mark-ring (list date)))))))) | |
2019 | 2032 |
2020 (defun calendar-exchange-point-and-mark () | 2033 (defun calendar-exchange-point-and-mark () |
2021 "Exchange the current cursor position with the marked date." | 2034 "Exchange the current cursor position with the marked date." |
2022 (interactive) | 2035 (interactive) |
2023 (let ((mark (car calendar-mark-ring)) | 2036 (let ((mark (car calendar-mark-ring)) |
2093 file. Do not include a trailing `.' in the strings specified in | 2106 file. Do not include a trailing `.' in the strings specified in |
2094 this variable, though you may use such in the diary file. If any | 2107 this variable, though you may use such in the diary file. If any |
2095 element of this array is nil, then the abbreviation will be | 2108 element of this array is nil, then the abbreviation will be |
2096 constructed as the first `calendar-abbrev-length' characters of the | 2109 constructed as the first `calendar-abbrev-length' characters of the |
2097 corresponding full name.") | 2110 corresponding full name.") |
2098 | |
2099 | |
2100 (defun calendar-read-date (&optional noday) | |
2101 "Prompt for Gregorian date. Return a list (month day year). | |
2102 If optional NODAY is t, does not ask for day, but just returns | |
2103 \(month nil year); if NODAY is any other non-nil value the value returned is | |
2104 \(month year)" | |
2105 (let* ((year (calendar-read | |
2106 "Year (>0): " | |
2107 (lambda (x) (> x 0)) | |
2108 (int-to-string (extract-calendar-year | |
2109 (calendar-current-date))))) | |
2110 (month-array calendar-month-name-array) | |
2111 (completion-ignore-case t) | |
2112 (month (cdr (assoc-string | |
2113 (completing-read | |
2114 "Month name: " | |
2115 (mapcar 'list (append month-array nil)) | |
2116 nil t) | |
2117 (calendar-make-alist month-array 1) t))) | |
2118 (last (calendar-last-day-of-month month year))) | |
2119 (if noday | |
2120 (if (eq noday t) | |
2121 (list month nil year) | |
2122 (list month year)) | |
2123 (list month | |
2124 (calendar-read (format "Day (1-%d): " last) | |
2125 (lambda (x) (and (< 0 x) (<= x last)))) | |
2126 year)))) | |
2127 | |
2128 (defun calendar-interval (mon1 yr1 mon2 yr2) | |
2129 "The number of months difference between MON1, YR1 and MON2, YR2. | |
2130 The result is positive if the second date is later than the first. | |
2131 Negative years are interpreted as years BC; -1 being 1 BC, and so on." | |
2132 (if (< yr1 0) (setq yr1 (1+ yr1))) ; -1 BC -> 0 AD, etc | |
2133 (if (< yr2 0) (setq yr2 (1+ yr2))) | |
2134 (+ (* 12 (- yr2 yr1)) | |
2135 (- mon2 mon1))) | |
2136 | |
2137 (defun calendar-abbrev-construct (abbrev full &optional period) | |
2138 "Internal calendar function to return a complete abbreviation array. | |
2139 ABBREV is an array of abbreviations, FULL the corresponding array | |
2140 of full names. The return value is the ABBREV array, with any nil | |
2141 elements replaced by the first three characters taken from the | |
2142 corresponding element of FULL. If optional argument PERIOD is non-nil, | |
2143 each element returned has a final `.' character." | |
2144 (let (elem array name) | |
2145 (dotimes (i (length full)) | |
2146 (setq name (aref full i) | |
2147 elem (or (aref abbrev i) | |
2148 (substring name 0 | |
2149 (min calendar-abbrev-length (length name)))) | |
2150 elem (format "%s%s" elem (if period "." "")) | |
2151 array (append array (list elem)))) | |
2152 (vconcat array))) | |
2153 | |
2154 (defvar calendar-font-lock-keywords | |
2155 `((,(concat (regexp-opt (mapcar 'identity calendar-month-name-array) t) | |
2156 " -?[0-9]+") | |
2157 . font-lock-function-name-face) ; month and year | |
2158 (,(regexp-opt | |
2159 (list (substring (aref calendar-day-name-array 6) 0 2) | |
2160 (substring (aref calendar-day-name-array 0) 0 2))) | |
2161 ;; Saturdays and Sundays are highlighted differently. | |
2162 . font-lock-comment-face) | |
2163 ;; First two chars of each day are used in the calendar. | |
2164 (,(regexp-opt (mapcar (lambda (x) (substring x 0 2)) | |
2165 calendar-day-name-array)) | |
2166 . font-lock-reference-face)) | |
2167 "Default keywords to highlight in Calendar mode.") | |
2168 | |
2169 (defun calendar-day-name (date &optional abbrev absolute) | |
2170 "Return a string with the name of the day of the week of DATE. | |
2171 DATE should be a list in the format (MONTH DAY YEAR), unless the | |
2172 optional argument ABSOLUTE is non-nil, in which case DATE should | |
2173 be an integer in the range 0 to 6 corresponding to the day of the | |
2174 week. Day names are taken from the variable `calendar-day-name-array', | |
2175 unless the optional argument ABBREV is non-nil, in which case | |
2176 the variable `calendar-day-abbrev-array' is used." | |
2177 (aref (if abbrev | |
2178 (calendar-abbrev-construct calendar-day-abbrev-array | |
2179 calendar-day-name-array) | |
2180 calendar-day-name-array) | |
2181 (if absolute date (calendar-day-of-week date)))) | |
2182 | 2111 |
2183 (defun calendar-make-alist (sequence &optional start-index filter abbrevs) | 2112 (defun calendar-make-alist (sequence &optional start-index filter abbrevs) |
2184 "Make an assoc list corresponding to SEQUENCE. | 2113 "Make an assoc list corresponding to SEQUENCE. |
2185 Each element of sequence will be associated with an integer, starting | 2114 Each element of sequence will be associated with an integer, starting |
2186 from 1, or from START-INDEX if that is non-nil. If a sequence ABBREVS | 2115 from 1, or from START-INDEX if that is non-nil. If a sequence ABBREVS |
2206 index) alist))) | 2135 index) alist))) |
2207 (if aseqp | 2136 (if aseqp |
2208 (setq elem (elt aseqp i) | 2137 (setq elem (elt aseqp i) |
2209 alist (cons (cons (if filter (funcall filter elem) elem) | 2138 alist (cons (cons (if filter (funcall filter elem) elem) |
2210 index) alist)))))) | 2139 index) alist)))))) |
2140 | |
2141 (defun calendar-read-date (&optional noday) | |
2142 "Prompt for Gregorian date. Return a list (month day year). | |
2143 If optional NODAY is t, does not ask for day, but just returns | |
2144 \(month nil year); if NODAY is any other non-nil value the value returned is | |
2145 \(month year)" | |
2146 (let* ((year (calendar-read | |
2147 "Year (>0): " | |
2148 (lambda (x) (> x 0)) | |
2149 (int-to-string (extract-calendar-year | |
2150 (calendar-current-date))))) | |
2151 (month-array calendar-month-name-array) | |
2152 (completion-ignore-case t) | |
2153 (month (cdr (assoc-string | |
2154 (completing-read | |
2155 "Month name: " | |
2156 (mapcar 'list (append month-array nil)) | |
2157 nil t) | |
2158 (calendar-make-alist month-array 1) t))) | |
2159 (last (calendar-last-day-of-month month year))) | |
2160 (if noday | |
2161 (if (eq noday t) | |
2162 (list month nil year) | |
2163 (list month year)) | |
2164 (list month | |
2165 (calendar-read (format "Day (1-%d): " last) | |
2166 (lambda (x) (and (< 0 x) (<= x last)))) | |
2167 year)))) | |
2168 | |
2169 (defun calendar-interval (mon1 yr1 mon2 yr2) | |
2170 "The number of months difference between MON1, YR1 and MON2, YR2. | |
2171 The result is positive if the second date is later than the first. | |
2172 Negative years are interpreted as years BC; -1 being 1 BC, and so on." | |
2173 (if (< yr1 0) (setq yr1 (1+ yr1))) ; -1 BC -> 0 AD, etc | |
2174 (if (< yr2 0) (setq yr2 (1+ yr2))) | |
2175 (+ (* 12 (- yr2 yr1)) | |
2176 (- mon2 mon1))) | |
2177 | |
2178 (defun calendar-abbrev-construct (abbrev full &optional period) | |
2179 "Internal calendar function to return a complete abbreviation array. | |
2180 ABBREV is an array of abbreviations, FULL the corresponding array | |
2181 of full names. The return value is the ABBREV array, with any nil | |
2182 elements replaced by the first three characters taken from the | |
2183 corresponding element of FULL. If optional argument PERIOD is non-nil, | |
2184 each element returned has a final `.' character." | |
2185 (let (elem array name) | |
2186 (dotimes (i (length full)) | |
2187 (setq name (aref full i) | |
2188 elem (or (aref abbrev i) | |
2189 (substring name 0 | |
2190 (min calendar-abbrev-length (length name)))) | |
2191 elem (format "%s%s" elem (if period "." "")) | |
2192 array (append array (list elem)))) | |
2193 (vconcat array))) | |
2194 | |
2195 (defvar calendar-font-lock-keywords | |
2196 `((,(concat (regexp-opt (mapcar 'identity calendar-month-name-array) t) | |
2197 " -?[0-9]+") | |
2198 . font-lock-function-name-face) ; month and year | |
2199 (,(regexp-opt | |
2200 (list (substring (aref calendar-day-name-array 6) 0 2) | |
2201 (substring (aref calendar-day-name-array 0) 0 2))) | |
2202 ;; Saturdays and Sundays are highlighted differently. | |
2203 . font-lock-comment-face) | |
2204 ;; First two chars of each day are used in the calendar. | |
2205 (,(regexp-opt (mapcar (lambda (x) (substring x 0 2)) | |
2206 calendar-day-name-array)) | |
2207 . font-lock-reference-face)) | |
2208 "Default keywords to highlight in Calendar mode.") | |
2209 | |
2210 (defun calendar-day-name (date &optional abbrev absolute) | |
2211 "Return a string with the name of the day of the week of DATE. | |
2212 DATE should be a list in the format (MONTH DAY YEAR), unless the | |
2213 optional argument ABSOLUTE is non-nil, in which case DATE should | |
2214 be an integer in the range 0 to 6 corresponding to the day of the | |
2215 week. Day names are taken from the variable `calendar-day-name-array', | |
2216 unless the optional argument ABBREV is non-nil, in which case | |
2217 the variable `calendar-day-abbrev-array' is used." | |
2218 (aref (if abbrev | |
2219 (calendar-abbrev-construct calendar-day-abbrev-array | |
2220 calendar-day-name-array) | |
2221 calendar-day-name-array) | |
2222 (if absolute date (calendar-day-of-week date)))) | |
2211 | 2223 |
2212 (defun calendar-month-name (month &optional abbrev) | 2224 (defun calendar-month-name (month &optional abbrev) |
2213 "Return a string with the name of month number MONTH. | 2225 "Return a string with the name of month number MONTH. |
2214 Months are numbered from one. Month names are taken from the | 2226 Months are numbered from one. Month names are taken from the |
2215 variable `calendar-month-name-array', unless the optional | 2227 variable `calendar-month-name-array', unless the optional |
2352 An optional parameter ABBREVIATE, when non-nil, causes the month | 2364 An optional parameter ABBREVIATE, when non-nil, causes the month |
2353 and day names to be abbreviated as specified by | 2365 and day names to be abbreviated as specified by |
2354 `calendar-month-abbrev-array' and `calendar-day-abbrev-array', | 2366 `calendar-month-abbrev-array' and `calendar-day-abbrev-array', |
2355 respectively. An optional parameter NODAYNAME, when t, omits the | 2367 respectively. An optional parameter NODAYNAME, when t, omits the |
2356 name of the day of the week." | 2368 name of the day of the week." |
2357 (let* ((dayname | 2369 (let* ((dayname (unless nodayname (calendar-day-name date abbreviate))) |
2358 (unless nodayname | |
2359 (calendar-day-name date abbreviate))) | |
2360 (month (extract-calendar-month date)) | 2370 (month (extract-calendar-month date)) |
2361 (monthname (calendar-month-name month abbreviate)) | 2371 (monthname (calendar-month-name month abbreviate)) |
2362 (day (int-to-string (extract-calendar-day date))) | 2372 (day (int-to-string (extract-calendar-day date))) |
2363 (month (int-to-string month)) | 2373 (month (int-to-string month)) |
2364 (year (int-to-string (extract-calendar-year date)))) | 2374 (year (int-to-string (extract-calendar-year date)))) |
2416 day year days-remaining (if (= days-remaining 1) "" "s")))) | 2426 day year days-remaining (if (= days-remaining 1) "" "s")))) |
2417 | 2427 |
2418 (defun calendar-print-other-dates () | 2428 (defun calendar-print-other-dates () |
2419 "Show dates on other calendars for date under the cursor." | 2429 "Show dates on other calendars for date under the cursor." |
2420 (interactive) | 2430 (interactive) |
2421 (let* ((date (calendar-cursor-to-date t))) | 2431 (let ((date (calendar-cursor-to-date t))) |
2422 (with-current-buffer (get-buffer-create other-calendars-buffer) | 2432 (with-current-buffer (get-buffer-create other-calendars-buffer) |
2423 (let ((inhibit-read-only t) | 2433 (let ((inhibit-read-only t) |
2424 (modified (buffer-modified-p))) | 2434 (modified (buffer-modified-p))) |
2425 (calendar-set-mode-line | 2435 (calendar-set-mode-line |
2426 (concat (calendar-date-string date) " (Gregorian)")) | 2436 (concat (calendar-date-string date) " (Gregorian)")) |
2471 | 2481 |
2472 (defun calendar-set-mode-line (str) | 2482 (defun calendar-set-mode-line (str) |
2473 "Set mode line to STR, centered, surrounded by dashes." | 2483 "Set mode line to STR, centered, surrounded by dashes." |
2474 (let* ((edges (window-edges)) | 2484 (let* ((edges (window-edges)) |
2475 ;; As per doc of window-width, total visible mode-line length. | 2485 ;; As per doc of window-width, total visible mode-line length. |
2476 (width (- (nth 2 edges) (nth 0 edges)))) | 2486 (width (- (nth 2 edges) (car edges)))) |
2477 (setq mode-line-format | 2487 (setq mode-line-format |
2478 (if buffer-file-name | 2488 (if buffer-file-name |
2479 `("-" mode-line-modified | 2489 `("-" mode-line-modified |
2480 ,(calendar-string-spread (list str) ?- (- width 6)) | 2490 ,(calendar-string-spread (list str) ?- (- width 6)) |
2481 "---") | 2491 "---") |