compile.el 82.6 KB
Newer Older
1
;;; compile.el --- run compiler as inferior of Emacs, parse error messages
Eric S. Raymond's avatar
Eric S. Raymond committed
2

3
;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 97, 98, 1999, 2001 Free Software Foundation, Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
4

5
;; Author: Roland McGrath <roland@gnu.org>
Eric S. Raymond's avatar
Eric S. Raymond committed
6
;; Maintainer: FSF
Eric S. Raymond's avatar
Eric S. Raymond committed
7
;; Keywords: tools, processes
Eric S. Raymond's avatar
Eric S. Raymond committed
8

Richard M. Stallman's avatar
Richard M. Stallman committed
9 10
;; This file is part of GNU Emacs.

Roland McGrath's avatar
Roland McGrath committed
11 12 13 14 15
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

Richard M. Stallman's avatar
Richard M. Stallman committed
16
;; GNU Emacs is distributed in the hope that it will be useful,
Roland McGrath's avatar
Roland McGrath committed
17 18 19 20 21
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
Erik Naggum's avatar
Erik Naggum committed
22 23 24
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
Richard M. Stallman's avatar
Richard M. Stallman committed
25

Eric S. Raymond's avatar
Eric S. Raymond committed
26 27 28 29 30
;;; Commentary:

;; This package provides the compile and grep facilities documented in
;; the Emacs user's manual.

Eric S. Raymond's avatar
Eric S. Raymond committed
31 32
;;; Code:

33 34 35 36 37 38
(defgroup compilation nil
  "Run compiler as inferior of Emacs, parse error messages."
  :group 'tools
  :group 'processes)


Roland McGrath's avatar
Roland McGrath committed
39
;;;###autoload
40 41 42 43
(defcustom compilation-mode-hook nil
  "*List of hook functions run by `compilation-mode' (see `run-hooks')."
  :type 'hook
  :group 'compilation)
Roland McGrath's avatar
Roland McGrath committed
44 45

;;;###autoload
46 47 48 49 50
(defcustom compilation-window-height nil
  "*Number of lines in a compilation window.  If nil, use Emacs default."
  :type '(choice (const :tag "Default" nil)
		 integer)
  :group 'compilation)
Roland McGrath's avatar
Roland McGrath committed
51

52
(defcustom compile-auto-highlight nil
53
  "*Specify how many compiler errors to highlight (and parse) initially.
54
\(Highlighting applies to an error message when the mouse is over it.)
55 56
If this is a number N, all compiler error messages in the first N lines
are highlighted and parsed as soon as they arrive in Emacs.
57
If t, highlight and parse the whole compilation output as soon as it arrives.
58 59 60
If nil, don't highlight or parse any of the buffer until you try to
move to the error messages.

61
Those messages which are not parsed and highlighted initially
62 63 64 65 66
will be parsed and highlighted as soon as you try to move to them."
  :type '(choice (const :tag "All" t)
		 (const :tag "None" nil)
		 (integer :tag "First N lines"))
  :group 'compilation)
67

68 69
(defcustom grep-command nil
  "The default grep command for \\[grep].
70 71 72 73
If the grep program used supports an option to always include file names
in its output (such as the `-H' option to GNU grep), it's a good idea to
include it when specifying `grep-command'.

74 75 76 77 78 79 80 81
The default value of this variable is set up by `grep-compute-defaults';
call that function before using this variable in your program."
  :type 'string
  :get '(lambda (symbol)
	  (or grep-command
	      (progn (grep-compute-defaults) grep-command)))
  :group 'compilation)

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
(defcustom grep-use-null-device 'auto-detect
  "If non-nil, append the value of `null-device' to grep commands.
This is done to ensure that the output of grep includes the filename of
any match in the case where only a single file is searched, and is not
necessary if the grep program used supports the `-H' option.

The default value of this variable is set up by `grep-compute-defaults';
call that function before using this variable in your program."
  :type 'boolean
  :get '(lambda (symbol)
	  (if (and grep-use-null-device (not (eq grep-use-null-device t)))
	      (progn (grep-compute-defaults) grep-use-null-device)
	    grep-use-null-device))
  :group 'compilation)

97 98 99 100 101 102 103 104 105 106
(defcustom grep-find-command nil
  "The default find command for \\[grep-find].
The default value of this variable is set up by `grep-compute-defaults';
call that function before using this variable in your program."
  :type 'string
  :get (lambda (symbol)
	 (or grep-find-command
	     (progn (grep-compute-defaults) grep-find-command)))
  :group 'compilation)

Richard M. Stallman's avatar
Richard M. Stallman committed
107 108
(defvar compilation-error-list nil
  "List of error message descriptors for visiting erring functions.
109 110
Each error descriptor is a cons (or nil).  Its car is a marker pointing to
an error message.  If its cdr is a marker, it points to the text of the
111 112 113
line the message is about.  If its cdr is a cons, it is a list
\(\(DIRECTORY . FILE\) LINE [COLUMN]\).  Or its cdr may be nil if that
error is not interesting.
Roland McGrath's avatar
Roland McGrath committed
114 115

The value may be t instead of a list; this means that the buffer of
Jim Blandy's avatar
Jim Blandy committed
116 117 118
error messages should be reparsed the next time the list of errors is wanted.

Some other commands (like `diff') use this list to control the error
119
message tracking facilities; if you change its structure, you should make
Jim Blandy's avatar
Jim Blandy committed
120 121
sure you also change those packages.  Perhaps it is better not to change
it at all.")
Richard M. Stallman's avatar
Richard M. Stallman committed
122 123 124 125

(defvar compilation-old-error-list nil
  "Value of `compilation-error-list' after errors were parsed.")

126
(defvar compilation-parse-errors-function 'compilation-parse-errors
Roland McGrath's avatar
Roland McGrath committed
127
  "Function to call to parse error messages from a compilation.
Roland McGrath's avatar
Roland McGrath committed
128 129
It takes args LIMIT-SEARCH and FIND-AT-LEAST.
If LIMIT-SEARCH is non-nil, don't bother parsing past that location.
130
If FIND-AT-LEAST is non-nil, don't bother parsing after finding that
131
many new errors.
Roland McGrath's avatar
Roland McGrath committed
132 133 134
It should read in the source files which have errors and set
`compilation-error-list' to a list with an element for each error message
found.  See that variable for more info.")
Richard M. Stallman's avatar
Richard M. Stallman committed
135

136 137 138 139 140 141 142
;;;###autoload
(defvar compilation-process-setup-function nil
  "*Function to call to customize the compilation process.
This functions is called immediately before the compilation process is
started.  It can be used to set any variables or functions that are used
while processing the output of the compilation process.")

Jim Blandy's avatar
Jim Blandy committed
143
;;;###autoload
Roland McGrath's avatar
Roland McGrath committed
144
(defvar compilation-buffer-name-function nil
Richard M. Stallman's avatar
Richard M. Stallman committed
145 146 147 148
  "Function to compute the name of a compilation buffer.
The function receives one argument, the name of the major mode of the
compilation buffer.  It should return a string.
nil means compute the name with `(concat \"*\" (downcase major-mode) \"*\")'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
149

Jim Blandy's avatar
Jim Blandy committed
150
;;;###autoload
Roland McGrath's avatar
Roland McGrath committed
151
(defvar compilation-finish-function nil
152
  "Function to call when a compilation process finishes.
Roland McGrath's avatar
Roland McGrath committed
153 154
It is called with two arguments: the compilation buffer, and a string
describing how the process finished.")
Richard M. Stallman's avatar
Richard M. Stallman committed
155

156 157
;;;###autoload
(defvar compilation-finish-functions nil
158
  "Functions to call when a compilation process finishes.
159 160 161
Each function is called with two arguments: the compilation buffer,
and a string describing how the process finished.")

Roland McGrath's avatar
Roland McGrath committed
162
(defvar compilation-last-buffer nil
Richard M. Stallman's avatar
Richard M. Stallman committed
163 164 165
  "The most recent compilation buffer.
A buffer becomes most recent when its compilation is started
or when it is used with \\[next-error] or \\[compile-goto-error].")
Richard M. Stallman's avatar
Richard M. Stallman committed
166

Roland McGrath's avatar
Roland McGrath committed
167 168 169 170 171 172
(defvar compilation-in-progress nil
  "List of compilation processes now running.")
(or (assq 'compilation-in-progress minor-mode-alist)
    (setq minor-mode-alist (cons '(compilation-in-progress " Compiling")
				 minor-mode-alist)))

Roland McGrath's avatar
Roland McGrath committed
173
(defvar compilation-parsing-end nil
174
  "Marker position of end of buffer when last error messages were parsed.")
Roland McGrath's avatar
Roland McGrath committed
175 176

(defvar compilation-error-message "No more errors"
Richard M. Stallman's avatar
Richard M. Stallman committed
177 178
  "Message to print when no more matches are found.")

179 180 181
(defvar compilation-arguments nil
  "Arguments that were given to `compile-internal'.")

Richard M. Stallman's avatar
Richard M. Stallman committed
182
(defvar compilation-num-errors-found)
Roland McGrath's avatar
Roland McGrath committed
183 184 185

(defvar compilation-error-regexp-alist
  '(
186
    ;; NOTE!  See also grep-regexp-alist, below.
187

Roland McGrath's avatar
Roland McGrath committed
188
    ;; 4.3BSD grep, cc, lint pass 1:
189 190 191 192 193
    ;; 	/usr/src/foo/foo.c(8): warning: w may be used before set
    ;; or GNU utilities:
    ;; 	foo.c:8: error message
    ;; or HP-UX 7.0 fc:
    ;; 	foo.f          :16    some horrible error message
194 195
    ;; or GNU utilities with column (GNAT 1.82):
    ;;   foo.adb:2:1: Unit name does not match file name
196 197
    ;; or with column and program name:
    ;;   jade:dbcommon.dsl:133:17:E: missing argument for function call
198
    ;;
199 200 201
    ;; We'll insist that the number be followed by a colon or closing
    ;; paren, because otherwise this matches just about anything
    ;; containing a number with spaces around it.
202 203 204 205

    ;; We insist on a non-digit in the file name
    ;; so that we don't mistake the file name for a command name
    ;; and take the line number as the file name.
206
    ("\\([a-zA-Z][-a-zA-Z._0-9]+: ?\\)?\
207
\\([a-zA-Z]?:?[^:( \t\n]*[^:( \t\n0-9][^:( \t\n]*\\)[:(][ \t]*\\([0-9]+\\)\
208
\\([) \t]\\|:\\(\\([0-9]+:\\)\\|[0-9]*[^:0-9]\\)\\)" 2 3 6)
209

210 211 212
    ;; Microsoft C/C++:
    ;;  keyboard.c(537) : warning C4005: 'min' : macro redefinition
    ;;  d:\tmp\test.c(23) : error C2143: syntax error : missing ';' before 'if'
213 214 215
    ;; This used to be less selective and allow characters other than
    ;; parens around the line number, but that caused confusion for
    ;; GNU-style error messages.
216
    ;; This used to reject spaces and dashes in file names,
217
    ;; but they are valid now; so I made it more strict about the error
218 219 220
    ;; message that follows.
    ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \
: \\(error\\|warning\\) C[0-9]+:" 1 3)
221

222
    ;; Borland C++, C++Builder:
223 224
    ;;  Error ping.c 15: Unable to open include file 'sys/types.h'
    ;;  Warning ping.c 68: Call to function 'func' with no prototype
225 226 227 228 229
    ;;  Error E2010 ping.c 15: Unable to open include file 'sys/types.h'
    ;;  Warning W1022 ping.c 68: Call to function 'func' with no prototype
    ("\\(Error\\|Warning\\) \\(\\([FEW][0-9]+\\) \\)?\
\\([a-zA-Z]?:?[^:( \t\n]+\\)\
 \\([0-9]+\\)\\([) \t]\\|:[^0-9\n]\\)" 4 5)
230

Roland McGrath's avatar
Roland McGrath committed
231
    ;; 4.3BSD lint pass 2
232
    ;; 	strcmp: variable # of args. llib-lc(359)  ::  /usr/src/foo/foo.c(8)
233
    (".*[ \t:]\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(](+[ \t]*\\([0-9]+\\))[:) \t]*$"
234
     1 2)
235

Roland McGrath's avatar
Roland McGrath committed
236
    ;; 4.3BSD lint pass 3
237
    ;; 	bloofle defined( /users/wolfgang/foo.c(4) ), but never used
Jim Blandy's avatar
Jim Blandy committed
238
    ;; This used to be
239
    ;; ("[ \t(]+\\([a-zA-Z]?:?[^:( \t\n]+\\)[:( \t]+\\([0-9]+\\)[:) \t]+" 1 2)
Jim Blandy's avatar
Jim Blandy committed
240
    ;; which is regexp Impressionism - it matches almost anything!
241
    (".*([ \t]*\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\))" 1 2)
242

243 244
    ;; MIPS lint pass<n>; looks good for SunPro lint also
    ;;  TrimMask (255) in solomon.c may be indistinguishable from TrimMasks (93) in solomon.c due to truncation
245
    ("[^\n ]+ (\\([0-9]+\\)) in \\([^ \n]+\\)" 2 1)
246
    ;;  name defined but never used: LinInt in cmap_calc.c(199)
247
    (".*in \\([^(\n]+\\)(\\([0-9]+\\))$" 1 2)
248

249
    ;; Ultrix 3.0 f77:
250
    ;;  fort: Severe: addstf.f, line 82: Missing operator or delimiter symbol
251 252
    ;; Some SGI cc version:
    ;;  cfe: Warning 835: foo.c, line 2: something
253
    ("\\(cfe\\|fort\\): [^:\n]*: \\([^ \n]*\\), line \\([0-9]+\\):" 2 3)
254
    ;;  Error on line 3 of t.f: Execution error unclassifiable statement
255
    ;; Unknown who does this:
256
    ;;  Line 45 of "foo.c": bloofle undefined
257 258 259
    ;; Absoft FORTRAN 77 Compiler 3.1.3
    ;;  error on line 19 of fplot.f: spelling error?
    ;;  warning on line 17 of fplot.f: data type is undefined for variable d
260
    ("\\(.* on \\)?[Ll]ine[ \t]+\\([0-9]+\\)[ \t]+\
261
of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2)
262 263 264

    ;; Apollo cc, 4.3BSD fc:
    ;;	"foo.f", line 3: Error: syntax error near end of statement
265 266
    ;; IBM RS6000:
    ;;  "vvouch.c", line 19.5: 1506-046 (S) Syntax error.
267 268
    ;; Microtec mcc68k:
    ;;  "foo.c", line 32 pos 1; (E) syntax error; unexpected symbol: "lossage"
269
    ;; GNAT (as of July 94):
270
    ;;  "foo.adb", line 2(11): warning: file name does not match ...
271 272
    ;; IBM AIX xlc compiler:
    ;;  "src/swapping.c", line 30.34: 1506-342 (W) "/*" detected in comment.
273
    (".*\"\\([^,\" \n\t]+\\)\", lines? \
274
\\([0-9]+\\)\\([\(.]\\([0-9]+\\)\)?\\)?[:., (-]" 1 2 4)
275

276 277 278 279
    ;; Caml compiler:
    ;;  File "foobar.ml", lines 5-8, characters 20-155: blah blah
   ("^File \"\\([^,\" \n\t]+\\)\", lines? \\([0-9]+\\)[-0-9]*, characters? \\([0-9]+\\)" 1 2 3)

280
    ;; MIPS RISC CC - the one distributed with Ultrix:
281
    ;;	ccom: Error: foo.c, line 2: syntax error
282
    ;; DEC AXP OSF/1 cc
283
    ;;  /usr/lib/cmplrs/cc/cfe: Error: foo.c: 1: blah blah
284
    ("[a-z0-9/]+: \\([eE]rror\\|[wW]arning\\): \\([^,\" \n\t]+\\)[,:] \\(line \\)?\\([0-9]+\\):" 2 4)
285 286 287

    ;; IBM AIX PS/2 C version 1.1:
    ;;	****** Error number 140 in line 8 of file errors.c ******
288
    (".*in line \\([0-9]+\\) of file \\([^ \n]+[^. \n]\\)\\.? " 2 1)
Roland McGrath's avatar
Roland McGrath committed
289 290
    ;; IBM AIX lint is too painful to do right this way.  File name
    ;; prefixes entire sections rather than being on each line.
291

292 293 294 295 296 297 298 299 300 301
    ;; SPARCcompiler Pascal:
    ;;           20      linjer      : array[1..4] of linje;
    ;; e 18480-----------^---  Inserted ';'
    ;; and
    ;; E 18520 line 61 -  0 is undefined
    ;; These messages don't contain a file name. Instead the compiler gives
    ;; a message whenever the file being compiled is changed.
    (" +\\([0-9]+\\) +.*\n[ew] [0-9]+-+" nil 1)
    ("[Ew] +[0-9]+ line \\([0-9]+\\) -  " nil 1)

302 303
    ;; Lucid Compiler, lcc 3.x
    ;; E, file.cc(35,52) Illegal operation on pointers
304
    ("[EW], \\([^(\n]*\\)(\\([0-9]+\\),[ \t]*\\([0-9]+\\)" 1 2 3)
305

306 307 308 309
    ;; This seems to be superfluous because the first pattern matches it.
    ;; ;; GNU messages with program name and optional column number.
    ;; ("[a-zA-Z]?:?[^0-9 \n\t:]+[^ \n\t:]*:[ \t]*\\([^ \n\t:]+\\):\
    ;;\\([0-9]+\\):\\(\\([0-9]+\\)[: \t]\\)?" 1 2 4)
310 311

    ;; Cray C compiler error messages
312 313
    ("\\(cc\\| cft\\)-[0-9]+ c\\(c\\|f77\\): ERROR \\([^,\n]+, \\)* File = \
\\([^,\n]+\\), Line = \\([0-9]+\\)" 4 5)
314 315 316 317 318

    ;; IBM C/C++ Tools 2.01:
    ;;  foo.c(2:0) : informational EDC0804: Function foo is not referenced.
    ;;  foo.c(3:8) : warning EDC0833: Implicit return statement encountered.
    ;;  foo.c(5:5) : error EDC0350: Syntax error.
319
    ("\\([^( \n\t]+\\)(\\([0-9]+\\):\\([0-9]+\\)) : " 1 2 3)
320

321 322 323 324 325
    ;; IAR Systems C Compiler:
    ;;  "foo.c",3  Error[32]: Error message
    ;;  "foo.c",3  Warning[32]: Error message
    ("\"\\(.*\\)\",\\([0-9]+\\)\\s-+\\(Error\\|Warning\\)\\[[0-9]+\\]:" 1 2)

326 327
    ;; Sun ada (VADS, Solaris):
    ;;  /home3/xdhar/rcds_rc/main.a, line 361, char 6:syntax error: "," inserted
328
    ("\\([^, \n\t]+\\), line \\([0-9]+\\), char \\([0-9]+\\)[:., \(-]" 1 2 3)
329 330 331

    ;; Perl -w:
    ;; syntax error at automake line 922, near "':'"
332 333 334
    ;; Perl debugging traces
    ;; store::odrecall('File_A', 'x2') called at store.pm line 90
    (".* at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" 1 2)
335 336 337 338 339

    ;; Oracle pro*c:
    ;; Semantic error at line 528, column 5, file erosacqdb.pc:
    ("Semantic error at line \\([0-9]+\\), column \\([0-9]+\\), file \\(.*\\):"
     3 1 2)
340 341 342 343

    ;; EPC F90 compiler:
    ;; Error 24 at (2:progran.f90) : syntax error
    ("Error [0-9]+ at (\\([0-9]*\\):\\([^)\n]+\\))" 2 1)
Karl Heuer's avatar
Karl Heuer committed
344

Dave Love's avatar
Dave Love committed
345
    ;; SGI IRIX MipsPro 7.3 compilers:
346 347 348 349
    ;; cc-1070 cc: ERROR File = linkl.c, Line = 38
    (".*: ERROR File = \\(.+\\), Line = \\([0-9]+\\)" 1 2)
    (".*: WARNING File = \\(.+\\), Line = \\([0-9]+\\)" 1 2)

Karl Heuer's avatar
Karl Heuer committed
350
    ;; Sun F90 error messages:
Dave Love's avatar
Dave Love committed
351
    ;; cf90-113 f90comp: ERROR NSE, File = Hoved.f90, Line = 16, Column = 3
Karl Heuer's avatar
Karl Heuer committed
352 353
    (".* ERROR [a-zA-Z0-9 ]+, File = \\(.+\\), Line = \\([0-9]+\\), Column = \\([0-9]+\\)"
     1 2 3)
Roland McGrath's avatar
Roland McGrath committed
354
    )
355

Richard M. Stallman's avatar
Richard M. Stallman committed
356
  "Alist that specifies how to match errors in compiler output.
357
Each elt has the form (REGEXP FILE-IDX LINE-IDX [COLUMN-IDX FILE-FORMAT...])
358 359
If REGEXP matches, the FILE-IDX'th subexpression gives the file name, and
the LINE-IDX'th subexpression gives the line number.  If COLUMN-IDX is
360 361 362 363
given, the COLUMN-IDX'th subexpression gives the column number on that line.
If any FILE-FORMAT is given, each is a format string to produce a file name to
try; %s in the string is replaced by the text matching the FILE-IDX'th
subexpression.")
Richard M. Stallman's avatar
Richard M. Stallman committed
364

365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
(defvar compilation-enter-directory-regexp-alist
  '(
    ;; Matches lines printed by the `-w' option of GNU Make.
    (".*: Entering directory `\\(.*\\)'$" 1)
    )
  "Alist specifying how to match lines that indicate a new current directory.
Note that the match is done at the beginning of lines.
Each elt has the form (REGEXP IDX).
If REGEXP matches, the IDX'th subexpression gives the directory name.

The default value matches lines printed by the `-w' option of GNU Make.")

(defvar compilation-leave-directory-regexp-alist
  '(
    ;; Matches lines printed by the `-w' option of GNU Make.
    (".*: Leaving directory `\\(.*\\)'$" 1)
    )
"Alist specifying how to match lines that indicate restoring current directory.
Note that the match is done at the beginning of lines.
Each elt has the form (REGEXP IDX).
If REGEXP matches, the IDX'th subexpression gives the name of the directory
Dave Love's avatar
Dave Love committed
386
being moved from.  If IDX is nil, the last directory entered \(by a line
387 388 389 390 391 392 393 394 395 396 397 398 399
matching `compilation-enter-directory-regexp-alist'\) is assumed.

The default value matches lines printed by the `-w' option of GNU Make.")

(defvar compilation-file-regexp-alist
  '(
    ;; This matches entries with date time year file-name: like
    ;; Thu May 14 10:46:12 1992  mom3.p:
    ("\\w\\w\\w \\w\\w\\w +[0-9]+ [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]  \\(.*\\):$" 1)
    )
  "Alist specifying how to match lines that indicate a new current file.
Note that the match is done at the beginning of lines.
Each elt has the form (REGEXP IDX).
Dave Love's avatar
Dave Love committed
400
If REGEXP matches, the IDX'th subexpression gives the file name.  This is
401 402 403 404 405 406 407 408 409 410 411
used with compilers that don't indicate file name in every error message.")

;; There is no generally useful regexp that will match non messages, but
;; in special cases there might be one. The lines that are not matched by
;; a regexp take much longer time than the ones that are recognized so if
;; you have same regexeps here, parsing is faster.
(defvar compilation-nomessage-regexp-alist
  '(
    )
  "Alist specifying how to match lines that have no message.
Note that the match is done at the beginning of lines.
Dave Love's avatar
Dave Love committed
412
Each elt has the form (REGEXP).  This alist is by default empty, but if
413 414
you have some good regexps here, the parsing of messages will be faster.")

415 416 417 418 419 420 421 422 423 424 425
(defcustom compilation-error-screen-columns t
  "*If non-nil, column numbers in error messages are screen columns.
Otherwise they are interpreted as character positions, with
each character occupying one column.
The default is to use screen columns, which requires that the compilation
program and Emacs agree about the display width of the characters,
especially the TAB character."
  :type 'boolean
  :group 'compilation
  :version "20.4")

426
(defcustom compilation-read-command t
Dave Love's avatar
Dave Love committed
427 428
  "*Non-nil means \\[compile] reads the compilation command to use.
Otherwise, \\[compile] just uses the value of `compile-command'."
429 430
  :type 'boolean
  :group 'compilation)
431

432
;;;###autoload
433
(defcustom compilation-ask-about-save t
Dave Love's avatar
Dave Love committed
434
  "*Non-nil means \\[compile] asks which buffers to save before compiling.
435 436 437
Otherwise, it saves all modified buffers without asking."
  :type 'boolean
  :group 'compilation)
438

439 440
;; Note: the character class after the optional drive letter does not
;; include a space to support file names with blanks.
Roland McGrath's avatar
Roland McGrath committed
441
(defvar grep-regexp-alist
442
  '(("\\([a-zA-Z]?:?[^:(\t\n]+\\)[:( \t]+\\([0-9]+\\)[:) \t]" 1 2))
Roland McGrath's avatar
Roland McGrath committed
443 444
  "Regexp used to match grep hits.  See `compilation-error-regexp-alist'.")

445
(defvar grep-program
446 447 448
  ;; Currently zgrep has trouble.  It runs egrep instead of grep,
  ;; and it doesn't pass along long options right.
  "grep"
449 450 451 452 453 454 455
  ;; (if (equal (condition-case nil	; in case "zgrep" isn't in exec-path
  ;; 		 (call-process "zgrep" nil nil nil
  ;; 			       "foo" null-device)
  ;; 	       (error nil))
  ;; 	     1)
  ;;     "zgrep"
  ;;   "grep")
456 457
  "The default grep program for `grep-command' and `grep-find-command'.
This variable's value takes effect when `grep-compute-defaults' is called.")
458

459 460 461 462
(defvar find-program "find"
  "The default find program for `grep-find-command'.
This variable's value takes effect when `grep-compute-defaults' is called.")

463
(defvar grep-find-use-xargs nil
464 465 466 467 468
  "Whether \\[grep-find] uses the `xargs' utility by default.

If nil, it uses `grep -exec'; if `gnu', it uses `find -print0' and `xargs -0';
if not nil and not `gnu', it uses `find -print' and `xargs'.

469
This variable's value takes effect when `grep-compute-defaults' is called.")
470

Roland McGrath's avatar
Roland McGrath committed
471
;;;###autoload
472
(defcustom compilation-search-path '(nil)
Roland McGrath's avatar
Roland McGrath committed
473
  "*List of directories to search for source files named in error messages.
Roland McGrath's avatar
Roland McGrath committed
474
Elements should be directory names, not file names of directories.
475 476 477 478
nil as an element means to try the default directory."
  :type '(repeat (choice (const :tag "Default" nil)
			 (string :tag "Directory")))
  :group 'compilation)
Richard M. Stallman's avatar
Richard M. Stallman committed
479

480 481
(defcustom compile-command "make -k "
  "*Last shell command used to do a compilation; default for next compilation.
Richard M. Stallman's avatar
Richard M. Stallman committed
482 483 484 485

Sometimes it is useful for files to supply local values for this variable.
You might also use mode hooks to specify it in certain modes, like this:

486 487 488 489
    (add-hook 'c-mode-hook
       (lambda ()
	 (unless (or (file-exists-p \"makefile\")
		     (file-exists-p \"Makefile\"))
490 491 492
	   (set (make-local-variable 'compile-command)
		(concat \"make -k \"
		        (file-name-sans-extension buffer-file-name))))))"
493 494
  :type 'string
  :group 'compilation)
Richard M. Stallman's avatar
Richard M. Stallman committed
495

Roland McGrath's avatar
Roland McGrath committed
496
(defvar compilation-directory-stack nil
Richard M. Stallman's avatar
Richard M. Stallman committed
497
  "Stack of previous directories for `compilation-leave-directory-regexp'.
498
The last element is the directory the compilation was started in.")
Roland McGrath's avatar
Roland McGrath committed
499

500 501
(defvar compilation-exit-message-function nil "\
If non-nil, called when a compilation process dies to return a status message.
502 503 504
This should be a function of three arguments: process status, exit status,
and exit message; it returns a cons (MESSAGE . MODELINE) of the strings to
write into the compilation buffer, and to put in its mode line.")
505

506 507 508 509
;; History of compile commands.
(defvar compile-history nil)
;; History of grep commands.
(defvar grep-history nil)
510
(defvar grep-find-history nil)
511

Simon Marshall's avatar
Simon Marshall committed
512 513 514 515 516
(defun compilation-mode-font-lock-keywords ()
  "Return expressions to highlight in Compilation mode."
  (nconc
   ;;
   ;; Compiler warning/error lines.
517 518 519
   (mapcar (function
	    (lambda (item)
	      ;; Prepend "^", adjusting FILE-IDX and LINE-IDX accordingly.
520 521 522 523 524 525 526 527
	      (let ((file-idx (nth 1 item))
		    (line-idx (nth 2 item))
		    (col-idx (nth 3 item))
		    keyword)
		(when (numberp col-idx)
		  (setq keyword
			(cons (list (1+ col-idx) 'font-lock-type-face nil t)
			      keyword)))
528 529 530 531 532 533 534 535 536
		(when (numberp line-idx)
		  (setq keyword
			(cons (list (1+ line-idx) 'font-lock-variable-name-face)
			      keyword)))
		(when (numberp file-idx)
		  (setq keyword
			(cons (list (1+ file-idx) 'font-lock-warning-face)
			      keyword)))
		(cons (concat "^\\(" (nth 0 item) "\\)") keyword))))
Simon Marshall's avatar
Simon Marshall committed
537 538 539
	   compilation-error-regexp-alist)
   (list
    ;;
540
    ;; Compiler output lines.  Recognize `make[n]:' lines too.
Simon Marshall's avatar
Simon Marshall committed
541 542 543
    '("^\\([A-Za-z_0-9/\.+-]+\\)\\(\\[\\([0-9]+\\)\\]\\)?[ \t]*:"
      (1 font-lock-function-name-face) (3 font-lock-comment-face nil t)))
   ))
544

Roland McGrath's avatar
Roland McGrath committed
545
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
546 547 548 549
(defun compile (command)
  "Compile the program including the current buffer.  Default: run `make'.
Runs COMMAND, a shell command, in a separate process asynchronously
with output going to the buffer `*compilation*'.
Roland McGrath's avatar
Roland McGrath committed
550

Richard M. Stallman's avatar
Richard M. Stallman committed
551 552 553
You can then use the command \\[next-error] to find the next error message
and move to the source code that caused it.

554 555 556
Interactively, prompts for the command if `compilation-read-command' is
non-nil; otherwise uses `compile-command'.  With prefix arg, always prompts.

Richard M. Stallman's avatar
Richard M. Stallman committed
557
To run more than one compilation at once, start one and rename the
Roland McGrath's avatar
Roland McGrath committed
558 559 560 561 562 563
\`*compilation*' buffer to some other name with \\[rename-buffer].
Then start the next one.

The name used for the buffer is actually whatever is returned by
the function in `compilation-buffer-name-function', so you can set that
to a function that generates a unique name."
564
  (interactive
565
   (if (or compilation-read-command current-prefix-arg)
566
       (list (read-from-minibuffer "Compile command: "
567
                                 (eval compile-command) nil nil
568
                                 '(compile-history . 1)))
569 570 571
     (list (eval compile-command))))
  (unless (equal command (eval compile-command))
    (setq compile-command command))
572
  (save-some-buffers (not compilation-ask-about-save) nil)
573
  (compile-internal command "No more errors"))
Richard M. Stallman's avatar
Richard M. Stallman committed
574

575
;; run compile with the default command line
576 577 578 579
(defun recompile ()
  "Re-compile the program including the current buffer."
  (interactive)
  (save-some-buffers (not compilation-ask-about-save) nil)
580
  (compile-internal (eval compile-command) "No more errors"))
581

582 583 584 585 586 587 588 589 590 591 592 593 594
(defun grep-process-setup ()
  "Set up `compilation-exit-message-function' for `grep'."
  (set (make-local-variable 'compilation-exit-message-function)
       (lambda (status code msg)
	 (if (eq status 'exit)
	     (cond ((zerop code)
		    '("finished (matches found)\n" . "matched"))
		   ((= code 1)
		    '("finished with no matches found\n" . "no match"))
		   (t
		    (cons msg code)))
	   (cons msg code)))))

595
(defun grep-compute-defaults ()
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
  (unless (or (not grep-use-null-device) (eq grep-use-null-device t))
    (setq grep-use-null-device
	  (with-temp-buffer
	    (let ((hello-file (expand-file-name "HELLO" data-directory)))
	      (not
	       (and (equal (condition-case nil
			       (if grep-command
				   ;; `grep-command' is already set, so
				   ;; use that for testing.
				   (call-process-shell-command
				    grep-command nil t nil
				    "^English" hello-file)
				 ;; otherwise use `grep-program'
				 (call-process grep-program nil t nil
					       "-nH" "^English" hello-file))
			     (error nil))
			   0)
		    (progn
		      (goto-char (point-min))
		      (looking-at
		       (concat (regexp-quote hello-file)
			       ":[0-9]+:English")))))))))
618 619
  (unless grep-command
    (setq grep-command
620 621 622 623 624 625 626 627
	  (let ((required-options (if grep-use-null-device "-n" "-nH")))
	    (if (equal (condition-case nil ; in case "grep" isn't in exec-path
			   (call-process grep-program nil nil nil
					 "-e" "foo" null-device)
			 (error nil))
		       1)
		(format "%s %s -e " grep-program required-options)
	      (format "%s %s " grep-program required-options)))))
628 629
  (unless grep-find-use-xargs
    (setq grep-find-use-xargs
630 631 632 633 634 635 636
	  (if (and
               (equal (call-process "find" nil nil nil
                                    null-device "-print0")
                      0)
               (equal (call-process "xargs" nil nil nil
                                    "-0" "-e" "echo")
		     0))
637
	      'gnu)))
638 639 640
  (unless grep-find-command
    (setq grep-find-command
	  (cond ((eq grep-find-use-xargs 'gnu)
641 642
		 (format "%s . -type f -print0 | xargs -0 -e %s"
			 find-program grep-command))
643
		(grep-find-use-xargs
644 645 646 647
		 (format "%s . -type f -print | xargs %s"
                         find-program grep-command))
		(t (cons (format "%s . -type f -exec %s {} %s \\;"
				 find-program grep-command null-device)
648
			 (+ 22 (length grep-command))))))))
649

Roland McGrath's avatar
Roland McGrath committed
650
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
651 652
(defun grep (command-args)
  "Run grep, with user-specified args, and collect output in a buffer.
Richard M. Stallman's avatar
Richard M. Stallman committed
653 654 655 656
While grep runs asynchronously, you can use \\[next-error] (M-x next-error),
or \\<compilation-minor-mode-map>\\[compile-goto-error] in the grep \
output buffer, to go to the lines
where grep found matches.
Roland McGrath's avatar
Roland McGrath committed
657

658
This command uses a special history list for its COMMAND-ARGS, so you can
659 660 661
easily repeat a grep command.

A prefix argument says to default the argument based upon the current
Karl Heuer's avatar
Karl Heuer committed
662 663 664
tag the cursor is over, substituting it into the last grep command
in the grep command history (or into `grep-command'
if that history list is empty)."
Richard M. Stallman's avatar
Richard M. Stallman committed
665
  (interactive
Karl Heuer's avatar
Karl Heuer committed
666
   (let (grep-default (arg current-prefix-arg))
667 668
     (unless (and grep-command
		  (or (not grep-use-null-device) (eq grep-use-null-device t)))
669
       (grep-compute-defaults))
Karl Heuer's avatar
Karl Heuer committed
670
     (when arg
671 672 673 674 675 676
       (let ((tag-default
	      (funcall (or find-tag-default-function
			   (get major-mode 'find-tag-default-function)
			   ;; We use grep-tag-default instead of
			   ;; find-tag-default, to avoid loading etags.
			   'grep-tag-default))))
Karl Heuer's avatar
Karl Heuer committed
677
	 (setq grep-default (or (car grep-history) grep-command))
678
	 ;; Replace the thing matching for with that around cursor
679 680 681 682
	 (when (string-match "[^ ]+\\s +\\(-[^ ]+\\s +\\)*\\(\"[^\"]+\"\\|[^ ]+\\)\\(\\s-+\\S-+\\)?" grep-default)
	   (unless (or (match-beginning 3) (not (stringp buffer-file-name)))
	     (setq grep-default (concat grep-default "*."
					(file-name-extension buffer-file-name))))
683 684
	   (setq grep-default (replace-match (or tag-default "")
					     t t grep-default 2)))))
685 686 687 688
     (list (read-from-minibuffer "Run grep (like this): "
				 (or grep-default grep-command)
				 nil nil 'grep-history))))

689 690 691
  ;; Setting process-setup-function makes exit-message-function work
  ;; even when async processes aren't supported.
  (let* ((compilation-process-setup-function 'grep-process-setup)
692
	 (buf (compile-internal (if (and grep-use-null-device null-device)
693
				    (concat command-args " " null-device)
694
				  command-args)
695 696 697
				"No more grep hits" "grep"
				;; Give it a simpler regexp to match.
				nil grep-regexp-alist)))))
Richard M. Stallman's avatar
Richard M. Stallman committed
698

699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
;; This is a copy of find-tag-default from etags.el.
(defun grep-tag-default ()
  (save-excursion
    (while (looking-at "\\sw\\|\\s_")
      (forward-char 1))
    (when (or (re-search-backward "\\sw\\|\\s_"
				  (save-excursion (beginning-of-line) (point))
				  t)
	      (re-search-forward "\\(\\sw\\|\\s_\\)+"
				 (save-excursion (end-of-line) (point))
				 t))
      (goto-char (match-end 0))
      (buffer-substring (point)
			(progn (forward-sexp -1)
			       (while (looking-at "\\s'")
				 (forward-char 1))
			       (point))))))
716 717 718

;;;###autoload
(defun grep-find (command-args)
Dave Love's avatar
Dave Love committed
719 720
  "Run grep via find, with user-specified args COMMAND-ARGS.
Collect output in a buffer.
721 722 723 724 725 726
While find runs asynchronously, you can use the \\[next-error] command
to find the text that grep hits refer to.

This command uses a special history list for its arguments, so you can
easily repeat a find command."
  (interactive
727 728 729 730 731 732
   (progn
     (unless grep-find-command
       (grep-compute-defaults))
     (list (read-from-minibuffer "Run find (like this): "
				 grep-find-command nil nil
				 'grep-find-history))))
733
  (let ((null-device nil))		; see grep
734 735
    (grep command-args)))

736 737 738 739 740 741 742
(defcustom compilation-scroll-output nil
  "*Non-nil to scroll the *compilation* buffer window as output appears.

Setting it causes the compilation-mode commands to put point at the
end of their output window so that the end of the output is always
visible rather than the begining."
  :type 'boolean
743
  :version "20.3"
744 745
  :group 'compilation)

Richard M. Stallman's avatar
Richard M. Stallman committed
746
(defun compile-internal (command error-message
747 748 749 750
				 &optional name-of-mode parser
				 error-regexp-alist name-function
				 enter-regexp-alist leave-regexp-alist
				 file-regexp-alist nomessage-regexp-alist)
Richard M. Stallman's avatar
Richard M. Stallman committed
751 752
  "Run compilation command COMMAND (low level interface).
ERROR-MESSAGE is a string to print if the user asks to see another error
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
and there are no more errors.  The rest of the arguments, 3-10 are optional.
For them nil means use the default.
NAME-OF-MODE is the name to display as the major mode in the compilation
buffer.  PARSER is the error parser function.  ERROR-REGEXP-ALIST is the error
message regexp alist to use.  NAME-FUNCTION is a function called to name the
buffer.  ENTER-REGEXP-ALIST is the enter directory message regexp alist to use.
LEAVE-REGEXP-ALIST is the leave directory message regexp alist to use.
FILE-REGEXP-ALIST is the change current file message regexp alist to use.
NOMESSAGE-REGEXP-ALIST is the nomessage regexp alist to use.
  The defaults for these variables are the global values of
\`compilation-parse-errors-function', `compilation-error-regexp-alist',
\`compilation-buffer-name-function', `compilation-enter-directory-regexp-alist',
\`compilation-leave-directory-regexp-alist', `compilation-file-regexp-alist',
\ and `compilation-nomessage-regexp-alist', respectively.
For arg 7-10 a value `t' means an empty alist.
Roland McGrath's avatar
Roland McGrath committed
768 769

Returns the compilation buffer created."
Roland McGrath's avatar
Roland McGrath committed
770
  (let (outbuf)
Richard M. Stallman's avatar
Richard M. Stallman committed
771
    (save-excursion
Roland McGrath's avatar
Roland McGrath committed
772 773 774 775 776 777 778 779 780 781 782 783 784
      (or name-of-mode
	  (setq name-of-mode "Compilation"))
      (setq outbuf
	    (get-buffer-create
	     (funcall (or name-function compilation-buffer-name-function
			  (function (lambda (mode)
				      (concat "*" (downcase mode) "*"))))
		      name-of-mode)))
      (set-buffer outbuf)
      (let ((comp-proc (get-buffer-process (current-buffer))))
	(if comp-proc
	    (if (or (not (eq (process-status comp-proc) 'run))
		    (yes-or-no-p
785 786
		     (format "A %s process is running; kill it? "
			     name-of-mode)))
Roland McGrath's avatar
Roland McGrath committed
787 788 789 790 791 792 793 794 795 796 797 798
		(condition-case ()
		    (progn
		      (interrupt-process comp-proc)
		      (sit-for 1)
		      (delete-process comp-proc))
		  (error nil))
	      (error "Cannot have two processes in `%s' at once"
		     (buffer-name))
	      )))
      ;; In case the compilation buffer is current, make sure we get the global
      ;; values of compilation-error-regexp-alist, etc.
      (kill-all-local-variables))
799 800 801 802 803 804 805 806 807 808 809 810
    (or error-regexp-alist
	(setq error-regexp-alist compilation-error-regexp-alist))
    (or enter-regexp-alist
	(setq enter-regexp-alist compilation-enter-directory-regexp-alist))
    (or leave-regexp-alist
	(setq leave-regexp-alist compilation-leave-directory-regexp-alist))
    (or file-regexp-alist
	(setq file-regexp-alist compilation-file-regexp-alist))
    (or nomessage-regexp-alist
	(setq nomessage-regexp-alist compilation-nomessage-regexp-alist))
    (or parser (setq parser compilation-parse-errors-function))
    (let ((thisdir default-directory)
811
	  outwin)
Roland McGrath's avatar
Roland McGrath committed
812 813 814 815 816 817
      (save-excursion
	;; Clear out the compilation buffer and make it writable.
	;; Change its default-directory to the directory where the compilation
	;; will happen, and insert a `cd' command to indicate this.
	(set-buffer outbuf)
	(setq buffer-read-only nil)
818
	(buffer-disable-undo (current-buffer))
Roland McGrath's avatar
Roland McGrath committed
819
	(erase-buffer)
820
	(buffer-enable-undo (current-buffer))
Roland McGrath's avatar
Roland McGrath committed
821 822 823 824 825 826 827 828
	(setq default-directory thisdir)
	(insert "cd " thisdir "\n" command "\n")
	(set-buffer-modified-p nil))
      ;; If we're already in the compilation buffer, go to the end
      ;; of the buffer, so point will track the compilation output.
      (if (eq outbuf (current-buffer))
	  (goto-char (point-max)))
      ;; Pop up the compilation buffer.
829
      (setq outwin (display-buffer outbuf nil t))
830 831
      (save-excursion
	(set-buffer outbuf)
832
	(compilation-mode name-of-mode)
833 834
	;; In what way is it non-ergonomic ?  -stef
	;; (toggle-read-only 1) ;;; Non-ergonomic.
835 836
	(set (make-local-variable 'compilation-parse-errors-function) parser)
	(set (make-local-variable 'compilation-error-message) error-message)
837 838 839 840 841 842 843 844 845 846
	(set (make-local-variable 'compilation-error-regexp-alist)
	     error-regexp-alist)
	(set (make-local-variable 'compilation-enter-directory-regexp-alist)
	     enter-regexp-alist)
	(set (make-local-variable 'compilation-leave-directory-regexp-alist)
	     leave-regexp-alist)
	(set (make-local-variable 'compilation-file-regexp-alist)
	     file-regexp-alist)
	(set (make-local-variable 'compilation-nomessage-regexp-alist)
	     nomessage-regexp-alist)
847 848 849 850 851 852
	(set (make-local-variable 'compilation-arguments)
	     (list command error-message
		   name-of-mode parser
		   error-regexp-alist name-function
		   enter-regexp-alist leave-regexp-alist
		   file-regexp-alist nomessage-regexp-alist))
853 854
        ;; This proves a good idea if the buffer's going to scroll
        ;; with lazy-lock on.
855
        (set (make-local-variable 'lazy-lock-defer-on-scrolling) t)
856 857 858 859 860
	(setq default-directory thisdir
	      compilation-directory-stack (list default-directory))
	(set-window-start outwin (point-min))
	(or (eq outwin (selected-window))
	    (set-window-point outwin (point-min)))
861
	(compilation-set-window-height outwin)
862 863
	(if compilation-process-setup-function
	    (funcall compilation-process-setup-function))
864
	;; Start the compilation.
865
	(if (fboundp 'start-process)
866 867 868 869 870
	    (let* ((process-environment
		    ;; Don't override users' setting of $EMACS.
		    (if (getenv "EMACS")
			process-environment
		      (cons "EMACS=t" process-environment)))
871 872 873
		   (proc (start-process-shell-command (downcase mode-name)
						      outbuf
						      command)))
874 875 876
	      (set-process-sentinel proc 'compilation-sentinel)
	      (set-process-filter proc 'compilation-filter)
	      (set-marker (process-mark proc) (point) outbuf)
877
	      (setq compilation-in-progress
878
		    (cons proc compilation-in-progress)))
879 880
	  ;; No asynchronous processes available.
	  (message "Executing `%s'..." command)
881 882
	  ;; Fake modeline display as if `start-process' were run.
	  (setq mode-line-process ":run")
883 884
	  (force-mode-line-update)
	  (sit-for 0)			; Force redisplay
885
	  (let ((status (call-process shell-file-name nil outbuf nil "-c"
886 887 888 889 890 891 892 893 894 895 896 897 898
				      command)))
	    (cond ((numberp status)
		   (compilation-handle-exit 'exit status
					    (if (zerop status)
						"finished\n"
					      (format "\
exited abnormally with code %d\n"
						      status))))
		  ((stringp status)
		   (compilation-handle-exit 'signal status
					    (concat status "\n")))
		  (t
		   (compilation-handle-exit 'bizarre status status))))
899 900
	  (message "Executing `%s'...done" command)))
      (if compilation-scroll-output
901
	  (save-selected-window
902
            (select-window outwin)
903
            (goto-char (point-max)))))
Roland McGrath's avatar
Roland McGrath committed
904 905
    ;; Make it so the next C-x ` will use this buffer.
    (setq compilation-last-buffer outbuf)))
Richard M. Stallman's avatar
Richard M. Stallman committed
906

907
(defun compilation-set-window-height (window)
Dave Love's avatar
Dave Love committed
908
  "Set the height of WINDOW according to `compilation-window-height'."
909 910 911 912 913
  (and compilation-window-height
       (= (window-width window) (frame-width (window-frame window)))
       ;; If window is alone in its frame, aside from a minibuffer,
       ;; don't change its height.
       (not (eq window (frame-root-window (window-frame window))))
914 915 916 917 918 919 920 921 922 923
       ;; This save-excursion prevents us from changing the current buffer,
       ;; which might not be the same as the selected window's buffer.
       (save-excursion
	 (let ((w (selected-window)))
	   (unwind-protect
	       (progn
		 (select-window window)
		 (enlarge-window (- compilation-window-height
				    (window-height))))
	     (select-window w))))))
924

925
(defvar compilation-minor-mode-map
Richard M. Stallman's avatar
Richard M. Stallman committed
926
  (let ((map (make-sparse-keymap)))
927
    (define-key map [mouse-2] 'compile-mouse-goto-error)
Richard M. Stallman's avatar
Richard M. Stallman committed
928
    (define-key map "\C-c\C-c" 'compile-goto-error)
929
    (define-key map "\C-m" 'compile-goto-error)
Roland McGrath's avatar
Roland McGrath committed
930
    (define-key map "\C-c\C-k" 'kill-compilation)
Roland McGrath's avatar
Roland McGrath committed
931 932
    (define-key map "\M-n" 'compilation-next-error)
    (define-key map "\M-p" 'compilation-previous-error)
Roland McGrath's avatar
Roland McGrath committed
933 934
    (define-key map "\M-{" 'compilation-previous-file)
    (define-key map "\M-}" 'compilation-next-file)
Richard M. Stallman's avatar
Richard M. Stallman committed
935
    map)
936
  "Keymap for `compilation-minor-mode'.")
937

938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961
(defvar compilation-shell-minor-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map [mouse-2] 'compile-mouse-goto-error)
    (define-key map "\M-\C-m" 'compile-goto-error)
    (define-key map "\M-\C-n" 'compilation-next-error)