Making GNU Emacs detect custom error messages - A Maven Example
GNU Emacs's compilation mode is capable of detecting error messages from various standard compilers and build tools. However, it is fairy common for one to run into a format of error message that Emacs can't handle by default.
As you know, Emacs is highly extensible and it provides compilation-error-regexp-alist for accomplishing this. I have done this a couple of times earlier and I had to do it one more time lately for adding regular expression for Maven error messages. Construction of these regular expressions is not fun for everyone. However, regexp-builder makes it easier to construct the regular expression interactively.
In summary, here is the customization that has to be added to .emacs.
(add-to-list 'compilation-error-regexp-alist 'maven) (add-to-list 'compilation-error-regexp-alist-alist '(maven "\\[ERROR\\] \\(.+?\\):\\[\\([0-9]+\\),\\([0-9]+\\)\\].\*" 1 2 3))
Here is what Emacs's inbuilt documentation says about compilation-error-regular-expression-alist:
Because the documentation around compilation-error-regexp-alist isn't very intuitive for most, I have decided to make this screencast that describes how to approach this from scratch. Sorry about the typos! For best quality, watch it in HD.
compilation-error-regexp-alist is a variable defined in `compile.el'. Its value is shown below. Documentation: Alist that specifies how to match errors in compiler output. On GNU and Unix, any string is a valid filename, so these matchers must make some common sense assumptions, which catch normal cases. A shorter list will be lighter on resource usage. Instead of an alist element, you can use a symbol, which is looked up in `compilation-error-regexp-alist-alist'. You can see the predefined symbols and their effects in the file `etc/compilation.txt' (linked below if you are customizing this). Each elt has the form (REGEXP FILE [LINE COLUMN TYPE HYPERLINK HIGHLIGHT...]). If REGEXP matches, the FILE'th subexpression gives the file name, and the LINE'th subexpression gives the line number. The COLUMN'th subexpression gives the column number on that line. If FILE, LINE or COLUMN are nil or that index didn't match, that information is not present on the matched line. In that case the file name is assumed to be the same as the previous one in the buffer, line number defaults to 1 and column defaults to beginning of line's indentation. FILE can also have the form (FILE FORMAT...), where the FORMATs (e.g. "%s.c") will be applied in turn to the recognized file name, until a file of that name is found. Or FILE can also be a function that returns (FILENAME) or (RELATIVE-FILENAME . DIRNAME). In the former case, FILENAME may be relative or absolute. LINE can also be of the form (LINE . END-LINE) meaning a range of lines. COLUMN can also be of the form (COLUMN . END-COLUMN) meaning a range of columns starting on LINE and ending on END-LINE, if that matched. TYPE is 2 or nil for a real error or 1 for warning or 0 for info. TYPE can also be of the form (WARNING . INFO). In that case this will be equivalent to 1 if the WARNING'th subexpression matched or else equivalent to 0 if the INFO'th subexpression matched. See `compilation-error-face', `compilation-warning-face', `compilation-info-face' and `compilation-skip-threshold'. What matched the HYPERLINK'th subexpression has `mouse-face' and `compilation-message-face' applied. If this is nil, the text matched by the whole REGEXP becomes the hyperlink. Additional HIGHLIGHTs take the shape (SUBMATCH FACE), where SUBMATCH is the number of a submatch and FACE is an expression which evaluates to a face name (a symbol or string). Alternatively, FACE can evaluate to a property list of the form (face FACE PROP1 VAL1 PROP2 VAL2 ...), in which case all the listed text properties PROP# are given values VAL# as well. You can customize this variable. For more information check the manuals.