(Fprocess_send_eof): Prooperly conditionalize prev. change.
[bpt/emacs.git] / lisp / paren.el
CommitLineData
5e28918b 1;;; paren.el --- highlight matching paren.
b578f267 2
673cc3c5 3;; Copyright (C) 1993, 1996 Free Software Foundation, Inc.
5e28918b 4
e4c37df7
JB
5;; Author: rms@gnu.ai.mit.edu
6;; Maintainer: FSF
7;; Keywords: languages, faces
5e2325c9 8
5e28918b
JB
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
b578f267
EN
22;; along with GNU Emacs; see the file COPYING. If not, write to the
23;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24;; Boston, MA 02111-1307, USA.
5e28918b
JB
25
26;;; Commentary:
27
28;; Load this and it will display highlighting on whatever
29;; paren matches the one before or after point.
30
31;;; Code:
32
eb0d9f08 33;; This is the overlay used to highlight the matching paren.
d1475aa1 34(defvar show-paren-overlay nil)
673cc3c5 35;; This is the overlay used to highlight the closeparen right before point.
eb0d9f08
RS
36(defvar show-paren-overlay-1 nil)
37
673cc3c5
RS
38(defvar show-paren-mode nil)
39(defvar show-paren-idle-timer nil)
40
eb0d9f08 41(defvar show-paren-mismatch-face nil)
5e28918b 42
673cc3c5
RS
43(defvar show-paren-delay (if (featurep 'lisp-float-type) 0.125 1)
44 "*Time in seconds to delay before showing the matching paren.")
45
30322a27 46(defvar show-paren-face 'region
673cc3c5
RS
47 "*Name of the face to use for showing the matching paren.")
48
49;;;###autoload
50(defun show-paren-mode (&optional arg)
51 "Toggle Show Paren mode.
52With prefix ARG, turn Show Paren mode on if and only if ARG is positive.
53Returns the new status of Show Paren mode (non-nil means on).
54
55When Show Paren mode is enabled, any matching parenthesis is highlighted
56after `show-paren-delay' seconds of Emacs idle time."
57 (interactive "P")
58 (if window-system
59 (let ((on-p (if arg
60 (> (prefix-numeric-value arg) 0)
61 (not show-paren-mode))))
62 (setq blink-matching-paren-on-screen (not on-p))
63 (and show-paren-idle-timer (cancel-timer show-paren-idle-timer))
64 (if on-p
65 (setq show-paren-idle-timer (run-with-idle-timer show-paren-delay t
66 'show-paren-function))
67 (and show-paren-overlay (overlay-buffer show-paren-overlay)
68 (delete-overlay show-paren-overlay))
69 (and show-paren-overlay-1 (overlay-buffer show-paren-overlay-1)
70 (delete-overlay show-paren-overlay-1)))
71 (setq show-paren-mode on-p))))
30322a27 72
d1475aa1
JB
73;; Find the place to show, if there is one,
74;; and show it until input arrives.
673cc3c5 75(defun show-paren-function ()
bac79b51 76 ;; Do nothing if no window system to display results with.
e4b93bab 77 ;; Do nothing if executing keyboard macro.
bac79b51 78 ;; Do nothing if input is pending.
26ee1a5d 79 (if window-system
80e16738 80 (let (pos dir mismatch (oldpos (point))
30322a27 81 (face show-paren-face))
cde4c890
RS
82 (cond ((eq (char-syntax (preceding-char)) ?\))
83 (setq dir -1))
84 ((eq (char-syntax (following-char)) ?\()
85 (setq dir 1)))
eb0d9f08
RS
86 (if dir
87 (save-excursion
88 (save-restriction
89 ;; Determine the range within which to look for a match.
90 (if blink-matching-paren-distance
91 (narrow-to-region (max (point-min)
92 (- (point) blink-matching-paren-distance))
93 (min (point-max)
94 (+ (point) blink-matching-paren-distance))))
95 ;; Scan across one sexp within that range.
0d554bae 96 ;; Errors or nil mean there is a mismatch.
eb0d9f08
RS
97 (condition-case ()
98 (setq pos (scan-sexps (point) dir))
0d554bae
RS
99 (error (setq pos t
100 mismatch t)))
101 ;; If found a "matching" paren, see if it is the right
102 ;; kind of paren to match the one we started at.
103 (if (integerp pos)
eb0d9f08
RS
104 (let ((beg (min pos oldpos)) (end (max pos oldpos)))
105 (and (/= (char-syntax (char-after beg)) ?\$)
106 (setq mismatch
f8e2c40c 107 (not (eq (char-before end)
080d320d
RS
108 ;; This can give nil.
109 (matching-paren (char-after beg))))))))
eb0d9f08
RS
110 ;; If they don't properly match, use a different face,
111 ;; or print a message.
112 (if mismatch
113 (progn
114 (and (null show-paren-mismatch-face)
115 (x-display-color-p)
00b05a42 116 (progn
fee7c89d
KH
117 (add-to-list 'facemenu-unlisted-faces
118 'paren-mismatch)
00b05a42
RS
119 (make-face 'paren-mismatch)
120 (or (face-nontrivial-p 'paren-mismatch t)
121 (progn
122 (set-face-background 'paren-mismatch
123 "purple")
124 (set-face-foreground 'paren-mismatch
125 "white")))
126 (setq show-paren-mismatch-face 'paren-mismatch)))
eb0d9f08
RS
127 (if show-paren-mismatch-face
128 (setq face show-paren-mismatch-face)
129 (message "Paren mismatch"))))
130 )))
80e16738 131 (cond (pos
0d554bae
RS
132 (if (or (= dir -1)
133 (not (integerp pos)))
eb0d9f08
RS
134 ;; If matching backwards, highlight the closeparen
135 ;; before point as well as its matching open.
0d554bae
RS
136 ;; If matching forward, and the openparen is unbalanced,
137 ;; highlight the paren at point to indicate misbalance.
138 (let ((from (if (= dir 1)
139 (point)
f8e2c40c 140 (forward-point -1)))
0d554bae 141 (to (if (= dir 1)
f8e2c40c 142 (forward-point 1)
0d554bae 143 (point))))
eb0d9f08 144 (if show-paren-overlay-1
776b7d5a 145 (move-overlay show-paren-overlay-1
0d554bae 146 from to
776b7d5a 147 (current-buffer))
eb0d9f08 148 (setq show-paren-overlay-1
0d554bae 149 (make-overlay from to)))
329ff3a4
RS
150 ;; Always set the overlay face, since it varies.
151 (overlay-put show-paren-overlay-1 'face face))
eb0d9f08
RS
152 ;; Otherwise, turn off any such highlighting.
153 (and show-paren-overlay-1
154 (overlay-buffer show-paren-overlay-1)
155 (delete-overlay show-paren-overlay-1)))
0d554bae
RS
156 ;; Turn on highlighting for the matching paren, if found.
157 ;; If it's an unmatched paren, turn off any such highlighting.
158 (or (and (not (integerp pos))
159 (delete-overlay show-paren-overlay))
f8e2c40c
KH
160 (save-excursion
161 (goto-char pos)
162 (if show-paren-overlay
163 (move-overlay show-paren-overlay
164 (forward-point (- dir))
165 pos
166 (current-buffer))
167 (setq show-paren-overlay
168 (make-overlay (forward-point (- dir)) pos)))))
329ff3a4
RS
169 ;; Always set the overlay face, since it varies.
170 (overlay-put show-paren-overlay 'face face))
80e16738 171 (t
eb0d9f08
RS
172 ;; If not at a paren that has a match,
173 ;; turn off any previous paren highlighting.
80e16738 174 (and show-paren-overlay (overlay-buffer show-paren-overlay)
eb0d9f08
RS
175 (delete-overlay show-paren-overlay))
176 (and show-paren-overlay-1 (overlay-buffer show-paren-overlay-1)
177 (delete-overlay show-paren-overlay-1)))))))
5e28918b 178
3a3236d2
JB
179(provide 'paren)
180
181;;; paren.el ends here