emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 7a6f5a5: Support state changing VC operations on directories in D


From: Juri Linkov
Subject: master 7a6f5a5: Support state changing VC operations on directories in Dired (bug#34949)
Date: Sun, 29 Mar 2020 18:34:57 -0400 (EDT)

branch: master
commit 7a6f5a5167037cdc3a0e9e312393781daedec085
Author: Juri Linkov <address@hidden>
Commit: Juri Linkov <address@hidden>

    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.
---
 etc/NEWS          |  4 ++--
 lisp/cedet/ede.el |  4 ++--
 lisp/desktop.el   |  2 +-
 lisp/dired-aux.el | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lisp/dired.el     |  1 +
 lisp/vc/vc-dir.el | 14 ++++++++++++-
 lisp/vc/vc.el     | 40 ++++++++---------------------------
 7 files changed, 90 insertions(+), 37 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 4b477e5..bb5f549 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -108,8 +108,8 @@ Mark mode, then Dired commands operate only on files in the 
active
 region.  The values 'file' and 'line' of this user option define the
 details of marking the file at the end of the region.
 
-*** State changing VC operations are supported in 'dired-mode' on files
-(but still not on directories).
+*** State changing VC operations are supported in Dired on files and
+directories with the help of new command 'dired-vc-next-action'.
 
 ** Change Logs and VC
 
diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el
index c203687..8c33611 100644
--- a/lisp/cedet/ede.el
+++ b/lisp/cedet/ede.el
@@ -470,7 +470,7 @@ To be used in hook functions."
          ;; Emacs 21 has no buffer file name for directory edits.
          ;; so we need to add these hacks in.
          (eq major-mode 'dired-mode)
-         (eq major-mode 'vc-dired-mode))
+         (eq major-mode 'vc-dir-mode))
       (ede-minor-mode 1)))
 
 (define-minor-mode ede-minor-mode
@@ -481,7 +481,7 @@ controlled project, then this mode is activated 
automatically
 provided `global-ede-mode' is enabled."
   :group 'ede
   (cond ((or (eq major-mode 'dired-mode)
-            (eq major-mode 'vc-dired-mode))
+            (eq major-mode 'vc-dir-mode))
         (ede-dired-minor-mode (if ede-minor-mode 1 -1)))
        (ede-minor-mode
         (if (not ede-constructing)
diff --git a/lisp/desktop.el b/lisp/desktop.el
index de601a4..9d117c6 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -534,7 +534,7 @@ can guess how to load the mode's definition.")
   '((defining-kbd-macro nil)
     (isearch-mode nil)
     (vc-mode nil)
-    (vc-dired-mode nil)
+    (vc-dir-mode nil)
     (erc-track-minor-mode nil)
     (savehist-mode nil))
   "Table mapping minor mode variables to minor mode functions.
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 6f50a3d..60a352d 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:
diff --git a/lisp/dired.el b/lisp/dired.el
index 41bbf9f..72d1cc2 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1870,6 +1870,7 @@ Do so according to the former subdir alist 
OLD-SUBDIR-ALIST."
     (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 b760e17..ab59439 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -696,6 +696,17 @@ share the same state."
                (vc-dir-mark-file crt)))
            (setq crt (ewoc-next vc-ewoc crt))))))))
 
+(defun vc-dir-mark-files (mark-files)
+  "Mark files specified by file names in the argument MARK-FILES.
+MARK-FILES should be a list of absolute filenames."
+  (ewoc-map
+   (lambda (filearg)
+     (when (member (expand-file-name (vc-dir-fileinfo->name filearg))
+                   mark-files)
+       (setf (vc-dir-fileinfo->marked filearg) t)
+       t))
+   vc-ewoc))
+
 (defun vc-dir-unmark-file ()
   ;; Unmark the current file and move to the next line.
   (let* ((crt (ewoc-locate vc-ewoc))
@@ -1193,7 +1204,8 @@ Throw an error if another update process is in progress."
                    (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.
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 607fb37..d4323d5 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1006,12 +1006,18 @@ Within directories, only files already under version 
control are noticed."
 
 (declare-function vc-dir-current-file "vc-dir" ())
 (declare-function vc-dir-deduce-fileset "vc-dir" (&optional 
state-model-only-files))
+(declare-function dired-vc-deduce-fileset "dired-aux" (&optional 
state-model-only-files not-state-changing))
 
-(defun vc-deduce-fileset (&optional observer allow-unregistered
+(defun vc-deduce-fileset (&optional not-state-changing
+                                   allow-unregistered
                                    state-model-only-files)
   "Deduce a set of files and a backend to which to apply an operation.
 Return (BACKEND FILESET FILESET-ONLY-FILES STATE CHECKOUT-MODEL).
 
+NOT-STATE-CHANGING if non-nil, means that the operation
+requesting the fileset doesn't intend to change VC state,
+such as printing the log or showing the diff.
+
 If we're in VC-dir mode, FILESET is the list of marked files,
 or the directory if no files are marked.
 Otherwise, if in a buffer visiting a version-controlled file,
@@ -1025,14 +1031,12 @@ the FILESET-ONLY-FILES STATE and MODEL info.  
Otherwise, that
 part may be skipped.
 
 BEWARE: this function may change the current buffer."
-  ;; FIXME: OBSERVER is unused.  The name is not intuitive and is not
-  ;; documented.  It's set to t when called from diff and print-log.
   (let (backend)
     (cond
      ((derived-mode-p 'vc-dir-mode)
       (vc-dir-deduce-fileset state-model-only-files))
      ((derived-mode-p 'dired-mode)
-      (vc-dired-deduce-fileset state-model-only-files observer))
+      (dired-vc-deduce-fileset state-model-only-files not-state-changing))
      ((setq backend (vc-backend buffer-file-name))
       (if state-model-only-files
        (list backend (list buffer-file-name)
@@ -1048,7 +1052,7 @@ BEWARE: this function may change the current buffer."
                                      (derived-mode-p 'dired-mode)))))
       (progn                  ;FIXME: Why not `with-current-buffer'? --Stef.
        (set-buffer vc-parent-buffer)
-       (vc-deduce-fileset observer allow-unregistered state-model-only-files)))
+       (vc-deduce-fileset not-state-changing allow-unregistered 
state-model-only-files)))
      ((and (derived-mode-p 'log-view-mode)
           (setq backend (vc-responsible-backend default-directory)))
       (list backend nil))
@@ -1065,32 +1069,6 @@ BEWARE: this function may change the current buffer."
              (list buffer-file-name))))
      (t (error "File is not under version control")))))
 
-(declare-function dired-get-marked-files "dired"
-                  (&optional localp arg filter distinguish-one-marked error))
-
-(defun vc-dired-deduce-fileset (&optional state-model-only-files observer)
-  (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 observer) (cl-some #'file-directory-p files))
-      (error "State changing VC operations on directories not supported in 
`dired-mode'"))
-
-    (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)))
-
 (defun vc-ensure-vc-buffer ()
   "Make sure that the current buffer visits a version-controlled file."
   (cond



reply via email to

[Prev in Thread] Current Thread [Next in Thread]