diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 6f50a3da6c..af4d29b556 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -3050,6 +3050,33 @@ dired-show-file-type (backward-delete-char 1)) (message "%s" (buffer-string))))) + +(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 ((mark-files + (let ((marked-files (dired-get-marked-files nil nil nil nil t))) + (when (cl-some #'file-directory-p marked-files) + 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-mark-files mark-files))) + (vc-dir-root) + (add-hook 'vc-dir-refresh-hook transient-hook nil t)) + (vc-next-action verbose)))) + + (provide 'dired-aux) ;; Local Variables: diff --git a/lisp/dired.el b/lisp/dired.el index 438f5e7d8b..51aaf6b01d 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1865,6 +1870,7 @@ dired-mode-map (define-key map "\177" 'dired-unmark-backward) (define-key map [remap undo] 'dired-undo) (define-key map [remap advertised-undo] 'dired-undo) + (define-key map [remap vc-next-action] 'dired-vc-next-action) ;; thumbnail manipulation (image-dired) (define-key map "\C-td" 'image-dired-display-thumbs) (define-key map "\C-tt" 'image-dired-tag-files) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 38b4937e85..43d4a7843c 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -771,6 +771,28 @@ vc-dir-toggle-mark (interactive "e") (vc-dir-at-event e (vc-dir-mark-unmark 'vc-dir-toggle-mark-file))) +(defun vc-dir-mark-files (mark-files) + (let* ((backend (vc-responsible-backend default-directory)) + (rootdir (vc-call-backend backend 'root default-directory))) + (when (listp mark-files) + (setq mark-files (mapcar (lambda (file) + (file-relative-name + (if (file-directory-p file) + (file-name-as-directory file) + file) + rootdir)) + mark-files))) + (vc-dir-unmark-all-files t) + (ewoc-map + (lambda (filearg) + (when (cond ((consp mark-files) + (member (vc-dir-fileinfo->name filearg) mark-files)) + ((eq mark-files 'registered) + (memq (vc-dir-fileinfo->state filearg) '(edited added removed)))) + (setf (vc-dir-fileinfo->marked filearg) t) + t)) + vc-ewoc))) + (defun vc-dir-clean-files () "Delete the marked files, or the current file if no marks. The files will not be marked as deleted in the version control @@ -1193,7 +1215,8 @@ vc-dir-refresh (if remaining (vc-dir-refresh-files (mapcar 'vc-dir-fileinfo->name remaining)) - (setq mode-line-process nil)))))))))))) + (setq mode-line-process nil) + (run-hooks 'vc-dir-refresh-hook)))))))))))) (defun vc-dir-show-fileentry (file) "Insert an entry for a specific file into the current *VC-dir* listing.