summaryrefslogtreecommitdiff
path: root/lisp/dired-aux.el
diff options
context:
space:
mode:
authorJuri Linkov <juri@linkov.net>2020-03-30 01:34:47 +0300
committerJuri Linkov <juri@linkov.net>2020-03-30 01:34:47 +0300
commit7a6f5a5167037cdc3a0e9e312393781daedec085 (patch)
tree4ecad790cfa5a3d82be76d7b672a22cce1153b02 /lisp/dired-aux.el
parent1276c8e10b000b571a12227ebe9216cc6305ef7f (diff)
downloademacs-7a6f5a5167037cdc3a0e9e312393781daedec085.tar.gz
emacs-7a6f5a5167037cdc3a0e9e312393781daedec085.tar.bz2
emacs-7a6f5a5167037cdc3a0e9e312393781daedec085.zip
Support state changing VC operations on directories in Dired (bug#34949)
* lisp/dired-aux.el (dired-vc-next-action): New command. (dired-vc-deduce-fileset): Rename from vc-dired-deduce-fileset in vc.el. * lisp/dired.el (dired-mode-map): Remap vc-next-action to dired-vc-next-action. * lisp/vc/vc-dir.el (vc-dir-mark-files): New function. (vc-dir-refresh): Run hook vc-dir-refresh-hook. * lisp/vc/vc.el (vc-deduce-fileset): Rename arg 'observer' to 'not-state-changing' and document it in docstring. (vc-dired-deduce-fileset): Rename to dired-vc-deduce-fileset in dired-aux.el. * lisp/cedet/ede.el (ede-turn-on-hook, ede-minor-mode): * lisp/desktop.el (desktop-minor-mode-table): Rename the long ago obsolete vc-dired-mode to vc-dir-mode.
Diffstat (limited to 'lisp/dired-aux.el')
-rw-r--r--lisp/dired-aux.el62
1 files changed, 62 insertions, 0 deletions
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 6f50a3da6ca..60a352d78e0 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -3050,6 +3050,68 @@ instead."
(backward-delete-char 1))
(message "%s" (buffer-string)))))
+
+;;; Version control from dired
+
+(declare-function vc-dir-unmark-all-files "vc-dir")
+(declare-function vc-dir-mark-files "vc-dir")
+
+;;;###autoload
+(defun dired-vc-next-action (verbose)
+ "Do the next version control operation on marked files/directories.
+When only files are marked then call `vc-next-action' with the
+same value of the VERBOSE argument.
+When also directories are marked then call `vc-dir' and mark
+the same files/directories in the VC-Dir buffer that were marked
+in the Dired buffer."
+ (interactive "P")
+ (let* ((marked-files
+ (dired-get-marked-files nil nil nil nil t))
+ (mark-files
+ (when (cl-some #'file-directory-p marked-files)
+ ;; Fix deficiency of Dired by adding slash to dirs
+ (mapcar (lambda (file)
+ (if (file-directory-p file)
+ (file-name-as-directory file)
+ file))
+ marked-files))))
+ (if mark-files
+ (let ((transient-hook (make-symbol "vc-dir-mark-files")))
+ (fset transient-hook
+ (lambda ()
+ (remove-hook 'vc-dir-refresh-hook transient-hook t)
+ (vc-dir-unmark-all-files t)
+ (vc-dir-mark-files mark-files)))
+ (vc-dir-root)
+ (add-hook 'vc-dir-refresh-hook transient-hook nil t))
+ (vc-next-action verbose))))
+
+(declare-function vc-compatible-state "vc")
+
+(defun dired-vc-deduce-fileset (&optional state-model-only-files not-state-changing)
+ (let ((backend (vc-responsible-backend default-directory))
+ (files (dired-get-marked-files nil nil nil nil t))
+ only-files-list
+ state
+ model)
+ (when (and (not not-state-changing) (cl-some #'file-directory-p files))
+ (user-error "State changing VC operations on directories supported only in `vc-dir'"))
+
+ (when state-model-only-files
+ (setq only-files-list (mapcar (lambda (file) (cons file (vc-state file))) files))
+ (setq state (cdar only-files-list))
+ ;; Check that all files are in a consistent state, since we use that
+ ;; state to decide which operation to perform.
+ (dolist (crt (cdr only-files-list))
+ (unless (vc-compatible-state (cdr crt) state)
+ (error "When applying VC operations to multiple files, the files are required\nto be in similar VC states.\n%s in state %s clashes with %s in state %s"
+ (car crt) (cdr crt) (caar only-files-list) state)))
+ (setq only-files-list (mapcar 'car only-files-list))
+ (when (and state (not (eq state 'unregistered)))
+ (setq model (vc-checkout-model backend only-files-list))))
+ (list backend files only-files-list state model)))
+
+
(provide 'dired-aux)
;; Local Variables: