1

I am trying to add a language called lesim to compilation mode so that errors are parsed correctly. The error line does not include the file name. Among the ways I have tried to get around this, what has worked best has been to store the filename in a variable and then set compilation-buffer-name-function to return that variable. This is what I have in the command that defines the major mode for the language:

(setq lesim--script-path (buffer-file-name))
(setq compilation-buffer-name-function (lambda (buf) lesim--script-path))

I then configure the compilation error alists like this:

(add-to-list 'compilation-error-regexp-alist 'lesim)
(add-to-list 'compilation-error-regexp-alist-alist
       '(lesim "Error on line \\([0-9]+\\): " nil 1))

I can see that providing nil for the FILE slot in the alist-alist causes compilation mode to run compilation-buffer-name-function (I can add a message in the lambda above and see that displayed in *Messages*). I can also see that "Error on line XXX" messages are highlighted, but when I follow the link I end up in the wrong file (at the correct line for the error message).

Here are other details: the language is implemented as a python program and when parsing fails there are first some python error messages and then the language's "Error on line XXX" message. When I follow the "Error on line XXX" link, I end up in one of the python files mentioned in one of the earlier python messages.

Another (more minor) issue is that I would like compilation mode to ignore the python messages as that's not something that needs concern the user trying to fix their own program.

EDIT: I found a partial solution but I am not 100% happy with it because it sets a global variable. So, this works:

(setq lesim--file (buffer-file-name)) ; store filename 
(add-to-list 'compilation-error-regexp-alist 'lesim)
(add-to-list 'compilation-error-regexp-alist-alist
         '(lesim
           "Error on line \\([0-9]+\\): "
           (lambda () lesim--file)
           1))

but it no longer works if I replace (lambda () lesim--file) with a function that looks for the file name in the compilation buffer for the file name. That is, the last part of the above code is:

(add-to-list 'compilation-error-regexp-alist-alist
         '(lesim
           "Error on line \\([0-9]+\\): "
           (lambda () (lesim-file))
           1))

where lesim-file is:

(defun lesim-file ()
   ""
   (save-excursion
     (save-restriction
       (widen)
       (goto-char (point-min))
       (when (re-search-forward (concat lesim-command " \\(.+\\)$"))
       (substring-no-properties (match-string 1))))))

I have tested that this correctly locates the file name in the compilation buffer.

As said, the solution with the global variable works, but it would be great if I could avoid the global variable since I can scan the compilation buffer for the file name...

Stefano
  • 131
  • 7

0 Answers0