Mercurial > hg > xemacs-beta
comparison lisp/packages/blink-paren.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 0293115a14e9 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;; blink-paren.el --- blink the matching paren, just like Zmacs | |
2 ;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. | |
3 | |
4 ;; Author: devin@lucid.com. | |
5 ;; Keywords: faces | |
6 | |
7 ;; This file is part of XEmacs. | |
8 | |
9 ;; XEmacs is free software; you can redistribute it and/or modify it | |
10 ;; under the terms of the GNU General Public License as published by | |
11 ;; the Free Software Foundation; either version 2, or (at your option) | |
12 ;; any later version. | |
13 | |
14 ;; XEmacs is distributed in the hope that it will be useful, but | |
15 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 ;; General Public License for more details. | |
18 | |
19 ;; You should have received a copy of the GNU General Public License | |
20 ;; along with XEmacs; see the file COPYING. If not, write to the Free | |
21 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
22 | |
23 ;;; Synched up with: Not in FSF. | |
24 | |
25 (defvar blink-paren-timeout 0.2 | |
26 "*If the cursor is on a parenthesis, the matching parenthesis will blink. | |
27 This variable controls how long each phase of the blink lasts in seconds. | |
28 This should be a fractional part of a second (a float.)") | |
29 | |
30 (defvar highlight-paren-expression nil | |
31 "*If true, highlight the whole expression of the paren under the cursor | |
32 instead of blinking (or highlighting) the matching paren. This will highlight | |
33 the expression using the `highlight-expression' face.") | |
34 | |
35 ;;; The blinking paren alternates between the faces blink-paren-on and | |
36 ;;; blink-paren-off. The default is for -on to look just like default | |
37 ;;; text, and -off to be invisible. You can change this so that, for | |
38 ;;; example, the blinking paren fluctuates between bold and italic... | |
39 ;;; | |
40 ;;; You can make the matching paren merely be highlighted (and not blink) | |
41 ;;; by setting the blink-paren-on and blink-paren-off faces to have the same | |
42 ;;; attributes; if you do this, then emacs will not consume as much CPU. | |
43 ;;; | |
44 ;;; If highlight-paren-expression is true, then the whole sexp between the | |
45 ;;; parens will be displayed in the `highlight-expression' face instead. | |
46 | |
47 (make-face 'blink-paren-on) | |
48 (make-face 'blink-paren-off) | |
49 (make-face 'highlight-expression) | |
50 | |
51 ;; extent used to change the face of the matching paren | |
52 (defvar blink-paren-extent nil) | |
53 | |
54 ;; timeout to blink the face | |
55 (defvar blink-paren-timeout-id nil) | |
56 | |
57 ;; find if we should look foward or backward to find the matching paren | |
58 (defun blink-paren-sexp-dir () | |
59 (cond ((and (< (point) (point-max)) | |
60 (eq (char-syntax (char-after (point))) ?\()) | |
61 1) | |
62 ((and (> (point) (point-min)) | |
63 (eq (char-syntax (char-after (- (point) 1))) ?\))) | |
64 -1) | |
65 (t ()))) | |
66 | |
67 ;; make an extent on the matching paren if any. return it. | |
68 (defun blink-paren-make-extent () | |
69 (let ((dir (blink-paren-sexp-dir))) | |
70 (and dir | |
71 (condition-case () | |
72 (let* ((parse-sexp-ignore-comments t) | |
73 (other-pos (let ((pmin (point-min)) | |
74 (pmax (point-max)) | |
75 (point (point))) | |
76 (unwind-protect | |
77 (progn | |
78 (narrow-to-region | |
79 (max pmin (- point blink-matching-paren-distance)) | |
80 (min pmax (+ point blink-matching-paren-distance))) | |
81 (forward-sexp dir) (point)) | |
82 (narrow-to-region pmin pmax) | |
83 (goto-char point)))) | |
84 (extent (if (= dir 1) | |
85 (make-extent (if highlight-paren-expression | |
86 (point) | |
87 (- other-pos 1)) | |
88 other-pos) | |
89 (make-extent other-pos | |
90 (if highlight-paren-expression | |
91 (point) | |
92 (+ other-pos 1)))))) | |
93 (set-extent-face extent (if highlight-paren-expression | |
94 'highlight-expression | |
95 'blink-paren-on)) | |
96 extent) | |
97 (error nil))))) | |
98 | |
99 ;; callback for the timeout | |
100 ;; swap the face of the extent on the matching paren | |
101 (defun blink-paren-timeout (arg) | |
102 ;; The extent could have been deleted for some reason and not point to a | |
103 ;; buffer anymore. So catch any error to remove the timeout. | |
104 (condition-case () | |
105 (set-extent-face blink-paren-extent | |
106 (if (eq (extent-face blink-paren-extent) | |
107 'blink-paren-on) | |
108 'blink-paren-off | |
109 'blink-paren-on)) | |
110 (error (blink-paren-pre-command)))) | |
111 | |
112 ;; called after each command is executed in the post-command-hook | |
113 ;; add the extent and the time-out if we are on a paren. | |
114 (defun blink-paren-post-command () | |
115 (blink-paren-pre-command) | |
116 (if (and (setq blink-paren-extent (blink-paren-make-extent)) | |
117 (not highlight-paren-expression) | |
118 (not (and (face-equal 'blink-paren-on 'blink-paren-off) | |
119 (progn | |
120 (set-extent-face blink-paren-extent 'blink-paren-on) | |
121 t))) | |
122 (or (floatp blink-paren-timeout) | |
123 (integerp blink-paren-timeout))) | |
124 (setq blink-paren-timeout-id | |
125 (add-timeout blink-paren-timeout 'blink-paren-timeout () | |
126 blink-paren-timeout)))) | |
127 | |
128 ;; called before a new command is executed in the pre-command-hook | |
129 ;; cleanup by removing the extent and the time-out | |
130 (defun blink-paren-pre-command () | |
131 (condition-case c ; don't ever signal an error in pre-command-hook! | |
132 (let ((inhibit-quit t)) | |
133 (if blink-paren-timeout-id | |
134 (disable-timeout (prog1 blink-paren-timeout-id | |
135 (setq blink-paren-timeout-id nil)))) | |
136 (if blink-paren-extent | |
137 (delete-extent (prog1 blink-paren-extent | |
138 (setq blink-paren-extent nil))))) | |
139 (error | |
140 (message "blink paren error! %s" c)))) | |
141 | |
142 | |
143 (defun blink-paren (&optional arg) | |
144 "Toggles paren blinking on and off. | |
145 With a positive argument, turns it on. | |
146 With a non-positive argument, turns it off." | |
147 (interactive "P") | |
148 (let* ((was-on (not (not (memq 'blink-paren-pre-command pre-command-hook)))) | |
149 (on-p (if (null arg) | |
150 (not was-on) | |
151 (> (prefix-numeric-value arg) 0)))) | |
152 (cond (on-p | |
153 | |
154 ;; in case blink paren was dumped, this needs to be setup | |
155 (or (face-differs-from-default-p 'blink-paren-off) | |
156 (progn | |
157 (set-face-background 'blink-paren-off (face-background 'default)) | |
158 (set-face-foreground 'blink-paren-off (face-background 'default)))) | |
159 | |
160 (or (face-differs-from-default-p 'highlight-expression) | |
161 (set-face-underline-p 'highlight-expression t)) | |
162 | |
163 (add-hook 'pre-command-hook 'blink-paren-pre-command) | |
164 (add-hook 'post-command-hook 'blink-paren-post-command) | |
165 (setq blink-matching-paren nil)) | |
166 (t | |
167 (remove-hook 'pre-command-hook 'blink-paren-pre-command) | |
168 (remove-hook 'post-command-hook 'blink-paren-post-command) | |
169 (and blink-paren-extent (detach-extent blink-paren-extent)) | |
170 (setq blink-matching-paren t))) | |
171 on-p)) | |
172 | |
173 (defun blink-paren-init () | |
174 "obsolete - use `blink-paren' instead." | |
175 (interactive) | |
176 (blink-paren 1)) | |
177 | |
178 (provide 'blink-paren) | |
179 | |
180 (blink-paren 1) |