# HG changeset patch # User Dan Nicolaescu # Date 1215281372 0 # Node ID 00812d11af934fd7f79c571e86138275d4e98ede # Parent 0197baf3734736229fb4ef78af682a4dadca7a0c * 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. diff -r 0197baf37347 -r 00812d11af93 lisp/ChangeLog --- 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 + * 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. diff -r 0197baf37347 -r 00812d11af93 lisp/vc-dir.el --- 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 diff -r 0197baf37347 -r 00812d11af93 lisp/vc-dispatcher.el --- 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)