From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier via Users list for the GNU Emacs text editor Newsgroups: gmane.emacs.help Subject: Re: Navigating an enormous code base Date: Tue, 13 Dec 2022 22:47:49 -0500 Message-ID: References: Reply-To: Stefan Monnier Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="36553"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) To: help-gnu-emacs@gnu.org Cancel-Lock: sha1:zc8uLebS+XgX+FXvpp/KXHopc38= Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Wed Dec 14 04:48:41 2022 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1p5Il7-0009KD-82 for geh-help-gnu-emacs@m.gmane-mx.org; Wed, 14 Dec 2022 04:48:41 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p5IkR-0006BH-SO; Tue, 13 Dec 2022 22:48:00 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5IkQ-0006B8-Q1 for help-gnu-emacs@gnu.org; Tue, 13 Dec 2022 22:47:58 -0500 Original-Received: from ciao.gmane.io ([116.202.254.214]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p5IkO-0007e5-VA for help-gnu-emacs@gnu.org; Tue, 13 Dec 2022 22:47:58 -0500 Original-Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1p5IkL-0008Jl-Rh for help-gnu-emacs@gnu.org; Wed, 14 Dec 2022 04:47:53 +0100 X-Injected-Via-Gmane: http://gmane.org/ Received-SPF: pass client-ip=116.202.254.214; envelope-from=geh-help-gnu-emacs@m.gmane-mx.org; helo=ciao.gmane.io X-Spam_score_int: -15 X-Spam_score: -1.6 X-Spam_bar: - X-Spam_report: (-1.6 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.help:141727 Archived-At: > 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)))))))))