annotate lisp/packages/paren.el @ 82:6a378aca36af r20-0b91

Import from CVS: tag r20-0b91
author cvs
date Mon, 13 Aug 2007 09:07:36 +0200
parents 131b0175ea99
children 4be1180a9e89
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1 ;;; paren.el --- highlight (un)matching parens and whole expressions
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
2
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
3 ;; Copyright (C) 1993 Free Software Foundation, Inc.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
4 ;; Copyright (C) 1993, 1994, 1995 Tinker Systems
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
5 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
6 ;; Author: Jonathan Stigelman <Stig@hackvan.com>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
7 ;; Note: (some code scammed from simple.el and blink-paren.el)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
8 ;; Maintainer: Jonathan Stigelman <Stig@hackvan.com>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
9 ;; Keywords: languages, faces
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
10
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
11 ;;; This file is part of XEmacs.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
12 ;;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
13 ;;; XEmacs is free software; you can redistribute it and/or modify
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
14 ;;; it under the terms of the GNU General Public License as published by
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
15 ;;; the Free Software Foundation; either version 2 of the License, or
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
16 ;;; (at your option) any later version.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
17 ;;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
18 ;;; XEmacs is distributed in the hope that it will be useful,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
19 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
20 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
21 ;;; GNU General Public License for more details.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
22 ;;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
23 ;;; You should have received a copy of the GNU General Public License
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
24 ;;; along with XEmacs; if not, write to the Free Software
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
25 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
26
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
27 ;;; Synched up with: Not synched with FSF.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
28 ;;; Way different from FSF.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
29
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
30 ;;; Commentary:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
31
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
32 ;; Purpose of this package:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
33 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
34 ;; This package highlights matching parens (or whole sexps) for easier
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
35 ;; editing of source code, particularly lisp source code.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
36 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
37 ;; The `paren-highlight' hook function runs after each command and
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
38 ;; checks to see if the cursor is at a parenthesis. If so, then it
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
39 ;; highlights, in one of several ways, the matching parenthesis.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
40 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
41 ;; Priority is given to matching parentheses right before the cursor because
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
42 ;; that's what makes sense when you're typing a lot of closed parentheses.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
43 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
44 ;; This is especially intuitive if you frequently use forward-sexp (M-C-f)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
45 ;; and backward-sexp (M-C-b) to maneuver around in source code.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
46 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
47 ;; Different faces are used for matching and mismatching parens so that it
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
48 ;; is easier to see mistakes as you type them. Audible feedback is optional.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
49 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
50 ;; If a (mis)matching paren is offscreen, then a message is sent to the modeline.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
51 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
52 ;; If paren-mode is `sexp', entire S-expressions are highlighted instead of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
53 ;; just matching parens.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
54
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
55 ;;; Code:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
56
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
57 (defvar paren-message-offscreen t
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
58 "*Display message if matching open paren is offscreen.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
59
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
60 (defvar paren-ding-unmatched nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
61 "*Make noise if the cursor is at an unmatched paren.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
62
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
63 If T, then typing or passing over an unmatched paren will ring the bell
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
64 using the `paren' sound. If NIL, then the bell will not ring even if an
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
65 unmatched paren is typed. If neither T or NIL, then the bell will not ring
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
66 when the cursor moves over unmatched parens but will ring if one is typed.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
67
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
68 ;;;###autoload
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
69 (defvar paren-mode nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
70 "*Sets the style of parenthesis highlighting.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
71 Valid values are nil, `blink-paren', `paren', and `sexp'.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
72 nil no parenthesis highlighting.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
73 blink-paren causes the matching paren to blink.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
74 paren causes the matching paren to be highlighted but not to blink.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
75 sexp whole expression enclosed by the local paren at its mate.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
76 nested (not yet implemented) use variable shading to see the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
77 nesting of an expression. Also groks regular expressions
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
78 and shell quoting.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
79
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
80 This variable is global by default, but you can make it buffer-local and
70
131b0175ea99 Import from CVS: tag r20-0b30
cvs
parents: 30
diff changeset
81 highlight parentheses differrently in different major modes.")
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
82
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
83 (make-face 'paren-match)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
84 (or (face-differs-from-default-p 'paren-match)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
85 (copy-face 'highlight 'paren-match))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
86
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
87 (make-face 'paren-mismatch)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
88 (cond ((face-differs-from-default-p 'paren-mismatch) nil)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
89 (t (let ((color-tag (list 'x 'color))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
90 (mono-tag (list 'x 'mono))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
91 (gray-tag (list 'x 'grayscale)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
92 (set-face-background 'paren-mismatch "DeepPink" 'global color-tag)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
93 (set-face-reverse-p 'paren-mismatch t 'global 'tty)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
94 (set-face-background 'paren-mismatch [modeline background] 'global
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
95 mono-tag)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
96 (set-face-foreground 'paren-mismatch [modeline foreground] 'global
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
97 mono-tag)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
98 (set-face-background 'paren-mismatch [modeline background] 'global
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
99 gray-tag)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
100 (set-face-foreground 'paren-mismatch [modeline foreground] 'global
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
101 gray-tag))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
102
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
103 (make-face 'paren-blink-off)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
104 (or (face-differs-from-default-p 'paren-blink-off)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
105 (set-face-foreground 'paren-blink-off (face-background 'default)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
106
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
107 ;; this is either paren-match or paren-mismatch...
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
108 (defvar paren-blink-on-face nil)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
109
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
110 (defvar paren-blink-interval 0.2
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
111 "*If the cursor is on a parenthesis, the matching parenthesis will blink.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
112 This variable controls how long each phase of the blink lasts in seconds.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
113 This should be a fractional part of a second (a float.)")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
114
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
115 (defvar paren-max-blinks (* 5 60 5) ; 5 minutes is plenty...
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
116 ;; idea from Eric Eide <eeide@jaguar.cs.utah.edu>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
117 "*Maximum number of times that a matching parenthesis will blink.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
118 Set this to NIL if you want indefinite blinking.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
119
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
120 ;; timeout to blink the face
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
121 (defvar paren-timeout-id nil)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
122
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
123 ;; Code:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
124
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
125 (defvar paren-n-blinks)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
126 (defvar paren-extent nil)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
127
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
128 ;; used to suppress messages from the same position so that other messages
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
129 ;; can be seen in the modeline.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
130 (make-variable-buffer-local
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
131 (defvar paren-message-suppress nil))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
132
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
133 (defsubst pos-visible-in-window-safe (pos)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
134 "safe version of pos-visible-in-window-p"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
135 (condition-case nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
136 ;; #### - is this needed in XEmacs???
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
137 (pos-visible-in-window-p pos)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
138 (args-out-of-range nil)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
139
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
140 ;; called before a new command is executed in the pre-command-hook
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
141 ;; cleanup by removing the extent and the time-out
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
142 (defun paren-nuke-extent ()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
143 (condition-case c ; don't ever signal an error in pre-command-hook!
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
144 (let ((inhibit-quit t))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
145 (if paren-timeout-id
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
146 (disable-timeout (prog1 paren-timeout-id
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
147 (setq paren-timeout-id nil))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
148 (if paren-extent
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
149 (delete-extent (prog1 paren-extent
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
150 (setq paren-extent nil)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
151 (error
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
152 (message "paren-nuke-extent error! %s" c))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
153
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
154 ;; callback for the timeout
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
155 ;; swap the face of the extent on the matching paren
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
156 (defun paren-blink-timeout (arg)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
157 ;; The extent could have been deleted for some reason and not point to a
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
158 ;; buffer anymore. So catch any error to remove the timeout.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
159 (condition-case ()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
160 (if (and paren-max-blinks
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
161 (> (setq paren-n-blinks (1+ paren-n-blinks)) paren-max-blinks))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
162 (paren-nuke-extent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
163 (set-extent-face paren-extent
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
164 (if (eq (extent-face paren-extent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
165 paren-blink-on-face)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
166 'paren-blink-off
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
167 paren-blink-on-face)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
168 (error (paren-nuke-extent))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
169
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
170
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
171 (defun paren-describe-match (pos mismatch)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
172 (or (window-minibuffer-p (selected-window))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
173 (save-excursion
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
174 (goto-char pos)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
175 (message "%s %s"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
176 (if mismatch "MISMATCH:" "Matches")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
177 ;; if there's stuff on this line preceding the paren, then
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
178 ;; display text from beginning of line to paren.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
179 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
180 ;; If, however, the paren is at the beginning of a line, then
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
181 ;; skip whitespace forward and display text from paren to end
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
182 ;; of the next line containing nonspace text.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
183 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
184 ;; If paren-backwards-message gravity were implemented, then
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
185 ;; perhaps it would reverse this behavior and look to the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
186 ;; previous line for meaningful context.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
187 (if (save-excursion
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
188 (skip-chars-backward " \t")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
189 (not (bolp)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
190 (concat (buffer-substring
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
191 (progn (beginning-of-line) (point))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
192 (1+ pos)) "...")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
193 (buffer-substring
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
194 pos (progn
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
195 (forward-char 1)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
196 (skip-chars-forward "\n \t")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
197 (end-of-line)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
198 (point))))))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
199
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
200 (defun paren-maybe-ding ()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
201 (and (or (eq paren-ding-unmatched t)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
202 (and paren-ding-unmatched
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
203 (eq this-command 'self-insert-command)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
204 (progn
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
205 (message "Unmatched parenthesis.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
206 (ding nil 'paren))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
207
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
208 ;; Find the place to show, if there is one,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
209 ;; and show it until input arrives.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
210 (defun paren-highlight ()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
211 "This highlights matching parentheses.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
212
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
213 See the variables:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
214 paren-message-offscreen use modeline when matchingparen is offscreen?
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
215 paren-ding-unmatched make noise when passing over mismatched parens?
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
216 paren-mode 'blink-paren, 'paren, or 'sexp
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
217 blink-matching-paren-distance maximum distance to search for parens.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
218
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
219 and the following faces:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
220 paren-match, paren-mismatch, paren-blink-off"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
221
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
222 ;; I suppose I could check here to see if a keyboard macro is executing,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
223 ;; but I did a quick empirical check and couldn't tell that there was any
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
224 ;; difference in performance
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
225
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
226 (let ((oldpos (point))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
227 (pface nil) ; face for paren...nil kills the overlay
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
228 (dir (and paren-mode
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
229 (not (input-pending-p))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
230 (not executing-kbd-macro)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
231 (cond ((eq (char-syntax (preceding-char)) ?\))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
232 -1)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
233 ((eq (char-syntax (following-char)) ?\()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
234 1))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
235 pos mismatch)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
236
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
237 (save-excursion
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
238 (if (or (not dir)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
239 (not (save-restriction
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
240 ;; Determine the range within which to look for a match.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
241 (if blink-matching-paren-distance
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
242 (narrow-to-region
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
243 (max (point-min)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
244 (- (point) blink-matching-paren-distance))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
245 (min (point-max)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
246 (+ (point) blink-matching-paren-distance))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
247
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
248 ;; Scan across one sexp within that range.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
249 (condition-case nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
250 (setq pos (scan-sexps (point) dir))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
251 ;; NOTE - if blink-matching-paren-distance is set,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
252 ;; then we can have spurious unmatched parens.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
253 (error (paren-maybe-ding)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
254 nil)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
255
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
256 ;; do nothing if we didn't find a matching paren...
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
257 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
258
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
259 ;; See if the "matching" paren is the right kind of paren
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
260 ;; to match the one we started at.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
261 (let ((beg (min pos oldpos)) (end (max pos oldpos)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
262 (setq mismatch
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
263 (and (/= (char-syntax (char-after beg)) ?\\)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
264 (/= (char-syntax (char-after beg)) ?\$)
24
4103f0995bd7 Import from CVS: tag r19-15b95
cvs
parents: 0
diff changeset
265 ;; XEmacs change
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
266 (/= (char-after (1- end))
70
131b0175ea99 Import from CVS: tag r20-0b30
cvs
parents: 30
diff changeset
267 (matching-paren (char-after beg)))))
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
268 (if (eq paren-mode 'sexp)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
269 (setq paren-extent (make-extent beg end))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
270 (and mismatch
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
271 (paren-maybe-ding))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
272 (setq pface (if mismatch
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
273 'paren-mismatch
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
274 'paren-match))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
275 (and (memq paren-mode '(blink-paren paren))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
276 (setq paren-extent (make-extent (- pos dir) pos)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
277
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
278 (if (and paren-message-offscreen
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
279 (eq dir -1)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
280 (not (eq paren-message-suppress (point)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
281 (not (window-minibuffer-p (selected-window)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
282 (not (pos-visible-in-window-safe pos)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
283 (progn
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
284 (setq paren-message-suppress (point))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
285 (paren-describe-match pos mismatch))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
286 (setq paren-message-suppress nil))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
287
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
288 ;; put the right face on the extent
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
289 (cond (pface
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
290 (set-extent-face paren-extent pface)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
291 (set-extent-priority paren-extent 100) ; want this to be high
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
292 (and (eq paren-mode 'blink-paren)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
293 (setq paren-blink-on-face pface
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
294 paren-n-blinks 0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
295 paren-timeout-id
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
296 (and paren-blink-interval
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
297 (add-timeout paren-blink-interval
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
298 'paren-blink-timeout
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
299 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
300 paren-blink-interval))))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
301 ))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
302
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
303 ;; kill off the competition, er, uh, eliminate redundancy...
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
304 (setq post-command-hook (delq 'show-paren-command-hook post-command-hook))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
305 (setq pre-command-hook (delq 'blink-paren-pre-command pre-command-hook))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
306 (setq post-command-hook (delq 'blink-paren-post-command post-command-hook))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
307
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
308 ;;;###autoload
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
309 (defun paren-set-mode (arg &optional quiet)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
310 "Cycles through possible values for `paren-mode', force off with negative arg.
70
131b0175ea99 Import from CVS: tag r20-0b30
cvs
parents: 30
diff changeset
311 When called from lisp, a symbolic value for `paren-mode' can be pased directly.
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
312 See also `paren-mode' and `paren-highlight'."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
313 (interactive "P")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
314 (let* ((paren-modes '(blink-paren paren sexp))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
315 (paren-next-modes (cons nil (append paren-modes (list nil)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
316 (setq paren-mode (if (and (numberp arg) (< arg 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
317 nil ; turn paren highlighting off
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
318 (cond ((and arg (symbolp arg)) arg)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
319 ((and (numberp arg) (> arg 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
320 (nth (1- arg) paren-modes))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
321 ((numberp arg) nil)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
322 (t (car (cdr (memq paren-mode
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
323 paren-next-modes)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
324 )))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
325 (cond (paren-mode
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
326 (add-hook 'post-command-hook 'paren-highlight)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
327 (add-hook 'pre-command-hook 'paren-nuke-extent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
328 (setq blink-matching-paren nil))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
329 ((not (local-variable-p 'paren-mode (current-buffer)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
330 (remove-hook 'post-command-hook 'paren-highlight)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
331 (remove-hook 'pre-command-hook 'paren-nuke-extent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
332 (paren-nuke-extent) ; overkill
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
333 (setq blink-matching-paren t)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
334 ))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
335 (or quiet (message "Paren mode is %s" (or paren-mode "OFF"))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
336
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
337 (eval-when-compile
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
338 ;; suppress compiler warning.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
339 (defvar highlight-paren-expression))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
340
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
341 (paren-set-mode (if (and (boundp 'highlight-paren-expression)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
342 ;; bletcherous blink-paren no-naming-convention
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
343 highlight-paren-expression)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
344 'sexp
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
345 (if (eq 'x (device-type (selected-device)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
346 'blink-paren
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
347 'paren))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
348 t)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
349
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
350 ;;;###autoload
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
351 (make-obsolete 'blink-paren 'paren-set-mode)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
352
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
353 ;;;###autoload
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
354 (defun blink-paren (&optional arg)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
355 "Obsolete. Use `paren-set-mode' instead."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
356 (interactive "P")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
357 (paren-set-mode (if (and (numberp arg) (> arg 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
358 'blink-paren -1) t))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
359
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
360 (provide 'blink-paren)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
361 (provide 'paren)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
362
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
363 ;; Local Variables:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
364 ;; byte-optimize: t
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
365 ;; End:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
366
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
367 ;;; paren.el ends here