Update for calendar.el name changes.
[bpt/emacs.git] / lisp / calendar / cal-move.el
CommitLineData
0808d911
ER
1;;; cal-move.el --- calendar functions for movement in the calendar
2
8b72699e 3;; Copyright (C) 1995, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
dbfca9c4 4;; Free Software Foundation, Inc.
0808d911
ER
5
6;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
aff88519 7;; Maintainer: Glenn Morris <rgm@gnu.org>
0808d911
ER
8;; Keywords: calendar
9;; Human-Keywords: calendar
10
11;; This file is part of GNU Emacs.
12
13;; GNU Emacs is free software; you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
075969b4 15;; the Free Software Foundation; either version 3, or (at your option)
0808d911
ER
16;; any later version.
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
b578f267 24;; along with GNU Emacs; see the file COPYING. If not, write to the
3a35cf56
LK
25;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26;; Boston, MA 02110-1301, USA.
0808d911
ER
27
28;;; Commentary:
29
b36e906d 30;; See calendar.el.
0808d911 31
0808d911
ER
32;;; Code:
33
cfcc468f
GM
34(require 'calendar)
35
36;;;###cal-autoload
37(defun calendar-cursor-to-nearest-date ()
38 "Move the cursor to the closest date.
39The position of the cursor is unchanged if it is already on a date.
40Returns the list (month day year) giving the cursor position."
3e0e034b
GM
41 (or (calendar-cursor-to-date)
42 (let ((column (current-column)))
cfcc468f
GM
43 (when (> 3 (count-lines (point-min) (point)))
44 (goto-line 3)
45 (move-to-column column))
46 (if (not (looking-at "[0-9]"))
47 (if (and (not (looking-at " *$"))
48 (or (< column 25)
49 (and (> column 27)
50 (< column 50))
51 (and (> column 52)
52 (< column 75))))
53 (progn
54 (re-search-forward "[0-9]" nil t)
55 (backward-char 1))
56 (re-search-backward "[0-9]" nil t)))
57 (calendar-cursor-to-date))))
58
e803eab7 59(defvar displayed-month) ; from calendar-generate
0b0f8fa4
GM
60(defvar displayed-year)
61
cfcc468f
GM
62;;;###cal-autoload
63(defun calendar-cursor-to-visible-date (date)
64 "Move the cursor to DATE that is on the screen."
e803eab7
GM
65 (let ((month (calendar-extract-month date))
66 (day (calendar-extract-day date))
67 (year (calendar-extract-year date)))
cfcc468f
GM
68 (goto-line (+ 3
69 (/ (+ day -1
70 (mod
71 (- (calendar-day-of-week (list month 1 year))
72 calendar-week-start-day)
73 7))
74 7)))
75 (move-to-column (+ 6
76 (* 25
77 (1+ (calendar-interval
78 displayed-month displayed-year month year)))
79 (* 3 (mod
80 (- (calendar-day-of-week date)
81 calendar-week-start-day)
82 7))))))
20eff799 83
6c1841ba 84;;;###cal-autoload
0808d911
ER
85(defun calendar-goto-today ()
86 "Reposition the calendar window so the current date is visible."
87 (interactive)
cfcc468f 88 (let ((today (calendar-current-date))) ; the date might have changed
0808d911 89 (if (not (calendar-date-is-visible-p today))
e803eab7
GM
90 (calendar-generate-window)
91 (calendar-update-mode-line)
d2e8c33b
RS
92 (calendar-cursor-to-visible-date today)))
93 (run-hooks 'calendar-move-hook))
0808d911 94
6c1841ba 95;;;###cal-autoload
0808d911
ER
96(defun calendar-forward-month (arg)
97 "Move the cursor forward ARG months.
98Movement is backward if ARG is negative."
99 (interactive "p")
100 (calendar-cursor-to-nearest-date)
101 (let* ((cursor-date (calendar-cursor-to-date t))
e803eab7
GM
102 (month (calendar-extract-month cursor-date))
103 (day (calendar-extract-day cursor-date))
104 (year (calendar-extract-year cursor-date))
b36e906d 105 (last (progn
e803eab7 106 (calendar-increment-month month year arg)
b36e906d
GM
107 (calendar-last-day-of-month month year)))
108 (day (min last day))
109 ;; Put the new month on the screen, if needed, and go to the new date.
110 (new-cursor-date (list month day year)))
111 (if (not (calendar-date-is-visible-p new-cursor-date))
112 (calendar-other-month month year))
113 (calendar-cursor-to-visible-date new-cursor-date))
d2e8c33b 114 (run-hooks 'calendar-move-hook))
0808d911 115
6c1841ba 116;;;###cal-autoload
0808d911
ER
117(defun calendar-forward-year (arg)
118 "Move the cursor forward by ARG years.
119Movement is backward if ARG is negative."
120 (interactive "p")
121 (calendar-forward-month (* 12 arg)))
122
6c1841ba 123;;;###cal-autoload
0808d911
ER
124(defun calendar-backward-month (arg)
125 "Move the cursor backward by ARG months.
126Movement is forward if ARG is negative."
127 (interactive "p")
128 (calendar-forward-month (- arg)))
129
6c1841ba 130;;;###cal-autoload
0808d911
ER
131(defun calendar-backward-year (arg)
132 "Move the cursor backward ARG years.
133Movement is forward is ARG is negative."
134 (interactive "p")
135 (calendar-forward-month (* -12 arg)))
136
6c1841ba 137;;;###cal-autoload
ab895089 138(defun calendar-scroll-left (&optional arg event)
0808d911
ER
139 "Scroll the displayed calendar left by ARG months.
140If ARG is negative the calendar is scrolled right. Maintains the relative
db940e42
GM
141position of the cursor with respect to the calendar as well as possible.
142EVENT is an event like `last-nonmenu-event'."
ab895089
SM
143 (interactive (list (prefix-numeric-value current-prefix-arg)
144 last-nonmenu-event))
f7b37bae 145 (unless arg (setq arg 1))
ab895089
SM
146 (save-selected-window
147 (select-window (posn-window (event-start event)))
148 (calendar-cursor-to-nearest-date)
cfcc468f
GM
149 (unless (zerop arg)
150 (let ((old-date (calendar-cursor-to-date))
151 (today (calendar-current-date))
152 (month displayed-month)
153 (year displayed-year))
e803eab7
GM
154 (calendar-increment-month month year arg)
155 (calendar-generate-window month year)
cfcc468f
GM
156 (calendar-cursor-to-visible-date
157 (cond
158 ((calendar-date-is-visible-p old-date) old-date)
159 ((calendar-date-is-visible-p today) today)
160 (t (list month 1 year))))))
ab895089
SM
161 (run-hooks 'calendar-move-hook)))
162
cfcc468f
GM
163(define-obsolete-function-alias
164 'scroll-calendar-left 'calendar-scroll-left "23.1")
165
6c1841ba 166;;;###cal-autoload
ab895089 167(defun calendar-scroll-right (&optional arg event)
0808d911
ER
168 "Scroll the displayed calendar window right by ARG months.
169If ARG is negative the calendar is scrolled left. Maintains the relative
db940e42
GM
170position of the cursor with respect to the calendar as well as possible.
171EVENT is an event like `last-nonmenu-event'."
ab895089
SM
172 (interactive (list (prefix-numeric-value current-prefix-arg)
173 last-nonmenu-event))
174 (calendar-scroll-left (- (or arg 1)) event))
0808d911 175
cfcc468f
GM
176(define-obsolete-function-alias
177 'scroll-calendar-right 'calendar-scroll-right "23.1")
178
6c1841ba 179;;;###cal-autoload
ab42e29d 180(defun calendar-scroll-left-three-months (arg)
0808d911
ER
181 "Scroll the displayed calendar window left by 3*ARG months.
182If ARG is negative the calendar is scrolled right. Maintains the relative
183position of the cursor with respect to the calendar as well as possible."
184 (interactive "p")
ab42e29d 185 (calendar-scroll-left (* 3 arg)))
0808d911 186
cfcc468f
GM
187(define-obsolete-function-alias 'scroll-calendar-left-three-months
188 'calendar-scroll-left-three-months "23.1")
189
6c1841ba 190;;;###cal-autoload
ab42e29d 191(defun calendar-scroll-right-three-months (arg)
0808d911
ER
192 "Scroll the displayed calendar window right by 3*ARG months.
193If ARG is negative the calendar is scrolled left. Maintains the relative
194position of the cursor with respect to the calendar as well as possible."
195 (interactive "p")
ab42e29d 196 (calendar-scroll-left (* -3 arg)))
0808d911 197
cfcc468f
GM
198(define-obsolete-function-alias 'scroll-calendar-right-three-months
199 'calendar-scroll-right-three-months "23.1")
0808d911 200
6c1841ba 201;;;###cal-autoload
0808d911
ER
202(defun calendar-forward-day (arg)
203 "Move the cursor forward ARG days.
204Moves backward if ARG is negative."
205 (interactive "p")
cfcc468f
GM
206 (unless (zerop arg)
207 (let* ((cursor-date (or (calendar-cursor-to-date)
208 (progn
209 (if (> arg 0) (setq arg (1- arg)))
210 (calendar-cursor-to-nearest-date))))
0808d911
ER
211 (new-cursor-date
212 (calendar-gregorian-from-absolute
213 (+ (calendar-absolute-from-gregorian cursor-date) arg)))
e803eab7
GM
214 (new-display-month (calendar-extract-month new-cursor-date))
215 (new-display-year (calendar-extract-year new-cursor-date)))
cfcc468f
GM
216 ;; Put the new month on the screen, if needed, and go to the new date.
217 (if (not (calendar-date-is-visible-p new-cursor-date))
218 (calendar-other-month new-display-month new-display-year))
219 (calendar-cursor-to-visible-date new-cursor-date)))
d2e8c33b 220 (run-hooks 'calendar-move-hook))
0808d911 221
6c1841ba 222;;;###cal-autoload
0808d911
ER
223(defun calendar-backward-day (arg)
224 "Move the cursor back ARG days.
225Moves forward if ARG is negative."
226 (interactive "p")
227 (calendar-forward-day (- arg)))
228
6c1841ba 229;;;###cal-autoload
0808d911
ER
230(defun calendar-forward-week (arg)
231 "Move the cursor forward ARG weeks.
232Moves backward if ARG is negative."
233 (interactive "p")
234 (calendar-forward-day (* arg 7)))
235
6c1841ba 236;;;###cal-autoload
0808d911
ER
237(defun calendar-backward-week (arg)
238 "Move the cursor back ARG weeks.
239Moves forward if ARG is negative."
240 (interactive "p")
241 (calendar-forward-day (* arg -7)))
242
6c1841ba 243;;;###cal-autoload
0808d911
ER
244(defun calendar-beginning-of-week (arg)
245 "Move the cursor back ARG calendar-week-start-day's."
246 (interactive "p")
247 (calendar-cursor-to-nearest-date)
248 (let ((day (calendar-day-of-week (calendar-cursor-to-date))))
249 (calendar-backward-day
250 (if (= day calendar-week-start-day)
251 (* 7 arg)
252 (+ (mod (- day calendar-week-start-day) 7)
253 (* 7 (1- arg)))))))
254
6c1841ba 255;;;###cal-autoload
0808d911
ER
256(defun calendar-end-of-week (arg)
257 "Move the cursor forward ARG calendar-week-start-day+6's."
258 (interactive "p")
259 (calendar-cursor-to-nearest-date)
260 (let ((day (calendar-day-of-week (calendar-cursor-to-date))))
261 (calendar-forward-day
262 (if (= day (mod (1- calendar-week-start-day) 7))
263 (* 7 arg)
264 (+ (- 6 (mod (- day calendar-week-start-day) 7))
265 (* 7 (1- arg)))))))
266
6c1841ba 267;;;###cal-autoload
0808d911
ER
268(defun calendar-beginning-of-month (arg)
269 "Move the cursor backward ARG month beginnings."
270 (interactive "p")
271 (calendar-cursor-to-nearest-date)
272 (let* ((date (calendar-cursor-to-date))
e803eab7
GM
273 (month (calendar-extract-month date))
274 (day (calendar-extract-day date))
275 (year (calendar-extract-year date)))
0808d911
ER
276 (if (= day 1)
277 (calendar-backward-month arg)
278 (calendar-cursor-to-visible-date (list month 1 year))
279 (calendar-backward-month (1- arg)))))
280
6c1841ba 281;;;###cal-autoload
0808d911
ER
282(defun calendar-end-of-month (arg)
283 "Move the cursor forward ARG month ends."
284 (interactive "p")
285 (calendar-cursor-to-nearest-date)
286 (let* ((date (calendar-cursor-to-date))
e803eab7
GM
287 (month (calendar-extract-month date))
288 (day (calendar-extract-day date))
289 (year (calendar-extract-year date))
b36e906d
GM
290 (last-day (calendar-last-day-of-month month year))
291 (last-day (progn
292 (unless (= day last-day)
293 (calendar-cursor-to-visible-date
294 (list month last-day year))
295 (setq arg (1- arg)))
e803eab7 296 (calendar-increment-month month year arg)
b36e906d
GM
297 (list month
298 (calendar-last-day-of-month month year)
299 year))))
300 (if (not (calendar-date-is-visible-p last-day))
301 (calendar-other-month month year)
302 (calendar-cursor-to-visible-date last-day)))
d2e8c33b 303 (run-hooks 'calendar-move-hook))
0808d911 304
6c1841ba 305;;;###cal-autoload
0808d911
ER
306(defun calendar-beginning-of-year (arg)
307 "Move the cursor backward ARG year beginnings."
308 (interactive "p")
309 (calendar-cursor-to-nearest-date)
310 (let* ((date (calendar-cursor-to-date))
e803eab7
GM
311 (month (calendar-extract-month date))
312 (day (calendar-extract-day date))
313 (year (calendar-extract-year date))
d2e8c33b
RS
314 (jan-first (list 1 1 year))
315 (calendar-move-hook nil))
0808d911
ER
316 (if (and (= day 1) (= 1 month))
317 (calendar-backward-month (* 12 arg))
318 (if (and (= arg 1)
319 (calendar-date-is-visible-p jan-first))
320 (calendar-cursor-to-visible-date jan-first)
25b11e01
GM
321 (calendar-other-month 1 (- year (1- arg)))
322 (calendar-cursor-to-visible-date (list 1 1 displayed-year)))))
d2e8c33b 323 (run-hooks 'calendar-move-hook))
0808d911 324
6c1841ba 325;;;###cal-autoload
0808d911
ER
326(defun calendar-end-of-year (arg)
327 "Move the cursor forward ARG year beginnings."
328 (interactive "p")
329 (calendar-cursor-to-nearest-date)
330 (let* ((date (calendar-cursor-to-date))
e803eab7
GM
331 (month (calendar-extract-month date))
332 (day (calendar-extract-day date))
333 (year (calendar-extract-year date))
d2e8c33b
RS
334 (dec-31 (list 12 31 year))
335 (calendar-move-hook nil))
0808d911
ER
336 (if (and (= day 31) (= 12 month))
337 (calendar-forward-month (* 12 arg))
338 (if (and (= arg 1)
339 (calendar-date-is-visible-p dec-31))
340 (calendar-cursor-to-visible-date dec-31)
25b11e01 341 (calendar-other-month 12 (+ year (1- arg)))
d2e8c33b
RS
342 (calendar-cursor-to-visible-date (list 12 31 displayed-year)))))
343 (run-hooks 'calendar-move-hook))
0808d911 344
6c1841ba 345;;;###cal-autoload
0808d911
ER
346(defun calendar-goto-date (date)
347 "Move cursor to DATE."
348 (interactive (list (calendar-read-date)))
e803eab7
GM
349 (let ((month (calendar-extract-month date))
350 (year (calendar-extract-year date)))
0808d911
ER
351 (if (not (calendar-date-is-visible-p date))
352 (calendar-other-month
353 (if (and (= month 1) (= year 1))
354 2
355 month)
356 year)))
d2e8c33b
RS
357 (calendar-cursor-to-visible-date date)
358 (run-hooks 'calendar-move-hook))
0808d911 359
6c1841ba 360;;;###cal-autoload
163fd24d 361(defun calendar-goto-day-of-year (year day &optional noecho)
cfcc468f 362 "Move cursor to YEAR, DAY number; echo DAY/YEAR unless NOECHO is non-nil.
163fd24d
GM
363Negative DAY counts backward from end of year."
364 (interactive
365 (let* ((year (calendar-read
366 "Year (>0): "
367 (lambda (x) (> x 0))
e803eab7 368 (int-to-string (calendar-extract-year
163fd24d
GM
369 (calendar-current-date)))))
370 (last (if (calendar-leap-year-p year) 366 365))
371 (day (calendar-read
372 (format "Day number (+/- 1-%d): " last)
5942f9af 373 (lambda (x) (and (<= 1 (abs x)) (<= (abs x) last))))))
163fd24d
GM
374 (list year day)))
375 (calendar-goto-date
376 (calendar-gregorian-from-absolute
377 (if (< 0 day)
378 (+ -1 day (calendar-absolute-from-gregorian (list 1 1 year)))
379 (+ 1 day (calendar-absolute-from-gregorian (list 12 31 year))))))
380 (or noecho (calendar-print-day-of-year)))
381
0808d911
ER
382(provide 'cal-move)
383
ab42e29d 384;; arch-tag: d0883c46-7e16-4914-8ff8-8f67e699b781
0808d911 385;;; cal-move.el ends here