]> git.eshelyaron.com Git - emacs.git/commitdiff
Support calling 'project-current' with custom prompt
authorDmitry Gutov <dmitry@gutov.dev>
Mon, 7 Oct 2024 23:03:04 +0000 (02:03 +0300)
committerEshel Yaron <me@eshelyaron.com>
Mon, 14 Oct 2024 17:33:05 +0000 (19:33 +0200)
* lisp/progmodes/project.el (project-current): Treat being passed
a string in the MAYBE-CURRENT argument specially (bug#70833).
(project-prompt-project-dir, project-prompt-project-name):
Handle it.

* etc/NEWS: Mention that change.

(cherry picked from commit 9904376c797665de47ff760bcf8c2fe33d7ae625)

etc/NEWS
lisp/minibuffer.el
lisp/progmodes/project.el

index 6674ab9d5ea1e56315dfe193bebe947e6f84694e..b55db508078640bec7d52cba1857fcb4665d701c 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -94,6 +94,12 @@ This hook allows you to control which tab-bar tabs are auto-resized.
 *** New command 'project-root-find-file'.
 It is equivalent to running ‘project-any-command’ with ‘find-file’.
 
+---
+*** The MAYBE-PROMPT argument of 'project-current' can be a string.
+When such value is used, the 'project-prompt' values are called with it
+as the first argument.  This is a way for the callers to indicate, for
+example, the reason or the context why the project is asked for.
+
 \f
 * Editing Changes in Emacs 31.1
 
index 55fe0b93b5ddcd3b46af9611c55712220d9c1513..1f52345dce14da08e8ddc3bb910c9394d5b98566 100644 (file)
@@ -6272,7 +6272,7 @@ This variable is used by the `format-prompt' function."
   :version "28.1"
   :type 'string)
 
-(defun format-prompt (prompt default &rest format-args)
+(defun format-prompt (prompt &optional default &rest format-args)
   "Format PROMPT with DEFAULT according to `minibuffer-default-prompt-format'.
 If FORMAT-ARGS is nil, PROMPT is used as a plain string.  If
 FORMAT-ARGS is non-nil, PROMPT is used as a format control
index c9e2dab100e2fe0379c031c9140025eb40783982..7d8b41c57a7d8e5ba899e207dc3516081b5780f0 100644 (file)
@@ -218,7 +218,8 @@ else prompt the user for the project to use.  To prompt for a
 project, call the function specified by `project-prompter', which
 returns the directory in which to look for the project.  If no
 project is found in that directory, return a \"transient\"
-project instance.
+project instance.  When MAYBE-PROMPT is a string, it's passed to the
+prompter function as an argument.
 
 The \"transient\" project instance is a special kind of value
 which denotes a project rooted in that directory and includes all
@@ -235,7 +236,8 @@ of the project instance object."
      (pr)
      ((unless project-current-directory-override
         maybe-prompt)
-      (setq directory (funcall project-prompter)
+      (setq directory (funcall project-prompter
+                               (when (stringp maybe-prompt) maybe-prompt))
             pr (project--find-in-directory directory))))
     (when maybe-prompt
       (if pr
@@ -1896,11 +1898,12 @@ the project list."
 
 (defvar project--dir-history)
 
-(defun project-prompt-project-dir ()
+(defun project-prompt-project-dir (&optional prompt)
   "Prompt the user for a directory that is one of the known project roots.
 The project is chosen among projects known from the project list,
 see `project-list-file'.
-It's also possible to enter an arbitrary directory not in the list."
+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)
   (let* ((dir-choice "... (choose a dir)")
          (choices
@@ -1914,18 +1917,20 @@ It's also possible to enter an arbitrary directory not in the list."
       ;; If the user simply pressed RET, do this again until they don't.
       (setq pr-dir
             (let (history-add-new-input)
-              (completing-read "Select project: " choices nil t nil 'project--dir-history))))
+              (completing-read (format-prompt (or prompt "Select project"))
+                               choices nil t nil 'project--dir-history))))
     (if (equal pr-dir dir-choice)
         (read-directory-name "Select directory: " default-directory nil t)
       pr-dir)))
 
 (defvar project--name-history)
 
-(defun project-prompt-project-name ()
+(defun project-prompt-project-name (&optional prompt)
   "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'.
-It's also possible to enter an arbitrary directory not in the list."
+It's also possible to enter an arbitrary directory not in the list.
+When PROMPT is non-nil, use it as the prompt string."
   (let* ((dir-choice "... (choose a dir)")
          project--name-history
          (choices
@@ -1949,7 +1954,8 @@ It's also possible to enter an arbitrary directory not in the list."
       ;; If the user simply pressed RET, do this again until they don't.
       (setq pr-name
             (let (history-add-new-input)
-              (completing-read "Select project: " table nil t nil 'project--name-history))))
+              (completing-read (format-prompt (or prompt "Select project"))
+                               table nil t nil 'project--name-history))))
     (if (equal pr-name dir-choice)
         (read-directory-name "Select directory: " default-directory nil t)
       (let ((proj (assoc pr-name choices)))