Mercurial > hg > xemacs-beta
comparison lisp/next-error.el @ 3000:5df5ea55d3fc
[xemacs-hg @ 2005-10-18 20:49:41 by malcolmp]
Sync of occur mode with GNU Emacs 22.0.50.1 (CVS)
author | malcolmp |
---|---|
date | Tue, 18 Oct 2005 20:49:43 +0000 |
parents | |
children | 1e7cc382eb16 |
comparison
equal
deleted
inserted
replaced
2999:77dd8b943765 | 3000:5df5ea55d3fc |
---|---|
1 ;;; next-error.el --- Next error support framework | |
2 | |
3 ;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |
4 ;; 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. | |
5 | |
6 ;; Maintainer: XEmacs Development Team | |
7 ;; Keywords: internal | |
8 | |
9 ;; This file is part of XEmacs. | |
10 | |
11 ;; XEmacs 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 ;; XEmacs 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 | |
22 ;; along with XEmacs; see the file COPYING. If not, write to the | |
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
24 ;; Boston, MA 02110-1301, USA. | |
25 | |
26 ;;; Synched up with: FSF 22.0.50.1 (CVS) | |
27 | |
28 (defgroup next-error nil | |
29 "`next-error' support framework." | |
30 :group 'compilation | |
31 :version "22.1") | |
32 | |
33 (defface next-error | |
34 '((t (:inherit region))) | |
35 "Face used to highlight next error locus." | |
36 :group 'next-error | |
37 :version "22.1") | |
38 | |
39 (defcustom next-error-highlight 0.1 | |
40 "*Highlighting of locations in selected source buffers. | |
41 If number, highlight the locus in `next-error' face for given time in seconds. | |
42 If t, use persistent overlays fontified in `next-error' face. | |
43 If nil, don't highlight the locus in the source buffer. | |
44 If `fringe-arrow', indicate the locus by the fringe arrow." | |
45 :type '(choice (number :tag "Delay") | |
46 (const :tag "Persistent overlay" t) | |
47 (const :tag "No highlighting" nil) | |
48 (const :tag "Fringe arrow" 'fringe-arrow)) | |
49 :group 'next-error | |
50 :version "22.1") | |
51 | |
52 (defcustom next-error-highlight-no-select 0.1 | |
53 "*Highlighting of locations in non-selected source buffers. | |
54 If number, highlight the locus in `next-error' face for given time in seconds. | |
55 If t, use persistent overlays fontified in `next-error' face. | |
56 If nil, don't highlight the locus in the source buffer. | |
57 If `fringe-arrow', indicate the locus by the fringe arrow." | |
58 :type '(choice (number :tag "Delay") | |
59 (const :tag "Persistent overlay" t) | |
60 (const :tag "No highlighting" nil) | |
61 (const :tag "Fringe arrow" 'fringe-arrow)) | |
62 :group 'next-error | |
63 :version "22.1") | |
64 | |
65 (defcustom next-error-hook nil | |
66 "*List of hook functions run by `next-error' after visiting source file." | |
67 :type 'hook | |
68 :group 'next-error) | |
69 | |
70 (defvar next-error-highlight-timer nil) | |
71 | |
72 ;(defvar next-error-overlay-arrow-position nil) | |
73 ;(put 'next-error-overlay-arrow-position 'overlay-arrow-string "=>") | |
74 ;(add-to-list 'overlay-arrow-variable-list 'next-error-overlay-arrow-position) | |
75 | |
76 (defvar next-error-last-buffer nil | |
77 "The most recent `next-error' buffer. | |
78 A buffer becomes most recent when its compilation, grep, or | |
79 similar mode is started, or when it is used with \\[next-error] | |
80 or \\[compile-goto-error].") | |
81 | |
82 (defvar next-error-function nil | |
83 "Function to use to find the next error in the current buffer. | |
84 The function is called with 2 parameters: | |
85 ARG is an integer specifying by how many errors to move. | |
86 RESET is a boolean which, if non-nil, says to go back to the beginning | |
87 of the errors before moving. | |
88 Major modes providing compile-like functionality should set this variable | |
89 to indicate to `next-error' that this is a candidate buffer and how | |
90 to navigate in it.") | |
91 | |
92 (make-variable-buffer-local 'next-error-function) | |
93 | |
94 (defsubst next-error-buffer-p (buffer | |
95 &optional avoid-current | |
96 extra-test-inclusive | |
97 extra-test-exclusive) | |
98 "Test if BUFFER is a `next-error' capable buffer. | |
99 | |
100 If AVOID-CURRENT is non-nil, treat the current buffer | |
101 as an absolute last resort only. | |
102 | |
103 The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer | |
104 that normally would not qualify. If it returns t, the buffer | |
105 in question is treated as usable. | |
106 | |
107 The function EXTRA-TEST-EXCLUSIVE, if non-nil is called in each buffer | |
108 that would normally be considered usable. If it returns nil, | |
109 that buffer is rejected." | |
110 (and (buffer-name buffer) ;First make sure it's live. | |
111 (not (and avoid-current (eq buffer (current-buffer)))) | |
112 (with-current-buffer buffer | |
113 (if next-error-function ; This is the normal test. | |
114 ;; Optionally reject some buffers. | |
115 (if extra-test-exclusive | |
116 (funcall extra-test-exclusive) | |
117 t) | |
118 ;; Optionally accept some other buffers. | |
119 (and extra-test-inclusive | |
120 (funcall extra-test-inclusive)))))) | |
121 | |
122 (defun next-error-find-buffer (&optional avoid-current | |
123 extra-test-inclusive | |
124 extra-test-exclusive) | |
125 "Return a `next-error' capable buffer. | |
126 If AVOID-CURRENT is non-nil, treat the current buffer | |
127 as an absolute last resort only. | |
128 | |
129 The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer | |
130 that normally would not qualify. If it returns t, the buffer | |
131 in question is treated as usable. | |
132 | |
133 The function EXTRA-TEST-EXCLUSIVE, if non-nil is called in each buffer | |
134 that would normally be considered usable. If it returns nil, | |
135 that buffer is rejected." | |
136 (or | |
137 ;; 1. If one window on the selected frame displays such buffer, return it. | |
138 (let ((window-buffers | |
139 (delete-dups | |
140 (delq nil (mapcar (lambda (w) | |
141 (if (next-error-buffer-p | |
142 (window-buffer w) | |
143 avoid-current | |
144 extra-test-inclusive extra-test-exclusive) | |
145 (window-buffer w))) | |
146 (window-list)))))) | |
147 (if (eq (length window-buffers) 1) | |
148 (car window-buffers))) | |
149 ;; 2. If next-error-last-buffer is an acceptable buffer, use that. | |
150 (if (and next-error-last-buffer | |
151 (next-error-buffer-p next-error-last-buffer avoid-current | |
152 extra-test-inclusive extra-test-exclusive)) | |
153 next-error-last-buffer) | |
154 ;; 3. If the current buffer is acceptable, choose it. | |
155 (if (next-error-buffer-p (current-buffer) avoid-current | |
156 extra-test-inclusive extra-test-exclusive) | |
157 (current-buffer)) | |
158 ;; 4. Look for any acceptable buffer. | |
159 (let ((buffers (buffer-list))) | |
160 (while (and buffers | |
161 (not (next-error-buffer-p | |
162 (car buffers) avoid-current | |
163 extra-test-inclusive extra-test-exclusive))) | |
164 (setq buffers (cdr buffers))) | |
165 (car buffers)) | |
166 ;; 5. Use the current buffer as a last resort if it qualifies, | |
167 ;; even despite AVOID-CURRENT. | |
168 (and avoid-current | |
169 (next-error-buffer-p (current-buffer) nil | |
170 extra-test-inclusive extra-test-exclusive) | |
171 (progn | |
172 (message "This is the only next-error capable buffer") | |
173 (current-buffer))) | |
174 ;; 6. Give up. | |
175 (error "No next-error capable buffer found"))) | |
176 | |
177 ;;;###autoload | |
178 (defun next-error (&optional arg reset) | |
179 "Visit next `next-error' message and corresponding source code. | |
180 | |
181 If all the error messages parsed so far have been processed already, | |
182 the message buffer is checked for new ones. | |
183 | |
184 A prefix ARG specifies how many error messages to move; | |
185 negative means move back to previous error messages. | |
186 Just \\[universal-argument] as a prefix means reparse the error message buffer | |
187 and start at the first error. | |
188 | |
189 The RESET argument specifies that we should restart from the beginning. | |
190 | |
191 \\[next-error] normally uses the most recently started | |
192 compilation, grep, or occur buffer. It can also operate on any | |
193 buffer with output from the \\[compile], \\[grep] commands, or, | |
194 more generally, on any buffer in Compilation mode or with | |
195 Compilation Minor mode enabled, or any buffer in which | |
196 `next-error-function' is bound to an appropriate function. | |
197 To specify use of a particular buffer for error messages, type | |
198 \\[next-error] in that buffer when it is the only one displayed | |
199 in the current frame. | |
200 | |
201 Once \\[next-error] has chosen the buffer for error messages, it | |
202 runs `next-error-hook' with `run-hooks', and stays with that buffer | |
203 until you use it in some other buffer which uses Compilation mode | |
204 or Compilation Minor mode. | |
205 | |
206 See variables `compilation-parse-errors-function' and | |
207 \`compilation-error-regexp-alist' for customization ideas." | |
208 (interactive "P") | |
209 (if (consp arg) (setq reset t arg nil)) | |
210 (when (setq next-error-last-buffer (next-error-find-buffer)) | |
211 ;; we know here that next-error-function is a valid symbol we can funcall | |
212 (with-current-buffer next-error-last-buffer | |
213 (funcall next-error-function (prefix-numeric-value arg) reset) | |
214 (run-hooks 'next-error-hook)))) | |
215 | |
216 (defalias 'goto-next-locus 'next-error) | |
217 (defalias 'next-match 'next-error) | |
218 | |
219 (defun previous-error (&optional n) | |
220 "Visit previous `next-error' message and corresponding source code. | |
221 | |
222 Prefix arg N says how many error messages to move backwards (or | |
223 forwards, if negative). | |
224 | |
225 This operates on the output from the \\[compile] and \\[grep] commands." | |
226 (interactive "p") | |
227 (next-error (- (or n 1)))) | |
228 | |
229 (defun first-error (&optional n) | |
230 "Restart at the first error. | |
231 Visit corresponding source code. | |
232 With prefix arg N, visit the source code of the Nth error. | |
233 This operates on the output from the \\[compile] command, for instance." | |
234 (interactive "p") | |
235 (next-error n t)) | |
236 | |
237 (defun next-error-no-select (&optional n) | |
238 "Move point to the next error in the `next-error' buffer and highlight match. | |
239 Prefix arg N says how many error messages to move forwards (or | |
240 backwards, if negative). | |
241 Finds and highlights the source line like \\[next-error], but does not | |
242 select the source buffer." | |
243 (interactive "p") | |
244 (let ((next-error-highlight next-error-highlight-no-select)) | |
245 (next-error n)) | |
246 (pop-to-buffer next-error-last-buffer)) | |
247 | |
248 (defun previous-error-no-select (&optional n) | |
249 "Move point to the previous error in the `next-error' buffer and highlight match. | |
250 Prefix arg N says how many error messages to move backwards (or | |
251 forwards, if negative). | |
252 Finds and highlights the source line like \\[previous-error], but does not | |
253 select the source buffer." | |
254 (interactive "p") | |
255 (next-error-no-select (- (or n 1)))) | |
256 | |
257 ;;; Internal variable for `next-error-follow-mode-post-command-hook'. | |
258 (defvar next-error-follow-last-line nil) | |
259 | |
260 (define-minor-mode next-error-follow-minor-mode | |
261 "Minor mode for compilation, occur and diff modes. | |
262 When turned on, cursor motion in the compilation, grep, occur or diff | |
263 buffer causes automatic display of the corresponding source code | |
264 location." | |
265 :group 'next-error :init-value nil :lighter " Fol" | |
266 (if (not next-error-follow-minor-mode) | |
267 (remove-hook 'post-command-hook 'next-error-follow-mode-post-command-hook t) | |
268 (add-hook 'post-command-hook 'next-error-follow-mode-post-command-hook nil t) | |
269 (make-local-variable 'next-error-follow-last-line))) | |
270 | |
271 ;;; Used as a `post-command-hook' by `next-error-follow-mode' | |
272 ;;; for the *Compilation* *grep* and *Occur* buffers. | |
273 (defun next-error-follow-mode-post-command-hook () | |
274 (unless (equal next-error-follow-last-line (line-number-at-pos)) | |
275 (setq next-error-follow-last-line (line-number-at-pos)) | |
276 (condition-case nil | |
277 (let ((compilation-context-lines nil)) | |
278 (setq compilation-current-error (point)) | |
279 (next-error-no-select 0)) | |
280 (error t)))) | |
281 | |
282 (provide 'next-error) |