branch: elpa/magit
commit 6177b4d210eaa57f4a91e41c6d66a18e0b659254
Author: Jonas Bernoulli <[email protected]>
Commit: Jonas Bernoulli <[email protected]>

    magit-read-worktree-directory-function: New option
    
    This replaces `magit-worktree-read-directory-name-function', which
    wasn't flexible enough.
---
 lisp/magit-worktree.el | 89 ++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 71 insertions(+), 18 deletions(-)

diff --git a/lisp/magit-worktree.el b/lisp/magit-worktree.el
index bfc7b5b2fa4..75af6a36840 100644
--- a/lisp/magit-worktree.el
+++ b/lisp/magit-worktree.el
@@ -30,14 +30,63 @@
 
 ;;; Options
 
-(defcustom magit-worktree-read-directory-name-function #'read-directory-name
-  "Function used to read a directory for worktree commands.
-This is called with one argument, the prompt, and can be used
-to, e.g., use a base directory other than `default-directory'.
-Used by `magit-worktree-checkout' and `magit-worktree-branch'."
-  :package-version '(magit . "3.0.0")
+(defcustom magit-read-worktree-directory-function
+  #'magit-read-worktree-directory-sibling
+  "Function used to read the directory to be used as a new worktree.
+This is called with two argument, the prompt and the branch to be
+checked out.  When not checking out a branch then use nil for the
+second argument."
+  :package-version '(magit . "4.3.9")
   :group 'magit-commands
-  :type 'function)
+  :type `(radio (function-item ,#'magit-read-worktree-directory)
+                (function-item ,#'magit-read-worktree-directory-nested)
+                (function-item ,#'magit-read-worktree-directory-sibling)
+                function))
+
+(defvar magit-worktree-read-directory-name-function nil
+  "Like `magit-read-worktree-directory-function' but takes only one argument.")
+(make-obsolete-variable 'magit-worktree-read-directory-name-function
+                        'magit-read-worktree-directory-function
+                        "Magit 4.3.9")
+
+;;; Functions
+
+(defun magit-read-worktree-directory (prompt _branch)
+  "Call `read-directory-name' with PROMPT, but ignoring _BRANCH."
+  (read-directory-name prompt))
+
+(defun magit-read-worktree-directory-nested (prompt branch)
+  "Call `read-directory-name' in current worktree.
+For `read-directory-name's INITIAL argument use a string based on
+BRANCH, replacing slashes with dashes.  If BRANCH is nil, use nil
+as INITIAL.  Always forward PROMPT as-is."
+  (read-directory-name prompt nil nil nil
+                       (and branch (string-replace "/" "-" branch))))
+
+(defun magit-read-worktree-directory-sibling (prompt branch)
+  "Call `read-directory-name' in parent directory of current worktree.
+For `read-directory-name's INITIAL argument use a string based on the
+name of the current worktree and BRANCH.  Use \"PREFIX_BRANCH\" where
+PREFIX is the name of the current worktree, up to the first underscore,
+and slashes in BRANCH are replaced with dashes.  If BRANCH is nil use
+just \"PREFIX_\".  Always forward PROMPT as-is."
+  (let* ((path (directory-file-name default-directory))
+         (name (file-name-nondirectory path)))
+    (read-directory-name
+     prompt (file-name-directory path) nil nil
+     (concat (if (string-match "/" name)
+                 (substring name 0 (match-beginning 0))
+               name)
+             "_"
+             (and branch (string-replace "/" "-" branch))))))
+
+(defun magit--read-worktree-directory (rev branchp)
+  (let ((default-directory (magit-toplevel))
+        (prompt (format "Checkout %s in new worktree: " rev)))
+    (if magit-worktree-read-directory-name-function
+        (funcall magit-worktree-read-directory-name-function prompt)
+      (funcall magit-read-worktree-directory-function
+               prompt (and branchp rev)))))
 
 ;;; Commands
 
@@ -54,26 +103,30 @@ Used by `magit-worktree-checkout' and 
`magit-worktree-branch'."
     ("g" "Visit worktree"        magit-worktree-status)]])
 
 ;;;###autoload
-(defun magit-worktree-checkout (directory branch)
-  "Checkout BRANCH in a new worktree at DIRECTORY."
+(defun magit-worktree-checkout (directory commit)
+  "Checkout COMMIT in a new worktree in DIRECTORY.
+COMMIT may, but does not have to be, a local branch.
+Interactively, use `magit-read-worktree-directory-function'."
   (interactive
-   (let ((branch (magit-read-branch-or-commit
+   (let ((commit (magit-read-branch-or-commit
                   "In new worktree; checkout" nil
                   (mapcar #'caddr (magit-list-worktrees)))))
-     (list (funcall magit-worktree-read-directory-name-function
-                    (format "Checkout %s in new worktree: " branch))
-           branch)))
+     (list (magit--read-worktree-directory commit (magit-local-branch-p 
commit))
+           commit)))
   (when (zerop (magit-run-git "worktree" "add"
-                              (magit--expand-worktree directory) branch))
+                              (magit--expand-worktree directory) commit))
     (magit-diff-visit-directory directory)))
 
 ;;;###autoload
 (defun magit-worktree-branch (directory branch start-point)
-  "Create a new BRANCH and check it out in a new worktree at DIRECTORY."
+  "Create a new BRANCH and check it out in a new worktree at DIRECTORY.
+Interactively, use `magit-read-worktree-directory-function'."
   (interactive
-   `(,(funcall magit-worktree-read-directory-name-function
-               "In new worktree; checkout new branch")
-     ,@(magit-branch-read-args "Create and checkout branch")))
+   (pcase-let
+       ((`(,branch ,start-point)
+         (magit-branch-read-args "In new worktree; checkout new branch")))
+     (list (magit--read-worktree-directory branch t)
+           branch start-point)))
   (when (zerop (magit-run-git "worktree" "add" "-b" branch
                               (magit--expand-worktree directory) start-point))
     (magit-diff-visit-directory directory)))

Reply via email to