Update years in copyright notice; nfc.
[bpt/emacs.git] / lisp / ruler-mode.el
index d6c205a..a441c3a 100644 (file)
@@ -1,6 +1,7 @@
 ;;; ruler-mode.el --- display a ruler in the header line
 
-;; Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+;; Copyright (C) 2001, 2002, 2003, 2004, 2005,
+;;   2006 Free Software Foundation, Inc.
 
 ;; Author: David Ponce <david@dponce.com>
 ;; Maintainer: David Ponce <david@dponce.com>
@@ -22,8 +23,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with this program; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
 ;;
 ;; The following faces are customizable:
 ;;
-;; - `ruler-mode-default-face' the ruler default face.
-;; - `ruler-mode-fill-column-face' the face used to highlight the
+;; - `ruler-mode-default' the ruler default face.
+;; - `ruler-mode-fill-column' the face used to highlight the
 ;;   `fill-column' character.
-;; - `ruler-mode-comment-column-face' the face used to highlight the
+;; - `ruler-mode-comment-column' the face used to highlight the
 ;;   `comment-column' character.
-;; - `ruler-mode-goal-column-face' the face used to highlight the
+;; - `ruler-mode-goal-column' the face used to highlight the
 ;;   `goal-column' character.
-;; - `ruler-mode-current-column-face' the face used to highlight the
+;; - `ruler-mode-current-column' the face used to highlight the
 ;;   `current-column' character.
-;; - `ruler-mode-tab-stop-face' the face used to highlight tab stop
+;; - `ruler-mode-tab-stop' the face used to highlight tab stop
 ;;   characters.
-;; - `ruler-mode-margins-face' the face used to highlight graduations
+;; - `ruler-mode-margins' the face used to highlight graduations
 ;;   in the `window-margins' areas.
-;; - `ruler-mode-fringes-face' the face used to highlight graduations
+;; - `ruler-mode-fringes' the face used to highlight graduations
 ;;   in the `window-fringes' areas.
-;; - `ruler-mode-column-number-face' the face used to highlight the
+;; - `ruler-mode-column-number' the face used to highlight the
 ;;   numbered graduations.
 ;;
-;; `ruler-mode-default-face' inherits from the built-in `default' face.
-;; All `ruler-mode' faces inherit from `ruler-mode-default-face'.
+;; `ruler-mode-default' inherits from the built-in `default' face.
+;; All `ruler-mode' faces inherit from `ruler-mode-default'.
 ;;
 ;; WARNING: To keep ruler graduations aligned on text columns it is
 ;; important to use the same font family and size for ruler and text
 ;; areas.
 ;;
-;; You can override the ruler format by defining an appropriate 
+;; You can override the ruler format by defining an appropriate
 ;; function as the buffer-local value of `ruler-mode-ruler-function'.
 
 ;; Installation
 
 (defgroup ruler-mode nil
   "Display a ruler in the header line."
-  :version "21.4"
+  :version "22.1"
   :group 'convenience)
 
 (defcustom ruler-mode-show-tab-stops nil
@@ -205,7 +206,7 @@ or remove a tab stop.  \\[ruler-mode-toggle-show-tab-stops] or
   :group 'ruler-mode
   :type 'boolean)
 \f
-(defface ruler-mode-default-face
+(defface ruler-mode-default
   '((((type tty))
      (:inherit default
                :background "grey64"
@@ -222,102 +223,83 @@ or remove a tab stop.  \\[ruler-mode-toggle-show-tab-stops] or
   "Default face used by the ruler."
   :group 'ruler-mode)
 
-(defface ruler-mode-pad-face
+(defface ruler-mode-pad
   '((((type tty))
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :background "grey50"
                ))
     (t
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :background "grey64"
                )))
   "Face used to pad inactive ruler areas."
   :group 'ruler-mode)
 
-(defface ruler-mode-margins-face
+(defface ruler-mode-margins
   '((t
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :foreground "white"
                )))
   "Face used to highlight margin areas."
   :group 'ruler-mode)
 
-(defface ruler-mode-fringes-face
+(defface ruler-mode-fringes
   '((t
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :foreground "green"
                )))
   "Face used to highlight fringes areas."
   :group 'ruler-mode)
 
-(defface ruler-mode-column-number-face
+(defface ruler-mode-column-number
   '((t
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :foreground "black"
                )))
   "Face used to highlight number graduations."
   :group 'ruler-mode)
 
-(defface ruler-mode-fill-column-face
+(defface ruler-mode-fill-column
   '((t
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :foreground "red"
                )))
   "Face used to highlight the fill column character."
   :group 'ruler-mode)
 
-(defface ruler-mode-comment-column-face
+(defface ruler-mode-comment-column
   '((t
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :foreground "red"
                )))
   "Face used to highlight the comment column character."
   :group 'ruler-mode)
 
-(defface ruler-mode-goal-column-face
+(defface ruler-mode-goal-column
   '((t
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :foreground "red"
                )))
   "Face used to highlight the goal column character."
   :group 'ruler-mode)
 
-(defface ruler-mode-tab-stop-face
+(defface ruler-mode-tab-stop
   '((t
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :foreground "steelblue"
                )))
   "Face used to highlight tab stop characters."
   :group 'ruler-mode)
 
-(defface ruler-mode-current-column-face
+(defface ruler-mode-current-column
   '((t
-     (:inherit ruler-mode-default-face
+     (:inherit ruler-mode-default
                :weight bold
                :foreground "yellow"
                )))
   "Face used to highlight the `current-column' character."
   :group 'ruler-mode)
 \f
-(defsubst ruler-mode-left-fringe-cols (&optional real)
-  "Return the width, measured in columns, of the left fringe area.
-If optional argument REAL is non-nil, return a real floating point
-number instead of a rounded integer value."
-  (fringe-columns 'left real))
-
-(defsubst ruler-mode-right-fringe-cols (&optional real)
-  "Return the width, measured in columns, of the right fringe area.
-If optional argument REAL is non-nil, return a real floating point
-number instead of a rounded integer value."
-  (fringe-columns 'right real))
-
-(defmacro ruler-mode-right-scroll-bar-cols ()
-  "Return the width, measured in columns, of the right vertical scrollbar."
-  '(scroll-bar-columns 'right))
-
-(defmacro ruler-mode-left-scroll-bar-cols ()
-  "Return the width, measured in columns, of the left vertical scrollbar."
-  '(scroll-bar-columns 'left))
 
 (defsubst ruler-mode-full-window-width ()
   "Return the full width of the selected window."
@@ -330,8 +312,8 @@ N is a column number relative to selected frame."
   (- n
      (car (window-edges))
      (or (car (window-margins)) 0)
-     (ruler-mode-left-fringe-cols)
-     (ruler-mode-left-scroll-bar-cols)))
+     (fringe-columns 'left)
+     (scroll-bar-columns 'left)))
 \f
 (defun ruler-mode-mouse-set-left-margin (start-event)
   "Set left margin end to the graduation where the mouse pointer is on.
@@ -344,10 +326,10 @@ START-EVENT is the mouse click event."
       (save-selected-window
         (select-window (posn-window start))
         (setq col (- (car (posn-col-row start)) (car (window-edges))
-                     (ruler-mode-left-scroll-bar-cols))
+                     (scroll-bar-columns 'left))
               w   (- (ruler-mode-full-window-width)
-                     (ruler-mode-left-scroll-bar-cols)
-                     (ruler-mode-right-scroll-bar-cols)))
+                     (scroll-bar-columns 'left)
+                     (scroll-bar-columns 'right)))
         (when (and (>= col 0) (< col w))
           (setq lm (window-margins)
                 rm (or (cdr lm) 0)
@@ -366,10 +348,10 @@ START-EVENT is the mouse click event."
       (save-selected-window
         (select-window (posn-window start))
         (setq col (- (car (posn-col-row start)) (car (window-edges))
-                     (ruler-mode-left-scroll-bar-cols))
+                     (scroll-bar-columns 'left))
               w   (- (ruler-mode-full-window-width)
-                     (ruler-mode-left-scroll-bar-cols)
-                     (ruler-mode-right-scroll-bar-cols)))
+                     (scroll-bar-columns 'left)
+                     (scroll-bar-columns 'right)))
         (when (and (>= col 0) (< col w))
           (setq lm  (window-margins)
                 rm  (or (cdr lm) 0)
@@ -438,7 +420,7 @@ dragging.  See also the variable `ruler-mode-dragged-symbol'."
          (message "Goal column set to %d (click on %s again to unset it)"
                   newc
                   (propertize (char-to-string ruler-mode-goal-column-char)
-                              'face 'ruler-mode-goal-column-face))
+                              'face 'ruler-mode-goal-column))
          nil) ;; Don't start dragging.
         )
        (if (eq 'click (ruler-mode-mouse-drag-any-column-iteration
@@ -550,19 +532,15 @@ START-EVENT is the mouse click event."
 
 (defvar ruler-mode-header-line-format-old nil
   "Hold previous value of `header-line-format'.")
-(make-variable-buffer-local 'ruler-mode-header-line-format-old)
 
-(defvar ruler-mode-ruler-function nil
-  "If non-nil, function to call to return ruler string.
+(defvar ruler-mode-ruler-function 'ruler-mode-ruler
+  "Function to call to return ruler header line format.
 This variable is expected to be made buffer-local by modes.")
 
 (defconst ruler-mode-header-line-format
-  '(:eval (funcall (if ruler-mode-ruler-function
-                      ruler-mode-ruler-function
-                    'ruler-mode-ruler)))
+  '(:eval (funcall ruler-mode-ruler-function))
   "`header-line-format' used in ruler mode.
-If the non-nil value for ruler-mode-ruler-function is given, use it.
-Else use `ruler-mode-ruler' is used as default value.")
+Call `ruler-mode-ruler-function' to compute the ruler value.")
 
 ;;;###autoload
 (define-minor-mode ruler-mode
@@ -575,18 +553,18 @@ Else use `ruler-mode-ruler' is used as default value.")
         ;; When `ruler-mode' is on save previous header line format
         ;; and install the ruler header line format.
         (when (local-variable-p 'header-line-format)
-          (setq ruler-mode-header-line-format-old header-line-format))
+          (set (make-local-variable 'ruler-mode-header-line-format-old)
+               header-line-format))
         (setq header-line-format ruler-mode-header-line-format)
-        (add-hook 'post-command-hook    ; add local hook
-                  #'force-mode-line-update nil t))
+        (add-hook 'post-command-hook 'force-mode-line-update nil t))
     ;; When `ruler-mode' is off restore previous header line format if
     ;; the current one is the ruler header line format.
     (when (eq header-line-format ruler-mode-header-line-format)
       (kill-local-variable 'header-line-format)
       (when (local-variable-p 'ruler-mode-header-line-format-old)
-        (setq header-line-format ruler-mode-header-line-format-old)))
-    (remove-hook 'post-command-hook     ; remove local hook
-                 #'force-mode-line-update t)))
+        (setq header-line-format ruler-mode-header-line-format-old)
+        (kill-local-variable 'ruler-mode-header-line-format-old)))
+    (remove-hook 'post-command-hook 'force-mode-line-update t)))
 \f
 ;; Add ruler-mode to the minor mode menu in the mode line
 (define-key mode-line-mode-menu [ruler-mode]
@@ -640,133 +618,133 @@ mouse-2: unset goal column"
 (defsubst ruler-mode-space (width &rest props)
   "Return a single space string of WIDTH times the normal character width.
 Optional argument PROPS specifies other text properties to apply."
-  (if (> width 0)
-      (apply 'propertize " " 'display (list 'space :width width) props)
-    ""))
+  (apply 'propertize " " 'display (list 'space :width width) props))
 \f
 (defun ruler-mode-ruler ()
-  "Return a string ruler."
-  (when ruler-mode
-    (let* ((w     (window-width))
-           (m     (window-margins))
-           (lsb   (ruler-mode-left-scroll-bar-cols))
-           (lf    (ruler-mode-left-fringe-cols t))
-           (lm    (or (car m) 0))
-           (rsb   (ruler-mode-right-scroll-bar-cols))
-           (rf    (ruler-mode-right-fringe-cols t))
-           (rm    (or (cdr m) 0))
-           (ruler (make-string w ruler-mode-basic-graduation-char))
-           (i     0)
-           (j     (window-hscroll))
-           k c l1 l2 r2 r1 h1 h2 f1 f2)
-
-      ;; Setup the default properties.
-      (put-text-property 0 w 'face 'ruler-mode-default-face ruler)
-      (put-text-property 0 w
-                         'help-echo
-                         (cond
-                          (ruler-mode-show-tab-stops
-                           ruler-mode-ruler-help-echo-when-tab-stops)
-                          (goal-column
-                           ruler-mode-ruler-help-echo-when-goal-column)
-                          (t
-                           ruler-mode-ruler-help-echo))
-                         ruler)
-      ;; Setup the local map.
-      (put-text-property 0 w 'local-map ruler-mode-map ruler)
-
-      ;; Setup the active area.
-      (while (< i w)
-        ;; Graduations.
-        (cond
-         ;; Show a number graduation.
-         ((= (mod j 10) 0)
-          (setq c (number-to-string (/ j 10))
-                m (length c)
-                k i)
-          (put-text-property
-           i (1+ i) 'face 'ruler-mode-column-number-face
-           ruler)
-          (while (and (> m 0) (>= k 0))
-            (aset ruler k (aref c (setq m (1- m))))
-            (setq k (1- k))))
-         ;; Show an intermediate graduation.
-         ((= (mod j 5) 0)
-          (aset ruler i ruler-mode-inter-graduation-char)))
-        ;; Special columns.
-        (cond
-         ;; Show the `current-column' marker.
-         ((= j (current-column))
-          (aset ruler i ruler-mode-current-column-char)
-          (put-text-property
-           i (1+ i) 'face 'ruler-mode-current-column-face
-           ruler))
-         ;; Show the `goal-column' marker.
-         ((and goal-column (= j goal-column))
-          (aset ruler i ruler-mode-goal-column-char)
-          (put-text-property
-           i (1+ i) 'face 'ruler-mode-goal-column-face
-           ruler)
-          (put-text-property
-           i (1+ i) 'help-echo ruler-mode-goal-column-help-echo
-           ruler))
-         ;; Show the `comment-column' marker.
-         ((= j comment-column)
-          (aset ruler i ruler-mode-comment-column-char)
-          (put-text-property
-           i (1+ i) 'face 'ruler-mode-comment-column-face
-           ruler)
-          (put-text-property
-           i (1+ i) 'help-echo ruler-mode-comment-column-help-echo
-           ruler))
-         ;; Show the `fill-column' marker.
-         ((= j fill-column)
-          (aset ruler i ruler-mode-fill-column-char)
-          (put-text-property
-           i (1+ i) 'face 'ruler-mode-fill-column-face
-           ruler)
-          (put-text-property
-           i (1+ i) 'help-echo ruler-mode-fill-column-help-echo
-           ruler))
-         ;; Show the `tab-stop-list' markers.
-         ((and ruler-mode-show-tab-stops (member j tab-stop-list))
-          (aset ruler i ruler-mode-tab-stop-char)
-          (put-text-property
-           i (1+ i) 'face 'ruler-mode-tab-stop-face
-           ruler)))
-        (setq i (1+ i)
-              j (1+ j)))
-
-      ;; Highlight the fringes and margins.
-      (if (nth 2 (window-fringes))
-          ;; fringes outside margins.
-          (setq l1 lf
-                l2 lm
-                r2 rm
-                r1 rf
-                h1 ruler-mode-fringe-help-echo
-                h2 ruler-mode-margin-help-echo
-                f1 'ruler-mode-fringes-face
-                f2 'ruler-mode-margins-face)
-        ;; fringes inside margins.
-        (setq l1 lm
-              l2 lf
-              r2 rf
-              r1 rm
-              h1 ruler-mode-margin-help-echo
-              h2 ruler-mode-fringe-help-echo
-              f1 'ruler-mode-margins-face
-              f2 'ruler-mode-fringes-face))
-      ;; Return the ruler propertized string.  Using list here,
-      ;; instead of concat visually separate the different areas.
-      (list
-       (ruler-mode-space lsb 'face 'ruler-mode-pad-face)
-       (ruler-mode-space l1 'face f1 'help-echo (format h1 "Left" l1))
-       (ruler-mode-space l2 'face f2 'help-echo (format h2 "Left" l2))
-       ruler
-       (ruler-mode-space r2 'face f2 'help-echo (format h2 "Right" r2))
-       (ruler-mode-space r1 'face f1 'help-echo (format h1 "Right" r1))
-       (ruler-mode-space rsb 'face 'ruler-mode-pad-face)))))
+  "Compute and return an header line ruler."
+  (let* ((w (window-width))
+         (m (window-margins))
+         (f (window-fringes))
+         (i 0)
+         (j (window-hscroll))
+         ;; Setup the scrollbar, fringes, and margins areas.
+         (lf (ruler-mode-space
+              'left-fringe
+              'face 'ruler-mode-fringes
+              'help-echo (format ruler-mode-fringe-help-echo
+                                 "Left" (or (car f) 0))))
+         (rf (ruler-mode-space
+              'right-fringe
+              'face 'ruler-mode-fringes
+              'help-echo (format ruler-mode-fringe-help-echo
+                                 "Right" (or (cadr f) 0))))
+         (lm (ruler-mode-space
+              'left-margin
+              'face 'ruler-mode-margins
+              'help-echo (format ruler-mode-margin-help-echo
+                                 "Left" (or (car m) 0))))
+         (rm (ruler-mode-space
+              'right-margin
+              'face 'ruler-mode-margins
+              'help-echo (format ruler-mode-margin-help-echo
+                                 "Right" (or (cdr m) 0))))
+         (sb (ruler-mode-space
+              'scroll-bar
+              'face 'ruler-mode-pad))
+         ;; Remember the scrollbar vertical type.
+         (sbvt (car (window-current-scroll-bars)))
+         ;; Create an "clean" ruler.
+         (ruler
+          (propertize
+           (make-string w ruler-mode-basic-graduation-char)
+           'face 'ruler-mode-default
+           'local-map ruler-mode-map
+           'help-echo (cond
+                       (ruler-mode-show-tab-stops
+                        ruler-mode-ruler-help-echo-when-tab-stops)
+                       (goal-column
+                        ruler-mode-ruler-help-echo-when-goal-column)
+                       (ruler-mode-ruler-help-echo))))
+         k c)
+    ;; Setup the active area.
+    (while (< i w)
+      ;; Graduations.
+      (cond
+       ;; Show a number graduation.
+       ((= (mod j 10) 0)
+        (setq c (number-to-string (/ j 10))
+              m (length c)
+              k i)
+        (put-text-property
+         i (1+ i) 'face 'ruler-mode-column-number
+         ruler)
+        (while (and (> m 0) (>= k 0))
+          (aset ruler k (aref c (setq m (1- m))))
+          (setq k (1- k))))
+       ;; Show an intermediate graduation.
+       ((= (mod j 5) 0)
+        (aset ruler i ruler-mode-inter-graduation-char)))
+      ;; Special columns.
+      (cond
+       ;; Show the `current-column' marker.
+       ((= j (current-column))
+        (aset ruler i ruler-mode-current-column-char)
+        (put-text-property
+         i (1+ i) 'face 'ruler-mode-current-column
+         ruler))
+       ;; Show the `goal-column' marker.
+       ((and goal-column (= j goal-column))
+        (aset ruler i ruler-mode-goal-column-char)
+        (put-text-property
+         i (1+ i) 'face 'ruler-mode-goal-column
+         ruler)
+       (put-text-property
+         i (1+ i) 'mouse-face 'mode-line-highlight
+         ruler)
+        (put-text-property
+         i (1+ i) 'help-echo ruler-mode-goal-column-help-echo
+         ruler))
+       ;; Show the `comment-column' marker.
+       ((= j comment-column)
+        (aset ruler i ruler-mode-comment-column-char)
+        (put-text-property
+         i (1+ i) 'face 'ruler-mode-comment-column
+         ruler)
+       (put-text-property
+         i (1+ i) 'mouse-face 'mode-line-highlight
+         ruler)
+        (put-text-property
+         i (1+ i) 'help-echo ruler-mode-comment-column-help-echo
+         ruler))
+       ;; Show the `fill-column' marker.
+       ((= j fill-column)
+        (aset ruler i ruler-mode-fill-column-char)
+        (put-text-property
+         i (1+ i) 'face 'ruler-mode-fill-column
+         ruler)
+       (put-text-property
+         i (1+ i) 'mouse-face 'mode-line-highlight
+         ruler)
+        (put-text-property
+         i (1+ i) 'help-echo ruler-mode-fill-column-help-echo
+         ruler))
+       ;; Show the `tab-stop-list' markers.
+       ((and ruler-mode-show-tab-stops (member j tab-stop-list))
+        (aset ruler i ruler-mode-tab-stop-char)
+        (put-text-property
+         i (1+ i) 'face 'ruler-mode-tab-stop
+         ruler)))
+      (setq i (1+ i)
+            j (1+ j)))
+    ;; Return the ruler propertized string.  Using list here,
+    ;; instead of concat visually separate the different areas.
+    (if (nth 2 (window-fringes))
+        ;; fringes outside margins.
+        (list "" (and (eq 'left sbvt) sb) lf lm
+              ruler rm rf (and (eq 'right sbvt) sb))
+      ;; fringes inside margins.
+      (list "" (and (eq 'left sbvt) sb) lm lf
+            ruler rf rm (and (eq 'right sbvt) sb)))))
 
 (provide 'ruler-mode)