Function: project-find-matching-file-or-directory

project-find-matching-file-or-directory is a byte-compiled function defined in project.el.gz.

Signature

(project-find-matching-file-or-directory CURRENT-PROJECT MIRROR-PROJECT)

Documentation

Visit file or directory in another project that matches the current one.

A file-visiting buffer's matching file has the same file name relative to the project root. A non-file-visiting buffer's matching directory has the same default-directory relative to the project root. As a special case, when point is on an inserted subdirectory in a Dired buffer, use that subdirectory instead of default-directory. CURRENT-PROJECT is the project instance for the current project. MIRROR-PROJECT is the project instance for the project to visit. Also skip to the same line number.

If the matching file does not exist in the other project, try going up the directory tree until encountering a file or directory that exists. For example, from a buffer visiting a file "lisp/vc/vc.el", if in the other project this file does not exist, try visiting "lisp/vc" if that exists as a file or directory.

If a matching directory does not exist in the other project, try going up the directory tree until encountering a directory that exists. For example, from a Dired buffer visiting a subdirectory named "lisp/vc/", if in the other project "lisp/vc" is missing or not a directory, try visiting a directory named "lisp/" in the other project.

This function is intended to be used as the value of project-find-matching-buffer-function.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/project.el.gz
(defun project-find-matching-file-or-directory (current-project mirror-project)
  "Visit file or directory in another project that matches the current one.
A file-visiting buffer's matching file has the same file name relative
to the project root.  A non-file-visiting buffer's matching directory
has the same `default-directory' relative to the project root.
As a special case, when point is on an inserted subdirectory in a Dired
buffer, use that subdirectory instead of `default-directory'.
CURRENT-PROJECT is the project instance for the current project.
MIRROR-PROJECT is the project instance for the project to visit.
Also skip to the same line number.

If the matching file does not exist in the other project, try going up
the directory tree until encountering a file or directory that exists.
For example, from a buffer visiting a file \"lisp/vc/vc.el\", if in the
other project this file does not exist, try visiting \"lisp/vc\" if that
exists as a file or directory.

If a matching directory does not exist in the other project, try going
up the directory tree until encountering a directory that exists.  For
example, from a Dired buffer visiting a subdirectory named \"lisp/vc/\",
if in the other project \"lisp/vc\" is missing or not a directory, try
visiting a directory named \"lisp/\" in the other project.

This function is intended to be used as the value of
`project-find-matching-buffer-function'."
  (let* ((line (line-number-at-pos nil t))
         (dirp (not (buffer-file-name)))
         (mirror-root (project-root mirror-project))
         (relative-name
          (file-relative-name (cond ((derived-mode-p 'dired-mode)
                                     (dired-current-directory))
                                    ((buffer-file-name))
                                    (t default-directory))
                              (project-root current-project)))
         (mirror-name (expand-file-name relative-name mirror-root))
         (orig-mirror-name mirror-name))
    (while (not (if dirp (file-directory-p mirror-name)
                  (file-exists-p mirror-name)))
      (setq mirror-name (directory-file-name
                         (file-name-parent-directory mirror-name)))
      (unless (file-in-directory-p mirror-name mirror-root)
        (user-error "`%s' not found in `%s'" relative-name mirror-root)))
    (find-file mirror-name)
    (save-restriction
      (widen)
      (goto-char (point-min))
      (forward-line (1- line)))
    (unless (equal mirror-name orig-mirror-name)
      (message "`%s' not found; visiting `%s' instead"
               (abbreviate-file-name orig-mirror-name)
               (abbreviate-file-name (if (file-directory-p mirror-name)
                                         (file-name-as-directory mirror-name)
                                       mirror-name))))))