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.
This commit is contained in:
Sean Whitton 2025-04-08 14:09:07 +08:00
parent 5f89eadb3f
commit b784f194f8
3 changed files with 43 additions and 40 deletions

View file

@ -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)

View file

@ -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 ()

View file

@ -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.