Function: compilation-find-file
compilation-find-file is a byte-compiled function defined in
compile.el.gz.
Signature
(compilation-find-file MARKER FILENAME DIRECTORY &rest FORMATS)
Documentation
Find a buffer for file FILENAME.
If FILENAME is not found at all, ask the user where to find it.
Pop up the buffer containing MARKER and scroll to MARKER if we ask
the user where to find the file.
Search the directories in compilation-search-path.
A nil in compilation-search-path means to try the
"current" directory, which is passed in DIRECTORY.
If DIRECTORY is relative, it is combined with default-directory.
If DIRECTORY is nil, that means use default-directory.
FORMATS, if given, is a list of formats to reformat FILENAME when
looking for it: for each element FMT in FORMATS, this function
attempts to find a file whose name is produced by (format FMT FILENAME).
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/compile.el.gz
(defun compilation-find-file (marker filename directory &rest formats)
"Find a buffer for file FILENAME.
If FILENAME is not found at all, ask the user where to find it.
Pop up the buffer containing MARKER and scroll to MARKER if we ask
the user where to find the file.
Search the directories in `compilation-search-path'.
A nil in `compilation-search-path' means to try the
\"current\" directory, which is passed in DIRECTORY.
If DIRECTORY is relative, it is combined with `default-directory'.
If DIRECTORY is nil, that means use `default-directory'.
FORMATS, if given, is a list of formats to reformat FILENAME when
looking for it: for each element FMT in FORMATS, this function
attempts to find a file whose name is produced by (format FMT FILENAME)."
(pcase-let ((`(,buffer ,spec-dir)
(compilation-find-file-1 marker filename directory formats)))
(while (null buffer) ;Repeat until the user selects an existing file.
;; The file doesn't exist. Ask the user where to find it.
(save-excursion ;This save-excursion is probably not right.
(let ((w (let ((pop-up-windows t))
(display-buffer (marker-buffer marker)
'(nil (allow-no-window . t))))))
(with-current-buffer (marker-buffer marker)
(goto-char marker)
(and w (progn (compilation-set-window w marker)
(compilation-set-overlay-arrow w))))
(let* ((name (read-file-name
(format-prompt "Find this %s in"
filename compilation-error)
spec-dir filename t nil
;; The predicate below is fine when called from
;; minibuffer-complete-and-exit, but it's too
;; restrictive otherwise, since it also prevents the
;; user from completing "fo" to "foo/" when she
;; wants to enter "foo/bar".
;;
;; Try to make sure the user can only select
;; a valid answer. This predicate may be ignored,
;; tho, so we still have to double-check afterwards.
;; TODO: We should probably fix read-file-name so
;; that it never ignores this predicate, even when
;; using popup dialog boxes.
;; (lambda (name)
;; (if (file-directory-p name)
;; (setq name (expand-file-name filename name)))
;; (file-exists-p name))
))
(origname name))
(cond
((not (file-exists-p name))
(message "Cannot find file `%s'" name)
(ding) (sit-for 2))
((and (file-directory-p name)
(not (file-exists-p
(setq name (compilation--expand-fn name filename)))))
(message "No `%s' in directory %s" filename origname)
(ding) (sit-for 2))
(t
(setq buffer (find-file-noselect name))))))))
;; Make intangible overlays tangible.
;; This is weird: it's not even clear which is the current buffer,
;; so the code below can't be expected to DTRT here. -- Stef
(dolist (ov (overlays-in (point-min) (point-max)))
(when (overlay-get ov 'intangible)
(overlay-put ov 'intangible nil)))
buffer))