From b784f194f8320d326c755dd49b31210977aae0e7 Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Tue, 8 Apr 2025 14:09:07 +0800 Subject: [PATCH] Factor out vc-only-files-state-and-model * lisp/dired-aux.el (vc-compatible-state): Delete declaration. (vc-only-files-state-and-model): Declare. (dired-vc-deduce-fileset): Factor out vc-only-files-state-and-model. * lisp/vc/vc-dir.el (require): Require cl-lib at load time, too. (vc-only-files-state-and-model): Declare. (vc-dir-deduce-fileset): Factor out vc-only-files-state-and-model. * lisp/vc/vc.el (vc-only-files-state-and-model): New function, factored out of dired-vc-deduce-fileset and vc-dir-deduce-fileset. --- lisp/dired-aux.el | 38 ++++++++++++++++---------------------- lisp/vc/vc-dir.el | 27 +++++++++------------------ lisp/vc/vc.el | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index f278b201ca6..676044972e9 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -3992,31 +3992,25 @@ In this case, the VERBOSE argument is ignored." (add-hook 'vc-dir-refresh-hook transient-hook nil t)) (vc-next-action verbose)))) -(declare-function vc-compatible-state "vc") +(declare-function vc-only-files-state-and-model "vc") ;;;###autoload -(defun dired-vc-deduce-fileset (&optional state-model-only-files not-state-changing) +(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))) + (files (dired-get-marked-files nil nil nil nil t))) + (when (and (not not-state-changing) + (cl-some #'file-directory-p files)) + (user-error "\ +State-changing VC operations on directories supported only from VC-Dir")) + (if state-model-only-files + (let ((only-files-list (mapcar (lambda (file) + (cons file (vc-state file))) + files))) + (cl-list* backend files + (vc-only-files-state-and-model only-files-list + backend))) + (list backend files)))) (provide 'dired-aux) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 1074986090e..b9d733d934b 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -44,7 +44,7 @@ (require 'seq) ;;; Code: -(eval-when-compile (require 'cl-lib)) +(require 'cl-lib) (declare-function fileloop-continue "fileloop") @@ -1464,12 +1464,11 @@ state of item at point, if any." (defun vc-dir-printer (fileentry) (vc-call-backend vc-dir-backend 'dir-printer fileentry)) +(declare-function vc-only-files-state-and-model "vc") + (defun vc-dir-deduce-fileset (&optional state-model-only-files) (let ((marked (vc-dir-marked-files)) - files - only-files-list - state - model) + files only-files-list) (if marked (progn (setq files marked) @@ -1479,19 +1478,11 @@ state of item at point, if any." (setq files (list crt)) (when state-model-only-files (setq only-files-list (vc-dir-child-files-and-states))))) - - (when state-model-only-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 vc-dir-backend only-files-list)))) - (list vc-dir-backend files only-files-list state model))) + (if state-model-only-files + (cl-list* vc-dir-backend files + (vc-only-files-state-and-model only-files-list + vc-dir-backend)) + (list vc-dir-backend files)))) ;;;###autoload (defun vc-dir-root () diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index c8bd4ca9e63..42591076d5c 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1284,6 +1284,24 @@ BEWARE: this function may change the current buffer." (unless (vc-backend buffer-file-name) (error "File %s is not under version control" buffer-file-name)))) +(defun vc-only-files-state-and-model (files backend) + "Compute last three `vc-deduce-fileset' return value elements for FILES. +FILES should be a pair, or list of pairs, of files and their VC states. +BACKEND is the VC backend responsible for FILES." + (let ((state (cdar files)) + (files* (mapcar #'car (ensure-list files)))) + ;; Check that all files are in a consistent state, since we use that + ;; state to decide which operation to perform. + (dolist (crt (cdr files)) + (unless (vc-compatible-state (cdr crt) state) + (error "\ +To apply VC operations to multiple files, the files must be in similar VC states. +%s in state %s clashes with %s in state %s" + (car crt) (cdr crt) (caar files) state))) + (list files* state + (and state (not (eq state 'unregistered)) + (vc-checkout-model backend files*))))) + ;;; Support for the C-x v v command. ;; This is where all the single-file-oriented code from before the fileset ;; rewrite lives.