(pr-get-symbol): Define during compile.
[bpt/emacs.git] / lisp / paren.el
index 50af83b..60c9aef 100644 (file)
@@ -1,8 +1,8 @@
-;;; paren.el --- highlight matching paren.
+;;; paren.el --- highlight matching paren
 
-;; Copyright (C) 1993, 1996 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1996, 2001 Free Software Foundation, Inc.
 
-;; Author: rms@gnu.ai.mit.edu
+;; Author: rms@gnu.org
 ;; Maintainer: FSF
 ;; Keywords: languages, faces
 
 
 ;;; Commentary:
 
-;; Load this and it will display highlighting on whatever
-;; paren matches the one before or after point.
+;; Put this into your ~/.emacs:
+
+;;  (show-paren-mode t)
+
+;; It will display highlighting on whatever paren matches the one
+;; before or after point.
 
 ;;; Code:
 
 ;; This is the overlay used to highlight the closeparen right before point.
 (defvar show-paren-overlay-1 nil)
 
-(defcustom show-paren-mode nil
-  "*Toggle Show Paren mode.
-When Show Paren mode is enabled, any matching parenthesis is highlighted
-after `show-paren-delay' seconds of Emacs idle time.
-Setting this variable directly does not take effect;
-use either \\[customize] or the function `show-paren-mode'."
-  :set (lambda (symbol value)
-        (show-paren-mode (or value 0)))
-  :initialize 'custom-initialize-default
-  :type 'boolean
-  :group 'paren-showing
-  :require 'paren)
-
 (defcustom show-paren-style 'parenthesis
   "*Style used when showing a matching paren.
 Valid styles are `parenthesis' (meaning show the matching paren),
@@ -68,22 +59,34 @@ otherwise)."
   :type '(number :tag "seconds")
   :group 'paren-showing)
 
+(defcustom show-paren-priority 1000
+  "*Priority of paren highlighting overlays."
+  :type 'integer
+  :group 'paren-showing
+  :version "21.1")
+
 (defcustom show-paren-ring-bell-on-mismatch nil
   "*If non-nil, beep if mismatched paren is detected."
   :type 'boolean
   :group 'paren-showing
   :version "20.3")
-  
+
 (defface show-paren-match-face
-  '((((class color)) (:background "turquoise"))
-    (t (:background "gray")))
+  '((((class color) (background light))
+     :background "turquoise")          ; looks OK on tty (becomes cyan)
+    (((class color) (background dark))
+     :background "steelblue3")         ; looks OK on tty (becomes blue)
+    (((background dark))
+     :background "grey50")
+    (t
+     :background "gray"))
   "Show Paren mode face used for a matching paren."
   :group 'faces
   :group 'paren-showing)
 
 (defface show-paren-mismatch-face
   '((((class color)) (:foreground "white" :background "purple"))
-    (t (:reverse-video t)))
+    (t (:inverse-video t)))
   "Show Paren mode face used for a mismatching paren."
   :group 'faces
   :group 'paren-showing)
@@ -91,24 +94,20 @@ otherwise)."
 (defvar show-paren-idle-timer nil)
 
 ;;;###autoload
-(defun show-paren-mode (&optional arg)
+(define-minor-mode show-paren-mode
   "Toggle Show Paren mode.
 With prefix ARG, turn Show Paren mode on if and only if ARG is positive.
 Returns the new status of Show Paren mode (non-nil means on).
 
 When Show Paren mode is enabled, any matching parenthesis is highlighted
 in `show-paren-style' after `show-paren-delay' seconds of Emacs idle time."
-  (interactive "P")
-  (let ((on-p (if arg
-                 (> (prefix-numeric-value arg) 0)
-               (not show-paren-mode))))
-    (setq show-paren-mode on-p)
+  :global t :group 'paren-showing
     ;; Turn off the usual paren-matching method
     ;; when this one is turned on.
     (if (local-variable-p 'show-paren-mode)
        (make-local-variable 'blink-matching-paren-on-screen)
       (kill-local-variable 'blink-matching-paren-on-screen))
-    (setq blink-matching-paren-on-screen (not on-p))
+    (setq blink-matching-paren-on-screen (not show-paren-mode))
 
     ;; Now enable or disable the mechanism.
     ;; First get rid of the old idle timer.
@@ -124,23 +123,22 @@ in `show-paren-style' after `show-paren-delay' seconds of Emacs idle time."
       (setq show-paren-idle-timer (run-with-idle-timer
                                   show-paren-delay t
                                   'show-paren-function)))
-    (unless on-p
+    (unless show-paren-mode
       (and show-paren-overlay
           (eq (overlay-buffer show-paren-overlay) (current-buffer))
           (delete-overlay show-paren-overlay))
       (and show-paren-overlay-1
           (eq (overlay-buffer show-paren-overlay-1) (current-buffer))
-          (delete-overlay show-paren-overlay-1)))))
+          (delete-overlay show-paren-overlay-1))))
 
 ;; Find the place to show, if there is one,
 ;; and show it until input arrives.
 (defun show-paren-function ()
   (if show-paren-mode
-      (let (pos dir mismatch face (oldpos (point)))
-       (cond ((eq (char-syntax (preceding-char)) ?\))
-              (setq dir -1))
-             ((eq (char-syntax (following-char)) ?\()
-              (setq dir 1)))
+      (let ((oldpos (point))
+           (dir (cond ((eq (car (syntax-after (1- (point)))) 5) -1)
+                      ((eq (car (syntax-after (point))) 4) 1)))
+           pos mismatch face)
        ;;
        ;; Find the other end of the sexp.
        (when dir
@@ -156,6 +154,14 @@ in `show-paren-style' after `show-paren-delay' seconds of Emacs idle time."
              (condition-case ()
                  (setq pos (scan-sexps (point) dir))
                (error (setq pos t mismatch t)))
+             ;; Move back the other way and verify we get back to the
+             ;; starting point.  If not, these two parens don't really match.
+             ;; Maybe the one at point is escaped and doesn't really count.
+             (when (integerp pos)
+               (unless (condition-case ()
+                           (eq (point) (scan-sexps pos (- dir)))
+                         (error nil))
+                 (setq pos nil)))
              ;; If found a "matching" paren, see if it is the right
              ;; kind of paren to match the one we started at.
              (when (integerp pos)
@@ -203,6 +209,7 @@ in `show-paren-style' after `show-paren-delay' seconds of Emacs idle time."
                  (move-overlay show-paren-overlay-1 from to (current-buffer))
                (setq show-paren-overlay-1 (make-overlay from to)))
              ;; Always set the overlay face, since it varies.
+             (overlay-put show-paren-overlay-1 'priority show-paren-priority)
              (overlay-put show-paren-overlay-1 'face face)))
          ;;
          ;; Turn on highlighting for the matching paren, if found.
@@ -226,6 +233,7 @@ in `show-paren-style' after `show-paren-delay' seconds of Emacs idle time."
              (setq show-paren-overlay (make-overlay from to))))
          ;;
          ;; Always set the overlay face, since it varies.
+         (overlay-put show-paren-overlay 'priority show-paren-priority)
          (overlay-put show-paren-overlay 'face face)))
     ;; show-paren-mode is nil in this buffer.
     (and show-paren-overlay
@@ -235,7 +243,4 @@ in `show-paren-style' after `show-paren-delay' seconds of Emacs idle time."
 
 (provide 'paren)
 
-(if show-paren-mode
-    (show-paren-mode t))
-
 ;;; paren.el ends here