From dcbbecd42f2b2a393a90c1fe9ad2b85e55bc7daa Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Tue, 29 Sep 2009 13:07:50 +0000 Subject: [PATCH] * vc-hooks.el (vc-dir-buffers): New var. (vc-state-refresh): New function. (vc-state): Use it. (vc-after-save): Always ask the backend to recompute the new state. Always call vc-dir if necessary, using vc-dir-buffers. * vc-dir.el (vc-dir-prepare-status-buffer, vc-dir-resynch-file): Use vc-dir-buffers. (vc-dir-mode): Use vc-dir-buffers rather than after-save-hook. (vc-dir-prepare-status-buffer, vc-dir-update) (vc-dir-resync-directory-files, vc-dir-resynch-file, vc-dir-mode): Don't call expand-file-name on default-directory. --- lisp/ChangeLog | 14 ++++++++++ lisp/vc-dir.el | 66 ++++++++++++++++++++++++------------------------ lisp/vc-hooks.el | 27 ++++++++++++-------- 3 files changed, 63 insertions(+), 44 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a0621474873..6b0069b7b04 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,17 @@ +2009-09-29 Stefan Monnier + + * vc-hooks.el (vc-dir-buffers): New var. + (vc-state-refresh): New function. + (vc-state): Use it. + (vc-after-save): Always ask the backend to recompute the new state. + Always call vc-dir if necessary, using vc-dir-buffers. + * vc-dir.el (vc-dir-prepare-status-buffer, vc-dir-resynch-file): + Use vc-dir-buffers. + (vc-dir-mode): Use vc-dir-buffers rather than after-save-hook. + (vc-dir-prepare-status-buffer, vc-dir-update) + (vc-dir-resync-directory-files, vc-dir-resynch-file, vc-dir-mode): + Don't call expand-file-name on default-directory. + 2009-09-29 Juanma Barranquero * speedbar.el (speedbar-item-delete): diff --git a/lisp/vc-dir.el b/lisp/vc-dir.el index b20e67b9488..f78ca1806c0 100644 --- a/lisp/vc-dir.el +++ b/lisp/vc-dir.el @@ -89,16 +89,16 @@ See `run-hooks'." (defun vc-dir-prepare-status-buffer (bname dir backend &optional create-new) "Find a buffer named BNAME showing DIR, or create a new one." (setq dir (file-name-as-directory (expand-file-name dir))) - (let* - ;; Look for another buffer name BNAME visiting the same directory. - ((buf (save-excursion - (unless create-new - (dolist (buffer (buffer-list)) - (set-buffer buffer) - (when (and (derived-mode-p 'vc-dir-mode) - (eq vc-dir-backend backend) - (string= (expand-file-name default-directory) dir)) - (return buffer))))))) + (let* ;; Look for another buffer name BNAME visiting the same directory. + ((buf (save-excursion + (unless create-new + (dolist (buffer vc-dir-buffers) + (when (buffer-live-p buffer) + (set-buffer buffer) + (when (and (derived-mode-p 'vc-dir-mode) + (eq vc-dir-backend backend) + (string= default-directory dir)) + (return buffer)))))))) (or buf ;; Create a new buffer named BNAME. (with-current-buffer (create-file-buffer bname) @@ -360,7 +360,7 @@ If NOINSERT, ignore elements on ENTRIES which are not in the ewoc." (unless node (ewoc-enter-last vc-ewoc (vc-dir-create-fileinfo - dotname nil nil nil (expand-file-name default-directory))) + dotname nil nil nil default-directory)) (setq node (ewoc-nth vc-ewoc 0))) (while (and entry node) @@ -849,7 +849,7 @@ If it is a file, return the corresponding cons for the file itself." ;; 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)) + (ddir default-directory) fileentries) (when files (dolist (crt files) @@ -860,25 +860,25 @@ If it is a file, return the corresponding cons for the file itself." (defun vc-dir-resynch-file (&optional fname) "Update the entries for FNAME in any directory buffers that list it." (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) - (let ((state (vc-dir-recompute-file-state file ddir))) - (vc-dir-update - (list state) - status-buf (eq (cadr state) 'up-to-date))))))))) - ;; 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)))) + (drop '())) + (save-current-buffer + ;; look for a vc-dir buffer that might show this file. + (dolist (status-buf vc-dir-buffers) + (if (not (buffer-live-p status-buf)) + (push status-buf drop) + (set-buffer status-buf) + (if (not (derived-mode-p 'vc-dir-mode)) + (push status-buf drop) + (let ((ddir default-directory)) + (when (vc-string-prefix-p ddir file) + (if (file-directory-p file) + (vc-dir-resync-directory-files file) + (let ((state (vc-dir-recompute-file-state file ddir))) + (vc-dir-update + (list state) + status-buf (eq (cadr state) 'up-to-date)))))))))) + ;; Remove out-of-date entries from vc-dir-buffers. + (dolist (b drop) (setq vc-dir-buffers (delq b vc-dir-buffers))))) (defvar use-vc-backend) ;; dynamically bound @@ -928,8 +928,8 @@ the *vc-dir* buffer. (set (make-local-variable 'vc-ewoc) (ewoc-create #'vc-dir-printer)) (set (make-local-variable 'revert-buffer-function) 'vc-dir-revert-buffer-function) - (setq list-buffers-directory (expand-file-name default-directory)) - (add-hook 'after-save-hook 'vc-dir-resynch-file) + (setq list-buffers-directory default-directory) + (add-to-list 'vc-dir-buffers (current-buffer)) ;; Make sure that if the directory buffer is killed, the update ;; process running in the background is also killed. (add-hook 'kill-buffer-query-functions 'vc-dir-kill-query nil t) diff --git a/lisp/vc-hooks.el b/lisp/vc-hooks.el index 3ce54881aee..125b57e3daa 100644 --- a/lisp/vc-hooks.el +++ b/lisp/vc-hooks.el @@ -517,12 +517,16 @@ status of this file." ;; FIXME: New (sub)states needed (?): ;; - `copied' and `moved' (might be handled by `removed' and `added') (or (vc-file-getprop file 'vc-state) - (when (> (length file) 0) + (when (> (length file) 0) ;Why?? --Stef (setq backend (or backend (vc-backend file))) (when backend - (vc-file-setprop - file 'vc-state - (vc-call-backend backend 'state-heuristic file)))))) + (vc-state-refresh file backend))))) + +(defun vc-state-refresh (file backend) + "Quickly recompute the `state' of FILE." + (vc-file-setprop + file 'vc-state + (vc-call-backend backend 'state-heuristic file))) (defsubst vc-up-to-date-p (file) "Convenience function that checks whether `vc-state' of FILE is `up-to-date'." @@ -728,6 +732,8 @@ Before doing that, check if there are any old backups and get rid of them." (declare-function vc-dir-resynch-file "vc-dir" (&optional fname)) +(defvar vc-dir-buffers nil "List of vc-dir buffers.") + (defun vc-after-save () "Function to be called by `basic-save-buffer' (in files.el)." ;; If the file in the current buffer is under version control, @@ -743,14 +749,13 @@ Before doing that, check if there are any old backups and get rid of them." ;; to avoid confusion. (vc-file-setprop file 'vc-checkout-time nil)) t) - (vc-up-to-date-p file) (eq (vc-checkout-model backend (list file)) 'implicit) - (vc-file-setprop file 'vc-state 'edited) - (vc-mode-line file backend) - ;; Try to avoid unnecessary work, a *vc-dir* buffer is - ;; present if and only if this is true. - (when (memq 'vc-dir-resynch-file after-save-hook) - (vc-dir-resynch-file file))))) + (vc-state-refresh file backend) + (vc-mode-line file backend)) + ;; Try to avoid unnecessary work, a *vc-dir* buffer is + ;; present if this is true. + (when vc-dir-buffers + (vc-dir-resynch-file file)))) (defvar vc-menu-entry '(menu-item "Version Control" vc-menu-map -- 2.39.2