Function: project-prompt-project-name

project-prompt-project-name is a byte-compiled function defined in project.el.gz.

Signature

(project-prompt-project-name &optional PROMPT PREDICATE REQUIRE-KNOWN)

Documentation

Prompt the user for a project, by name, that is one of the known project roots.

The project is chosen among projects known from the project list, see project-list-file. If PROMPT is non-nil, use it as the prompt string. If PREDICATE is non-nil, filter possible project choices using this function; see project-prompter for more details. Unless REQUIRE-KNOWN is non-nil, it's also possible to enter an arbitrary directory not in the list of known projects.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/project.el.gz
(defun project-prompt-project-name (&optional prompt predicate require-known)
  "Prompt the user for a project, by name, that is one of the known project roots.
The project is chosen among projects known from the project list,
see `project-list-file'.
If PROMPT is non-nil, use it as the prompt string.
If PREDICATE is non-nil, filter possible project choices using this
function; see `project-prompter' for more details.
Unless REQUIRE-KNOWN is non-nil, it's also possible to enter an
arbitrary directory not in the list of known projects."
  (when-let* ((pred (alist-get 'prompt project-prune-zombie-projects))
              (inhibit-message t))
    (project--delete-zombie-projects pred))
  (let* ((dir-choice "... (choose a dir)")
         project--name-history
         (current (and-let* ((p (project-current))
                             (_ (or (null predicate)
                                    (funcall predicate
                                             (project-root p)))))
                    (project-name p)))
         (choices
          (let (ret)
            ;; Iterate in reverse order so project--name-history is in
            ;; the same order as project--list.
            (dolist (dir (reverse (project-known-project-roots)))
              ;; We filter out directories that no longer map to a project,
              ;; since they don't have a clean project-name.
              (when-let* (((or (not predicate) (funcall predicate dir)))
                          (proj (project--find-in-directory dir))
                          (name (project-name proj)))
                (push name project--name-history)
                (push (cons name proj) ret)))
            (reverse ret)))
         ;; XXX: Just using this for the category (for the substring
         ;; completion style).
         (table (project--file-completion-table
                 (reverse (if require-known choices
                            (cons dir-choice choices)))))
         (pr-name ""))
    (while (string-empty-p pr-name)
      ;; If the user simply pressed RET (and CURRENT is nil), do this
      ;; again until they don't.
      (setq pr-name
            (let (history-add-new-input)
              (completing-read
               ;; Emacs 28.1+: Use `format-prompt'.
               (cond (prompt (format "%s: " prompt))
                     (current "Select project (default current project): ")
                     (t "Select project: "))
               table nil t nil 'project--name-history current))))
    (if (equal pr-name dir-choice)
        (read-directory-name "Select directory: " default-directory nil t)
      (let ((proj (assoc pr-name choices)))
        (if (stringp proj) proj (project-root (cdr proj)))))))