Commit 9ffae6d0 authored by Stefan Monnier's avatar Stefan Monnier

* progmodes/compile.el: Don't use font-lock any more.

parents b1ea593c 55fb9013
......@@ -321,6 +321,9 @@ prompts for a number to count from and for a format string.
* Changes in Specialized Modes and Packages in Emacs 24.1
** The compile.el mode can be used without font-lock-mode.
`compilation-parse-errors-function' is now obsolete.
** The Landmark game is now invoked with `landmark', not `lm'.
** Prolog mode has been completely revamped, with lots of additional
......@@ -13,6 +13,89 @@
2011-01-28 Stefan Monnier <>
* progmodes/compile.el: Don't use font-lock any more.
(compilation-error-regexp-alist-alist): Change handling of makepp
so it preserves the warning/error distinction on subsequent files.
Simplify various rules.
(compilation-directory-properties): Use font-lock-face.
Add a compilation-message property.
(compilation-internal-error-properties): Use font-lock-face.
Don't set the compilation-debug property here.
(compilation--put-prop, compilation--remove-properties)
(compilation--parse-region, compilation--ensure-parse)
(compilation--ensure-parse): New functions.
(compilation-parse-errors): New function, largely inspired of
compilation-mode-font-lock-keywords. Set compilation-debug here.
(compilation--parsed): New var.
(compilation--flush-parse): Use compilation--ensure-parse.
(compilation-start): Don't call font-lock.
(compilation-turn-on-font-lock): Remove.
(compilation-setup): Don't set font-lock-extra-managed-props not change
other font-lock settings, other than keywords.
Don't activate font-lock-mode.
Set change-major-mode-hook and before-change-functions.
(compilation--unsetup): Remove properties and hooks.
(compilation-next-single-property-change): New function.
(compilation-next-error): Use it to parse when needed.
(compile-goto-error): Parse buffer as needed.
(compilation--compat-error-properties): Don't need a dummy `face'
property any more.
2011-01-28 Stefan Monnier <>
* progmodes/compile.el: Use accessors for clarity and fix omake hack.
(compilation-process-setup-function): Fix docstring's false promises.
(compilation-error-regexp-alist-alist): Catch omake's continuous
recompilation message and avoid reuse of old markers.
(compilation-parse-errors-function): Declare obsolete.
(compilation-buffer-modtime): Remove.
(compilation--make-cdrloc, compilation--loc->col)
(compilation--loc->line, compilation--loc->file-struct)
(compilation--loc->marker, compilation--loc->visited)
(compilation--make-file-struct, compilation--file-struct->file-spec)
(compilation--file-struct->loc-tree): New macros. Use them.
(compilation--message): New defstruct. Use them.
(compilation-next-error-function): Don't mess with timestamps to try
and guess when to reparse.
2011-01-28 Stefan Monnier <>
* textmodes/tex-mode.el: Get rid of compilation-parse-errors-function
(tex-old-error-file-name): New function,
extracted from tex-compilation-parse-errors.
(tex-compilation-parse-errors): Remove.
(tex-error-regexp-alist): New var.
(tex-shell): Use it to avoid compilation-parse-errors-function.
* progmodes/grep.el (grep-regexp-alist): Tighten regexp.
(grep-mode-font-lock-keywords): Remove regexp that seems like
a left-over from before we used compile.el.
(grep-mode-font-lock-keywords): Call syntax-ppss-flush-cache when
modifying the buffer within with-silent-modifications.
* progmodes/compile.el: Cleanup text-properties namespace by using
`compilation-message' instead of `message', `compilation-directory'
instead of `directory', and `compilation-debug' instead of `debug'.
(compilation-last-buffer, compilation-parsing-end)
(compilation-error-list, compilation-old-error-list): Move to the
compatibility part of the code.
(compilation-error-properties): If `file' is a function, let it return
a file name.
(compilation-mode-font-lock-keywords): Be more conservative with the
omake "^ *" pattern prefix, to try and minimize the risk of
pathologically slow regexp matching.
(compilation-start): Use inhibit-read-only.
(compilation--unsetup): New function.
(compilation-shell-minor-mode, compilation-minor-mode): Use it.
(compilation-filter): Minor tweaks.
(compilation-next-error-function): Try and avoid abusing variables.
(compilation--flush-file-structure): New fun.
(compilation-fake-loc): Use it to improve behavior when file is reused.
(debug-ignored-errors): Add "Moved past last ...".
(compilation--compat-parse-errors): Rename by doubling the "-".
Port features from the previous prolog.el to the new one.
* progmodes/prolog.el (prolog-system): Add GNU and ECLiPSe options.
(prolog-program-name, prolog-program-switches, prolog-consult-string)
......@@ -27,7 +110,7 @@
(prolog-inferior-self-insert-command): New command.
(prolog-inferior-mode-map): Use it.
(prolog-inferior-error-regexp-alist): New var.
(prolog-inferior-mode): Use it, along with compilation-shell-minor-mode.
(prolog-inferior-mode): Use it, with compilation-shell-minor-mode.
(prolog-input-filter): Use derived-mode-p.
(prolog-inferior-guess-flavor): New function.
(prolog-ensure-process): Use it. Use make-comint-in-buffer rather than
This diff is collapsed.
......@@ -341,7 +341,7 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
(defconst grep-regexp-alist
'(("^\\(.+?\\)\\(:[ \t]*\\)\\([0-9]+\\)\\2"
'(("^\\(.+?\\)\\(:[ \t]*\\)\\([1-9][0-9]*\\)\\2"
1 3)
;; Rule to match column numbers is commented out since no known grep
;; produces them
......@@ -384,7 +384,6 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
(defvar grep-mode-font-lock-keywords
'(;; Command output lines.
("^\\([A-Za-z_0-9/\.+-]+\\)[ \t]*:" 1 font-lock-function-name-face)
(": \\(.+\\): \\(?:Permission denied\\|No such \\(?:file or directory\\|device or address\\)\\)$"
1 grep-error-face)
;; remove match from grep-regexp-alist before fontifying
......@@ -399,7 +398,8 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
(1 grep-error-face)
(2 grep-error-face nil t))
("^.+?-[0-9]+-.*\n" (0 grep-context-face))
;; Highlight grep matches and delete markers
;; Highlight grep matches and delete markers.
;; FIXME: Modifying the buffer text from font-lock is a bad idea!
;; Refontification does not work after the markers have been
;; deleted. So we use the font-lock-face property here as Font
......@@ -409,12 +409,14 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
;; Delete markers with `replace-match' because it updates
;; the match-data, whereas `delete-region' would render it obsolete.
(syntax-ppss-flush-cache (match-beginning 0))
(replace-match "" t t nil 3)
(replace-match "" t t nil 1))))
;; Delete all remaining escape sequences
((lambda (bound))
(replace-match "" t t nil 1))))
(syntax-ppss-flush-cache (match-beginning 0))
(replace-match "" t t))))
"Additional things to highlight in grep output.
This gets tacked on the end of the generated expressions.")
......@@ -1812,11 +1812,70 @@ Mark is left at original location."
;; Why use a shell instead of running TeX directly? Because if TeX
;; gets stuck, the user can switch to the shell window and type at it.
(defvar tex-error-parse-syntax-table
(let ((st (make-syntax-table)))
(modify-syntax-entry ?\( "()" st)
(modify-syntax-entry ?\) ")(" st)
(modify-syntax-entry ?\\ "\\" st)
(modify-syntax-entry ?\{ "_" st)
(modify-syntax-entry ?\} "_" st)
(modify-syntax-entry ?\[ "_" st)
(modify-syntax-entry ?\] "_" st)
;; Single quotations may appear in errors
(modify-syntax-entry ?\" "_" st)
"Syntax-table used while parsing TeX error messages.")
(defun tex-old-error-file-name ()
;; This is unreliable, partly because we don't try very hard, and
;; partly because TeX's output format is eminently ambiguous and unfriendly
;; to automation.
(with-syntax-table tex-error-parse-syntax-table
(backward-up-list 1)
(skip-syntax-forward "(_")
(while (not (let ((try-filename (thing-at-point 'filename)))
(and try-filename
(not (string= "" try-filename))
(file-readable-p try-filename))))
(skip-syntax-backward "(_")
(backward-up-list 1)
(skip-syntax-forward "(_"))
(thing-at-point 'filename)))))
(defconst tex-error-regexp-alist
;; First alternative handles the newer --file-line-error style:
;; ./test2.tex:14: Too many }'s.
;; Second handles the old-style, which spans two lines but doesn't include
;; any file info:
;; ! Too many }'s.
;; l.396 toto}
("^l\\.\\([1-9][0-9]*\\) \\(?:\\.\\.\\.\\)?\\(.*\\)$"
tex-old-error-file-name 1 nil nil nil
;; Since there's no filename to highlight, let's highlight the message.
(2 compilation-error-face))
;; A few common warning messages.
("^\\(?:Und\\|Ov\\)erfull \\\\[hv]box .* at lines? \\(\\([1-9][0-9]*\\)\\(?:--\\([1-9][0-9]*\\)\\)?\\)$"
tex-old-error-file-name (2 . 3) nil 1 nil
(1 compilation-warning-face))
("^(Font) *\\([^ \n].* on input line \\([1-9][0-9]*\\)\\)\\.$"
tex-old-error-file-name 2 nil 1 1
(2 compilation-warning-face))
;; Included files get output as (<file> ...).
;; FIXME: there tend to be a crapload of them at the beginning of the
;; output which aren't that interesting. Maybe we should filter out
;; all the file name that start with /usr/share?
;; ("(\\.?/\\([^() \n]+\\)" 1 nil nil 0)
;; The utility functions:
(define-derived-mode tex-shell shell-mode "TeX-Shell"
(set (make-local-variable 'compilation-parse-errors-function)
(set (make-local-variable 'compilation-error-regexp-alist)
(compilation-shell-minor-mode t))
......@@ -2314,113 +2373,6 @@ Only applies the FSPEC to the args part of FORMAT."
(setq tex-last-buffer-texed (current-buffer)))
(defvar tex-error-parse-syntax-table
(let ((st (make-syntax-table)))
(modify-syntax-entry ?\( "()" st)
(modify-syntax-entry ?\) ")(" st)
(modify-syntax-entry ?\\ "\\" st)
(modify-syntax-entry ?\{ "_" st)
(modify-syntax-entry ?\} "_" st)
(modify-syntax-entry ?\[ "_" st)
(modify-syntax-entry ?\] "_" st)
;; Single quotations may appear in errors
(modify-syntax-entry ?\" "_" st)
"Syntax-table used while parsing TeX error messages.")
(defun tex-compilation-parse-errors (limit-search find-at-least)
"Parse the current buffer as TeX error messages.
See the variable `compilation-parse-errors-function' for the interface it uses.
This function parses only the last TeX compilation.
It works on TeX compilations only. It is necessary for that purpose,
since TeX does not put file names and line numbers on the same line as
for the error messages."
(require 'thingatpt)
(setq compilation-error-list nil)
(let ((default-directory ; Perhaps dir has changed meanwhile.
(file-name-directory (buffer-file-name tex-last-buffer-texed)))
found-desired (num-errors-found 0)
last-filename last-linenum last-position
begin-of-error end-of-error errfilename)
;; Don't reparse messages already seen at last parse.
(goto-char compilation-parsing-end)
;; Parse messages.
(while (and (not (or found-desired (eobp)))
;; First alternative handles the newer --file-line-error style:
;; ./test2.tex:14: Too many }'s.
;; Second handles the old-style:
;; ! Too many }'s.
(prog1 (re-search-forward
"^\\(?:\\([^:\n]+\\):[[:digit:]]+:\\|!\\) " nil 'move)
(setq begin-of-error (match-beginning 0)
end-of-error (match-end 0)
errfilename (match-string 1)))
"^l\\.\\([0-9]+\\) \\(\\.\\.\\.\\)?\\(.*\\)$" nil 'move))
(let* ((this-error (copy-marker begin-of-error))
(linenum (string-to-number (match-string 1)))
(error-text (regexp-quote (match-string 3)))
;; Prefer --file-liner-error filename if we have it.
(or errfilename
(with-syntax-table tex-error-parse-syntax-table
(backward-up-list 1)
(skip-syntax-forward "(_")
(while (not
(and (setq try-filename (thing-at-point
(not (string= "" try-filename))
(file-readable-p try-filename)))
(skip-syntax-backward "(_")
(backward-up-list 1)
(skip-syntax-forward "(_"))
(thing-at-point 'filename)))))
(or (null last-filename)
(not (string-equal last-filename filename))))
(if (equal filename (concat tex-zap-file ".tex"))
(find-file-noselect filename))
(if new-file
(goto-char (point-min))
(forward-line (1- linenum))
(setq last-position nil))
(goto-char last-position)
(forward-line (- linenum last-linenum)))
;; first try a forward search for the error text,
;; then a backward search limited by the last error.
(let ((starting-point (point)))
(or (re-search-forward error-text nil t)
(re-search-backward error-text last-position t)
(goto-char starting-point)))
(goto-char this-error)
(if (and compilation-error-list
(or (and find-at-least
(>= num-errors-found
(and limit-search
(>= end-of-error limit-search)))
(setq found-desired t)
(setq num-errors-found (1+ num-errors-found)
last-filename filename
last-linenum linenum
last-position error-location
compilation-error-list ; Add the new error
(cons (cons this-error error-location)
(goto-char end-of-error)))))
(set-marker compilation-parsing-end (point))
(setq compilation-error-list (nreverse compilation-error-list)))
;;; The commands:
(defun tex-region (beg end)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment