On Thu, Nov 24, 2022 at 6:22 AM Eli Zaretskii <eliz@gnu.org> wrote:
> From: João Távora <joaotavora@gmail.com>
> Date: Wed, 23 Nov 2022 20:33:04 +0000
> Cc: Stefan Monnier <monnier@iro.umontreal.ca>,
>  Danny Freeman <danny@dfreeman.email>,
>  Eric Abrahamsen <eric@ericabrahamsen.net>, emacs-devel <emacs-devel@gnu.org>
>
>   (defun joaot/sub-projects (dir)
>     (let* ((super (project-current))
>            (super-root (project-root super))
>            (relative (file-relative-name dir super-root))
>            (d (car (split-string relative "/"))))
>       (when (member d '("lisp" "src"))
>         (cons 'transient (expand-file-name (concat d "/") super-root)))))

Is this okay for code outside project.el to know the internal structure of a
project object in general, and in particular cons "by hand" a 'transient'
project object?  I thought this was a closely-guarded implementation detail
that even doc strings are not allowed to divulge?

I don't think it's okay, no.  But I don't think project.el offers constructors
for project objects (if it does, then I am happy to use them), so I used
this (cons 'transient...) as a placeholder and a demonstration.

Another very similar way to go about this would be for joaot/sub-projects
to be named project-sub-products and live in project.el, where it would
be free to access its own internals.

(defvar project-sub-project-prefixes nil
  "List of strings designating sub-projects.
This variable should be set directory-locally.")

(defun project-sub-projects (dir)
  (let* ((super (project-current))
         (super-root (project-root super))
         (relative (file-relative-name dir super-root))
         (d (car (split-string relative "/"))))
    (cl-loop for prefix in project-sub-project-prefixes
             when (string-prefix-p prefix relative)
             return (cons 'transient (expand-file-name prefix super-root)))))

Then it would be a question of setting project-sub-project-prefixes
to, say, '("lisp/progmodes" "test" "doc" "src") in Emacs's .dir-locals
(or using dir-locals-set-class-variables as an alternative).

João