More small edits for doc/lispref
[bpt/emacs.git] / lisp / calendar / cal-move.el
index ec902c1..a6991e4 100644 (file)
@@ -1,12 +1,12 @@
 ;;; cal-move.el --- calendar functions for movement in the calendar
 
-;; Copyright (C) 1995, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1995, 2001-2012  Free Software Foundation, Inc.
 
 ;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
 ;; Maintainer: Glenn Morris <rgm@gnu.org>
 ;; Keywords: calendar
 ;; Human-Keywords: calendar
+;; Package: calendar
 
 ;; This file is part of GNU Emacs.
 
 
 ;;; Code:
 
+;; FIXME should calendar just require this?
 (require 'calendar)
 
+
+;; Note that this is not really the "closest" date.
+;; In most cases, it just searches forwards for the next day.
 ;;;###cal-autoload
 (defun calendar-cursor-to-nearest-date ()
   "Move the cursor to the closest date.
 The position of the cursor is unchanged if it is already on a date.
 Returns the list (month day year) giving the cursor position."
   (or (calendar-cursor-to-date)
-      (let ((column (current-column)))
-        (when (> 3 (count-lines (point-min) (point)))
-          (goto-line 3)
-          (move-to-column column))
-        (if (not (looking-at "[0-9]"))
-            (if (and (not (looking-at " *$"))
-                     (or (< column 25)
-                         (and (> column 27)
-                              (< column 50))
-                         (and (> column 52)
-                              (< column 75))))
-                (progn
-                  (re-search-forward "[0-9]" nil t)
-                  (backward-char 1))
-              (re-search-backward "[0-9]" nil t)))
+      (let* ((col (current-column))
+             (edges (cdr (assoc (calendar-column-to-segment)
+                                calendar-month-edges)))
+             (last (nth 2 edges))
+             (right (nth 3 edges)))
+        (when (< (count-lines (point-min) (point)) calendar-first-date-row)
+          (goto-char (point-min))
+          (forward-line (1- calendar-first-date-row))
+          (move-to-column col))
+        ;; The date positions are fixed and computable, but searching
+        ;; is probably more flexible.  Need to consider blank days at
+        ;; start and end of month if computing positions.
+        ;; 'date text-property is used to exclude intermonth text.
+        (unless (and (looking-at "[0-9]")
+                     (get-text-property (point) 'date))
+          ;; We search forwards for a number, except close to the RH
+          ;; margin of a month, where we search backwards.
+          ;; Note that the searches can go to other lines.
+          (if (or (looking-at " *$")
+                  (and (> col last) (< col right)))
+              (while (and (re-search-backward "[0-9]" nil t)
+                          (not (get-text-property (point) 'date))))
+            (while (and (re-search-forward "[0-9]" nil t)
+                        (not (get-text-property (1- (point)) 'date))))
+            (backward-char 1)))
         (calendar-cursor-to-date))))
 
 (defvar displayed-month)                ; from calendar-generate
@@ -63,21 +77,23 @@ Returns the list (month day year) giving the cursor position."
   (let ((month (calendar-extract-month date))
         (day (calendar-extract-day date))
         (year (calendar-extract-year date)))
-    (goto-line (+ 3
-                  (/ (+ day  -1
-                        (mod
-                         (- (calendar-day-of-week (list month 1 year))
-                            calendar-week-start-day)
-                         7))
-                     7)))
-    (move-to-column (+ 6
-                       (* 25
+    (goto-char (point-min))
+    (forward-line (+ calendar-first-date-row -1
+                     (/ (+ day -1
+                           (mod
+                            (- (calendar-day-of-week (list month 1 year))
+                               calendar-week-start-day)
+                            7))
+                        7)))
+    (move-to-column (+ calendar-left-margin (1- calendar-day-digit-width)
+                       (* calendar-month-width
                           (1+ (calendar-interval
                                displayed-month displayed-year month year)))
-                       (* 3 (mod
-                             (- (calendar-day-of-week date)
-                                calendar-week-start-day)
-                             7))))))
+                       (* calendar-column-width
+                          (mod
+                           (- (calendar-day-of-week date)
+                              calendar-week-start-day)
+                           7))))))
 
 ;;;###cal-autoload
 (defun calendar-goto-today ()
@@ -176,23 +192,39 @@ EVENT is an event like `last-nonmenu-event'."
   'scroll-calendar-right 'calendar-scroll-right "23.1")
 
 ;;;###cal-autoload
-(defun calendar-scroll-left-three-months (arg)
+(defun calendar-scroll-left-three-months (arg &optional event)
   "Scroll the displayed calendar window left by 3*ARG months.
 If ARG is negative the calendar is scrolled right.  Maintains the relative
-position of the cursor with respect to the calendar as well as possible."
-  (interactive "p")
-  (calendar-scroll-left (* 3 arg)))
+position of the cursor with respect to the calendar as well as possible.
+EVENT is an event like `last-nonmenu-event'."
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     last-nonmenu-event))
+  (calendar-scroll-left (* 3 arg) event))
 
 (define-obsolete-function-alias 'scroll-calendar-left-three-months
   'calendar-scroll-left-three-months "23.1")
 
+;; cf scroll-bar-toolkit-scroll
 ;;;###cal-autoload
-(defun calendar-scroll-right-three-months (arg)
+(defun calendar-scroll-toolkit-scroll (event)
+  "Function to scroll the calendar after a toolkit scroll-bar click."
+  (interactive "e")
+  (let ((part (nth 4 (event-end event))))
+    ;; Not bothering with drag events (handle, end-scroll).
+    (cond ((memq part '(above-handle up top))
+           (calendar-scroll-right nil event))
+          ((memq part '(below-handle down bottom))
+           (calendar-scroll-left nil event)))))
+
+;;;###cal-autoload
+(defun calendar-scroll-right-three-months (arg &optional event)
   "Scroll the displayed calendar window right by 3*ARG months.
 If ARG is negative the calendar is scrolled left.  Maintains the relative
-position of the cursor with respect to the calendar as well as possible."
-  (interactive "p")
-  (calendar-scroll-left (* -3 arg)))
+position of the cursor with respect to the calendar as well as possible.
+EVENT is an event like `last-nonmenu-event'."
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     last-nonmenu-event))
+  (calendar-scroll-left (* -3 arg) event))
 
 (define-obsolete-function-alias 'scroll-calendar-right-three-months
   'calendar-scroll-right-three-months "23.1")
@@ -212,9 +244,14 @@ Moves backward if ARG is negative."
              (+ (calendar-absolute-from-gregorian cursor-date) arg)))
            (new-display-month (calendar-extract-month new-cursor-date))
            (new-display-year (calendar-extract-year new-cursor-date)))
-      ;; Put the new month on the screen, if needed, and go to the new date.
-      (if (not (calendar-date-is-visible-p new-cursor-date))
-          (calendar-other-month new-display-month new-display-year))
+      ;; Put the new month on the screen, if needed.
+      (unless (calendar-date-is-visible-p new-cursor-date)
+        ;; The next line gives smoother scrolling IMO (one month at a
+        ;; time rather than two).
+        (calendar-increment-month new-display-month new-display-year
+                                  (if (< arg 0) 1 -1))
+        (calendar-other-month new-display-month new-display-year))
+      ;; Go to the new date.
       (calendar-cursor-to-visible-date new-cursor-date)))
   (run-hooks 'calendar-move-hook))
 
@@ -380,5 +417,4 @@ Negative DAY counts backward from end of year."
 
 (provide 'cal-move)
 
-;; arch-tag: d0883c46-7e16-4914-8ff8-8f67e699b781
 ;;; cal-move.el ends here