Subject: bug#12492: Acknowledgement (24.2.50; Open vc-dir buffer easier and faster)

From: Juri Linkov <[email-masked]>
Date: Fri, 28 Feb 2020 00:50:45 +0200

> I'd prefer an option whose customization would allow `C-x v d'
> to always use the root.

Given all the discussed constraints (no change in default behavior of
`C-x v d' is allowed, etc.), I see one way to close this bug report -
to add a customizable variable:

diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index e5c5e16a17..2699f8155b 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -1285,6 +1285,22 @@ vc-dir-deduce-fileset
 	(setq model (vc-checkout-model vc-dir-backend only-files-list))))
     (list vc-dir-backend files only-files-list state model)))
 
+(defcustom vc-dir-default-directory nil
+  "Default directory name for the command `vc-dir'.
+When nil, `vc-dir' reads a directory name using the minibuffer.
+When non-nil and the current directory is under version control,
+`vc-dir' doesn't ask for a directory name and uses the VC root directory.
+When a string and `vc-dir' is invoked in a directory outside of
+version control, then this string is used as a default directory name.
+
+However, the prefix arg of `vc-dir' overrides this customization
+and still asks for a directory name and backend."
+  :type '(choice (const :tag "Ask for directory" nil)
+                 (const :tag "Use VC root directory" t)
+                 (string :tag "Custom directory"))
+  :group 'vc
+  :version "28.1")
+
 ;;;###autoload
 (defun vc-dir (dir &optional backend)
   "Show the VC status for \"interesting\" files in and below DIR.
@@ -1304,22 +1320,29 @@ vc-dir
 \\{vc-dir-mode-map}"
 
   (interactive
-   (list
-    ;; When you hit C-x v d in a visited VC file,
-    ;; the *vc-dir* buffer visits the directory under its truename;
-    ;; therefore it makes sense to always do that.
-    ;; Otherwise if you do C-x v d -> C-x C-f -> C-c v d
-    ;; you may get a new *vc-dir* buffer, different from the original
-    (file-truename (read-directory-name "VC status for directory: "
-					(vc-root-dir) nil t
-					nil))
-    (if current-prefix-arg
-	(intern
-	 (completing-read
-	  "Use VC backend: "
-	  (mapcar (lambda (b) (list (symbol-name b)))
-		  vc-handled-backends)
-	  nil t nil nil)))))
+   (let ((dir
+          ;; When you hit C-x v d in a visited VC file,
+          ;; the *vc-dir* buffer visits the directory under its truename;
+          ;; therefore it makes sense to always do that.
+          ;; Otherwise if you do C-x v d -> C-x C-f -> C-x v d
+          ;; you may get a new *vc-dir* buffer, different from the original
+          (file-truename
+           (let ((root-dir (vc-root-dir)))
+             (if (and vc-dir-default-directory
+                      (not current-prefix-arg)
+                      (or root-dir (and (stringp vc-dir-default-directory)
+                                        (file-directory-p vc-dir-default-directory))))
+                 (or root-dir vc-dir-default-directory)
+               (read-directory-name "VC status for directory: "
+                                    (vc-root-dir) nil t nil))))))
+     (list dir (if current-prefix-arg
+                   (intern
+                    (completing-read
+                     "Use VC backend: "
+                     (mapcar (lambda (b) (list (symbol-name b)))
+                             vc-handled-backends)
+                     nil t nil nil (symbol-name (ignore-errors
+                                                  (vc-responsible-backend dir)))))))))
   (unless backend
     (setq backend (vc-responsible-backend dir)))
   (let (pop-up-windows)		      ; based on cvs-examine; bug#6204