help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Navigating an enormous code base


From: Stefan Monnier
Subject: Re: Navigating an enormous code base
Date: Tue, 13 Dec 2022 22:47:49 -0500
User-agent: Gnus/5.13 (Gnus v5.13)

> There could be several notions of "sibling":
> - jump from /foo/bar/main/src/hello.c to /foo/bar/stable/src/hello.c.
> - jump from /foo/bar/main/src/hello.c to 
> /foo/bar/main/test/src/hello-tests.el.
> - jump from /foo/bar/main/src/hello.c to /foo/bar/main/src/hello.h.

The function below can do all three given the appropriate hint:
- "stable" for the first.
- "-tests" for the second.
- ".h" for the third.

It can also find "/foo/bar/stable/src/hello.h" when given the hint
"stable/.h".


        Stefan


(defun my-other-files (hint file)
  (cl-assert (file-name-absolute-p file))
  (named-let loop ((fullname file)
                   (hint hint)
                   (rest nil))
    (if (file-name-directory hint)
        (let* ((hintbase (directory-file-name (file-name-directory hint)))
               (hintend (file-name-nondirectory hint)))
          (apply #'append
                 (mapcar (lambda (x)
                           (let ((default-directory
                                  (file-name-as-directory (car x)))
                                 (tail (cdr x)))
                             (mapcar
                              (lambda (x)
                                (cons (file-name-concat default-directory
                                                        (car x))
                                      (cdr x)))
                              (loop tail hintend rest))))
                         (loop fullname hintbase rest))))
      (let ((dir (file-name-directory fullname))
            (file (file-name-nondirectory fullname))
            (names '())
            (re (regexp-quote hint)))
        (when dir
          (dolist (candidate (directory-files dir nil re))
            (when (string-match re candidate)
              (let ((prefix (substring candidate 0 (match-beginning 0)))
                    (suffix (substring candidate (match-end 0))))
                (when (and (>= (length file)
                               (+ (length prefix) (length suffix)))
                           (string-prefix-p prefix file)
                           (string-suffix-p suffix file))
                  (push candidate names)))))
          (nconc
           (mapcar (lambda (name) (cons (file-name-concat dir name) rest)) 
names)
           (when (> (length dir)
                    (length (setq dir (directory-file-name dir))))
             (loop dir hint (if rest (file-name-concat file rest) file)))))))))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]