:group 'project
:package-version '(project . "0.8.2"))
+(defcustom project-prune-zombie-projects #'project-prune-zombies-default
+ "Remove automatically from project list all the projects that were removed.
+The value can be a predicate function which takes one argument, and
+should return non-nil if the project should be removed.
+If set to nil, all the inaccessible projects will not be removed automatically."
+ :type '(choice (const :tag "Default (remove non-remote projects)"
+ project-prune-zombies-default)
+ (const :tag "Remove any project" identity)
+ (function :tag "Custom function")
+ (const :tag "Disable auto-deletion" nil))
+ :version "31.1"
+ :group 'project)
+
+(defun project-prune-zombies-default (project)
+ "Default function used in `project-prune-zombie-projects'.
+Return non-nil if PROJECT is not a remote project."
+ (not (file-remote-p project)))
+
(defun project--read-project-buffer ()
(let* ((pr (project-current t))
(current-buffer (current-buffer))
(defun project--ensure-read-project-list ()
"Initialize `project--list' if it isn't already initialized."
(when (eq project--list 'unset)
- (project--read-project-list)))
+ (project--read-project-list)
+ (if-let* (project-prune-zombie-projects
+ ((consp project--list))
+ (inhibit-message t))
+ (project-forget-zombie-projects))))
(defun project--write-project-list ()
"Save `project--list' in `project-list-file'."
It's also possible to enter an arbitrary directory not in the list.
When PROMPT is non-nil, use it as the prompt string."
(project--ensure-read-project-list)
+ (if-let* (project-prune-zombie-projects
+ (inhibit-message t))
+ (project-forget-zombie-projects))
(let* ((dir-choice "... (choose a dir)")
(choices
;; XXX: Just using this for the category (for the substring
see `project-list-file'.
It's also possible to enter an arbitrary directory not in the list.
When PROMPT is non-nil, use it as the prompt string."
+ (if-let* (project-prune-zombie-projects
+ (inhibit-message t))
+ (project-forget-zombie-projects))
(let* ((dir-choice "... (choose a dir)")
project--name-history
(choices
"Forget all known projects that don't exist any more."
(interactive)
(dolist (proj (project-known-project-roots))
- (unless (file-exists-p proj)
+ (when (and (if project-prune-zombie-projects
+ (funcall project-prune-zombie-projects proj)
+ t)
+ (not (file-exists-p proj)))
(project-forget-project proj))))
(defun project-read-ancestor-directory (prompt)