Mercurial > emacs
changeset 94059:c249cf124bd6
(vc-status-update): Revert an incorrect rewrite. Add some
comments.
(vc-status-refresh-files): New function.
(vc-status-refresh): Use `vc-status-refresh-files' to refresh the
state of up-to-date files.
(vc-default-dir-status-files): New function.
author | Alexandre Julliard <julliard@winehq.org> |
---|---|
date | Sun, 13 Apr 2008 18:06:35 +0000 |
parents | 5e1992e5137e |
children | 6c138603231c |
files | lisp/vc.el |
diffstat | 1 files changed, 82 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/vc.el Sun Apr 13 16:29:55 2008 +0000 +++ b/lisp/vc.el Sun Apr 13 18:06:35 2008 +0000 @@ -184,12 +184,20 @@ ;; when all the results have been computed. ;; To provide more backend specific functionality for `vc-status' ;; the following functions might be needed: `status-extra-headers', -;; `status-printer', `extra-status-menu' and `status-fileinfo-extra'. +;; `status-printer', `extra-status-menu' and `dir-status-files'. ;; This function is used by `vc-status', a replacement for ;; `vc-dired'. vc-status is still under development, and is NOT ;; feature complete. As such, the requirements for this function ;; might change. This is a replacement for `dir-state'. ;; +;; - dir-status-files (dir files default-state update-function) +;; +;; This function is identical to dir-status except that it should +;; only report status for the specified FILES. Also it needs to +;; report on all requested files, including up-to-date or ignored +;; files. If not provided, the default is to consider that the files +;; are in DEFAULT-STATE. +;; ;; - status-extra-headers (dir) ;; ;; Return a string that will be added to the *vc-status* buffer header. @@ -643,11 +651,6 @@ ;; - vc-status needs a command to insert a file entry in the status ;; display, similar to `cvs-mode-insert'. ;; -;; - the dir-status backend function should take as an argument an -;; optional fileset, and should return the results just for that -;; fileset. This can be used to speed up status buffer updates -;; after VC operations. -;; ;; - vc-status: refresh should not completely wipe out the current ;; contents of the vc-status buffer. ;; @@ -2715,7 +2718,9 @@ state ;; For storing backend specific information. extra - marked) + marked + ;; To keep track of not updated files during a global refresh + needs-update) (defvar vc-status nil) @@ -2998,9 +3003,8 @@ (put 'vc-status-mode 'mode-class 'special) -(defun vc-status-update (entries buffer &optional noinsert) - "Update BUFFER's ewoc from the list of ENTRIES. -If NOINSERT, ignore elements on ENTRIES which are not in the ewoc." +(defun vc-status-update (entries buffer) + "Update BUFFER's ewoc from the list of ENTRIES." ;; Add ENTRIES to the vc-status buffer BUFFER. (with-current-buffer buffer ;; Insert the entries sorted by name into the ewoc. @@ -3009,35 +3013,64 @@ (setq entries (sort entries (lambda (entry1 entry2) (string-lessp (car entry1) (car entry2))))) - (let ((entry (car entries)) - (node (ewoc-nth vc-status 0))) - (while (and entry node) - (let ((entryfile (car entry)) - (nodefile (vc-status-fileinfo->name (ewoc-data node)))) - (cond - ((string-lessp nodefile entryfile) - (setq node (ewoc-next vc-status node))) - ((string-lessp nodefile entryfile) - (unless noinsert - (ewoc-enter-before vc-status node - (apply 'vc-status-create-fileinfo entry))) - (setq entries (cdr entries) entry (car entries))) - (t - (setf (vc-status-fileinfo->state (ewoc-data node)) (nth 1 entry)) - (setf (vc-status-fileinfo->extra (ewoc-data node)) (nth 2 entry)) - (ewoc-invalidate vc-status node) - (setq entries (cdr entries) entry (car entries)) - (setq node (ewoc-next vc-status node)))))) - (unless (or node noinsert) - ;; We're past the last node, all remaining entries go to the end. - (while entries - (ewoc-enter-last vc-status - (apply 'vc-status-create-fileinfo (pop entries)))))))) + (let ((entry (pop entries)) + (node (ewoc-nth vc-status 0))) + (while entry + (let ((file (car entry))) + ;; Note: we always keep node pointing to the last inserted entry + ;; in order to catch duplicates in the entries list + (cond ((not node) + (setq node (ewoc-enter-last vc-status + (apply 'vc-status-create-fileinfo entry))) + (setq entry (pop entries))) + ((string-lessp (vc-status-fileinfo->name (ewoc-data node)) file) + (setq node (ewoc-next vc-status node))) + ((string-equal (vc-status-fileinfo->name (ewoc-data node)) file) + (setf (vc-status-fileinfo->state (ewoc-data node)) (nth 1 entry)) + (setf (vc-status-fileinfo->extra (ewoc-data node)) (nth 2 entry)) + (setf (vc-status-fileinfo->needs-update (ewoc-data node)) nil) + (ewoc-invalidate vc-status node) + (setq entry (pop entries))) + (t + (setq node (ewoc-enter-before vc-status node + (apply 'vc-status-create-fileinfo entry))) + (setq entry (pop entries))))))))) (defun vc-status-busy () (and (buffer-live-p vc-status-process-buffer) (get-buffer-process vc-status-process-buffer))) +(defun vc-status-refresh-files (files default-state) + "Refresh some files in the VC status buffer." + (let ((backend (vc-responsible-backend default-directory)) + (status-buffer (current-buffer)) + (def-dir default-directory)) + (vc-set-mode-line-busy-indicator) + ;; Call the `dir-status-file' backend function. + ;; `dir-status-file' is supposed to be asynchronous. + ;; It should compute the results, and then call the function + ;; passed as an argument in order to update the vc-status buffer + ;; with the results. + (unless (buffer-live-p vc-status-process-buffer) + (setq vc-status-process-buffer + (generate-new-buffer (format " *VC-%s* tmp status" backend)))) + (lexical-let ((buffer (current-buffer))) + (with-current-buffer vc-status-process-buffer + (cd def-dir) + (erase-buffer) + (vc-call-backend + backend 'dir-status-files def-dir files default-state + (lambda (entries &optional more-to-come) + ;; ENTRIES is a list of (FILE VC_STATE EXTRA) items. + ;; If MORE-TO-COME is true, then more updates will come from + ;; the asynchronous process. + (with-current-buffer buffer + (vc-status-update entries buffer) + (unless more-to-come + (setq mode-line-process nil) + ;; Remove the ones that haven't been updated at all + (ewoc-filter vc-status (lambda (info) (not (vc-status-fileinfo->needs-update info)))))))))))) + (defun vc-status-refresh () "Refresh the contents of the VC status buffer. Throw an error if another update process is in progress." @@ -3062,8 +3095,9 @@ (unless (buffer-live-p vc-status-process-buffer) (setq vc-status-process-buffer (generate-new-buffer (format " *VC-%s* tmp status" backend)))) - (lexical-let ((oldentries (ewoc-collect vc-status (lambda (_) t))) - (buffer (current-buffer))) + ;; set the needs-update flag on all entries + (ewoc-map (lambda (info) (setf (vc-status-fileinfo->needs-update info) t) nil) vc-status) + (lexical-let ((buffer (current-buffer))) (with-current-buffer vc-status-process-buffer (cd def-dir) (erase-buffer) @@ -3074,20 +3108,16 @@ ;; If MORE-TO-COME is true, then more updates will come from ;; the asynchronous process. (with-current-buffer buffer - (dolist (entry entries) - (setq oldentries - (delq (member (car entry) oldentries) oldentries))) (vc-status-update entries buffer) - (ewoc-goto-node vc-status (ewoc-nth vc-status 0)) - ;; No more updates are expected from the asynchronous process. (unless more-to-come - ;; We are done, turn off the mode-line "in progress" message. - (setq mode-line-process nil) - ;; Update old entries that were not mentioned, and were - ;; hence implicitly given as uptodate. - (dolist (entry oldentries) - (setf (vc-status-fileinfo->state entry) 'up-to-date)) - (vc-status-update oldentries buffer 'noinsert)))))))))) + (let ((remaining + (ewoc-collect vc-status + (lambda (info) (vc-status-fileinfo->needs-update info))))) + (if remaining + (vc-status-refresh-files + (mapcar (lambda (info) (vc-status-fileinfo->name info)) remaining) + 'up-to-date) + (setq mode-line-process nil)))))))))))) (defun vc-status-kill-dir-status-process () "Kill the temporary buffer and associated process." @@ -3993,6 +4023,10 @@ (defalias 'vc-default-revision-completion-table 'ignore) +(defun vc-default-dir-status-files (backend dir files default-state update-function) + (funcall update-function + (mapcar (lambda (file) (list file default-state)) files))) + (defun vc-check-headers () "Check if the current file has any headers in it." (interactive)