(Frename_buffer): Rename arg NAME to NEWNAME.
[bpt/emacs.git] / lisp / paren.el
CommitLineData
5e28918b 1;;; paren.el --- highlight matching paren.
e788f291 2;; Copyright (C) 1993 Free Software Foundation, Inc.
5e28918b 3
e4c37df7
JB
4;; Author: rms@gnu.ai.mit.edu
5;; Maintainer: FSF
6;; Keywords: languages, faces
5e2325c9 7
5e28918b
JB
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to
22;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
24;;; Commentary:
25
26;; Load this and it will display highlighting on whatever
27;; paren matches the one before or after point.
28
29;;; Code:
30
eb0d9f08 31;; This is the overlay used to highlight the matching paren.
d1475aa1 32(defvar show-paren-overlay nil)
eb0d9f08
RS
33;; This is the overlay used to highlight the closeparen
34;; right before point.
35(defvar show-paren-overlay-1 nil)
36
37(defvar show-paren-mismatch-face nil)
5e28918b 38
30322a27
RS
39(defvar show-paren-face 'region
40 "*Name of face to use for showing the matching paren.")
41
d1475aa1
JB
42;; Find the place to show, if there is one,
43;; and show it until input arrives.
44(defun show-paren-command-hook ()
bac79b51 45 ;; Do nothing if no window system to display results with.
e4b93bab 46 ;; Do nothing if executing keyboard macro.
bac79b51 47 ;; Do nothing if input is pending.
d196a64d 48 (if (and window-system (not executing-kbd-macro) (sit-for 0 100))
80e16738 49 (let (pos dir mismatch (oldpos (point))
30322a27 50 (face show-paren-face))
cde4c890
RS
51 (cond ((eq (char-syntax (preceding-char)) ?\))
52 (setq dir -1))
53 ((eq (char-syntax (following-char)) ?\()
54 (setq dir 1)))
eb0d9f08
RS
55 (if dir
56 (save-excursion
57 (save-restriction
58 ;; Determine the range within which to look for a match.
59 (if blink-matching-paren-distance
60 (narrow-to-region (max (point-min)
61 (- (point) blink-matching-paren-distance))
62 (min (point-max)
63 (+ (point) blink-matching-paren-distance))))
64 ;; Scan across one sexp within that range.
65 (condition-case ()
66 (setq pos (scan-sexps (point) dir))
67 (error nil))
68 ;; See if the "matching" paren is the right kind of paren
69 ;; to match the one we started at.
70 (if pos
71 (let ((beg (min pos oldpos)) (end (max pos oldpos)))
72 (and (/= (char-syntax (char-after beg)) ?\$)
73 (setq mismatch
080d320d
RS
74 (not (eq (char-after (1- end))
75 ;; This can give nil.
76 (matching-paren (char-after beg))))))))
eb0d9f08
RS
77 ;; If they don't properly match, use a different face,
78 ;; or print a message.
79 (if mismatch
80 (progn
81 (and (null show-paren-mismatch-face)
82 (x-display-color-p)
e8f9dff9 83 (or (internal-find-face 'paren-mismatch)
eb0d9f08 84 (progn
a1251f79 85 (make-face 'paren-mismatch)
30322a27 86 (set-face-background 'paren-mismatch
a060984a
RS
87 "purple")
88 (set-face-foreground 'paren-mismatch
89 "white")))
e8f9dff9 90 (setq show-paren-mismatch-face 'paren-mismatch))
eb0d9f08
RS
91 (if show-paren-mismatch-face
92 (setq face show-paren-mismatch-face)
93 (message "Paren mismatch"))))
94 )))
80e16738 95 (cond (pos
eb0d9f08
RS
96 (if (= dir -1)
97 ;; If matching backwards, highlight the closeparen
98 ;; before point as well as its matching open.
99 (progn
100 (if show-paren-overlay-1
776b7d5a
RS
101 (move-overlay show-paren-overlay-1
102 (+ (point) dir) (point)
103 (current-buffer))
eb0d9f08 104 (setq show-paren-overlay-1
329ff3a4
RS
105 (make-overlay (- pos dir) pos)))
106 ;; Always set the overlay face, since it varies.
107 (overlay-put show-paren-overlay-1 'face face))
eb0d9f08
RS
108 ;; Otherwise, turn off any such highlighting.
109 (and show-paren-overlay-1
110 (overlay-buffer show-paren-overlay-1)
111 (delete-overlay show-paren-overlay-1)))
112 ;; Turn on highlighting for the matching paren.
80e16738 113 (if show-paren-overlay
776b7d5a
RS
114 (move-overlay show-paren-overlay (- pos dir) pos
115 (current-buffer))
80e16738 116 (setq show-paren-overlay
329ff3a4
RS
117 (make-overlay (- pos dir) pos)))
118 ;; Always set the overlay face, since it varies.
119 (overlay-put show-paren-overlay 'face face))
80e16738 120 (t
eb0d9f08
RS
121 ;; If not at a paren that has a match,
122 ;; turn off any previous paren highlighting.
80e16738 123 (and show-paren-overlay (overlay-buffer show-paren-overlay)
eb0d9f08
RS
124 (delete-overlay show-paren-overlay))
125 (and show-paren-overlay-1 (overlay-buffer show-paren-overlay-1)
126 (delete-overlay show-paren-overlay-1)))))))
5e28918b 127
eb0d9f08
RS
128(if window-system
129 (progn
130 (setq blink-paren-function nil)
131 (add-hook 'post-command-hook 'show-paren-command-hook)))
520bca57
RS
132;;; This is in case paren.el is preloaded.
133(add-hook 'window-setup-hook
134 (function (lambda ()
135 (if window-system
136 (progn
137 (setq blink-paren-function nil)
138 (add-hook 'post-command-hook
139 'show-paren-command-hook))))))
3a3236d2
JB
140(provide 'paren)
141
142;;; paren.el ends here