On Jun 22, 2023, at 10:58 AM, Daniel MartÃn <mardani29@yahoo.es> wrote:
Dave Abrahams <dave@boostpro.com> writes:
Swift is a programming language. When its assertions (like C's
assert() macro) fail, a diagnostic is output with a file ID and
line. The file ID looks like a path, but it's really not. If it's a
path in the filesystem, that's coincidental but it's likely to point
to the right file. I don't want to manually hunt down the file every
time an assertion fails; I'd rather emacs made an educated guess based
on the current project. It's obviously not the right answer for
everyone, but I'd like to have the hooks needed to implement that
without too much hackery.
This is the Elisp code you posted on GitHub, based on customizingcompilation-parse-errors-filename-function:(defun dwa/path-tails-matching (path paths) "Returns the elements of PATHS with PATH as their suffix, matching by path component." (let ((tail (file-name-concat "/" path))) (seq-filter (lambda (full-path) (string-suffix-p tail full-path)) paths)))(defun dwa/compilation-parse-errors-filename-in-project (path-in-error) "If PATH-IN-ERROR is found in the filesystem, returns itunchanged; otherwise tries to return a unique file in the currentproject likely to be identified by PATH-IN-ERROR. ReturnsPATH-IN-ERROR unchanged if no such file can be found." (if (file-exists-p path-in-error) path-in-error ;; First look for relative path suffixes. (let* ((candidates (project-files (project-current t))) (full-matches (dwa/path-tails-matching path-in-error candidates))) ;; If not found, try just the filename component of ;; path-in-error; Swift assertions are weird and include a ;; module name that doesn't necessarily correspond to anything in the ;; filesystem. (cond ((null full-matches) (let ((filename-matches (dwa/path-tails-matching (file-name-nondirectory path-in-error) candidates))) (cond ((null filename-matches) path-in-error) ;; unique match; return it ((null (cadr filename-matches)) (car filename-matches)) ;; multiple matches; consider prompting for the user to select one. (t path-in-error)))) ;; unique match; return it ((null (cadr matches)) (car matches)) ; multiple matches; consider prompting for the user to select one. (t path-in-error)))))(setq compilation-parse-errors-filename-function 'dwa/compilation-parse-errors-filename-in-project)I've tried it and it seems to work well, although I agree that the codeis a bit hacky and prone to error. How would the new hooks you proposesimplify this customization code?
It would not. The problem with this code is that it runs too early. That means two things:
1. if you get 1000 errors in different files, this code will try to resolve each one, accessing the filesystem during parsing, before the compilation buffer even font locks, which is really inefficient especially if you only care about the first of these errors.
2. There's no good way to prompt the user for a match when there are multiple matches.
I want a hook that will be run at the time compile.el currently prompts me to locate the file in the filesystem: the first time I visit an error at a given path and no file is found there by emacs.
Yes, I think I could probably get where I need to by advising compilation-find-file.