(jdb): Add gud-pstar to dump object information.
[bpt/emacs.git] / lisp / progmodes / compile.el
CommitLineData
55535639 1;;; compile.el --- run compiler as inferior of Emacs, parse error messages
fad160d5 2
930a3e46 3;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
ae940284 4;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
049dcb6f 5;; Free Software Foundation, Inc.
3a801d0c 6
7837c247
SM
7;; Authors: Roland McGrath <roland@gnu.org>,
8;; Daniel Pfeiffer <occitan@esperanto.org>
d1c7011d 9;; Maintainer: FSF
e9571d2a 10;; Keywords: tools, processes
d1c7011d 11
55dfd2c4
RS
12;; This file is part of GNU Emacs.
13
b1fc2b50 14;; GNU Emacs is free software: you can redistribute it and/or modify
29add8b9 15;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
16;; the Free Software Foundation, either version 3 of the License, or
17;; (at your option) any later version.
29add8b9 18
55dfd2c4 19;; GNU Emacs is distributed in the hope that it will be useful,
29add8b9
RM
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
b1fc2b50 25;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
55dfd2c4 26
5cc57841
ER
27;;; Commentary:
28
7837c247
SM
29;; This package provides the compile facilities documented in the Emacs user's
30;; manual.
5cc57841 31
c536bb39 32;; This mode uses some complex data-structures:
7837c247 33
c536bb39 34;; LOC (or location) is a list of (COLUMN LINE FILE-STRUCTURE)
7837c247
SM
35
36;; COLUMN and LINE are numbers parsed from an error message. COLUMN and maybe
37;; LINE will be nil for a message that doesn't contain them. Then the
38;; location refers to a indented beginning of line or beginning of file.
39;; Once any location in some file has been jumped to, the list is extended to
b84acff6
SS
40;; (COLUMN LINE FILE-STRUCTURE MARKER TIMESTAMP . VISITED)
41;; for all LOCs pertaining to that file.
7837c247
SM
42;; MARKER initially points to LINE and COLUMN in a buffer visiting that file.
43;; Being a marker it sticks to some text, when the buffer grows or shrinks
44;; before that point. VISITED is t if we have jumped there, else nil.
b84acff6
SS
45;; TIMESTAMP is necessary because of "incremental compilation": `omake -P'
46;; polls filesystem for changes and recompiles when a file is modified
47;; using the same *compilation* buffer. this necessitates re-parsing markers.
7837c247 48
c536bb39
SM
49;; FILE-STRUCTURE is a list of
50;; ((FILENAME . DIRECTORY) FORMATS (LINE LOC ...) ...)
7837c247
SM
51
52;; FILENAME is a string parsed from an error message. DIRECTORY is a string
53;; obtained by following directory change messages. DIRECTORY will be nil for
54;; an absolute filename. FORMATS is a list of formats to apply to FILENAME if
55;; a file of that name can't be found.
56;; The rest of the list is an alist of elements with LINE as key. The keys
57;; are either nil or line numbers. If present, nil comes first, followed by
58;; the numbers in decreasing order. The LOCs for each line are again an alist
59;; ordered the same way. Note that the whole file structure is referenced in
60;; every LOC.
61
c536bb39 62;; MESSAGE is a list of (LOC TYPE END-LOC)
7837c247
SM
63
64;; TYPE is 0 for info or 1 for warning if the message matcher identified it as
65;; such, 2 otherwise (for a real error). END-LOC is a LOC pointing to the
4fffd73b 66;; other end, if the parsed message contained a range. If the end of the
7837c247
SM
67;; range didn't specify a COLUMN, it defaults to -1, meaning end of line.
68;; These are the value of the `message' text-properties in the compilation
69;; buffer.
70
24299582
DP
71;;; Code:
72
583a15bb 73(eval-when-compile (require 'cl))
c45e48d2 74(require 'tool-bar)
72fcf382 75(require 'comint)
583a15bb 76
e623859c
JB
77(defvar font-lock-extra-managed-props)
78(defvar font-lock-keywords)
79(defvar font-lock-maximum-size)
80(defvar font-lock-support-mode)
81
82
c5049fa0
RS
83(defgroup compilation nil
84 "Run compiler as inferior of Emacs, parse error messages."
85 :group 'tools
86 :group 'processes)
87
88
7c163413 89;;;###autoload
c5049fa0 90(defcustom compilation-mode-hook nil
813fb3fe 91 "List of hook functions run by `compilation-mode' (see `run-mode-hooks')."
c5049fa0
RS
92 :type 'hook
93 :group 'compilation)
7c163413 94
dd93e6da
SS
95;;;###autoload
96(defcustom compilation-start-hook nil
97 "List of hook functions run by `compilation-start' on the compilation process.
98\(See `run-hook-with-args').
99If you use \"omake -P\" and do not want \\[save-buffers-kill-terminal] to ask whether you want
100the compilation to be killed, you can use this hook:
101 (add-hook 'compilation-start-hook
102 (lambda (process) (set-process-query-on-exit-flag process nil)) nil t)"
103 :type 'hook
104 :group 'compilation)
105
7c163413 106;;;###autoload
c5049fa0 107(defcustom compilation-window-height nil
813fb3fe 108 "Number of lines in a compilation window. If nil, use Emacs default."
c5049fa0
RS
109 :type '(choice (const :tag "Default" nil)
110 integer)
111 :group 'compilation)
d3cb357b 112
7837c247
SM
113(defvar compilation-first-column 1
114 "*This is how compilers number the first column, usually 1 or 0.")
55dfd2c4 115
e335e194
GM
116(defvar compilation-parse-errors-filename-function nil
117 "Function to call to post-process filenames while parsing error messages.
118It takes one arg FILENAME which is the name of a file as found
119in the compilation output, and should return a transformed file name.")
120
49683a13
EZ
121;;;###autoload
122(defvar compilation-process-setup-function nil
123 "*Function to call to customize the compilation process.
6f5b7627 124This function is called immediately before the compilation process is
49683a13 125started. It can be used to set any variables or functions that are used
9ac57479
KS
126while processing the output of the compilation process. The function
127is called with variables `compilation-buffer' and `compilation-window'
7837c247 128bound to the compilation buffer and window, respectively.")
49683a13 129
aa228418 130;;;###autoload
d3cb357b 131(defvar compilation-buffer-name-function nil
6c43f2f9
RS
132 "Function to compute the name of a compilation buffer.
133The function receives one argument, the name of the major mode of the
134compilation buffer. It should return a string.
f441be5b 135If nil, compute the name with `(concat \"*\" (downcase major-mode) \"*\")'.")
55dfd2c4 136
aa228418 137;;;###autoload
d3cb357b 138(defvar compilation-finish-function nil
c5049fa0 139 "Function to call when a compilation process finishes.
d3cb357b 140It is called with two arguments: the compilation buffer, and a string
620d3304 141describing how the process finished.")
3c9e7f42
RS
142
143(make-obsolete-variable 'compilation-finish-function
f441be5b 144 "use `compilation-finish-functions', but it works a little differently."
3c9e7f42 145 "22.1")
55dfd2c4 146
4cc36b17
RS
147;;;###autoload
148(defvar compilation-finish-functions nil
c5049fa0 149 "Functions to call when a compilation process finishes.
4cc36b17
RS
150Each function is called with two arguments: the compilation buffer,
151and a string describing how the process finished.")
152
ebff767c
RM
153(defvar compilation-in-progress nil
154 "List of compilation processes now running.")
155(or (assq 'compilation-in-progress minor-mode-alist)
156 (setq minor-mode-alist (cons '(compilation-in-progress " Compiling")
157 minor-mode-alist)))
158
7837c247
SM
159(defvar compilation-error "error"
160 "Stem of message to print when no matches are found.")
6c43f2f9 161
58856335 162(defvar compilation-arguments nil
7837c247 163 "Arguments that were given to `compilation-start'.")
58856335 164
6c43f2f9 165(defvar compilation-num-errors-found)
d3cb357b 166
7837c247
SM
167(defconst compilation-error-regexp-alist-alist
168 '((absoft
169 "^\\(?:[Ee]rror on \\|[Ww]arning on\\( \\)\\)?[Ll]ine[ \t]+\\([0-9]+\\)[ \t]+\
170of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
5dfa3d35 171
7837c247
SM
172 (ada
173 "\\(warning: .*\\)? at \\([^ \n]+\\):\\([0-9]+\\)$" 2 3 nil (1))
c7c5bbc0 174
7837c247
SM
175 (aix
176 " in line \\([0-9]+\\) of file \\([^ \n]+[^. \n]\\)\\.? " 2 1)
e1f540f2 177
7837c247
SM
178 (ant
179 "^[ \t]*\\[[^] \n]+\\][ \t]*\\([^: \n]+\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):[0-9]+:[0-9]+:\\)?\
180\\( warning\\)?" 1 2 3 (4))
e1f540f2 181
7837c247
SM
182 (bash
183 "^\\([^: \n\t]+\\): line \\([0-9]+\\):" 1 2)
e1f540f2 184
7837c247
SM
185 (borland
186 "^\\(?:Error\\|Warnin\\(g\\)\\) \\(?:[FEW][0-9]+ \\)?\
187\\([a-zA-Z]?:?[^:( \t\n]+\\)\
188 \\([0-9]+\\)\\(?:[) \t]\\|:[^0-9\n]\\)" 2 3 nil (1))
189
190 (caml
f6164cdd
DP
191 "^ *File \\(\"?\\)\\([^,\" \n\t<>]+\\)\\1, lines? \\([0-9]+\\)-?\\([0-9]+\\)?\\(?:$\\|,\
192\\(?: characters? \\([0-9]+\\)-?\\([0-9]+\\)?:\\)?\\([ \n]Warning:\\)?\\)"
193 2 (3 . 4) (5 . 6) (7))
7837c247
SM
194
195 (comma
196 "^\"\\([^,\" \n\t]+\\)\", line \\([0-9]+\\)\
197\\(?:[(. pos]+\\([0-9]+\\))?\\)?[:.,; (-]\\( warning:\\|[-0-9 ]*(W)\\)?" 1 2 3 (4))
198
c39bf546
DP
199 (edg-1
200 "^\\([^ \n]+\\)(\\([0-9]+\\)): \\(?:error\\|warnin\\(g\\)\\|remar\\(k\\)\\)"
201 1 2 nil (3 . 4))
202 (edg-2
203 "at line \\([0-9]+\\) of \"\\([^ \n]+\\)\"$"
204 2 1 nil 0)
205
7837c247 206 (epc
c39bf546 207 "^Error [0-9]+ at (\\([0-9]+\\):\\([^)\n]+\\))" 2 1)
7837c247 208
12221c84
DP
209 (ftnchek
210 "\\(^Warning .*\\)? line[ \n]\\([0-9]+\\)[ \n]\\(?:col \\([0-9]+\\)[ \n]\\)?file \\([^ :;\n]+\\)"
211 4 2 3 (1))
9fcabe79 212
7837c247
SM
213 (iar
214 "^\"\\(.*\\)\",\\([0-9]+\\)\\s-+\\(?:Error\\|Warnin\\(g\\)\\)\\[[0-9]+\\]:"
215 1 2 nil (3))
216
217 (ibm
218 "^\\([^( \n\t]+\\)(\\([0-9]+\\):\\([0-9]+\\)) :\
219 \\(?:warnin\\(g\\)\\|informationa\\(l\\)\\)?" 1 2 3 (4 . 5))
220
6f5b7627 221 ;; fixme: should be `mips'
7837c247 222 (irix
9fcabe79
DP
223 "^[-[:alnum:]_/ ]+: \\(?:\\(?:[sS]evere\\|[eE]rror\\|[wW]arnin\\(g\\)\\|[iI]nf\\(o\\)\\)[0-9 ]*: \\)?\
224\\([^,\" \n\t]+\\)\\(?:, line\\|:\\) \\([0-9]+\\):" 3 4 nil (1 . 2))
7837c247
SM
225
226 (java
227 "^\\(?:[ \t]+at \\|==[0-9]+== +\\(?:at\\|b\\(y\\)\\)\\).+(\\([^()\n]+\\):\\([0-9]+\\))$" 2 3 nil (1))
228
229 (jikes-file
230 "^\\(?:Found\\|Issued\\) .* compiling \"\\(.+\\)\":$" 1 nil nil 0)
231 (jikes-line
232 "^ *\\([0-9]+\\)\\.[ \t]+.*\n +\\(<-*>\n\\*\\*\\* \\(?:Error\\|Warnin\\(g\\)\\)\\)"
233 nil 1 nil 2 0
234 (2 (compilation-face '(3))))
235
7837c247 236 (gnu
b8fa0ffd
SM
237 ;; I have no idea what this first line is supposed to match, but it
238 ;; makes things ambiguous with output such as "foo:344:50:blabla" since
239 ;; the "foo" part can match this first line (in which case the file
0ab31e4a
SM
240 ;; name as "344"). To avoid this, the second line disallows filenames
241 ;; exclusively composed of digits. --Stef
242 ;; Similarly, we get lots of false positives with messages including
243 ;; times of the form "HH:MM:SS" where MM is taken as a line number, so
244 ;; the last line tries to rule out message where the info after the
245 ;; line number starts with "SS". --Stef
bb6da2f8
SM
246
247 ;; The core of the regexp is the one with *?. It says that a file name
248 ;; can be composed of any non-newline char, but it also rules out some
249 ;; valid but unlikely cases, such as a trailing space or a space
250 ;; followed by a -.
6f5b7627 251 "^\\(?:[[:alpha:]][-[:alnum:].]+: ?\\)?\
bb6da2f8 252\\([0-9]*[^0-9\n]\\(?:[^\n ]\\| [^-/\n]\\)*?\\): ?\
8decc87f 253\\([0-9]+\\)\\(?:\\([.:]\\)\\([0-9]+\\)\\)?\
721451bc 254\\(?:-\\([0-9]+\\)?\\(?:\\.\\([0-9]+\\)\\)?\\)?:\
7837c247 255\\(?: *\\(\\(?:Future\\|Runtime\\)?[Ww]arning\\|W:\\)\\|\
d40a86f9 256 *\\([Ii]nfo\\(?:\\>\\|rmationa?l?\\)\\|I:\\|instantiated from\\|[Nn]ote\\)\\|\
0ab31e4a 257\[0-9]?\\(?:[^0-9\n]\\|$\\)\\|[0-9][0-9][0-9]\\)"
7837c247
SM
258 1 (2 . 5) (4 . 6) (7 . 8))
259
6e1a9597
CY
260 ;; The `gnu' style above can incorrectly match gcc's "In file
261 ;; included from" message, so we process that first. -- cyd
262 (gcc-include
263 "^\\(?:In file included\\| \\) from \
264\\(.+\\):\\([0-9]+\\)\\(?:\\(:\\)\\|\\(,\\)\\)?" 1 2 nil (3 . 4))
265
7837c247
SM
266 (lcc
267 "^\\(?:E\\|\\(W\\)\\), \\([^(\n]+\\)(\\([0-9]+\\),[ \t]*\\([0-9]+\\)"
268 2 3 4 (1))
269
270 (makepp
250540cd 271 "^makepp\\(?:\\(?:: warning\\(:\\).*?\\|\\(: Scanning\\|: [LR]e?l?oading makefile\\|: Imported\\|log:.*?\\) \\|: .*?\\)\
3b79dd20 272`\\(\\(\\S +?\\)\\(?::\\([0-9]+\\)\\)?\\)['(]\\)"
7837c247 273 4 5 nil (1 . 2) 3
3b79dd20 274 ("`\\(\\(\\S +?\\)\\(?::\\([0-9]+\\)\\)?\\)['(]" nil nil
7837c247
SM
275 (2 compilation-info-face)
276 (3 compilation-line-face nil t)
51c8ad03 277 (1 (compilation-error-properties 2 3 nil nil nil 0 nil)
7837c247
SM
278 append)))
279
f7a2e634
CY
280 ;; This regexp is pathologically slow on long lines (Bug#3441).
281 ;; (maven
282 ;; ;; Maven is a popular build tool for Java. Maven is Free Software.
283 ;; "\\(.*?\\):\\[\\([0-9]+\\),\\([0-9]+\\)\\]" 1 2 3)
8fca0544 284
6f5b7627 285 ;; Should be lint-1, lint-2 (SysV lint)
7837c247
SM
286 (mips-1
287 " (\\([0-9]+\\)) in \\([^ \n]+\\)" 2 1)
288 (mips-2
289 " in \\([^()\n ]+\\)(\\([0-9]+\\))$" 1 2)
290
291 (msft
db0095e0 292 ;; AFAWK, The message may be a "warning", "error", or "fatal error".
28547c1f 293 "^\\([0-9]+>\\)?\\(\\(?:[a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \
db0095e0 294: \\(?:warnin\\(g\\)\\|[a-z ]+\\) C[0-9]+:" 2 3 nil (4))
7837c247 295
0fdb20bb
SS
296 (omake
297 ;; "omake -P" reports "file foo changed"
298 ;; (useful if you do "cvs up" and want to see what has changed)
299 "omake: file \\(.*\\) changed" 1)
300
7837c247 301 (oracle
b3ef54c5
DP
302 "^\\(?:Semantic error\\|Error\\|PCC-[0-9]+:\\).* line \\([0-9]+\\)\
303\\(?:\\(?:,\\| at\\)? column \\([0-9]+\\)\\)?\
304\\(?:,\\| in\\| of\\)? file \\(.*?\\):?$"
7837c247 305 3 1 2)
40d63d1f 306
049dcb6f
GM
307 ;; "during global destruction": This comes out under "use
308 ;; warnings" in recent perl when breaking circular references
309 ;; during program or thread exit.
7837c247 310 (perl
049dcb6f
GM
311 " at \\([^ \n]+\\) line \\([0-9]+\\)\\(?:[,.]\\|$\\| \
312during global destruction\\.$\\)" 1 2)
7837c247 313
fa2a4e7d
MH
314 (php
315 "\\(?:Parse\\|Fatal\\) error: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)"
316 2 3 nil nil)
317
7837c247
SM
318 (rxp
319 "^\\(?:Error\\|Warnin\\(g\\)\\):.*\n.* line \\([0-9]+\\) char\
320 \\([0-9]+\\) of file://\\(.+\\)"
321 4 2 3 (1))
322
323 (sparc-pascal-file
324 "^\\w\\w\\w \\w\\w\\w +[0-3]?[0-9] +[0-2][0-9]:[0-5][0-9]:[0-5][0-9]\
325 [12][09][0-9][0-9] +\\(.*\\):$"
326 1 nil nil 0)
327 (sparc-pascal-line
328 "^\\(\\(?:E\\|\\(w\\)\\) +[0-9]+\\) line \\([0-9]+\\) - "
329 nil 3 nil (2) nil (1 (compilation-face '(2))))
330 (sparc-pascal-example
331 "^ +\\([0-9]+\\) +.*\n\\(\\(?:e\\|\\(w\\)\\) [0-9]+\\)-+"
332 nil 1 nil (3) nil (2 (compilation-face '(3))))
333
334 (sun
6f5b7627 335 ": \\(?:ERROR\\|WARNIN\\(G\\)\\|REMAR\\(K\\)\\) \\(?:[[:alnum:] ]+, \\)?\
7837c247
SM
336File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
337 3 4 5 (1 . 2))
338
339 (sun-ada
340 "^\\([^, \n\t]+\\), line \\([0-9]+\\), char \\([0-9]+\\)[:., \(-]" 1 2 3)
341
9d8a1add 342 (watcom
bf3e72ae 343 "\\(\\(?:[a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)): ?\
ed66ce21
CY
344\\(?:\\(Error! E[0-9]+\\)\\|\\(Warning! W[0-9]+\\)\\):"
345 1 2 nil (4))
9d8a1add 346
7837c247
SM
347 (4bsd
348 "\\(?:^\\|:: \\|\\S ( \\)\\(/[^ \n\t()]+\\)(\\([0-9]+\\))\
0c9a01ff
MY
349\\(?:: \\(warning:\\)?\\|$\\| ),\\)" 1 2 nil (3))
350
351 (gcov-file
b8fa0ffd 352 "^ *-: *\\(0\\):Source:\\(.+\\)$"
eb3d9609
MY
353 2 1 nil 0 nil
354 (1 compilation-line-face prepend) (2 compilation-info-face prepend))
355 (gcov-header
356 "^ *-: *\\(0\\):\\(?:Object\\|Graph\\|Data\\|Runs\\|Programs\\):.+$"
357 nil 1 nil 0 nil
358 (1 compilation-line-face prepend))
359 ;; Underlines over all lines of gcov output are too uncomfortable to read.
360 ;; However, hyperlinks embedded in the lines are useful.
361 ;; So I put default face on the lines; and then put
362 ;; compilation-*-face by manually to eliminate the underlines.
363 ;; The hyperlinks are still effective.
364 (gcov-nomark
365 "^ *-: *\\([1-9]\\|[0-9]\\{2,\\}\\):.*$"
366 nil 1 nil 0 nil
367 (0 'default t)
368 (1 compilation-line-face prepend))
0c9a01ff 369 (gcov-called-line
eb3d9609 370 "^ *\\([0-9]+\\): *\\([0-9]+\\):.*$"
b8fa0ffd 371 nil 2 nil 0 nil
eb3d9609
MY
372 (0 'default t)
373 (1 compilation-info-face prepend) (2 compilation-line-face prepend))
374 (gcov-never-called
b8fa0ffd 375 "^ *\\(#####\\): *\\([0-9]+\\):.*$"
eb3d9609
MY
376 nil 2 nil 2 nil
377 (0 'default t)
378 (1 compilation-error-face prepend) (2 compilation-line-face prepend))
ddab7705 379
3dc4febd 380 (perl--Pod::Checker
ddab7705
VJL
381 ;; podchecker error messages, per Pod::Checker.
382 ;; The style is from the Pod::Checker::poderror() function, eg.
383 ;; *** ERROR: Spurious text after =cut at line 193 in file foo.pm
384 ;;
385 ;; Plus end_pod() can give "at line EOF" instead of a
386 ;; number, so for that match "on line N" which is the
387 ;; originating spot, eg.
388 ;; *** ERROR: =over on line 37 without closing =back at line EOF in file bar.pm
389 ;;
390 ;; Plus command() can give both "on line N" and "at line N";
391 ;; the latter is desired and is matched because the .* is
392 ;; greedy.
393 ;; *** ERROR: =over on line 1 without closing =back (at head1) at line 3 in file x.pod
394 ;;
395 "^\\*\\*\\* \\(?:ERROR\\|\\(WARNING\\)\\).* \\(?:at\\|on\\) line \
396\\([0-9]+\\) \\(?:.* \\)?in file \\([^ \t\n]+\\)"
397 3 2 nil (1))
3dc4febd 398 (perl--Test
ddab7705
VJL
399 ;; perl Test module error messages.
400 ;; Style per the ok() function "$context", eg.
401 ;; # Failed test 1 in foo.t at line 6
402 ;;
403 "^# Failed test [0-9]+ in \\([^ \t\r\n]+\\) at line \\([0-9]+\\)"
404 1 2)
3dc4febd 405 (perl--Test2
01f179de
GM
406 ;; Or when comparing got/want values,
407 ;; # Test 2 got: "xx" (t-compilation-perl-2.t at line 10)
408 ;;
409 ;; And under Test::Harness they're preceded by progress stuff with
410 ;; \r and "NOK",
411 ;; ... NOK 1# Test 1 got: "1234" (t/foo.t at line 46)
412 ;;
413 "^\\(.*NOK.*\\)?# Test [0-9]+ got:.* (\\([^ \t\r\n]+\\) at line \
414\\([0-9]+\\))"
415 2 3)
3dc4febd 416 (perl--Test::Harness
ddab7705
VJL
417 ;; perl Test::Harness output, eg.
418 ;; NOK 1# Test 1 got: "1234" (t/foo.t at line 46)
419 ;;
420 ;; Test::Harness is slightly designed for tty output, since
421 ;; it prints CRs to overwrite progress messages, but if you
422 ;; run it in with M-x compile this pattern can at least step
423 ;; through the failures.
424 ;;
425 "^.*NOK.* \\([^ \t\r\n]+\\) at line \\([0-9]+\\)"
426 1 2)
3dc4febd 427 (weblint
ddab7705
VJL
428 ;; The style comes from HTML::Lint::Error::as_string(), eg.
429 ;; index.html (13:1) Unknown element <fdjsk>
430 ;;
431 ;; The pattern only matches filenames without spaces, since that
432 ;; should be usual and should help reduce the chance of a false
433 ;; match of a message from some unrelated program.
434 ;;
435 ;; This message style is quite close to the "ibm" entry which is
436 ;; for IBM C, though that ibm bit doesn't put a space after the
437 ;; filename.
438 ;;
439 "^\\([^ \t\r\n(]+\\) (\\([0-9]+\\):\\([0-9]+\\)) "
440 1 2 3)
eb3d9609 441 )
7837c247
SM
442 "Alist of values for `compilation-error-regexp-alist'.")
443
444(defcustom compilation-error-regexp-alist
445 (mapcar 'car compilation-error-regexp-alist-alist)
6c43f2f9 446 "Alist that specifies how to match errors in compiler output.
7957baea 447On GNU and Unix, any string is a valid filename, so these
7837c247
SM
448matchers must make some common sense assumptions, which catch
449normal cases. A shorter list will be lighter on resource usage.
450
451Instead of an alist element, you can use a symbol, which is
452looked up in `compilation-error-regexp-alist-alist'. You can see
453the predefined symbols and their effects in the file
6f5b7627 454`etc/compilation.txt' (linked below if you are customizing this).
7837c247
SM
455
456Each elt has the form (REGEXP FILE [LINE COLUMN TYPE HYPERLINK
457HIGHLIGHT...]). If REGEXP matches, the FILE'th subexpression
458gives the file name, and the LINE'th subexpression gives the line
459number. The COLUMN'th subexpression gives the column number on
460that line.
461
462If FILE, LINE or COLUMN are nil or that index didn't match, that
463information is not present on the matched line. In that case the
464file name is assumed to be the same as the previous one in the
465buffer, line number defaults to 1 and column defaults to
466beginning of line's indentation.
467
468FILE can also have the form (FILE FORMAT...), where the FORMATs
469\(e.g. \"%s.c\") will be applied in turn to the recognized file
470name, until a file of that name is found. Or FILE can also be a
4aede2f2
RS
471function that returns (FILENAME) or (RELATIVE-FILENAME . DIRNAME).
472In the former case, FILENAME may be relative or absolute.
7837c247
SM
473
474LINE can also be of the form (LINE . END-LINE) meaning a range
475of lines. COLUMN can also be of the form (COLUMN . END-COLUMN)
476meaning a range of columns starting on LINE and ending on
477END-LINE, if that matched.
478
479TYPE is 2 or nil for a real error or 1 for warning or 0 for info.
480TYPE can also be of the form (WARNING . INFO). In that case this
481will be equivalent to 1 if the WARNING'th subexpression matched
482or else equivalent to 0 if the INFO'th subexpression matched.
483See `compilation-error-face', `compilation-warning-face',
484`compilation-info-face' and `compilation-skip-threshold'.
485
486What matched the HYPERLINK'th subexpression has `mouse-face' and
487`compilation-message-face' applied. If this is nil, the text
488matched by the whole REGEXP becomes the hyperlink.
489
490Additional HIGHLIGHTs as described under `font-lock-keywords' can
491be added."
492 :type `(set :menu-tag "Pick"
493 ,@(mapcar (lambda (elt)
494 (list 'const (car elt)))
495 compilation-error-regexp-alist-alist))
496 :link `(file-link :tag "example file"
eeb3ede4 497 ,(expand-file-name "compilation.txt" data-directory))
7837c247 498 :group 'compilation)
55dfd2c4 499
98d4c36f 500;;;###autoload(put 'compilation-directory 'safe-local-variable 'stringp)
ebb8cb68
EZ
501(defvar compilation-directory nil
502 "Directory to restore to when doing `recompile'.")
503
7837c247
SM
504(defvar compilation-directory-matcher
505 '("\\(?:Entering\\|Leavin\\(g\\)\\) directory `\\(.+\\)'$" (2 . 1))
506 "A list for tracking when directories are entered or left.
434520fa 507If nil, do not track directories, e.g. if all file names are absolute. The
7837c247
SM
508first element is the REGEXP matching these messages. It can match any number
509of variants, e.g. different languages. The remaining elements are all of the
510form (DIR . LEAVE). If for any one of these the DIR'th subexpression
511matches, that is a directory name. If LEAVE is nil or the corresponding
512LEAVE'th subexpression doesn't match, this message is about going into another
513directory. If it does match anything, this message is about going back to the
514directory we were in before the last entering message. If you change this,
515you may also want to change `compilation-page-delimiter'.")
516
517(defvar compilation-page-delimiter
518 "^\\(?:\f\\|.*\\(?:Entering\\|Leaving\\) directory `.+'\n\\)+"
519 "Value of `page-delimiter' in Compilation mode.")
520
521(defvar compilation-mode-font-lock-keywords
0ab31e4a 522 '(;; configure output lines.
7837c247
SM
523 ("^[Cc]hecking \\(?:[Ff]or \\|[Ii]f \\|[Ww]hether \\(?:to \\)?\\)?\\(.+\\)\\.\\.\\. *\\(?:(cached) *\\)?\\(\\(yes\\(?: .+\\)?\\)\\|no\\|\\(.*\\)\\)$"
524 (1 font-lock-variable-name-face)
38dbf92b 525 (2 (compilation-face '(4 . 3))))
7837c247 526 ;; Command output lines. Recognize `make[n]:' lines too.
6f5b7627 527 ("^\\([[:alnum:]_/.+-]+\\)\\(\\[\\([0-9]+\\)\\]\\)?[ \t]*:"
7837c247
SM
528 (1 font-lock-function-name-face) (3 compilation-line-face nil t))
529 (" --?o\\(?:utfile\\|utput\\)?[= ]?\\(\\S +\\)" . 1)
47f97084
RF
530 ("^Compilation \\(finished\\).*"
531 (0 '(face nil message nil help-echo nil mouse-face nil) t)
314b410b 532 (1 compilation-info-face))
0ab31e4a 533 ("^Compilation \\(exited abnormally\\|interrupt\\|killed\\|terminated\\|segmentation fault\\)\\(?:.*with code \\([0-9]+\\)\\)?.*"
47f97084 534 (0 '(face nil message nil help-echo nil mouse-face nil) t)
314b410b
JL
535 (1 compilation-error-face)
536 (2 compilation-error-face nil t)))
7837c247
SM
537 "Additional things to highlight in Compilation mode.
538This gets tacked on the end of the generated expressions.")
a24770bc 539
9ac57479
KS
540(defvar compilation-highlight-regexp t
541 "Regexp matching part of visited source lines to highlight temporarily.
542Highlight entire line if t; don't highlight source lines if nil.")
543
544(defvar compilation-highlight-overlay nil
545 "Overlay used to temporarily highlight compilation matches.")
546
f8e03ecb 547(defcustom compilation-error-screen-columns t
813fb3fe 548 "If non-nil, column numbers in error messages are screen columns.
f8e03ecb
AS
549Otherwise they are interpreted as character positions, with
550each character occupying one column.
551The default is to use screen columns, which requires that the compilation
552program and Emacs agree about the display width of the characters,
553especially the TAB character."
554 :type 'boolean
555 :group 'compilation
556 :version "20.4")
557
c5049fa0 558(defcustom compilation-read-command t
813fb3fe 559 "Non-nil means \\[compile] reads the compilation command to use.
851231e9 560Otherwise, \\[compile] just uses the value of `compile-command'."
c5049fa0
RS
561 :type 'boolean
562 :group 'compilation)
90016295 563
e83be080 564;;;###autoload
c5049fa0 565(defcustom compilation-ask-about-save t
813fb3fe 566 "Non-nil means \\[compile] asks which buffers to save before compiling.
c5049fa0
RS
567Otherwise, it saves all modified buffers without asking."
568 :type 'boolean
569 :group 'compilation)
90016295 570
7c163413 571;;;###autoload
c5049fa0 572(defcustom compilation-search-path '(nil)
813fb3fe 573 "List of directories to search for source files named in error messages.
d3cb357b 574Elements should be directory names, not file names of directories.
f441be5b 575The value nil as an element means to try the default directory."
c5049fa0
RS
576 :type '(repeat (choice (const :tag "Default" nil)
577 (string :tag "Directory")))
578 :group 'compilation)
55dfd2c4 579
7957baea 580;;;###autoload
c5049fa0 581(defcustom compile-command "make -k "
813fb3fe 582 "Last shell command used to do a compilation; default for next compilation.
55dfd2c4
RS
583
584Sometimes it is useful for files to supply local values for this variable.
585You might also use mode hooks to specify it in certain modes, like this:
586
61c4aaf8 587 (add-hook 'c-mode-hook
61c4aaf8
RS
588 (lambda ()
589 (unless (or (file-exists-p \"makefile\")
590 (file-exists-p \"Makefile\"))
5b6858da
SM
591 (set (make-local-variable 'compile-command)
592 (concat \"make -k \"
7837c247 593 (file-name-sans-extension buffer-file-name))))))"
c5049fa0
RS
594 :type 'string
595 :group 'compilation)
631c8020 596;;;###autoload(put 'compile-command 'safe-local-variable 'stringp)
55dfd2c4 597
7957baea 598;;;###autoload
93ef35e4 599(defcustom compilation-disable-input nil
813fb3fe 600 "If non-nil, send end-of-file as compilation process input.
3fa37cd1 601This only affects platforms that support asynchronous processes (see
bac3a1c9 602`start-process'); synchronous compilation processes never accept input."
3fa37cd1
EZ
603 :type 'boolean
604 :group 'compilation
605 :version "22.1")
606
7837c247
SM
607;; A weak per-compilation-buffer hash indexed by (FILENAME . DIRECTORY). Each
608;; value is a FILE-STRUCTURE as described above, with the car eq to the hash
4fffd73b 609;; key. This holds the tree seen from root, for storing new nodes.
7837c247
SM
610(defvar compilation-locs ())
611
612(defvar compilation-debug nil
6f5b7627 613 "*Set this to t before creating a *compilation* buffer.
7837c247
SM
614Then every error line will have a debug text property with the matcher that
615fit this line and the match data. Use `describe-text-properties'.")
d3cb357b 616
01f89d11
RM
617(defvar compilation-exit-message-function nil "\
618If non-nil, called when a compilation process dies to return a status message.
fd5e58d7
RM
619This should be a function of three arguments: process status, exit status,
620and exit message; it returns a cons (MESSAGE . MODELINE) of the strings to
621write into the compilation buffer, and to put in its mode line.")
01f89d11 622
c20f961b
JPW
623(defvar compilation-environment nil
624 "*List of environment variables for compilation to inherit.
625Each element should be a string of the form ENVVARNAME=VALUE.
626This list is temporarily prepended to `process-environment' prior to
627starting the compilation process.")
628
770970cb
RS
629;; History of compile commands.
630(defvar compile-history nil)
770970cb 631
fa947ef3
JL
632(defface compilation-error
633 '((t :inherit font-lock-warning-face))
634 "Face used to highlight compiler errors."
da742205 635 :group 'compilation
fa947ef3
JL
636 :version "22.1")
637
541a6d0d 638(defface compilation-warning
bc3621a0
EZ
639 '((((class color) (min-colors 16)) (:foreground "Orange" :weight bold))
640 (((class color)) (:foreground "cyan" :weight bold))
7837c247
SM
641 (t (:weight bold)))
642 "Face used to highlight compiler warnings."
da742205 643 :group 'compilation
bf247b6e 644 :version "22.1")
7837c247 645
541a6d0d 646(defface compilation-info
e4aa3c94 647 '((((class color) (min-colors 16) (background light))
bc3621a0 648 (:foreground "Green3" :weight bold))
ea81d57e
DN
649 (((class color) (min-colors 88) (background dark))
650 (:foreground "Green1" :weight bold))
e4aa3c94 651 (((class color) (min-colors 16) (background dark))
bc3621a0
EZ
652 (:foreground "Green" :weight bold))
653 (((class color)) (:foreground "green" :weight bold))
7837c247 654 (t (:weight bold)))
fa947ef3 655 "Face used to highlight compiler information."
da742205 656 :group 'compilation
bf247b6e 657 :version "22.1")
7837c247 658
a5f1c37e 659(defface compilation-line-number
38dbf92b 660 '((t :inherit font-lock-variable-name-face))
fa947ef3 661 "Face for displaying line numbers in compiler messages."
da742205 662 :group 'compilation
a5f1c37e
RS
663 :version "22.1")
664
665(defface compilation-column-number
38dbf92b 666 '((t :inherit font-lock-type-face))
fa947ef3 667 "Face for displaying column numbers in compiler messages."
da742205 668 :group 'compilation
a5f1c37e
RS
669 :version "22.1")
670
f4beca06 671(defcustom compilation-message-face 'underline
7837c247
SM
672 "Face name to use for whole messages.
673Faces `compilation-error-face', `compilation-warning-face',
674`compilation-info-face', `compilation-line-face' and
f4beca06
RS
675`compilation-column-face' get prepended to this, when applicable."
676 :type 'face
677 :group 'compilation
678 :version "22.1")
7837c247 679
38dbf92b 680(defvar compilation-error-face 'compilation-error
7837c247
SM
681 "Face name to use for file name in error messages.")
682
38dbf92b 683(defvar compilation-warning-face 'compilation-warning
7837c247
SM
684 "Face name to use for file name in warning messages.")
685
38dbf92b 686(defvar compilation-info-face 'compilation-info
7837c247
SM
687 "Face name to use for file name in informational messages.")
688
a5f1c37e 689(defvar compilation-line-face 'compilation-line-number
38dbf92b 690 "Face name to use for line numbers in compiler messages.")
7837c247 691
a5f1c37e 692(defvar compilation-column-face 'compilation-column-number
fa947ef3 693 "Face name to use for column numbers in compiler messages.")
7837c247
SM
694
695;; same faces as dired uses
696(defvar compilation-enter-directory-face 'font-lock-function-name-face
fa947ef3 697 "Face name to use for entering directory messages.")
7837c247
SM
698
699(defvar compilation-leave-directory-face 'font-lock-type-face
fa947ef3 700 "Face name to use for leaving directory messages.")
7837c247
SM
701
702
703
c536bb39 704;; Used for compatibility with the old compile.el.
0ff7f01e 705(defvaralias 'compilation-last-buffer 'next-error-last-buffer)
6f5b7627 706(defvar compilation-parsing-end (make-marker))
c536bb39
SM
707(defvar compilation-parse-errors-function nil)
708(defvar compilation-error-list nil)
709(defvar compilation-old-error-list nil)
710
813fb3fe 711(defcustom compilation-auto-jump-to-first-error nil
6cc725cd 712 "If non-nil, automatically jump to the first error during compilation."
765831a0
DN
713 :type 'boolean
714 :group 'compilation
715 :version "23.1")
813fb3fe
SM
716
717(defvar compilation-auto-jump-to-next nil
718 "If non-nil, automatically jump to the next error encountered.")
719(make-variable-buffer-local 'compilation-auto-jump-to-next)
720
97546017
DN
721
722(defvar compilation-skip-to-next-location t
723 "*If non-nil, skip multiple error messages for the same source location.")
724
725(defcustom compilation-skip-threshold 1
726 "Compilation motion commands skip less important messages.
727The value can be either 2 -- skip anything less than error, 1 --
728skip anything less than warning or 0 -- don't skip any messages.
729Note that all messages not positively identified as warning or
730info, are considered errors."
731 :type '(choice (const :tag "Warnings and info" 2)
732 (const :tag "Info" 1)
733 (const :tag "None" 0))
734 :group 'compilation
735 :version "22.1")
736
737(defcustom compilation-skip-visited nil
738 "Compilation motion commands skip visited messages if this is t.
739Visited messages are ones for which the file, line and column have been jumped
740to from the current content in the current compilation buffer, even if it was
741from a different message."
742 :type 'boolean
743 :group 'compilation
744 :version "22.1")
745
7837c247
SM
746(defun compilation-face (type)
747 (or (and (car type) (match-end (car type)) compilation-warning-face)
748 (and (cdr type) (match-end (cdr type)) compilation-info-face)
749 compilation-error-face))
750
deda0c65
DP
751;; Internal function for calculating the text properties of a directory
752;; change message. The directory property is important, because it is
753;; the stack of nested enter-messages. Relative filenames on the following
754;; lines are relative to the top of the stack.
7837c247
SM
755(defun compilation-directory-properties (idx leave)
756 (if leave (setq leave (match-end leave)))
757 ;; find previous stack, and push onto it, or if `leave' pop it
758 (let ((dir (previous-single-property-change (point) 'directory)))
759 (setq dir (if dir (or (get-text-property (1- dir) 'directory)
760 (get-text-property dir 'directory))))
761 `(face ,(if leave
762 compilation-leave-directory-face
763 compilation-enter-directory-face)
764 directory ,(if leave
765 (or (cdr dir)
766 '(nil)) ; nil only isn't a property-change
767 (cons (match-string-no-properties idx) dir))
768 mouse-face highlight
6f5b7627 769 keymap compilation-button-map
5ae48997 770 help-echo "mouse-2: visit destination directory")))
7837c247 771
4fffd73b 772;; Data type `reverse-ordered-alist' retriever. This function retrieves the
7837c247
SM
773;; KEY element from the ALIST, creating it in the right position if not already
774;; present. ALIST structure is
775;; '(ANCHOR (KEY1 ...) (KEY2 ...)... (KEYn ALIST ...))
776;; ANCHOR is ignored, but necessary so that elements can be inserted. KEY1
4fffd73b 777;; may be nil. The other KEYs are ordered backwards so that growing line
7837c247
SM
778;; numbers can be inserted in front and searching can abort after half the
779;; list on average.
6f5b7627 780(eval-when-compile ;Don't keep it at runtime if not needed.
7837c247
SM
781(defmacro compilation-assq (key alist)
782 `(let* ((l1 ,alist)
783 (l2 (cdr l1)))
784 (car (if (if (null ,key)
785 (if l2 (null (caar l2)))
786 (while (if l2 (if (caar l2) (< ,key (caar l2)) t))
787 (setq l1 l2
788 l2 (cdr l1)))
789 (if l2 (eq ,key (caar l2))))
790 l2
6f5b7627 791 (setcdr l1 (cons (list ,key) l2)))))))
7837c247 792
813fb3fe
SM
793(defun compilation-auto-jump (buffer pos)
794 (with-current-buffer buffer
795 (goto-char pos)
93c0985f
JL
796 (let ((win (get-buffer-window buffer 0)))
797 (if win (set-window-point win pos)))
78dc87a2
JL
798 (if compilation-auto-jump-to-first-error
799 (compile-goto-error))))
7837c247
SM
800
801;; This function is the central driver, called when font-locking to gather
802;; all information needed to later jump to corresponding source code.
803;; Return a property list with all meta information on this error location.
f0685ed1 804
7837c247 805(defun compilation-error-properties (file line end-line col end-col type fmt)
813fb3fe
SM
806 (unless (< (next-single-property-change (match-beginning 0)
807 'directory nil (point))
7837c247
SM
808 (point))
809 (if file
810 (if (functionp file)
811 (setq file (funcall file))
812 (let (dir)
813 (setq file (match-string-no-properties file))
814 (unless (file-name-absolute-p file)
815 (setq dir (previous-single-property-change (point) 'directory)
816 dir (if dir (or (get-text-property (1- dir) 'directory)
817 (get-text-property dir 'directory)))))
efb0e677 818 (setq file (cons file (car dir)))))
7837c247 819 ;; This message didn't mention one, get it from previous
f0685ed1
RS
820 (let ((prev-pos
821 ;; Find the previous message.
822 (previous-single-property-change (point) 'message)))
823 (if prev-pos
824 ;; Get the file structure that belongs to it.
825 (let* ((prev
826 (or (get-text-property (1- prev-pos) 'message)
827 (get-text-property prev-pos 'message)))
828 (prev-struct
829 (car (nth 2 (car prev)))))
830 ;; Construct FILE . DIR from that.
831 (if prev-struct
832 (setq file (cons (car prev-struct)
833 (cadr prev-struct))))))
834 (unless file
835 (setq file '("*unknown*")))))
7837c247
SM
836 ;; All of these fields are optional, get them only if we have an index, and
837 ;; it matched some part of the message.
838 (and line
839 (setq line (match-string-no-properties line))
840 (setq line (string-to-number line)))
841 (and end-line
842 (setq end-line (match-string-no-properties end-line))
843 (setq end-line (string-to-number end-line)))
9dc3a46a
JL
844 (if col
845 (if (functionp col)
846 (setq col (funcall col))
847 (and
848 (setq col (match-string-no-properties col))
849 (setq col (- (string-to-number col) compilation-first-column)))))
850 (if (and end-col (functionp end-col))
851 (setq end-col (funcall end-col))
852 (if (and end-col (setq end-col (match-string-no-properties end-col)))
853 (setq end-col (- (string-to-number end-col) compilation-first-column -1))
854 (if end-line (setq end-col -1))))
eb6fb6e2 855 (if (consp type) ; not a static type, check what it is.
7837c247
SM
856 (setq type (or (and (car type) (match-end (car type)) 1)
857 (and (cdr type) (match-end (cdr type)) 0)
858 2)))
813fb3fe
SM
859
860 (when (and compilation-auto-jump-to-next
861 (>= type compilation-skip-threshold))
862 (kill-local-variable 'compilation-auto-jump-to-next)
863 (run-with-timer 0 nil 'compilation-auto-jump
864 (current-buffer) (match-beginning 0)))
865
efb0e677
SM
866 (compilation-internal-error-properties file line end-line col end-col type fmt)))
867
9c8e6c85
SM
868(defun compilation-move-to-column (col screen)
869 "Go to column COL on the current line.
870If SCREEN is non-nil, columns are screen columns, otherwise, they are
871just char-counts."
872 (if screen
ee15d759 873 (move-to-column (max col 0))
9c8e6c85
SM
874 (goto-char (min (+ (line-beginning-position) col) (line-end-position)))))
875
7957baea 876(defun compilation-internal-error-properties (file line end-line col end-col type fmts)
efb0e677
SM
877 "Get the meta-info that will be added as text-properties.
878LINE, END-LINE, COL, END-COL are integers or nil.
7957baea
RS
879TYPE can be 0, 1, or 2, meaning error, warning, or just info.
880FILE should be (FILENAME) or (RELATIVE-FILENAME . DIRNAME) or nil.
881FMTS is a list of format specs for transforming the file name.
882 (See `compilation-error-regexp-alist'.)"
efb0e677 883 (unless file (setq file '("*unknown*")))
7957baea
RS
884 (let* ((file-struct (compilation-get-file-structure file fmts))
885 ;; Get first already existing marker (if any has one, all have one).
886 ;; Do this first, as the compilation-assq`s may create new nodes.
887 (marker-line (car (cddr file-struct))) ; a line structure
efb0e677
SM
888 (marker (nth 3 (cadr marker-line))) ; its marker
889 (compilation-error-screen-columns compilation-error-screen-columns)
890 end-marker loc end-loc)
891 (if (not (and marker (marker-buffer marker)))
7957baea 892 (setq marker nil) ; no valid marker for this file
dbd97672
DP
893 (setq loc (or line 1)) ; normalize no linenumber to line 1
894 (catch 'marker ; find nearest loc, at least one exists
7957baea 895 (dolist (x (nthcdr 3 file-struct)) ; loop over remaining lines
dbd97672 896 (if (> (car x) loc) ; still bigger
efb0e677 897 (setq marker-line x)
dbd97672
DP
898 (if (> (- (or (car marker-line) 1) loc)
899 (- loc (car x))) ; current line is nearer
efb0e677
SM
900 (setq marker-line x))
901 (throw 'marker t))))
902 (setq marker (nth 3 (cadr marker-line))
dbd97672 903 marker-line (or (car marker-line) 1))
efb0e677 904 (with-current-buffer (marker-buffer marker)
8dfb3e16
RS
905 (save-excursion
906 (save-restriction
907 (widen)
908 (goto-char (marker-position marker))
909 (when (or end-col end-line)
910 (beginning-of-line (- (or end-line line) marker-line -1))
911 (if (or (null end-col) (< end-col 0))
912 (end-of-line)
913 (compilation-move-to-column
914 end-col compilation-error-screen-columns))
915 (setq end-marker (list (point-marker))))
916 (beginning-of-line (if end-line
917 (- line end-line -1)
918 (- loc marker-line -1)))
919 (if col
920 (compilation-move-to-column
921 col compilation-error-screen-columns)
922 (forward-to-indentation 0))
923 (setq marker (list (point-marker)))))))
efb0e677 924
7957baea 925 (setq loc (compilation-assq line (cdr file-struct)))
efb0e677 926 (if end-line
7957baea 927 (setq end-loc (compilation-assq end-line (cdr file-struct))
efb0e677
SM
928 end-loc (compilation-assq end-col end-loc))
929 (if end-col ; use same line element
930 (setq end-loc (compilation-assq end-col loc))))
931 (setq loc (compilation-assq col loc))
932 ;; If they are new, make the loc(s) reference the file they point to.
7957baea 933 (or (cdr loc) (setcdr loc `(,line ,file-struct ,@marker)))
efb0e677 934 (if end-loc
7957baea
RS
935 (or (cdr end-loc)
936 (setcdr end-loc `(,(or end-line line) ,file-struct ,@end-marker))))
efb0e677
SM
937
938 ;; Must start with face
939 `(face ,compilation-message-face
940 message (,loc ,type ,end-loc)
941 ,@(if compilation-debug
942 `(debug (,(assoc (with-no-warnings matcher) font-lock-keywords)
943 ,@(match-data))))
944 help-echo ,(if col
945 "mouse-2: visit this file, line and column"
946 (if line
947 "mouse-2: visit this file and line"
948 "mouse-2: visit this file"))
949 keymap compilation-button-map
950 mouse-face highlight)))
7837c247 951
e93b2a55
SM
952(defun compilation-mode-font-lock-keywords ()
953 "Return expressions to highlight in Compilation mode."
91fa27cd
SM
954 (if compilation-parse-errors-function
955 ;; An old package! Try the compatibility code.
956 '((compilation-compat-parse-errors))
957 (append
958 ;; make directory tracking
959 (if compilation-directory-matcher
960 `((,(car compilation-directory-matcher)
961 ,@(mapcar (lambda (elt)
962 `(,(car elt)
963 (compilation-directory-properties
964 ,(car elt) ,(cdr elt))
0ea50e43 965 t t))
91fa27cd
SM
966 (cdr compilation-directory-matcher)))))
967
968 ;; Compiler warning/error lines.
969 (mapcar
970 (lambda (item)
971 (if (symbolp item)
972 (setq item (cdr (assq item
973 compilation-error-regexp-alist-alist))))
974 (let ((file (nth 1 item))
975 (line (nth 2 item))
976 (col (nth 3 item))
977 (type (nth 4 item))
2b1d2412 978 (pat (car item))
91fa27cd 979 end-line end-col fmt)
2b1d2412
SS
980 ;; omake reports some error indented, so skip the indentation.
981 ;; another solution is to modify (some?) regexps in
982 ;; `compilation-error-regexp-alist'.
983 ;; note that omake usage is not limited to ocaml and C (for stubs).
984 (unless (string-match (concat "^" (regexp-quote "^ *")) pat)
985 (setq pat (concat "^ *"
986 (if (= ?^ (aref pat 0))
987 (substring pat 1)
988 pat))))
b3a7f48f
DP
989 (if (consp file) (setq fmt (cdr file) file (car file)))
990 (if (consp line) (setq end-line (cdr line) line (car line)))
91fa27cd 991 (if (consp col) (setq end-col (cdr col) col (car col)))
b3a7f48f 992
544dccaa 993 (if (functionp line)
91fa27cd
SM
994 ;; The old compile.el had here an undocumented hook that
995 ;; allowed `line' to be a function that computed the actual
996 ;; error location. Let's do our best.
2b1d2412 997 `(,pat
0ea50e43
RS
998 (0 (save-match-data
999 (compilation-compat-error-properties
1000 (funcall ',line (cons (match-string ,file)
1001 (cons default-directory
1002 ',(nthcdr 4 item)))
1003 ,(if col `(match-string ,col))))))
91fa27cd 1004 (,file compilation-error-face t))
b3a7f48f 1005
f71d34b0
SM
1006 (unless (or (null (nth 5 item)) (integerp (nth 5 item)))
1007 (error "HYPERLINK should be an integer: %s" (nth 5 item)))
1008
2b1d2412 1009 `(,pat
91fa27cd
SM
1010
1011 ,@(when (integerp file)
1012 `((,file ,(if (consp type)
1013 `(compilation-face ',type)
1014 (aref [compilation-info-face
1015 compilation-warning-face
1016 compilation-error-face]
1017 (or type 2))))))
1018
1019 ,@(when line
1020 `((,line compilation-line-face nil t)))
1021 ,@(when end-line
1022 `((,end-line compilation-line-face nil t)))
1023
9dc3a46a 1024 ,@(when (integerp col)
91fa27cd 1025 `((,col compilation-column-face nil t)))
9dc3a46a 1026 ,@(when (integerp end-col)
91fa27cd
SM
1027 `((,end-col compilation-column-face nil t)))
1028
1029 ,@(nthcdr 6 item)
1030 (,(or (nth 5 item) 0)
1031 (compilation-error-properties ',file ,line ,end-line
1032 ,col ,end-col ',(or type 2)
1033 ',fmt)
1034 append))))) ; for compilation-message-face
1035 compilation-error-regexp-alist)
1036
1037 compilation-mode-font-lock-keywords)))
7837c247 1038
430aee8b
SS
1039(defun compilation-read-command (command)
1040 (read-shell-command "Compile command: " command
1041 (if (equal (car compile-history) command)
1042 '(compile-history . 1)
1043 'compile-history)))
1044
01f89d11 1045\f
d3cb357b 1046;;;###autoload
7837c247 1047(defun compile (command &optional comint)
55dfd2c4
RS
1048 "Compile the program including the current buffer. Default: run `make'.
1049Runs COMMAND, a shell command, in a separate process asynchronously
1050with output going to the buffer `*compilation*'.
d3cb357b 1051
55dfd2c4
RS
1052You can then use the command \\[next-error] to find the next error message
1053and move to the source code that caused it.
1054
8f72171b
RS
1055If optional second arg COMINT is t the buffer will be in Comint mode with
1056`compilation-shell-minor-mode'.
1057
08b1edf4
RM
1058Interactively, prompts for the command if `compilation-read-command' is
1059non-nil; otherwise uses `compile-command'. With prefix arg, always prompts.
c39bf546
DP
1060Additionally, with universal prefix arg, compilation buffer will be in
1061comint mode, i.e. interactive.
08b1edf4 1062
7d1dad0c 1063To run more than one compilation at once, start one then rename
c72095b3 1064the \`*compilation*' buffer to some other name with
7d1dad0c
RS
1065\\[rename-buffer]. Then _switch buffers_ and start the new compilation.
1066It will create a new \`*compilation*' buffer.
1067
1068On most systems, termination of the main compilation process
1069kills its subprocesses.
d3cb357b
RM
1070
1071The name used for the buffer is actually whatever is returned by
1072the function in `compilation-buffer-name-function', so you can set that
1073to a function that generates a unique name."
90016295 1074 (interactive
c39bf546 1075 (list
20320c65
JL
1076 (let ((command (eval compile-command)))
1077 (if (or compilation-read-command current-prefix-arg)
430aee8b 1078 (compilation-read-command command)
20320c65 1079 command))
c39bf546 1080 (consp current-prefix-arg)))
5b6858da
SM
1081 (unless (equal command (eval compile-command))
1082 (setq compile-command command))
90016295 1083 (save-some-buffers (not compilation-ask-about-save) nil)
091525d5 1084 (setq-default compilation-directory default-directory)
7837c247 1085 (compilation-start command comint))
55dfd2c4 1086
5b6858da 1087;; run compile with the default command line
430aee8b 1088(defun recompile (&optional edit-command)
6867356a 1089 "Re-compile the program including the current buffer.
6f5b7627 1090If this is run in a Compilation mode buffer, re-use the arguments from the
430aee8b
SS
1091original use. Otherwise, recompile using `compile-command'.
1092If the optional argument `edit-command' is non-nil, the command can be edited."
1093 (interactive "P")
e60476ca 1094 (save-some-buffers (not compilation-ask-about-save) nil)
091525d5 1095 (let ((default-directory (or compilation-directory default-directory)))
430aee8b
SS
1096 (when edit-command
1097 (setcar compilation-arguments
1098 (compilation-read-command (car compilation-arguments))))
7837c247
SM
1099 (apply 'compilation-start (or compilation-arguments
1100 `(,(eval compile-command))))))
09843b4a 1101
b5812513 1102(defcustom compilation-scroll-output nil
813fb3fe 1103 "Non-nil to scroll the *compilation* buffer window as output appears.
b5812513 1104
6f5b7627 1105Setting it causes the Compilation mode commands to put point at the
b5812513 1106end of their output window so that the end of the output is always
78dc87a2
JL
1107visible rather than the beginning.
1108
1109The value `first-error' stops scrolling at the first error, and leaves
1110point on its location in the *compilation* buffer."
1111 :type '(choice (const :tag "No scrolling" nil)
1112 (const :tag "Scroll compilation output" t)
1113 (const :tag "Stop scrolling at the first error" first-error))
a46fddeb 1114 :version "20.3"
b5812513
DL
1115 :group 'compilation)
1116
7bdb67b2 1117
ae0cc840 1118(defun compilation-buffer-name (mode-name mode-command name-function)
7bdb67b2
GM
1119 "Return the name of a compilation buffer to use.
1120If NAME-FUNCTION is non-nil, call it with one argument MODE-NAME
1121to determine the buffer name.
1122Likewise if `compilation-buffer-name-function' is non-nil.
7d1dad0c 1123If current buffer has the major mode MODE-COMMAND,
7bdb67b2
GM
1124return the name of the current buffer, so that it gets reused.
1125Otherwise, construct a buffer name from MODE-NAME."
dc2feacf 1126 (cond (name-function
7bdb67b2 1127 (funcall name-function mode-name))
dc2feacf 1128 (compilation-buffer-name-function
7bdb67b2 1129 (funcall compilation-buffer-name-function mode-name))
be947101 1130 ((eq mode-command major-mode)
7bdb67b2
GM
1131 (buffer-name))
1132 (t
1133 (concat "*" (downcase mode-name) "*"))))
1134
7837c247
SM
1135;; This is a rough emulation of the old hack, until the transition to new
1136;; compile is complete.
55dfd2c4 1137(defun compile-internal (command error-message
a24770bc
RS
1138 &optional name-of-mode parser
1139 error-regexp-alist name-function
1140 enter-regexp-alist leave-regexp-alist
23b0c5fc 1141 file-regexp-alist nomessage-regexp-alist
9ac57479 1142 no-async highlight-regexp local-map)
7837c247
SM
1143 (if parser
1144 (error "Compile now works very differently, see `compilation-error-regexp-alist'"))
1145 (let ((compilation-error-regexp-alist
1146 (append file-regexp-alist (or error-regexp-alist
1147 compilation-error-regexp-alist)))
1148 (compilation-error (replace-regexp-in-string "^No more \\(.+\\)s\\.?"
1149 "\\1" error-message)))
1150 (compilation-start command nil name-function highlight-regexp)))
ddb1f2e3 1151(make-obsolete 'compile-internal 'compilation-start "22.1")
7837c247 1152
a24c45d2 1153;;;###autoload
7837c247 1154(defun compilation-start (command &optional mode name-function highlight-regexp)
55dfd2c4 1155 "Run compilation command COMMAND (low level interface).
489a8034 1156If COMMAND starts with a cd command, that becomes the `default-directory'.
9ac57479
KS
1157The rest of the arguments are optional; for them, nil means use the default.
1158
7837c247 1159MODE is the major mode to set in the compilation buffer. Mode
6f5b7627 1160may also be t meaning use `compilation-shell-minor-mode' under `comint-mode'.
7d1dad0c 1161
5b317d74 1162If NAME-FUNCTION is non-nil, call it with one argument (the mode name)
7d1dad0c
RS
1163to determine the buffer name. Otherwise, the default is to
1164reuses the current buffer if it has the proper major mode,
1165else use or create a buffer with name based on the major mode.
23b0c5fc 1166
9ac57479 1167If HIGHLIGHT-REGEXP is non-nil, `next-error' will temporarily highlight
6f5b7627 1168the matching section of the visited source line; the default is to use the
9ac57479
KS
1169global value of `compilation-highlight-regexp'.
1170
646bd331 1171Returns the compilation buffer created."
7837c247 1172 (or mode (setq mode 'compilation-mode))
489a8034
DP
1173 (let* ((name-of-mode
1174 (if (eq mode t)
72fcf382 1175 "compilation"
489a8034 1176 (replace-regexp-in-string "-mode$" "" (symbol-name mode))))
199143f1 1177 (thisdir default-directory)
489a8034 1178 outwin outbuf)
c536bb39
SM
1179 (with-current-buffer
1180 (setq outbuf
1181 (get-buffer-create
be947101 1182 (compilation-buffer-name name-of-mode mode name-function)))
d3cb357b
RM
1183 (let ((comp-proc (get-buffer-process (current-buffer))))
1184 (if comp-proc
1185 (if (or (not (eq (process-status comp-proc) 'run))
1186 (yes-or-no-p
bea1d57a
JB
1187 (format "A %s process is running; kill it? "
1188 name-of-mode)))
d3cb357b
RM
1189 (condition-case ()
1190 (progn
1191 (interrupt-process comp-proc)
1192 (sit-for 1)
1193 (delete-process comp-proc))
1194 (error nil))
1195 (error "Cannot have two processes in `%s' at once"
7837c247 1196 (buffer-name)))))
199143f1
DP
1197 ;; first transfer directory from where M-x compile was called
1198 (setq default-directory thisdir)
d42c87ab
RS
1199 ;; Make compilation buffer read-only. The filter can still write it.
1200 ;; Clear out the compilation buffer.
199143f1
DP
1201 (let ((inhibit-read-only t)
1202 (default-directory thisdir))
813fb3fe
SM
1203 ;; Then evaluate a cd command if any, but don't perform it yet, else
1204 ;; start-command would do it again through the shell: (cd "..") AND
1205 ;; sh -c "cd ..; make"
199143f1
DP
1206 (cd (if (string-match "^\\s *cd\\(?:\\s +\\(\\S +?\\)\\)?\\s *[;&\n]" command)
1207 (if (match-end 1)
12221c84 1208 (substitute-env-vars (match-string 1 command))
199143f1
DP
1209 "~")
1210 default-directory))
abed5267 1211 (erase-buffer)
6d2957c4
RS
1212 ;; Select the desired mode.
1213 (if (not (eq mode t))
ec4e0abc
SM
1214 (progn
1215 (buffer-disable-undo)
1216 (funcall mode))
6d2957c4
RS
1217 (setq buffer-read-only nil)
1218 (with-no-warnings (comint-mode))
1219 (compilation-shell-minor-mode))
5f3ca1ba
SS
1220 ;; Remember the original dir, so we can use it when we recompile.
1221 ;; default-directory' can't be used reliably for that because it may be
1222 ;; affected by the special handling of "cd ...;".
1223 ;; NB: must be fone after (funcall mode) as that resets local variables
1224 (set (make-local-variable 'compilation-directory) thisdir)
6d2957c4
RS
1225 (if highlight-regexp
1226 (set (make-local-variable 'compilation-highlight-regexp)
1227 highlight-regexp))
78dc87a2
JL
1228 (if (or compilation-auto-jump-to-first-error
1229 (eq compilation-scroll-output 'first-error))
813fb3fe 1230 (set (make-local-variable 'compilation-auto-jump-to-next) t))
6d2957c4 1231 ;; Output a mode setter, for saving and later reloading this buffer.
d42c87ab 1232 (insert "-*- mode: " name-of-mode
4b025f47 1233 "; default-directory: " (prin1-to-string default-directory)
a67e5425 1234 " -*-\n"
314b410b
JL
1235 (format "%s started at %s\n\n"
1236 mode-name
1237 (substring (current-time-string) 0 19))
a67e5425 1238 command "\n")
abed5267 1239 (setq thisdir default-directory))
7837c247 1240 (set-buffer-modified-p nil))
7837c247 1241 ;; Pop up the compilation buffer.
c34dc850
GM
1242 ;; http://lists.gnu.org/archive/html/emacs-devel/2007-11/msg01638.html
1243 (setq outwin (display-buffer outbuf))
7837c247 1244 (with-current-buffer outbuf
577bf5d2
JL
1245 (let ((process-environment
1246 (append
1247 compilation-environment
1248 (if (if (boundp 'system-uses-terminfo) ; `if' for compiler warning
1249 system-uses-terminfo)
1250 (list "TERM=dumb" "TERMCAP="
1251 (format "COLUMNS=%d" (window-width)))
1252 (list "TERM=emacs"
1253 (format "TERMCAP=emacs:co#%d:tc=unknown:"
1254 (window-width))))
1255 ;; Set the EMACS variable, but
1256 ;; don't override users' setting of $EMACS.
4b1aaa8b 1257 (unless (getenv "EMACS")
e725507a
CY
1258 (list "EMACS=t"))
1259 (list "INSIDE_EMACS=t")
a9e11582 1260 (copy-sequence process-environment))))
577bf5d2
JL
1261 (set (make-local-variable 'compilation-arguments)
1262 (list command mode name-function highlight-regexp))
1263 (set (make-local-variable 'revert-buffer-function)
1264 'compilation-revert-buffer)
1265 (set-window-start outwin (point-min))
2d0a22f8
RS
1266
1267 ;; Position point as the user will see it.
1268 (let ((desired-visible-point
1269 ;; Put it at the end if `compilation-scroll-output' is set.
1270 (if compilation-scroll-output
1271 (point-max)
1272 ;; Normally put it at the top.
1273 (point-min))))
1274 (if (eq outwin (selected-window))
1275 (goto-char desired-visible-point)
1276 (set-window-point outwin desired-visible-point)))
1277
577bf5d2
JL
1278 ;; The setup function is called before compilation-set-window-height
1279 ;; so it can set the compilation-window-height buffer locally.
1280 (if compilation-process-setup-function
1281 (funcall compilation-process-setup-function))
1282 (compilation-set-window-height outwin)
1283 ;; Start the compilation.
2a12d736
EZ
1284 (if (fboundp 'start-process)
1285 (let ((proc
1286 (if (eq mode t)
1287 ;; comint uses `start-file-process'.
1288 (get-buffer-process
1289 (with-no-warnings
1290 (comint-exec
1291 outbuf (downcase mode-name)
1292 (if (file-remote-p default-directory)
1293 "/bin/sh"
1294 shell-file-name)
1295 nil `("-c" ,command))))
1296 (start-file-process-shell-command (downcase mode-name)
1297 outbuf command))))
1298 ;; Make the buffer's mode line show process state.
1299 (setq mode-line-process
1300 (list (propertize ":%s" 'face 'compilation-warning)))
1301 (set-process-sentinel proc 'compilation-sentinel)
1302 (unless (eq mode t)
1303 ;; Keep the comint filter, since it's needed for proper handling
1304 ;; of the prompts.
1305 (set-process-filter proc 'compilation-filter))
1306 ;; Use (point-max) here so that output comes in
1307 ;; after the initial text,
1308 ;; regardless of where the user sees point.
1309 (set-marker (process-mark proc) (point-max) outbuf)
1310 (when compilation-disable-input
1311 (condition-case nil
1312 (process-send-eof proc)
1313 ;; The process may have exited already.
1314 (error nil)))
dd93e6da
SS
1315 (run-hook-with-args 'compilation-start-hook proc)
1316 (setq compilation-in-progress
2a12d736
EZ
1317 (cons proc compilation-in-progress)))
1318 ;; No asynchronous processes available.
1319 (message "Executing `%s'..." command)
1320 ;; Fake modeline display as if `start-process' were run.
ddb1f2e3 1321 (setq mode-line-process
2a12d736
EZ
1322 (list (propertize ":run" 'face 'compilation-warning)))
1323 (force-mode-line-update)
1324 (sit-for 0) ; Force redisplay
1325 (save-excursion
1326 ;; Insert the output at the end, after the initial text,
1327 ;; regardless of where the user sees point.
1328 (goto-char (point-max))
1329 (let* ((buffer-read-only nil) ; call-process needs to modify outbuf
1330 (status (call-process shell-file-name nil outbuf nil "-c"
1331 command)))
1332 (cond ((numberp status)
1333 (compilation-handle-exit
1334 'exit status
1335 (if (zerop status)
1336 "finished\n"
1337 (format "exited abnormally with code %d\n" status))))
1338 ((stringp status)
1339 (compilation-handle-exit 'signal status
1340 (concat status "\n")))
1341 (t
1342 (compilation-handle-exit 'bizarre status status)))))
1343 ;; Without async subprocesses, the buffer is not yet
1344 ;; fontified, so fontify it now.
1345 (let ((font-lock-verbose nil)) ; shut up font-lock messages
1346 (font-lock-fontify-buffer))
1347 (set-buffer-modified-p nil)
1348 (message "Executing `%s'...done" command)))
199143f1 1349 ;; Now finally cd to where the shell started make/grep/...
e6f3e104
MR
1350 (setq default-directory thisdir)
1351 ;; The following form selected outwin ever since revision 1.183,
1352 ;; so possibly messing up point in some other window (bug#1073).
1353 ;; Moved into the scope of with-current-buffer, though still with
1354 ;; complete disregard for the case when compilation-scroll-output
1355 ;; equals 'first-error (martin 2008-10-04).
1356 (when compilation-scroll-output
1357 (goto-char (point-max))))
1358
043442b4 1359 ;; Make it so the next C-x ` will use this buffer.
5d9f0de2 1360 (setq next-error-last-buffer outbuf)))
55dfd2c4 1361
c94b02d6 1362(defun compilation-set-window-height (window)
851231e9 1363 "Set the height of WINDOW according to `compilation-window-height'."
9ac57479
KS
1364 (let ((height (buffer-local-value 'compilation-window-height (window-buffer window))))
1365 (and height
0dad3dfe 1366 (window-full-width-p window)
9ac57479
KS
1367 ;; If window is alone in its frame, aside from a minibuffer,
1368 ;; don't change its height.
1369 (not (eq window (frame-root-window (window-frame window))))
b3ef54c5
DP
1370 ;; Stef said that doing the saves in this order is safer:
1371 (save-excursion
9ac57479 1372 (save-selected-window
b3ef54c5
DP
1373 (select-window window)
1374 (enlarge-window (- height (window-height))))))))
c94b02d6 1375
4282eba1 1376(defvar compilation-menu-map
93260283
DN
1377 (let ((map (make-sparse-keymap "Errors"))
1378 (opt-map (make-sparse-keymap "Skip")))
4282eba1 1379 (define-key map [stop-subjob]
38805987
DN
1380 '(menu-item "Stop Compilation" kill-compilation
1381 :help "Kill the process made by the M-x compile or M-x grep commands"))
93260283
DN
1382 (define-key map [compilation-mode-separator3]
1383 '("----" . nil))
1384 (define-key map [compilation-next-error-follow-minor-mode]
1385 '(menu-item
1386 "Auto Error Display" next-error-follow-minor-mode
1387 :help "Display the error under cursor when moving the cursor"
1388 :button (:toggle . next-error-follow-minor-mode)))
1389 (define-key map [compilation-skip]
1390 (cons "Skip Less Important Messages" opt-map))
1391 (define-key opt-map [compilation-skip-none]
1392 '(menu-item "Don't Skip Any Messages"
1393 (lambda ()
1394 (interactive)
1395 (customize-set-variable 'compilation-skip-threshold 0))
1396 :help "Do not skip any type of messages"
1397 :button (:radio . (eq compilation-skip-threshold 0))))
1398 (define-key opt-map [compilation-skip-info]
1399 '(menu-item "Skip Info"
1400 (lambda ()
1401 (interactive)
1402 (customize-set-variable 'compilation-skip-threshold 1))
1403 :help "Skip anything less than warning"
1404 :button (:radio . (eq compilation-skip-threshold 1))))
1405 (define-key opt-map [compilation-skip-warning-and-info]
1406 '(menu-item "Skip Warnings and Info"
1407 (lambda ()
1408 (interactive)
1409 (customize-set-variable 'compilation-skip-threshold 2))
1410 :help "Skip over Warnings and Info, stop for errors"
1411 :button (:radio . (eq compilation-skip-threshold 2))))
4282eba1
SM
1412 (define-key map [compilation-mode-separator2]
1413 '("----" . nil))
9ac57479 1414 (define-key map [compilation-first-error]
38805987
DN
1415 '(menu-item "First Error" first-error
1416 :help "Restart at the first error, visit corresponding source code"))
9ac57479 1417 (define-key map [compilation-previous-error]
38805987
DN
1418 '(menu-item "Previous Error" previous-error
1419 :help "Visit previous `next-error' message and corresponding source code"))
9ac57479 1420 (define-key map [compilation-next-error]
38805987
DN
1421 '(menu-item "Next Error" next-error
1422 :help "Visit next `next-error' message and corresponding source code"))
4282eba1
SM
1423 map))
1424
0b18a8f6 1425(defvar compilation-minor-mode-map
55dfd2c4 1426 (let ((map (make-sparse-keymap)))
9da85ee5 1427 (define-key map [mouse-2] 'compile-goto-error)
0ac804df 1428 (define-key map [follow-link] 'mouse-face)
55dfd2c4 1429 (define-key map "\C-c\C-c" 'compile-goto-error)
4e7ce12e 1430 (define-key map "\C-m" 'compile-goto-error)
d3cb357b 1431 (define-key map "\C-c\C-k" 'kill-compilation)
646bd331
RM
1432 (define-key map "\M-n" 'compilation-next-error)
1433 (define-key map "\M-p" 'compilation-previous-error)
d1ed4475
RM
1434 (define-key map "\M-{" 'compilation-previous-file)
1435 (define-key map "\M-}" 'compilation-next-file)
86c7460f
SS
1436 (define-key map "g" 'recompile) ; revert
1437 (define-key map "q" 'quit-window)
4282eba1
SM
1438 ;; Set up the menu-bar
1439 (define-key map [menu-bar compilation]
1440 (cons "Errors" compilation-menu-map))
55dfd2c4 1441 map)
4f6e4ad6 1442 "Keymap for `compilation-minor-mode'.")
0b18a8f6 1443
a24770bc
RS
1444(defvar compilation-shell-minor-mode-map
1445 (let ((map (make-sparse-keymap)))
a24770bc
RS
1446 (define-key map "\M-\C-m" 'compile-goto-error)
1447 (define-key map "\M-\C-n" 'compilation-next-error)
1448 (define-key map "\M-\C-p" 'compilation-previous-error)
1449 (define-key map "\M-{" 'compilation-previous-file)
1450 (define-key map "\M-}" 'compilation-next-file)
1451 ;; Set up the menu-bar
4282eba1
SM
1452 (define-key map [menu-bar compilation]
1453 (cons "Errors" compilation-menu-map))
a24770bc
RS
1454 map)
1455 "Keymap for `compilation-shell-minor-mode'.")
1456
60470fd2
SM
1457(defvar compilation-button-map
1458 (let ((map (make-sparse-keymap)))
1459 (define-key map [mouse-2] 'compile-goto-error)
0ac804df 1460 (define-key map [follow-link] 'mouse-face)
60470fd2
SM
1461 (define-key map "\C-m" 'compile-goto-error)
1462 map)
1463 "Keymap for compilation-message buttons.")
1464(fset 'compilation-button-map compilation-button-map)
1465
0b18a8f6 1466(defvar compilation-mode-map
4282eba1 1467 (let ((map (make-sparse-keymap)))
261b01c6
RS
1468 ;; Don't inherit from compilation-minor-mode-map,
1469 ;; because that introduces a menu bar item we don't want.
1470 ;; That confuses C-down-mouse-3.
5988691b 1471 (define-key map [mouse-2] 'compile-goto-error)
0ac804df 1472 (define-key map [follow-link] 'mouse-face)
5988691b
RS
1473 (define-key map "\C-c\C-c" 'compile-goto-error)
1474 (define-key map "\C-m" 'compile-goto-error)
1475 (define-key map "\C-c\C-k" 'kill-compilation)
1476 (define-key map "\M-n" 'compilation-next-error)
1477 (define-key map "\M-p" 'compilation-previous-error)
1478 (define-key map "\M-{" 'compilation-previous-file)
1479 (define-key map "\M-}" 'compilation-next-file)
70fec115
JL
1480 (define-key map "\t" 'compilation-next-error)
1481 (define-key map [backtab] 'compilation-previous-error)
86c7460f
SS
1482 (define-key map "g" 'recompile) ; revert
1483 (define-key map "q" 'quit-window)
5988691b 1484
0b18a8f6
RM
1485 (define-key map " " 'scroll-up)
1486 (define-key map "\^?" 'scroll-down)
221206e3 1487 (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
9ac57479 1488
e60476ca 1489 ;; Set up the menu-bar
5988691b
RS
1490 (let ((submap (make-sparse-keymap "Compile")))
1491 (define-key map [menu-bar compilation]
1492 (cons "Compile" submap))
1493 (set-keymap-parent submap compilation-menu-map))
4282eba1 1494 (define-key map [menu-bar compilation compilation-separator2]
e60476ca 1495 '("----" . nil))
9ac57479 1496 (define-key map [menu-bar compilation compilation-grep]
38805987
DN
1497 '(menu-item "Search Files (grep)..." grep
1498 :help "Run grep, with user-specified args, and collect output in a buffer"))
9ac57479 1499 (define-key map [menu-bar compilation compilation-recompile]
38805987
DN
1500 '(menu-item "Recompile" recompile
1501 :help "Re-compile the program including the current buffer"))
9ac57479 1502 (define-key map [menu-bar compilation compilation-compile]
38805987
DN
1503 '(menu-item "Compile..." compile
1504 :help "Compile the program including the current buffer. Default: run `make'"))
0b18a8f6
RM
1505 map)
1506 "Keymap for compilation log buffers.
4282eba1 1507`compilation-minor-mode-map' is a parent of this.")
55dfd2c4 1508
c45e48d2 1509(defvar compilation-mode-tool-bar-map
b4bd2cbe
CY
1510 ;; When bootstrapping, tool-bar-map is not properly initialized yet,
1511 ;; so don't do anything.
1512 (when (keymapp (butlast tool-bar-map))
1513 (let ((map (butlast (copy-keymap tool-bar-map)))
1514 (help (last tool-bar-map))) ;; Keep Help last in tool bar
1515 (tool-bar-local-item
1516 "left-arrow" 'previous-error-no-select 'previous-error-no-select map
1517 :rtl "right-arrow"
1518 :help "Goto previous error")
1519 (tool-bar-local-item
1520 "right-arrow" 'next-error-no-select 'next-error-no-select map
1521 :rtl "left-arrow"
1522 :help "Goto next error")
1523 (tool-bar-local-item
1524 "cancel" 'kill-compilation 'kill-compilation map
1525 :enable '(let ((buffer (compilation-find-buffer)))
1526 (get-buffer-process buffer))
1527 :help "Stop compilation")
1528 (tool-bar-local-item
1529 "refresh" 'recompile 'recompile map
1530 :help "Restart compilation")
1531 (append map help))))
c45e48d2 1532
0a35bd79
RS
1533(put 'compilation-mode 'mode-class 'special)
1534
501cf428 1535;;;###autoload
d42c87ab 1536(defun compilation-mode (&optional name-of-mode)
55dfd2c4
RS
1537 "Major mode for compilation log buffers.
1538\\<compilation-mode-map>To visit the source for a line-numbered error,
d3cb357b 1539move point to the error message line and type \\[compile-goto-error].
7c163413
RM
1540To kill the compilation, type \\[kill-compilation].
1541
2894bd96 1542Runs `compilation-mode-hook' with `run-mode-hooks' (which see).
8ff2ed52
RS
1543
1544\\{compilation-mode-map}"
55dfd2c4 1545 (interactive)
9af0d309 1546 (kill-all-local-variables)
55dfd2c4 1547 (use-local-map compilation-mode-map)
a1562258
SM
1548 ;; Let windows scroll along with the output.
1549 (set (make-local-variable 'window-point-insertion-type) t)
c45e48d2 1550 (set (make-local-variable 'tool-bar-map) compilation-mode-tool-bar-map)
0b18a8f6 1551 (setq major-mode 'compilation-mode
d42c87ab 1552 mode-name (or name-of-mode "Compilation"))
7837c247
SM
1553 (set (make-local-variable 'page-delimiter)
1554 compilation-page-delimiter)
0b18a8f6 1555 (compilation-setup)
bd8c6db5 1556 (setq buffer-read-only t)
7837c247
SM
1557 (run-mode-hooks 'compilation-mode-hook))
1558
1559(defmacro define-compilation-mode (mode name doc &rest body)
1560 "This is like `define-derived-mode' without the PARENT argument.
1561The parent is always `compilation-mode' and the customizable `compilation-...'
bac3a1c9
JL
1562variables are also set from the name of the mode you have chosen,
1563by replacing the first word, e.g `compilation-scroll-output' from
1564`grep-scroll-output' if that variable exists."
7837c247
SM
1565 (let ((mode-name (replace-regexp-in-string "-mode\\'" "" (symbol-name mode))))
1566 `(define-derived-mode ,mode compilation-mode ,name
1567 ,doc
1568 ,@(mapcar (lambda (v)
1569 (setq v (cons v
1570 (intern-soft (replace-regexp-in-string
1571 "^compilation" mode-name
1572 (symbol-name v)))))
1573 (and (cdr v)
1574 (or (boundp (cdr v))
1575 (if (boundp 'byte-compile-bound-variables)
1576 (memq (cdr v) byte-compile-bound-variables)))
1577 `(set (make-local-variable ',(car v)) ,(cdr v))))
1578 '(compilation-buffer-name-function
1579 compilation-directory-matcher
1580 compilation-error
1581 compilation-error-regexp-alist
1582 compilation-error-regexp-alist-alist
1583 compilation-error-screen-columns
1584 compilation-finish-function
1585 compilation-finish-functions
1586 compilation-first-column
1587 compilation-mode-font-lock-keywords
1588 compilation-page-delimiter
1589 compilation-parse-errors-filename-function
1590 compilation-process-setup-function
1591 compilation-scroll-output
1592 compilation-search-path
1593 compilation-skip-threshold
1594 compilation-window-height))
1595 ,@body)))
0b18a8f6 1596
58856335 1597(defun compilation-revert-buffer (ignore-auto noconfirm)
9ed2ab9f
RS
1598 (if buffer-file-name
1599 (let (revert-buffer-function)
9ac57479 1600 (revert-buffer ignore-auto noconfirm))
9ed2ab9f 1601 (if (or noconfirm (yes-or-no-p (format "Restart compilation? ")))
7837c247
SM
1602 (apply 'compilation-start compilation-arguments))))
1603
c536bb39
SM
1604(defvar compilation-current-error nil
1605 "Marker to the location from where the next error will be found.
1606The global commands next/previous/first-error/goto-error use this.")
51c8ad03 1607
9b7b51a2
SM
1608(defvar compilation-messages-start nil
1609 "Buffer position of the beginning of the compilation messages.
1610If nil, use the beginning of buffer.")
1611
7837c247
SM
1612;; A function name can't be a hook, must be something with a value.
1613(defconst compilation-turn-on-font-lock 'turn-on-font-lock)
58856335 1614
7837c247 1615(defun compilation-setup (&optional minor)
6f5b7627
SM
1616 "Prepare the buffer for the compilation parsing commands to work.
1617Optional argument MINOR indicates this is called from
1618`compilation-minor-mode'."
51c8ad03 1619 (make-local-variable 'compilation-current-error)
9b7b51a2 1620 (make-local-variable 'compilation-messages-start)
18aac618 1621 (make-local-variable 'compilation-error-screen-columns)
b3a7f48f 1622 (make-local-variable 'overlay-arrow-position)
8b71e4d1 1623 (set (make-local-variable 'overlay-arrow-string) "")
6a1cdc5b
JL
1624 (setq next-error-overlay-arrow-position nil)
1625 (add-hook 'kill-buffer-hook
1626 (lambda () (setq next-error-overlay-arrow-position nil)) nil t)
9b7b51a2
SM
1627 ;; Note that compilation-next-error-function is for interfacing
1628 ;; with the next-error function in simple.el, and it's only
1629 ;; coincidentally named similarly to compilation-next-error.
1630 (setq next-error-function 'compilation-next-error-function)
00d6fd04
MA
1631 (set (make-local-variable 'comint-file-name-prefix)
1632 (or (file-remote-p default-directory) ""))
7837c247
SM
1633 (set (make-local-variable 'font-lock-extra-managed-props)
1634 '(directory message help-echo mouse-face debug))
1635 (set (make-local-variable 'compilation-locs)
1636 (make-hash-table :test 'equal :weakness 'value))
6f5b7627 1637 ;; lazy-lock would never find the message unless it's scrolled to.
c536bb39
SM
1638 ;; jit-lock might fontify some things too late.
1639 (set (make-local-variable 'font-lock-support-mode) nil)
7837c247 1640 (set (make-local-variable 'font-lock-maximum-size) nil)
963b2040
CY
1641 (if minor
1642 (let ((fld font-lock-defaults))
f6164cdd 1643 (font-lock-add-keywords nil (compilation-mode-font-lock-keywords))
f6164cdd
DP
1644 (if font-lock-mode
1645 (if fld
1646 (font-lock-fontify-buffer)
1647 (font-lock-change-mode)
1648 (turn-on-font-lock))
963b2040 1649 (turn-on-font-lock)))
49d11c49 1650 (setq font-lock-defaults '(compilation-mode-font-lock-keywords t))
963b2040
CY
1651 ;; maybe defer font-lock till after derived mode is set up
1652 (run-mode-hooks 'compilation-turn-on-font-lock)))
0b18a8f6 1653
7052680b 1654;;;###autoload
4282eba1 1655(define-minor-mode compilation-shell-minor-mode
7052680b
RS
1656 "Toggle compilation shell minor mode.
1657With arg, turn compilation mode on if and only if arg is positive.
4282eba1
SM
1658In this minor mode, all the error-parsing commands of the
1659Compilation major mode are available but bound to keys that don't
1660collide with Shell mode. See `compilation-mode'.
7052680b 1661Turning the mode on runs the normal hook `compilation-shell-minor-mode-hook'."
7837c247 1662 nil " Shell-Compile"
d408fed8 1663 :group 'compilation
7837c247
SM
1664 (if compilation-shell-minor-mode
1665 (compilation-setup t)
1666 (font-lock-remove-keywords nil (compilation-mode-font-lock-keywords))
1667 (font-lock-fontify-buffer)))
7052680b 1668
d6bd8dca 1669;;;###autoload
4282eba1 1670(define-minor-mode compilation-minor-mode
0b18a8f6
RM
1671 "Toggle compilation minor mode.
1672With arg, turn compilation mode on if and only if arg is positive.
4282eba1
SM
1673In this minor mode, all the error-parsing commands of the
1674Compilation major mode are available. See `compilation-mode'.
fee3f63a 1675Turning the mode on runs the normal hook `compilation-minor-mode-hook'."
7837c247 1676 nil " Compilation"
d408fed8 1677 :group 'compilation
7837c247
SM
1678 (if compilation-minor-mode
1679 (compilation-setup t)
1680 (font-lock-remove-keywords nil (compilation-mode-font-lock-keywords))
1681 (font-lock-fontify-buffer)))
55dfd2c4 1682
fd5e58d7 1683(defun compilation-handle-exit (process-status exit-status msg)
f441be5b 1684 "Write MSG in the current buffer and hack its `mode-line-process'."
d42c87ab 1685 (let ((inhibit-read-only t)
fd5e58d7
RM
1686 (status (if compilation-exit-message-function
1687 (funcall compilation-exit-message-function
1688 process-status exit-status msg)
1689 (cons msg exit-status)))
1690 (omax (point-max))
c96e025a
GM
1691 (opoint (point))
1692 (cur-buffer (current-buffer)))
b3a7f48f 1693 ;; Record where we put the message, so we can ignore it later on.
fd5e58d7
RM
1694 (goto-char omax)
1695 (insert ?\n mode-name " " (car status))
0eac1faa 1696 (if (and (numberp compilation-window-height)
7837c247
SM
1697 (zerop compilation-window-height))
1698 (message "%s" (cdr status)))
01c50447
RS
1699 (if (bolp)
1700 (forward-char -1))
fd5e58d7 1701 (insert " at " (substring (current-time-string) 0 19))
01c50447 1702 (goto-char (point-max))
47092737
RS
1703 ;; Prevent that message from being recognized as a compilation error.
1704 (add-text-properties omax (point)
1705 (append '(compilation-handle-exit t) nil))
a8bdd228
DN
1706 (setq mode-line-process
1707 (let ((out-string (format ":%s [%s]" process-status (cdr status)))
a46b95a8
JL
1708 (msg (format "%s %s" mode-name
1709 (replace-regexp-in-string "\n?$" "" (car status)))))
1710 (message "%s" msg)
1711 (propertize out-string
1712 'help-echo msg 'face (if (> exit-status 0)
1713 'compilation-error
1714 'compilation-info))))
fd5e58d7
RM
1715 ;; Force mode line redisplay soon.
1716 (force-mode-line-update)
1717 (if (and opoint (< opoint omax))
1718 (goto-char opoint))
a5f1c37e
RS
1719 (with-no-warnings
1720 (if compilation-finish-function
c96e025a
GM
1721 (funcall compilation-finish-function cur-buffer msg)))
1722 (run-hook-with-args 'compilation-finish-functions cur-buffer msg)))
fd5e58d7 1723
55dfd2c4 1724;; Called when compilation process changes state.
55dfd2c4 1725(defun compilation-sentinel (proc msg)
d3cb357b 1726 "Sentinel for compilation buffers."
b3a7f48f
DP
1727 (if (memq (process-status proc) '(exit signal))
1728 (let ((buffer (process-buffer proc)))
1729 (if (null (buffer-name buffer))
1730 ;; buffer killed
1731 (set-process-buffer proc nil)
1732 (with-current-buffer buffer
1733 ;; Write something in the compilation buffer
1734 ;; and hack its mode line.
1735 (compilation-handle-exit (process-status proc)
1736 (process-exit-status proc)
1737 msg)
1738 ;; Since the buffer and mode line will show that the
1739 ;; process is dead, we can delete it now. Otherwise it
1740 ;; will stay around until M-x list-processes.
1741 (delete-process proc)))
1742 (setq compilation-in-progress (delq proc compilation-in-progress)))))
55dfd2c4 1743
ad62b7f1
RM
1744(defun compilation-filter (proc string)
1745 "Process filter for compilation buffers.
20179516
SS
1746Just inserts the text,
1747handles carriage motion (see `comint-inhibit-carriage-motion'),
1748and runs `compilation-filter-hook'."
ec4e0abc
SM
1749 (when (buffer-live-p (process-buffer proc))
1750 (with-current-buffer (process-buffer proc)
1751 (let ((inhibit-read-only t)
1752 ;; `save-excursion' doesn't use the right insertion-type for us.
0b508a27
RS
1753 (pos (copy-marker (point) t))
1754 (min (point-min-marker))
1755 (max (point-max-marker)))
ec4e0abc
SM
1756 (unwind-protect
1757 (progn
0b508a27
RS
1758 ;; If we are inserting at the end of the accessible part
1759 ;; of the buffer, keep the inserted text visible.
1760 (set-marker-insertion-type max t)
1761 (widen)
ec4e0abc
SM
1762 (goto-char (process-mark proc))
1763 ;; We used to use `insert-before-markers', so that windows with
1764 ;; point at `process-mark' scroll along with the output, but we
1765 ;; now use window-point-insertion-type instead.
1766 (insert string)
20179516
SS
1767 (unless comint-inhibit-carriage-motion
1768 (comint-carriage-motion (process-mark proc) (point)))
ec4e0abc
SM
1769 (set-marker (process-mark proc) (point))
1770 (run-hooks 'compilation-filter-hook))
0b508a27
RS
1771 (goto-char pos)
1772 (narrow-to-region min max)
1773 (set-marker min nil)
1774 (set-marker max nil))))))
b5bb472e 1775
5d9f0de2
KS
1776;;; test if a buffer is a compilation buffer, assuming we're in the buffer
1777(defsubst compilation-buffer-internal-p ()
1778 "Test if inside a compilation buffer."
1779 (local-variable-p 'compilation-locs))
1780
1781;;; test if a buffer is a compilation buffer, using compilation-buffer-internal-p
51ba27e7 1782(defsubst compilation-buffer-p (buffer)
5d9f0de2
KS
1783 "Test if BUFFER is a compilation buffer."
1784 (with-current-buffer buffer
1785 (compilation-buffer-internal-p)))
7837c247 1786
060d5dc1
CY
1787(defmacro compilation-loop (< property-change 1+ error limit)
1788 `(let (opt)
1789 (while (,< n 0)
1790 (setq opt pt)
1791 (or (setq pt (,property-change pt 'message))
1792 ;; Handle the case where where the first error message is
1793 ;; at the start of the buffer, and n < 0.
1794 (if (or (eq (get-text-property ,limit 'message)
1795 (get-text-property opt 'message))
1796 (eq pt opt))
1797 (error ,error compilation-error)
1798 (setq pt ,limit)))
1799 ;; prop 'message usually has 2 changes, on and off, so
1800 ;; re-search if off
1801 (or (setq msg (get-text-property pt 'message))
1802 (if (setq pt (,property-change pt 'message nil ,limit))
1803 (setq msg (get-text-property pt 'message)))
1804 (error ,error compilation-error))
1805 (or (< (cadr msg) compilation-skip-threshold)
1806 (if different-file
1807 (eq (prog1 last (setq last (nth 2 (car msg))))
1808 last))
1809 (if compilation-skip-visited
b84acff6 1810 (nthcdr 5 (car msg)))
060d5dc1
CY
1811 (if compilation-skip-to-next-location
1812 (eq (car msg) loc))
1813 ;; count this message only if none of the above are true
1814 (setq n (,1+ n))))))
7837c247 1815
51c8ad03 1816(defun compilation-next-error (n &optional different-file pt)
646bd331 1817 "Move point to the next error in the compilation buffer.
d0048c60 1818This function does NOT find the source line like \\[next-error].
851231e9
DL
1819Prefix arg N says how many error messages to move forwards (or
1820backwards, if negative).
d0048c60
EZ
1821Optional arg DIFFERENT-FILE, if non-nil, means find next error for a
1822file that is different from the current one.
1823Optional arg PT, if non-nil, specifies the value of point to start
1824looking for the next message."
646bd331
RM
1825 (interactive "p")
1826 (or (compilation-buffer-p (current-buffer))
851231e9 1827 (error "Not in a compilation buffer"))
51c8ad03 1828 (or pt (setq pt (point)))
51c8ad03 1829 (let* ((msg (get-text-property pt 'message))
250962b3 1830 ;; `loc' is used by the compilation-loop macro.
51c8ad03
DP
1831 (loc (car msg))
1832 last)
7837c247
SM
1833 (if (zerop n)
1834 (unless (or msg ; find message near here
c536bb39
SM
1835 (setq msg (get-text-property (max (1- pt) (point-min))
1836 'message)))
7837c247 1837 (setq pt (previous-single-property-change pt 'message nil
c536bb39 1838 (line-beginning-position)))
b3a7f48f 1839 (unless (setq msg (get-text-property (max (1- pt) (point-min)) 'message))
7837c247 1840 (setq pt (next-single-property-change pt 'message nil
c536bb39 1841 (line-end-position)))
b3a7f48f
DP
1842 (or (setq msg (get-text-property pt 'message))
1843 (setq pt (point)))))
7837c247 1844 (setq last (nth 2 (car msg)))
51c8ad03
DP
1845 (if (>= n 0)
1846 (compilation-loop > next-single-property-change 1-
1847 (if (get-buffer-process (current-buffer))
1848 "No more %ss yet"
060d5dc1
CY
1849 "Moved past last %s")
1850 (point-max))
c536bb39
SM
1851 ;; Don't move "back" to message at or before point.
1852 ;; Pass an explicit (point-min) to make sure pt is non-nil.
1853 (setq pt (previous-single-property-change pt 'message nil (point-min)))
51c8ad03 1854 (compilation-loop < previous-single-property-change 1+
060d5dc1 1855 "Moved back before first %s" (point-min))))
7837c247
SM
1856 (goto-char pt)
1857 (or msg
1858 (error "No %s here" compilation-error))))
646bd331
RM
1859
1860(defun compilation-previous-error (n)
1861 "Move point to the previous error in the compilation buffer.
851231e9
DL
1862Prefix arg N says how many error messages to move backwards (or
1863forwards, if negative).
7837c247 1864Does NOT find the source line like \\[previous-error]."
646bd331
RM
1865 (interactive "p")
1866 (compilation-next-error (- n)))
1867
b5bb472e 1868(defun compilation-next-file (n)
24299582
DP
1869 "Move point to the next error for a different file than the current one.
1870Prefix arg N says how many files to move forwards (or backwards, if negative)."
b5bb472e 1871 (interactive "p")
7837c247 1872 (compilation-next-error n t))
b5bb472e
RM
1873
1874(defun compilation-previous-file (n)
24299582
DP
1875 "Move point to the previous error for a different file than the current one.
1876Prefix arg N says how many files to move backwards (or forwards, if negative)."
b5bb472e
RM
1877 (interactive "p")
1878 (compilation-next-file (- n)))
1879
55dfd2c4 1880(defun kill-compilation ()
b765ba64 1881 "Kill the process made by the \\[compile] or \\[grep] commands."
55dfd2c4 1882 (interactive)
d3cb357b 1883 (let ((buffer (compilation-find-buffer)))
55dfd2c4 1884 (if (get-buffer-process buffer)
d3cb357b 1885 (interrupt-process (get-buffer-process buffer))
bac3a1c9 1886 (error "The %s process is not running" (downcase mode-name)))))
d3cb357b 1887
9da85ee5 1888(defalias 'compile-mouse-goto-error 'compile-goto-error)
c536bb39 1889
9da85ee5
SM
1890(defun compile-goto-error (&optional event)
1891 "Visit the source for the error message at point.
7837c247 1892Use this command in a compilation log buffer. Sets the mark at point there."
9da85ee5 1893 (interactive (list last-input-event))
a6cd3f65 1894 (if event (posn-set-point (event-end event)))
d3cb357b 1895 (or (compilation-buffer-p (current-buffer))
851231e9 1896 (error "Not in a compilation buffer"))
b3a7f48f
DP
1897 (if (get-text-property (point) 'directory)
1898 (dired-other-window (car (get-text-property (point) 'directory)))
1899 (push-mark)
1900 (setq compilation-current-error (point))
942c40e3 1901 (next-error-internal)))
55dfd2c4 1902
749354f0 1903(defun compilation-find-buffer (&optional avoid-current)
7d1dad0c 1904 "Return a compilation buffer.
0dad3dfe
MR
1905If AVOID-CURRENT is nil, and the current buffer is a compilation buffer,
1906return it. If AVOID-CURRENT is non-nil, return the current buffer only
1907as a last resort."
1908 (if (and (compilation-buffer-internal-p) (not avoid-current))
7d1dad0c
RS
1909 (current-buffer)
1910 (next-error-find-buffer avoid-current 'compilation-buffer-internal-p)))
d3cb357b
RM
1911
1912;;;###autoload
5d9f0de2 1913(defun compilation-next-error-function (n &optional reset)
a5f1c37e
RS
1914 "Advance to the next error message and visit the file where the error was.
1915This is the value of `next-error-function' in Compilation buffers."
7837c247 1916 (interactive "p")
5d9f0de2
KS
1917 (when reset
1918 (setq compilation-current-error nil))
7837c247 1919 (let* ((columns compilation-error-screen-columns) ; buffer's local value
b84acff6 1920 (last 1) timestamp
51c8ad03 1921 (loc (compilation-next-error (or n 1) nil
9b7b51a2
SM
1922 (or compilation-current-error
1923 compilation-messages-start
1924 (point-min))))
7837c247
SM
1925 (end-loc (nth 2 loc))
1926 (marker (point-marker)))
51c8ad03 1927 (setq compilation-current-error (point-marker)
b3a7f48f
DP
1928 overlay-arrow-position
1929 (if (bolp)
1930 compilation-current-error
9b7b51a2 1931 (copy-marker (line-beginning-position)))
51c8ad03 1932 loc (car loc))
b84acff6
SS
1933 ;; If loc contains no marker, no error in that file has been visited.
1934 ;; If the marker is invalid the buffer has been killed.
1935 ;; If the file is newer than the timestamp, it has been modified
1936 ;; (`omake -P' polls filesystem for changes and recompiles when needed
1937 ;; in the same process and buffer).
1938 ;; So, recalculate all markers for that file.
1939 (unless (and (nth 3 loc) (marker-buffer (nth 3 loc))
77041513
SM
1940 ;; There may be no timestamp info if the loc is a `fake-loc'.
1941 ;; So we skip the time-check here, although we should maybe
1942 ;; change `compilation-fake-loc' to add timestamp info.
1943 (or (null (nth 4 loc))
1944 (equal (nth 4 loc)
1945 (setq timestamp
1946 (with-current-buffer
1947 (marker-buffer (nth 3 loc))
1948 (visited-file-modtime))))))
c536bb39 1949 (with-current-buffer (compilation-find-file marker (caar (nth 2 loc))
7957baea 1950 (cadr (car (nth 2 loc))))
7837c247
SM
1951 (save-restriction
1952 (widen)
c536bb39 1953 (goto-char (point-min))
7837c247
SM
1954 ;; Treat file's found lines in forward order, 1 by 1.
1955 (dolist (line (reverse (cddr (nth 2 loc))))
1956 (when (car line) ; else this is a filename w/o a line#
1957 (beginning-of-line (- (car line) last -1))
1958 (setq last (car line)))
1959 ;; Treat line's found columns and store/update a marker for each.
1960 (dolist (col (cdr line))
1961 (if (car col)
1962 (if (eq (car col) -1) ; special case for range end
1963 (end-of-line)
9c8e6c85 1964 (compilation-move-to-column (car col) columns))
7837c247
SM
1965 (beginning-of-line)
1966 (skip-chars-forward " \t"))
eb6fb6e2 1967 (if (nth 3 col)
7837c247
SM
1968 (set-marker (nth 3 col) (point))
1969 (setcdr (nthcdr 2 col) `(,(point-marker)))))))))
1970 (compilation-goto-locus marker (nth 3 loc) (nth 3 end-loc))
b84acff6
SS
1971 (setcdr (nthcdr 3 loc) (list timestamp))
1972 (setcdr (nthcdr 4 loc) t))) ; Set this one as visited.
7837c247 1973
e3bef839
SM
1974(defvar compilation-gcpro nil
1975 "Internal variable used to keep some values from being GC'd.")
1976(make-variable-buffer-local 'compilation-gcpro)
1977
eb6fb6e2
DP
1978(defun compilation-fake-loc (marker file &optional line col)
1979 "Preassociate MARKER with FILE.
dbd97672 1980FILE should be ABSOLUTE-FILENAME or (RELATIVE-FILENAME . DIRNAME).
eb6fb6e2
DP
1981This is useful when you compile temporary files, but want
1982automatic translation of the messages to the real buffer from
1983which the temporary file came. This only works if done before a
1984message about FILE appears!
1985
1986Optional args LINE and COL default to 1 and beginning of
1987indentation respectively. The marker is expected to reflect
1988this. In the simplest case the marker points to the first line
1989of the region that was saved to the temp file.
1990
1991If you concatenate several regions into the temp file (e.g. a
1992header with variable assignments and a code region), you must
1993call this several times, once each for the last line of one
1994region and the first line of the next region."
1995 (or (consp file) (setq file (list file)))
dbd97672 1996 (setq file (compilation-get-file-structure file))
e3bef839 1997 ;; Between the current call to compilation-fake-loc and the first occurrence
77041513 1998 ;; of an error message referring to `file', the data is only kept in the
e3bef839
SM
1999 ;; weak hash-table compilation-locs, so we need to prevent this entry
2000 ;; in compilation-locs from being GC'd away. --Stef
2001 (push file compilation-gcpro)
eb6fb6e2
DP
2002 (let ((loc (compilation-assq (or line 1) (cdr file))))
2003 (setq loc (compilation-assq col loc))
2004 (if (cdr loc)
2005 (setcdr (cddr loc) (list marker))
dbd97672 2006 (setcdr loc (list line file marker)))
eb6fb6e2
DP
2007 loc))
2008
8b71e4d1
NR
2009(defcustom compilation-context-lines nil
2010 "Display this many lines of leading context before the current message.
2011If nil and the left fringe is displayed, don't scroll the
2012compilation output window; an arrow in the left fringe points to
2013the current message. If nil and there is no left fringe, the message
2014displays at the top of the window; there is no arrow."
a3a9c080 2015 :type '(choice integer (const :tag "No window scrolling" nil))
f6164cdd 2016 :group 'compilation
bf247b6e 2017 :version "22.1")
7837c247
SM
2018
2019(defsubst compilation-set-window (w mk)
6f5b7627 2020 "Align the compilation output window W with marker MK near top."
a3a9c080
JL
2021 (if (integerp compilation-context-lines)
2022 (set-window-start w (save-excursion
8b71e4d1
NR
2023 (goto-char mk)
2024 (beginning-of-line
2025 (- 1 compilation-context-lines))
2026 (point)))
3c9e7f42
RS
2027 ;; If there is no left fringe.
2028 (if (equal (car (window-fringes)) 0)
8b71e4d1
NR
2029 (set-window-start w (save-excursion
2030 (goto-char mk)
2031 (beginning-of-line 1)
2032 (point)))))
2033 (set-window-point w mk))
7837c247 2034
0ea50e43
RS
2035(defvar next-error-highlight-timer)
2036
7837c247 2037(defun compilation-goto-locus (msg mk end-mk)
6f5b7627 2038 "Jump to an error corresponding to MSG at MK.
9dc3a46a
JL
2039All arguments are markers. If END-MK is non-nil, mark is set there
2040and overlay is highlighted between MK and END-MK."
eaa3cac5 2041 ;; Show compilation buffer in other window, scrolled to this error.
e5456e73
SM
2042 (let* ((from-compilation-buffer (eq (window-buffer (selected-window))
2043 (marker-buffer msg)))
2044 ;; Use an existing window if it is in a visible frame.
7bbbd31f 2045 (pre-existing (get-buffer-window (marker-buffer msg) 0))
e5456e73
SM
2046 (w (if (and from-compilation-buffer pre-existing)
2047 ;; Calling display-buffer here may end up (partly) hiding
2048 ;; the error location if the two buffers are in two
2049 ;; different frames. So don't do it if it's not necessary.
2050 pre-existing
2051 (let ((display-buffer-reuse-frames t)
2052 (pop-up-windows t))
2053 ;; Pop up a window.
2054 (display-buffer (marker-buffer msg)))))
7837c247
SM
2055 (highlight-regexp (with-current-buffer (marker-buffer msg)
2056 ;; also do this while we change buffer
2057 (compilation-set-window w msg)
9ac57479 2058 compilation-highlight-regexp)))
7bbbd31f
SM
2059 ;; Ideally, the window-size should be passed to `display-buffer' (via
2060 ;; something like special-display-buffer) so it's only used when
2061 ;; creating a new window.
2062 (unless pre-existing (compilation-set-window-height w))
9ac57479 2063
e5456e73
SM
2064 (if from-compilation-buffer
2065 ;; If the compilation buffer window was selected,
2066 ;; keep the compilation buffer in this window;
2067 ;; display the source in another window.
2068 (let ((pop-up-windows t))
2069 (pop-to-buffer (marker-buffer mk) 'other-window))
2070 (if (window-dedicated-p (selected-window))
2071 (pop-to-buffer (marker-buffer mk))
2072 (switch-to-buffer (marker-buffer mk))))
2073 ;; If narrowing gets in the way of going to the right place, widen.
2074 (unless (eq (goto-char mk) (point))
2075 (widen)
2076 (goto-char mk))
2077 (if end-mk
2078 (push-mark end-mk t)
2079 (if mark-active (setq mark-active)))
2080 ;; If hideshow got in the way of
2081 ;; seeing the right place, open permanently.
2082 (dolist (ov (overlays-at (point)))
2083 (when (eq 'hs (overlay-get ov 'invisible))
2084 (delete-overlay ov)
2085 (goto-char mk)))
2086
9dc3a46a 2087 (when highlight-regexp
073fcaf6
JL
2088 (if (timerp next-error-highlight-timer)
2089 (cancel-timer next-error-highlight-timer))
9ac57479 2090 (unless compilation-highlight-overlay
c536bb39
SM
2091 (setq compilation-highlight-overlay
2092 (make-overlay (point-min) (point-min)))
2beb6aa0 2093 (overlay-put compilation-highlight-overlay 'face 'next-error))
7837c247 2094 (with-current-buffer (marker-buffer mk)
9ac57479 2095 (save-excursion
9dc3a46a 2096 (if end-mk (goto-char end-mk) (end-of-line))
c536bb39 2097 (let ((end (point)))
9dc3a46a 2098 (if mk (goto-char mk) (beginning-of-line))
9ac57479 2099 (if (and (stringp highlight-regexp)
7837c247 2100 (re-search-forward highlight-regexp end t))
9ac57479
KS
2101 (progn
2102 (goto-char (match-beginning 0))
2beb6aa0
JL
2103 (move-overlay compilation-highlight-overlay
2104 (match-beginning 0) (match-end 0)
2105 (current-buffer)))
2106 (move-overlay compilation-highlight-overlay
2107 (point) end (current-buffer)))
63522e3a
RS
2108 (if (or (eq next-error-highlight t)
2109 (numberp next-error-highlight))
2110 ;; We want highlighting: delete overlay on next input.
2111 (add-hook 'pre-command-hook
2112 'compilation-goto-locus-delete-o)
2113 ;; We don't want highlighting: delete overlay now.
2114 (delete-overlay compilation-highlight-overlay))
2115 ;; We want highlighting for a limited time:
2116 ;; set up a timer to delete it.
2117 (when (numberp next-error-highlight)
2118 (setq next-error-highlight-timer
2119 (run-at-time next-error-highlight nil
2120 'compilation-goto-locus-delete-o)))))))
2beb6aa0 2121 (when (and (eq next-error-highlight 'fringe-arrow))
63522e3a 2122 ;; We want a fringe arrow (instead of highlighting).
6a1cdc5b
JL
2123 (setq next-error-overlay-arrow-position
2124 (copy-marker (line-beginning-position))))))
2125
63522e3a
RS
2126(defun compilation-goto-locus-delete-o ()
2127 (delete-overlay compilation-highlight-overlay)
2128 ;; Get rid of timer and hook that would try to do this again.
2129 (if (timerp next-error-highlight-timer)
2130 (cancel-timer next-error-highlight-timer))
2131 (remove-hook 'pre-command-hook
2132 'compilation-goto-locus-delete-o))
eaa3cac5 2133\f
7957baea 2134(defun compilation-find-file (marker filename directory &rest formats)
851231e9 2135 "Find a buffer for file FILENAME.
5099d512
EZ
2136If FILENAME is not found at all, ask the user where to find it.
2137Pop up the buffer containing MARKER and scroll to MARKER if we ask
2138the user where to find the file.
ffb4b7a1
SM
2139Search the directories in `compilation-search-path'.
2140A nil in `compilation-search-path' means to try the
7957baea 2141\"current\" directory, which is passed in DIRECTORY.
f441be5b
JB
2142If DIRECTORY is relative, it is combined with `default-directory'.
2143If DIRECTORY is nil, that means use `default-directory'.
5099d512
EZ
2144FORMATS, if given, is a list of formats to reformat FILENAME when
2145looking for it: for each element FMT in FORMATS, this function
2146attempts to find a file whose name is produced by (format FMT FILENAME)."
20c1daec 2147 (or formats (setq formats '("%s")))
b8fa0ffd
SM
2148 (let ((dirs compilation-search-path)
2149 (spec-dir (if directory
2150 (expand-file-name directory)
2151 default-directory))
2152 buffer thisdir fmts name)
2153 (if (file-name-absolute-p filename)
2154 ;; The file name is absolute. Use its explicit directory as
2155 ;; the first in the search path, and strip it from FILENAME.
2156 (setq filename (abbreviate-file-name (expand-file-name filename))
2157 dirs (cons (file-name-directory filename) dirs)
2158 filename (file-name-nondirectory filename)))
2159 ;; Now search the path.
2160 (while (and dirs (null buffer))
2161 (setq thisdir (or (car dirs) spec-dir)
2162 fmts formats)
2163 ;; For each directory, try each format string.
2164 (while (and fmts (null buffer))
2165 (setq name (expand-file-name (format (car fmts) filename) thisdir)
2166 buffer (and (file-exists-p name)
2167 (find-file-noselect name))
2168 fmts (cdr fmts)))
2169 (setq dirs (cdr dirs)))
f65b9df2
SM
2170 (while (null buffer) ;Repeat until the user selects an existing file.
2171 ;; The file doesn't exist. Ask the user where to find it.
2172 (save-excursion ;This save-excursion is probably not right.
2173 (let ((pop-up-windows t))
2174 (compilation-set-window (display-buffer (marker-buffer marker))
2175 marker)
2176 (let* ((name (read-file-name
2177 (format "Find this %s in (default %s): "
2178 compilation-error filename)
44038dc8
SM
2179 spec-dir filename t nil
2180 ;; The predicate below is fine when called from
2181 ;; minibuffer-complete-and-exit, but it's too
2182 ;; restrictive otherwise, since it also prevents the
2183 ;; user from completing "fo" to "foo/" when she
2184 ;; wants to enter "foo/bar".
f441be5b 2185 ;;
44038dc8
SM
2186 ;; Try to make sure the user can only select
2187 ;; a valid answer. This predicate may be ignored,
2188 ;; tho, so we still have to double-check afterwards.
2189 ;; TODO: We should probably fix read-file-name so
2190 ;; that it never ignores this predicate, even when
2191 ;; using popup dialog boxes.
2192 ;; (lambda (name)
2193 ;; (if (file-directory-p name)
2194 ;; (setq name (expand-file-name filename name)))
2195 ;; (file-exists-p name))
2196 ))
f65b9df2
SM
2197 (origname name))
2198 (cond
2199 ((not (file-exists-p name))
2200 (message "Cannot find file `%s'" name)
2201 (ding) (sit-for 2))
2202 ((and (file-directory-p name)
2203 (not (file-exists-p
2204 (setq name (expand-file-name filename name)))))
2205 (message "No `%s' in directory %s" filename origname)
2206 (ding) (sit-for 2))
2207 (t
2208 (setq buffer (find-file-noselect name))))))))
b8fa0ffd 2209 ;; Make intangible overlays tangible.
f65b9df2
SM
2210 ;; This is weird: it's not even clear which is the current buffer,
2211 ;; so the code below can't be expected to DTRT here. -- Stef
2212 (dolist (ov (overlays-in (point-min) (point-max)))
2213 (when (overlay-get ov 'intangible)
2214 (overlay-put ov 'intangible nil)))
b8fa0ffd 2215 buffer))
721cfafe 2216
dbd97672
DP
2217(defun compilation-get-file-structure (file &optional fmt)
2218 "Retrieve FILE's file-structure or create a new one.
7957baea
RS
2219FILE should be (FILENAME) or (RELATIVE-FILENAME . DIRNAME).
2220In the former case, FILENAME may be relative or absolute.
dbd97672 2221
7957baea 2222The file-structure looks like this:
34a9bf20 2223 (list (list FILENAME [DIR-FROM-PREV-MSG]) FMT LINE-STRUCT...)"
dbd97672
DP
2224 (or (gethash file compilation-locs)
2225 ;; File was not previously encountered, at least not in the form passed.
2226 ;; Let's normalize it and look again.
2227 (let ((filename (car file))
7957baea
RS
2228 ;; Get the specified directory from FILE.
2229 (spec-directory (if (cdr file)
2230 (file-truename (cdr file)))))
dbd97672
DP
2231
2232 ;; Check for a comint-file-name-prefix and prepend it if appropriate.
2233 ;; (This is very useful for compilation-minor-mode in an rlogin-mode
2234 ;; buffer.)
7957baea
RS
2235 (when (and (boundp 'comint-file-name-prefix)
2236 (not (equal comint-file-name-prefix "")))
2237 (if (file-name-absolute-p filename)
2238 (setq filename
2239 (concat comint-file-name-prefix filename))
2240 (if spec-directory
2241 (setq spec-directory
2242 (file-truename
2243 (concat comint-file-name-prefix spec-directory))))))
dbd97672
DP
2244
2245 ;; If compilation-parse-errors-filename-function is
2246 ;; defined, use it to process the filename.
2247 (when compilation-parse-errors-filename-function
2248 (setq filename
2249 (funcall compilation-parse-errors-filename-function
2250 filename)))
2251
2252 ;; Some compilers (e.g. Sun's java compiler, reportedly) produce bogus
2253 ;; file names like "./bar//foo.c" for file "bar/foo.c";
2254 ;; expand-file-name will collapse these into "/foo.c" and fail to find
2255 ;; the appropriate file. So we look for doubled slashes in the file
2256 ;; name and fix them.
2257 (setq filename (command-line-normalize-file-name filename))
2258
dbd97672
DP
2259 ;; Store it for the possibly unnormalized name
2260 (puthash file
2261 ;; Retrieve or create file-structure for normalized name
e68b1841
GM
2262 ;; The gethash used to not use spec-directory, but
2263 ;; this leads to errors when files in different
2264 ;; directories have the same name:
2265 ;; http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00463.html
2266 (or (gethash (cons filename spec-directory) compilation-locs)
34a9bf20 2267 (puthash (cons filename spec-directory)
7957baea
RS
2268 (list (list filename spec-directory) fmt)
2269 compilation-locs))
dbd97672 2270 compilation-locs))))
51501e54 2271
7837c247 2272(add-to-list 'debug-ignored-errors "^No more [-a-z ]+s yet$")
f1ed9461 2273
c536bb39
SM
2274;;; Compatibility with the old compile.el.
2275
2276(defun compile-buffer-substring (n) (if n (match-string n)))
2277
2278(defun compilation-compat-error-properties (err)
6f5b7627 2279 "Map old-style error ERR to new-style message."
efb0e677
SM
2280 ;; Old-style structure is (MARKER (FILE DIR) LINE COL) or
2281 ;; (MARKER . MARKER).
2282 (let ((dst (cdr err)))
2283 (if (markerp dst)
2284 ;; Must start with a face, for font-lock.
2285 `(face nil
2286 message ,(list (list nil nil nil dst) 2)
2287 help-echo "mouse-2: visit the source location"
2288 keymap compilation-button-map
2289 mouse-face highlight)
2290 ;; Too difficult to do it by hand: dispatch to the normal code.
2291 (let* ((file (pop dst))
2292 (line (pop dst))
2293 (col (pop dst))
2294 (filename (pop file))
2295 (dirname (pop file))
2296 (fmt (pop file)))
2297 (compilation-internal-error-properties
2298 (cons filename dirname) line nil col nil 2 fmt)))))
c536bb39
SM
2299
2300(defun compilation-compat-parse-errors (limit)
2301 (when compilation-parse-errors-function
2302 ;; FIXME: We should remove the rest of the compilation keywords
2303 ;; but we can't do that from here because font-lock is using
2304 ;; the value right now. --stef
2305 (save-excursion
2306 (setq compilation-error-list nil)
2307 ;; Reset compilation-parsing-end each time because font-lock
2308 ;; might force us the re-parse many times (typically because
2309 ;; some code adds some text-property to the output that we
2310 ;; already parsed). You might say "why reparse", well:
2311 ;; because font-lock has just removed the `message' property so
2312 ;; have to do it all over again.
2313 (if compilation-parsing-end
2314 (set-marker compilation-parsing-end (point))
2315 (setq compilation-parsing-end (point-marker)))
2316 (condition-case nil
2317 ;; Ignore any error: we're calling this function earlier than
2318 ;; in the old compile.el so things might not all be setup yet.
2319 (funcall compilation-parse-errors-function limit nil)
2320 (error nil))
2321 (dolist (err (if (listp compilation-error-list) compilation-error-list))
2322 (let* ((src (car err))
2323 (dst (cdr err))
2324 (loc (cond ((markerp dst) (list nil nil nil dst))
2325 ((consp dst)
2326 (list (nth 2 dst) (nth 1 dst)
2327 (cons (cdar dst) (caar dst)))))))
2328 (when loc
2329 (goto-char src)
2330 ;; (put-text-property src (line-end-position) 'font-lock-face 'font-lock-warning-face)
2331 (put-text-property src (line-end-position)
2332 'message (list loc 2)))))))
2333 (goto-char limit)
2334 nil)
2335
9b7b51a2 2336;; Beware: this is not only compatiblity code. New code stil uses it. --Stef
c536bb39
SM
2337(defun compilation-forget-errors ()
2338 ;; In case we hit the same file/line specs, we want to recompute a new
2339 ;; marker for them, so flush our cache.
b3a7f48f 2340 (setq compilation-locs (make-hash-table :test 'equal :weakness 'value))
e3bef839 2341 (setq compilation-gcpro nil)
c536bb39
SM
2342 ;; FIXME: the old code reset the directory-stack, so maybe we should
2343 ;; put a `directory change' marker of some sort, but where? -stef
b3a7f48f 2344 ;;
c536bb39
SM
2345 ;; FIXME: The old code moved compilation-current-error (which was
2346 ;; virtually represented by a mix of compilation-parsing-end and
2347 ;; compilation-error-list) to point-min, but that was only meaningful for
2348 ;; the internal uses of compilation-forget-errors: all calls from external
2349 ;; packages seem to be followed by a move of compilation-parsing-end to
b956d64f 2350 ;; something equivalent to point-max. So we heuristically move
c536bb39 2351 ;; compilation-current-error to point-max (since the external package
b956d64f 2352 ;; won't know that it should do it). --Stef
9b7b51a2
SM
2353 (setq compilation-current-error nil)
2354 (let* ((proc (get-buffer-process (current-buffer)))
2355 (mark (if proc (process-mark proc)))
2356 (pos (or mark (point-max))))
2357 (setq compilation-messages-start
2358 ;; In the future, ignore the text already present in the buffer.
2359 ;; Since many process filter functions insert before markers,
2360 ;; we need to put ours just before the insertion point rather
2361 ;; than at the insertion point. If that's not possible, then
2362 ;; don't use a marker. --Stef
b956d64f
SM
2363 (if (> pos (point-min)) (copy-marker (1- pos)) pos)))
2364 ;; Again, since this command is used in buffers that contain several
2365 ;; compilations, to set the beginning of "this compilation", it's a good
2366 ;; place to reset compilation-auto-jump-to-next.
2367 (set (make-local-variable 'compilation-auto-jump-to-next)
78dc87a2
JL
2368 (or compilation-auto-jump-to-first-error
2369 (eq compilation-scroll-output 'first-error))))
c536bb39 2370
0c9a01ff
MY
2371;;;###autoload
2372(add-to-list 'auto-mode-alist '("\\.gcov\\'" . compilation-mode))
2373
4746118a 2374(provide 'compile)
fad160d5 2375
822001db 2376;; arch-tag: 12465727-7382-4f72-b234-79855a00dd8c
fad160d5 2377;;; compile.el ends here