Subject: bug#63870: 29.0.90; project.el can't dynamically populate the project list

From: Eli Zaretskii <[email-masked]>
Date: Wed, 28 Jun 2023 14:24:46 +0300

> From: Spencer Baugh <[email-masked]>
> Date: Tue, 27 Jun 2023 15:27:30 -0400
> 
> +(defun project-check-project (dir)
> +  "If there's a project at DIR, remember it; otherwise, forget it.
> +
> +Return the found project, if any."
> +  (let ((pr (project--find-in-directory dir)))
> +    (if pr (project-remember-project pr)
> +      (project-forget-project (file-name-as-directory dir)))
> +    pr))
> +
> +(defun project--watch-cb-children (recursive predicate event)
> +  (unless (eq (cl-second event) 'stopped)
> +    (dolist (file (cddr event))
> +      (condition-case _ (project-watch file recursive predicate)
> +        ((file-error file-notify-error))))))
> +
> +(defun project--watch-cb-this (dir event)
> +  (unless (eq (cl-second event) 'stopped)
> +    (when (project-check-project dir)
> +      (file-notify-rm-watch (cl-first event)))))
> +
> +(defun project--file-notify-watch (dir callback &optional init)
> +  "Like `file-notify-add-watch' but also calls CALLBACK immediately."
> +  (let ((watch (file-notify-add-watch dir '(change) callback)))
> +    (funcall callback (append (list watch 'started) init))))

Beware of watching a tree recursively: file notifications are not very
scalable, for more than one reason.  For example, the inotify backend
consumes a file descriptor and a slot in the descriptor set monitored
by pselect per each file/directory you watch.  And watching many
directories can overwhelm Emacs if some program (even unrelated to
Emacs) performs many file operations in that directory; VCS programs
are notorious in this regard, e.g., when you update from upstream.

> +(defun project-watch (dir &optional recursive predicate)
> +  "Watch DIR until it becomes a project.
> +
> +We stop watching DIR once it becomes a project.

This never explains what it means for a directory to "become a
project".  It should, because this doc string begs that question.

> +If RECURSIVE is an integer greater than 0, we'll also run
> +`project-watch' on directories which appear inside DIR,
> +passing (1- RECURSIVE) as RECURSIVE.  To achieve this, we'll
> +continue watching DIR even if it becomes a project.  This can be
> +expensive, so it's better to pass small values of RECURSIVE, like
> +1 or 2.

Are you sure this feature justifies the risks?  When would someone
want to use it, while simultaneously limiting the value of RECURSIVE
to some small integer?  (And what is considered "small" for these
purposes?)

Thanks.