changeset 96520:00812d11af93

* vc-dir.el (vc-dir-find-child-files): New function. (vc-dir-resync-directory-files): New function. (vc-dir-recompute-file-state): New function, broken out of ... (vc-dir-resynch-file): ... here. Also deal with directories. * vc-dispatcher.el (vc-resynch-buffers-in-directory): New function. (vc-resynch-buffer): Use it.
author Dan Nicolaescu <dann@ics.uci.edu>
date Sat, 05 Jul 2008 18:09:32 +0000
parents 0197baf37347
children 90bd26fe8c92
files lisp/ChangeLog lisp/vc-dir.el lisp/vc-dispatcher.el
diffstat 3 files changed, 78 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Sat Jul 05 18:04:26 2008 +0000
+++ b/lisp/ChangeLog	Sat Jul 05 18:09:32 2008 +0000
@@ -1,5 +1,12 @@
 2008-07-05  Dan Nicolaescu  <dann@ics.uci.edu>
 
+	* vc-dir.el (vc-dir-find-child-files): New function.
+	(vc-dir-resync-directory-files): New function.
+	(vc-dir-recompute-file-state): New function, broken out of ...
+	(vc-dir-resynch-file): ... here.  Also deal with directories.
+	* vc-dispatcher.el (vc-resynch-buffers-in-directory): New function.
+	(vc-resynch-buffer): Use it.
+
 	* vc-hg.el (vc-hg-registered): Do not set vc-state.
 
 	* vc-annotate.el (vc-annotate-mode-menu): Add separator.
--- a/lisp/vc-dir.el	Sat Jul 05 18:04:26 2008 +0000
+++ b/lisp/vc-dir.el	Sat Jul 05 18:09:32 2008 +0000
@@ -770,37 +770,65 @@
 	     (vc-dir-fileinfo->state crt-data)) result))
     result))
 
+(defun vc-dir-recompute-file-state (fname def-dir)
+  (let* ((file-short (file-relative-name fname def-dir))
+	 (state (vc-call-backend vc-dir-backend 'state fname))
+	 (extra (vc-call-backend vc-dir-backend
+				 'status-fileinfo-extra fname)))
+    (list file-short state extra)))
+
+(defun vc-dir-find-child-files (dirname)
+  ;; Give a DIRNAME string return the list of all child files shown in
+  ;; the current *vc-dir* buffer.
+  (let ((crt (ewoc-nth vc-ewoc 0))
+	children
+	dname)
+    ;; Find DIR
+    (while (and crt (not (vc-string-prefix-p
+			  dirname (vc-dir-node-directory crt))))
+      (setq crt (ewoc-next vc-ewoc crt)))
+    (while (and crt (vc-string-prefix-p
+		     dirname
+		     (setq dname (vc-dir-node-directory crt))))
+      (let ((data (ewoc-data crt)))
+	(unless (vc-dir-fileinfo->directory data)
+	  (push (expand-file-name (vc-dir-fileinfo->name data)) children)))
+      (setq crt (ewoc-next vc-ewoc crt)))
+    children))
+
+(defun vc-dir-resync-directory-files (dirname)
+  ;; Update the entries for all the child files of DIRNAME shown in
+  ;; the current *vc-dir* buffer.
+  (let ((files (vc-dir-find-child-files dirname))
+	(ddir (expand-file-name default-directory))
+	fileentries)
+    (when files
+      (dolist (crt files)
+	(push (vc-dir-recompute-file-state crt ddir)
+	      fileentries))
+      (vc-dir-update fileentries (current-buffer)))))
+
 (defun vc-dir-resynch-file (&optional fname)
   "Update the entries for FILE in any directory buffers that list it."
-  (let ((file (or fname (expand-file-name buffer-file-name))))
-    (if (file-directory-p file)
-	;; FIXME: Maybe this should never happen?
-        ;; FIXME: But it is useful to update the state of a directory
-	;; (more precisely the files in the directory) after some VC
-	;; operations.
-	nil
-      (let ((found-vc-dir-buf nil))
-	(save-excursion
-	  (dolist (status-buf (buffer-list))
-	    (set-buffer status-buf)
-	    ;; look for a vc-dir buffer that might show this file.
-	    (when (derived-mode-p 'vc-dir-mode)
-	      (setq found-vc-dir-buf t)
-	      (let ((ddir (expand-file-name default-directory)))
-		(when (vc-string-prefix-p ddir file)
-		  (let*
-                      ;; FIXME: Any reason we don't use file-relative-name?
-		      ((file-short (substring file (length ddir)))
-		       (state (vc-call-backend vc-dir-backend 'state file))
-		       (extra (vc-call-backend vc-dir-backend
-					       'status-fileinfo-extra file))
-		       (entry
-			(list file-short state extra)))
-		    (vc-dir-update (list entry) status-buf))))))
-	  ;; We didn't find any vc-dir buffers, remove the hook, it is
-	  ;; not needed.
-	  (unless found-vc-dir-buf
-            (remove-hook 'after-save-hook 'vc-dir-resynch-file)))))))
+  (let ((file (or fname (expand-file-name buffer-file-name)))
+	(found-vc-dir-buf nil))
+    (save-excursion
+      (dolist (status-buf (buffer-list))
+	(set-buffer status-buf)
+	;; look for a vc-dir buffer that might show this file.
+	(when (derived-mode-p 'vc-dir-mode)
+	  (setq found-vc-dir-buf t)
+	  (let ((ddir (expand-file-name default-directory)))
+	    (when (vc-string-prefix-p ddir file)
+	      (if (file-directory-p file)
+		  (vc-dir-resync-directory-files file)
+		(vc-dir-update
+		 (list (vc-dir-recompute-file-state file ddir))
+		 status-buf)))))))
+    ;; We didn't find any vc-dir buffers, remove the hook, it is
+    ;; not needed.
+    (unless found-vc-dir-buf
+      (remove-hook 'after-save-hook 'vc-dir-resynch-file))))
 
 (defvar use-vc-backend)  ;; dynamically bound
 
--- a/lisp/vc-dispatcher.el	Sat Jul 05 18:04:26 2008 +0000
+++ b/lisp/vc-dispatcher.el	Sat Jul 05 18:09:32 2008 +0000
@@ -480,15 +480,25 @@
 	 (kill-buffer (current-buffer)))))
 
 (declare-function vc-dir-resynch-file "vc-dir" (&optional fname))
+(declare-function vc-string-prefix-p "vc" (prefix string))
+
+(defun vc-resynch-buffers-in-directory (directory &optional keep noquery)
+  "Resync all buffers that visit files in DIRECTORY."
+  (dolist (buffer (buffer-list))
+    (let ((fname (buffer-file-name buffer)))
+      (when (and fname (vc-string-prefix-p directory fname))
+	(vc-resynch-buffer fname keep noquery)))))
 
 (defun vc-resynch-buffer (file &optional keep noquery)
   "If FILE is currently visited, resynch its buffer."
   (if (string= buffer-file-name file)
       (vc-resynch-window file keep noquery)
-    (let ((buffer (get-file-buffer file)))
-      (when buffer
-	(with-current-buffer buffer
-	  (vc-resynch-window file keep noquery)))))
+    (if (file-directory-p file)
+	(vc-resynch-buffers-in-directory file keep noquery)
+      (let ((buffer (get-file-buffer file)))
+	(when buffer
+	  (with-current-buffer buffer
+	    (vc-resynch-window file keep noquery))))))
   ;; Try to avoid unnecessary work, a *vc-dir* buffer is only present
   ;; if this is true.
   (when (memq 'vc-dir-resynch-file after-save-hook)