aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2008-04-11 15:17:59 +0000
committerStefan Monnier2008-04-11 15:17:59 +0000
commitc1b513745f93bee34f47901216db2f315b837b20 (patch)
tree764bd2cda1f2db22703a0ba49101603b023a86fc
parentda5a7abbc428c5db1dd5660f61e76719e99b4ce1 (diff)
downloademacs-c1b513745f93bee34f47901216db2f315b837b20.tar.gz
emacs-c1b513745f93bee34f47901216db2f315b837b20.zip
Change `dir-status' to not take (and pass) status-buffer.
(vc-status-create-fileinfo): Make `extra' optional. (vc-status-busy): New fun. (vc-status-menu-map): Use it. (vc-status-crt-marked): Remove. (vc-status-update): Rename from vc-status-add-entries. Add argument so as to prevent addition of entries. Rewrite. (vc-update-vc-status-buffer): Remove. (vc-status-refresh): Don't remove old entries, set them to up-to-date instead. Also do it after the update is complete. (vc-status-marked-files): η-reduce.
-rw-r--r--lisp/ChangeLog12
-rw-r--r--lisp/vc-bzr.el8
-rw-r--r--lisp/vc-cvs.el8
-rw-r--r--lisp/vc-git.el18
-rw-r--r--lisp/vc-hg.el8
-rw-r--r--lisp/vc-rcs.el4
-rw-r--r--lisp/vc-sccs.el4
-rw-r--r--lisp/vc-svn.el6
-rw-r--r--lisp/vc.el188
9 files changed, 130 insertions, 126 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 7f6b38f9ab1..2a01d952a11 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,17 @@
12008-04-11 Stefan Monnier <monnier@iro.umontreal.ca> 12008-04-11 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * vc.el: Change `dir-status' to not take (and pass) status-buffer.
4 (vc-status-create-fileinfo): Make `extra' optional.
5 (vc-status-busy): New fun.
6 (vc-status-menu-map): Use it.
7 (vc-status-crt-marked): Remove.
8 (vc-status-update): Rename from vc-status-add-entries.
9 Add argument so as to prevent addition of entries. Rewrite.
10 (vc-update-vc-status-buffer): Remove.
11 (vc-status-refresh): Don't remove old entries, set them to
12 up-to-date instead. Also do it after the update is complete.
13 (vc-status-marked-files): η-reduce.
14
3 * dired.el (dired-read-dir-and-switches): Use read-directory-name even 15 * dired.el (dired-read-dir-and-switches): Use read-directory-name even
4 for non-dialogs. 16 for non-dialogs.
5 17
diff --git a/lisp/vc-bzr.el b/lisp/vc-bzr.el
index 87335c63f12..7db90173ee3 100644
--- a/lisp/vc-bzr.el
+++ b/lisp/vc-bzr.el
@@ -658,7 +658,7 @@ Optional argument LOCALP is always ignored."
658 (vc-default-dired-state-info 'Bzr file))) 658 (vc-default-dired-state-info 'Bzr file)))
659 659
660;; XXX: this needs testing, it's probably incomplete. 660;; XXX: this needs testing, it's probably incomplete.
661(defun vc-bzr-after-dir-status (update-function status-buffer) 661(defun vc-bzr-after-dir-status (update-function)
662 (let ((status-str nil) 662 (let ((status-str nil)
663 (file nil) 663 (file nil)
664 (translation '(("+N" . added) 664 (translation '(("+N" . added)
@@ -693,16 +693,16 @@ Optional argument LOCALP is always ignored."
693 (line-end-position)) 693 (line-end-position))
694 translated) result)) 694 translated) result))
695 (forward-line)) 695 (forward-line))
696 (funcall update-function result status-buffer))) 696 (funcall update-function result)))
697 697
698;; XXX Experimental function for the vc-dired replacement. 698;; XXX Experimental function for the vc-dired replacement.
699;; XXX This probably needs some further refinement and testing. 699;; XXX This probably needs some further refinement and testing.
700(defun vc-bzr-dir-status (dir update-function status-buffer) 700(defun vc-bzr-dir-status (dir update-function)
701 "Return a list of conses (file . state) for DIR." 701 "Return a list of conses (file . state) for DIR."
702 ;; XXX: Is this the right command to use? 702 ;; XXX: Is this the right command to use?
703 (vc-bzr-command "status" (current-buffer) 'async dir "-v" "-S") 703 (vc-bzr-command "status" (current-buffer) 'async dir "-v" "-S")
704 (vc-exec-after 704 (vc-exec-after
705 `(vc-bzr-after-dir-status (quote ,update-function) ,status-buffer))) 705 `(vc-bzr-after-dir-status (quote ,update-function))))
706 706
707;;; Revision completion 707;;; Revision completion
708 708
diff --git a/lisp/vc-cvs.el b/lisp/vc-cvs.el
index fd48e5a7fee..80c8e526ecd 100644
--- a/lisp/vc-cvs.el
+++ b/lisp/vc-cvs.el
@@ -855,7 +855,7 @@ state."
855 (forward-line 1)))) 855 (forward-line 1))))
856 856
857;; XXX Experimental function for the vc-dired replacement. 857;; XXX Experimental function for the vc-dired replacement.
858(defun vc-cvs-after-dir-status (update-function status-buffer) 858(defun vc-cvs-after-dir-status (update-function)
859 ;; Heavily inspired by vc-cvs-parse-status. AKA a quick hack. 859 ;; Heavily inspired by vc-cvs-parse-status. AKA a quick hack.
860 ;; It needs a lot of testing. 860 ;; It needs a lot of testing.
861 (let ((status nil) 861 (let ((status nil)
@@ -909,14 +909,14 @@ state."
909 (push (list file status) result)))))) 909 (push (list file status) result))))))
910 (goto-char (point-max)) 910 (goto-char (point-max))
911 (widen)) 911 (widen))
912 (funcall update-function result status-buffer))) 912 (funcall update-function result)))
913 913
914;; XXX Experimental function for the vc-dired replacement. 914;; XXX Experimental function for the vc-dired replacement.
915(defun vc-cvs-dir-status (dir update-function status-buffer) 915(defun vc-cvs-dir-status (dir update-function)
916 "Create a list of conses (file . state) for DIR." 916 "Create a list of conses (file . state) for DIR."
917 (vc-cvs-command (current-buffer) 'async dir "status") 917 (vc-cvs-command (current-buffer) 'async dir "status")
918 (vc-exec-after 918 (vc-exec-after
919 `(vc-cvs-after-dir-status (quote ,update-function) ,status-buffer))) 919 `(vc-cvs-after-dir-status (quote ,update-function))))
920 920
921(defun vc-cvs-get-entries (dir) 921(defun vc-cvs-get-entries (dir)
922 "Insert the CVS/Entries file from below DIR into the current buffer. 922 "Insert the CVS/Entries file from below DIR into the current buffer.
diff --git a/lisp/vc-git.el b/lisp/vc-git.el
index f3765aaba6f..e1276955aeb 100644
--- a/lisp/vc-git.el
+++ b/lisp/vc-git.el
@@ -313,13 +313,13 @@
313;; Variable used to keep the intermediate results for vc-git-status. 313;; Variable used to keep the intermediate results for vc-git-status.
314(defvar vc-git-status-result nil) 314(defvar vc-git-status-result nil)
315 315
316(defun vc-git-after-dir-status-stage2 (update-function status-buffer) 316(defun vc-git-after-dir-status-stage2 (update-function)
317 (goto-char (point-min)) 317 (goto-char (point-min))
318 (while (re-search-forward "\\([^\0]*?\\)\0" nil t 1) 318 (while (re-search-forward "\\([^\0]*?\\)\0" nil t 1)
319 (push (list (match-string 1) 'unregistered (vc-git-create-extra-fileinfo 0 0)) vc-git-status-result)) 319 (push (list (match-string 1) 'unregistered (vc-git-create-extra-fileinfo 0 0)) vc-git-status-result))
320 (funcall update-function (nreverse vc-git-status-result) status-buffer)) 320 (funcall update-function (nreverse vc-git-status-result)))
321 321
322(defun vc-git-after-dir-status-stage1 (update-function status-buffer) 322(defun vc-git-after-dir-status-stage1 (update-function)
323 (goto-char (point-min)) 323 (goto-char (point-min))
324 (while (re-search-forward 324 (while (re-search-forward
325 ":\\([0-7]\\{6\\}\\) \\([0-7]\\{6\\}\\) [0-9a-f]\\{40\\} [0-9a-f]\\{40\\} \\(\\([ADMUT]\\)\0\\([^\0]+\\)\\|\\([CR]\\)[0-9]*\0\\([^\0]+\\)\0\\([^\0]+\\)\\)\0" 325 ":\\([0-7]\\{6\\}\\) \\([0-7]\\{6\\}\\) [0-9a-f]\\{40\\} [0-9a-f]\\{40\\} \\(\\([ADMUT]\\)\0\\([^\0]+\\)\\|\\([CR]\\)[0-9]*\0\\([^\0]+\\)\0\\([^\0]+\\)\\)\0"
@@ -339,9 +339,9 @@
339 (vc-git-command (current-buffer) 'async nil "ls-files" "-z" "-o" 339 (vc-git-command (current-buffer) 'async nil "ls-files" "-z" "-o"
340 "--directory" "--no-empty-directory" "--exclude-standard") 340 "--directory" "--no-empty-directory" "--exclude-standard")
341 (vc-exec-after 341 (vc-exec-after
342 `(vc-git-after-dir-status-stage2 (quote ,update-function) ,status-buffer))) 342 `(vc-git-after-dir-status-stage2 (quote ,update-function))))
343 343
344(defun vc-git-after-dir-status-stage1-empty-db (update-function status-buffer) 344(defun vc-git-after-dir-status-stage1-empty-db (update-function)
345 (goto-char (point-min)) 345 (goto-char (point-min))
346 (while (re-search-forward "\\([0-7]\\{6\\}\\) [0-9a-f]\\{40\\} 0\t\\([^\0]+\\)\0" nil t) 346 (while (re-search-forward "\\([0-7]\\{6\\}\\) [0-9a-f]\\{40\\} 0\t\\([^\0]+\\)\0" nil t)
347 (let ((new-perm (string-to-number (match-string 1) 8)) 347 (let ((new-perm (string-to-number (match-string 1) 8))
@@ -351,9 +351,9 @@
351 (vc-git-command (current-buffer) 'async nil "ls-files" "-z" "-o" 351 (vc-git-command (current-buffer) 'async nil "ls-files" "-z" "-o"
352 "--directory" "--no-empty-directory" "--exclude-standard") 352 "--directory" "--no-empty-directory" "--exclude-standard")
353 (vc-exec-after 353 (vc-exec-after
354 `(vc-git-after-dir-status-stage2 (quote ,update-function) ,status-buffer))) 354 `(vc-git-after-dir-status-stage2 (quote ,update-function))))
355 355
356(defun vc-git-dir-status (dir update-function status-buffer) 356(defun vc-git-dir-status (dir update-function)
357 "Return a list of conses (file . state) for DIR." 357 "Return a list of conses (file . state) for DIR."
358 ;; Further things that would have to be fixed later: 358 ;; Further things that would have to be fixed later:
359 ;; - how to handle unregistered directories 359 ;; - how to handle unregistered directories
@@ -364,10 +364,10 @@
364 (vc-git-command (current-buffer) 'async nil "ls-files" "-z" "-c" "-s") 364 (vc-git-command (current-buffer) 'async nil "ls-files" "-z" "-c" "-s")
365 (vc-exec-after 365 (vc-exec-after
366 `(vc-git-after-dir-status-stage1-empty-db 366 `(vc-git-after-dir-status-stage1-empty-db
367 (quote ,update-function) ,status-buffer))) 367 (quote ,update-function))))
368 (vc-git-command (current-buffer) 'async nil "diff-index" "-z" "-M" "HEAD") 368 (vc-git-command (current-buffer) 'async nil "diff-index" "-z" "-M" "HEAD")
369 (vc-exec-after 369 (vc-exec-after
370 `(vc-git-after-dir-status-stage1 (quote ,update-function) ,status-buffer)))) 370 `(vc-git-after-dir-status-stage1 (quote ,update-function)))))
371 371
372(defun vc-git-status-extra-headers (dir) 372(defun vc-git-status-extra-headers (dir)
373 (let ((str (with-output-to-string 373 (let ((str (with-output-to-string
diff --git a/lisp/vc-hg.el b/lisp/vc-hg.el
index 2a65691cb9d..c9cfc8eff61 100644
--- a/lisp/vc-hg.el
+++ b/lisp/vc-hg.el
@@ -475,7 +475,7 @@ REV is the revision to check out into WORKFILE."
475(define-derived-mode vc-hg-incoming-mode vc-hg-log-view-mode "Hg-Incoming") 475(define-derived-mode vc-hg-incoming-mode vc-hg-log-view-mode "Hg-Incoming")
476 476
477;; XXX Experimental function for the vc-dired replacement. 477;; XXX Experimental function for the vc-dired replacement.
478(defun vc-hg-after-dir-status (update-function status-buffer) 478(defun vc-hg-after-dir-status (update-function)
479 (let ((status-char nil) 479 (let ((status-char nil)
480 (file nil) 480 (file nil)
481 (translation '((?= . up-to-date) 481 (translation '((?= . up-to-date)
@@ -498,13 +498,13 @@ REV is the revision to check out into WORKFILE."
498 (when (and translated (not (eq (cdr translated) 'up-to-date))) 498 (when (and translated (not (eq (cdr translated) 'up-to-date)))
499 (push (list file (cdr translated)) result)) 499 (push (list file (cdr translated)) result))
500 (forward-line)) 500 (forward-line))
501 (funcall update-function result status-buffer))) 501 (funcall update-function result)))
502 502
503;; XXX Experimental function for the vc-dired replacement. 503;; XXX Experimental function for the vc-dired replacement.
504(defun vc-hg-dir-status (dir update-function status-buffer) 504(defun vc-hg-dir-status (dir update-function)
505 (vc-hg-command (current-buffer) 'async dir "status") 505 (vc-hg-command (current-buffer) 'async dir "status")
506 (vc-exec-after 506 (vc-exec-after
507 `(vc-hg-after-dir-status (quote ,update-function) ,status-buffer))) 507 `(vc-hg-after-dir-status (quote ,update-function))))
508 508
509;; XXX this adds another top level menu, instead figure out how to 509;; XXX this adds another top level menu, instead figure out how to
510;; replace the Log-View menu. 510;; replace the Log-View menu.
diff --git a/lisp/vc-rcs.el b/lisp/vc-rcs.el
index d3785847966..ac882762b62 100644
--- a/lisp/vc-rcs.el
+++ b/lisp/vc-rcs.el
@@ -182,7 +182,7 @@ For a description of possible values, see `vc-check-master-templates'."
182 (vc-rcs-state file))))) 182 (vc-rcs-state file)))))
183 183
184;; XXX Experimental function for the vc-dired replacement. 184;; XXX Experimental function for the vc-dired replacement.
185(defun vc-rcs-dir-status (dir update-function status-buffer) 185(defun vc-rcs-dir-status (dir update-function)
186 ;; XXX: quick hack, there should be a better way to do this, 186 ;; XXX: quick hack, there should be a better way to do this,
187 ;; but it's not worse than vc-dired :-). 187 ;; but it's not worse than vc-dired :-).
188 (let ((flist (vc-expand-dirs (list dir))) 188 (let ((flist (vc-expand-dirs (list dir)))
@@ -191,7 +191,7 @@ For a description of possible values, see `vc-check-master-templates'."
191 (let ((state (vc-state file)) 191 (let ((state (vc-state file))
192 (frel (file-relative-name file))) 192 (frel (file-relative-name file)))
193 (push (list frel state) result))) 193 (push (list frel state) result)))
194 (funcall update-function result status-buffer))) 194 (funcall update-function result)))
195 195
196(defun vc-rcs-working-revision (file) 196(defun vc-rcs-working-revision (file)
197 "RCS-specific version of `vc-working-revision'." 197 "RCS-specific version of `vc-working-revision'."
diff --git a/lisp/vc-sccs.el b/lisp/vc-sccs.el
index 22b73104d34..d2288d0da6d 100644
--- a/lisp/vc-sccs.el
+++ b/lisp/vc-sccs.el
@@ -145,7 +145,7 @@ For a description of possible values, see `vc-check-master-templates'."
145 (vc-sccs-state file))) 145 (vc-sccs-state file)))
146 146
147;; XXX Experimental function for the vc-dired replacement. 147;; XXX Experimental function for the vc-dired replacement.
148(defun vc-sccs-dir-status (dir update-function status-buffer) 148(defun vc-sccs-dir-status (dir update-function)
149 ;; XXX: quick hack, there should be a better way to do this, 149 ;; XXX: quick hack, there should be a better way to do this,
150 ;; but it's not worse than vc-dired :-). 150 ;; but it's not worse than vc-dired :-).
151 (let ((flist (vc-expand-dirs (list dir))) 151 (let ((flist (vc-expand-dirs (list dir)))
@@ -154,7 +154,7 @@ For a description of possible values, see `vc-check-master-templates'."
154 (let ((state (vc-state file)) 154 (let ((state (vc-state file))
155 (frel (file-relative-name file))) 155 (frel (file-relative-name file)))
156 (push (list frel state) result))) 156 (push (list frel state) result)))
157 (funcall update-function result status-buffer))) 157 (funcall update-function result)))
158 158
159(defun vc-sccs-working-revision (file) 159(defun vc-sccs-working-revision (file)
160 "SCCS-specific version of `vc-working-revision'." 160 "SCCS-specific version of `vc-working-revision'."
diff --git a/lisp/vc-svn.el b/lisp/vc-svn.el
index 1328765a8fe..e9b17d3ea57 100644
--- a/lisp/vc-svn.el
+++ b/lisp/vc-svn.el
@@ -158,7 +158,7 @@ If you want to force an empty list of arguments, use t."
158 (vc-svn-command t 0 nil "status" (if localp "-v" "-u")) 158 (vc-svn-command t 0 nil "status" (if localp "-v" "-u"))
159 (vc-svn-parse-status)))) 159 (vc-svn-parse-status))))
160 160
161(defun vc-svn-after-dir-status (callback buffer) 161(defun vc-svn-after-dir-status (callback)
162 (let ((state-map '((?A . added) 162 (let ((state-map '((?A . added)
163 (?C . conflict) 163 (?C . conflict)
164 (?D . removed) 164 (?D . removed)
@@ -177,13 +177,13 @@ If you want to force an empty list of arguments, use t."
177 (setq result (cons (list filename state) result))))) 177 (setq result (cons (list filename state) result)))))
178 (funcall callback result buffer))) 178 (funcall callback result buffer)))
179 179
180(defun vc-svn-dir-status (dir callback buffer) 180(defun vc-svn-dir-status (dir callback)
181 "Run 'svn status' for DIR and update BUFFER via CALLBACK. 181 "Run 'svn status' for DIR and update BUFFER via CALLBACK.
182CALLBACK is called as (CALLBACK RESULT BUFFER), where 182CALLBACK is called as (CALLBACK RESULT BUFFER), where
183RESULT is a list of conses (FILE . STATE) for directory DIR." 183RESULT is a list of conses (FILE . STATE) for directory DIR."
184 (vc-svn-command (current-buffer) 'async nil "status") 184 (vc-svn-command (current-buffer) 'async nil "status")
185 (vc-exec-after 185 (vc-exec-after
186 `(vc-svn-after-dir-status (quote ,callback) ,buffer))) 186 `(vc-svn-after-dir-status (quote ,callback))))
187 187
188(defun vc-svn-working-revision (file) 188(defun vc-svn-working-revision (file)
189 "SVN-specific version of `vc-working-revision'." 189 "SVN-specific version of `vc-working-revision'."
diff --git a/lisp/vc.el b/lisp/vc.el
index 970b6d7ab28..b5d98384c6a 100644
--- a/lisp/vc.el
+++ b/lisp/vc.el
@@ -168,7 +168,7 @@
168;; in older versions this method was not required to recurse into 168;; in older versions this method was not required to recurse into
169;; subdirectories.) 169;; subdirectories.)
170;; 170;;
171;; - dir-status (dir update-function status-buffer) 171;; - dir-status (dir update-function)
172;; 172;;
173;; Produce RESULT: a list of lists of the form (FILE VC-STATE EXTRA) 173;; Produce RESULT: a list of lists of the form (FILE VC-STATE EXTRA)
174;; for the files in DIR. 174;; for the files in DIR.
@@ -176,11 +176,11 @@
176;; If a command needs to be run to compute this list, it should be 176;; If a command needs to be run to compute this list, it should be
177;; run asynchronously using (current-buffer) as the buffer for the 177;; run asynchronously using (current-buffer) as the buffer for the
178;; command. When RESULT is computed, it should be passed back by 178;; command. When RESULT is computed, it should be passed back by
179;; doing: (funcall UPDATE-FUNCTION RESULT STATUS-BUFFER nil). 179;; doing: (funcall UPDATE-FUNCTION RESULT nil).
180;; If the backend uses a process filter, hence it produces partial results, 180;; If the backend uses a process filter, hence it produces partial results,
181;; they can be passed back by doing: 181;; they can be passed back by doing:
182;; (funcall UPDATE-FUNCTION RESULT STATUS-BUFFER t) 182;; (funcall UPDATE-FUNCTION RESULT t)
183;; and then do a (funcall UPDATE-FUNCTION RESULT STATUS-BUFFER nil) 183;; and then do a (funcall UPDATE-FUNCTION RESULT nil)
184;; when all the results have been computed. 184;; when all the results have been computed.
185;; To provide more backend specific functionality for `vc-status' 185;; To provide more backend specific functionality for `vc-status'
186;; the following functions might be needed: `status-extra-headers', 186;; the following functions might be needed: `status-extra-headers',
@@ -582,6 +582,9 @@
582 582
583;;; Todo: 583;;; Todo:
584 584
585;; - vc-status-kill-dir-status-process should not be specific to dir-status,
586;; it should work for other async commands as well (pull/push/...).
587;;
585;; - vc-update/vc-merge should deal with VC systems that don't 588;; - vc-update/vc-merge should deal with VC systems that don't
586;; update/merge on a file basis, but on a whole repository basis. 589;; update/merge on a file basis, but on a whole repository basis.
587;; 590;;
@@ -1438,10 +1441,8 @@ Otherwise, throw an error."
1438 (error "All members of a fileset must be under the same version-control system.")))) 1441 (error "All members of a fileset must be under the same version-control system."))))
1439 marked)) 1442 marked))
1440 ((eq major-mode 'vc-status-mode) 1443 ((eq major-mode 'vc-status-mode)
1441 (let ((marked (vc-status-marked-files))) 1444 (or (vc-status-marked-files)
1442 (if marked 1445 (list (vc-status-current-file))))
1443 marked
1444 (list (vc-status-current-file)))))
1445 ((vc-backend buffer-file-name) 1446 ((vc-backend buffer-file-name)
1446 (list buffer-file-name)) 1447 (list buffer-file-name))
1447 ((and vc-parent-buffer (or (buffer-file-name vc-parent-buffer) 1448 ((and vc-parent-buffer (or (buffer-file-name vc-parent-buffer)
@@ -2705,14 +2706,16 @@ With prefix arg READ-SWITCHES, specify a value to override
2705;; Each item displayed corresponds to one of these defstructs. 2706;; Each item displayed corresponds to one of these defstructs.
2706(defstruct (vc-status-fileinfo 2707(defstruct (vc-status-fileinfo
2707 (:copier nil) 2708 (:copier nil)
2709 (:type list) ;So we can use `member' on lists of FIs.
2708 (:constructor 2710 (:constructor
2709 vc-status-create-fileinfo (name state extra &optional marked)) 2711 ;; We could define it as an alias for `list'.
2712 vc-status-create-fileinfo (name state &optional extra marked))
2710 (:conc-name vc-status-fileinfo->)) 2713 (:conc-name vc-status-fileinfo->))
2711 marked 2714 name ;Keep it as first, for `member'.
2712 state 2715 state
2713 name
2714 ;; For storing backend specific information. 2716 ;; For storing backend specific information.
2715 extra) 2717 extra
2718 marked)
2716 2719
2717(defvar vc-status nil) 2720(defvar vc-status nil)
2718 2721
@@ -2804,11 +2807,11 @@ specific headers."
2804 :help "Quit")) 2807 :help "Quit"))
2805 (define-key map [kill] 2808 (define-key map [kill]
2806 '(menu-item "Kill Update Command" vc-status-kill-dir-status-process 2809 '(menu-item "Kill Update Command" vc-status-kill-dir-status-process
2807 :enable vc-status-process-buffer 2810 :enable (vc-status-busy)
2808 :help "Kill the command that updates VC status buffer")) 2811 :help "Kill the command that updates VC status buffer"))
2809 (define-key map [refresh] 2812 (define-key map [refresh]
2810 '(menu-item "Refresh" vc-status-refresh 2813 '(menu-item "Refresh" vc-status-refresh
2811 :enable (not vc-status-process-buffer) 2814 :enable (not (vc-status-busy))
2812 :help "Refresh the contents of the VC status buffer")) 2815 :help "Refresh the contents of the VC status buffer"))
2813 (define-key map [remup] 2816 (define-key map [remup]
2814 '(menu-item "Hide up-to-date" vc-status-hide-up-to-date 2817 '(menu-item "Hide up-to-date" vc-status-hide-up-to-date
@@ -2974,16 +2977,12 @@ specific headers."
2974(defvar vc-status-process-buffer nil 2977(defvar vc-status-process-buffer nil
2975 "The buffer used for the asynchronous call that computes the VC status.") 2978 "The buffer used for the asynchronous call that computes the VC status.")
2976 2979
2977(defvar vc-status-crt-marked nil
2978 "The list of marked files before `vc-status-refresh'.")
2979
2980(defun vc-status-mode () 2980(defun vc-status-mode ()
2981 "Major mode for VC status. 2981 "Major mode for VC status.
2982\\{vc-status-mode-map}" 2982\\{vc-status-mode-map}"
2983 (setq mode-name "VC Status") 2983 (setq mode-name "VC Status")
2984 (setq major-mode 'vc-status-mode) 2984 (setq major-mode 'vc-status-mode)
2985 (setq buffer-read-only t) 2985 (setq buffer-read-only t)
2986 (set (make-local-variable 'vc-status-crt-marked) nil)
2987 (use-local-map vc-status-mode-map) 2986 (use-local-map vc-status-mode-map)
2988 (set (make-local-variable 'tool-bar-map) vc-status-tool-bar-map) 2987 (set (make-local-variable 'tool-bar-map) vc-status-tool-bar-map)
2989 (let ((buffer-read-only nil) 2988 (let ((buffer-read-only nil)
@@ -2999,76 +2998,52 @@ specific headers."
2999 2998
3000(put 'vc-status-mode 'mode-class 'special) 2999(put 'vc-status-mode 'mode-class 'special)
3001 3000
3002(defun vc-status-add-entries (entries buffer) 3001(defun vc-status-update (entries buffer &optional noinsert)
3002 "Update BUFFER's ewoc from the list of ENTRIES.
3003If NOINSERT, ignore elements on ENTRIES which are not in the ewoc."
3003 ;; Add ENTRIES to the vc-status buffer BUFFER. 3004 ;; Add ENTRIES to the vc-status buffer BUFFER.
3004 (with-current-buffer buffer 3005 (with-current-buffer buffer
3005 (when entries 3006 ;; Insert the entries sorted by name into the ewoc.
3006 ;; Insert the entries sorted by name into the ewoc. 3007 ;; We assume the ewoc is sorted too, which should be the
3007 ;; We assume the ewoc is sorted too, which should be the 3008 ;; case if we always add entries with vc-status-update.
3008 ;; case if we always add entries with vc-status-add-entries. 3009 (setq entries (sort entries
3009 (setq entries (sort (copy-sequence entries) 3010 (lambda (entry1 entry2)
3010 (lambda (entry1 entry2) 3011 (string-lessp (car entry1) (car entry2)))))
3011 (string-lessp (car entry1) (car entry2))))) 3012 (let ((entry (car entries))
3012 (let ((entry (pop entries)) 3013 (node (ewoc-nth vc-status 0)))
3013 (node (ewoc-nth vc-status 0))) 3014 (while (and entry node)
3014 (while entry 3015 (let ((entryfile (car entry))
3015 (while (and vc-status-crt-marked 3016 (nodefile (vc-status-fileinfo->name (ewoc-data node))))
3016 (string-lessp (car vc-status-crt-marked) (car entry))) 3017 (cond
3017 (setq vc-status-crt-marked (cdr vc-status-crt-marked))) 3018 ((string-lessp nodefile entryfile)
3018 (let* ((file (car entry)) 3019 (setq node (ewoc-next vc-status node)))
3019 (state (nth 1 entry)) 3020 ((string-lessp nodefile entryfile)
3020 (extra (nth 2 entry)) 3021 (unless noinsert
3021 (marked (and vc-status-crt-marked 3022 (ewoc-enter-before vc-status node
3022 (string-equal (car vc-status-crt-marked) file)))) 3023 (apply 'vc-status-create-fileinfo entry)))
3023 (cond ((not node) 3024 (setq entries (cdr entries) entry (car entries)))
3024 (setq node (ewoc-enter-last vc-status 3025 (t
3025 (vc-status-create-fileinfo file state extra marked))) 3026 (setf (vc-status-fileinfo->state (ewoc-data node)) (nth 1 entry))
3026 (setq entry (pop entries))) 3027 (setf (vc-status-fileinfo->extra (ewoc-data node)) (nth 2 entry))
3027 ((string-lessp (vc-status-fileinfo->name (ewoc-data node)) file) 3028 (ewoc-invalidate vc-status node)
3028 (setq node (ewoc-next vc-status node))) 3029 (setq entries (cdr entries) entry (car entries))
3029 ((string-equal (vc-status-fileinfo->name (ewoc-data node)) file) 3030 (setq node (ewoc-next vc-status node))))))
3030 (setf (vc-status-fileinfo->state (ewoc-data node)) state) 3031 (unless (or node noinsert)
3031 (setf (vc-status-fileinfo->extra (ewoc-data node)) extra) 3032 ;; We're past the last node, all remaining entries go to the end.
3032 (ewoc-invalidate vc-status node) 3033 (while entries
3033 (setq entry (pop entries))) 3034 (ewoc-enter-last vc-status
3034 (t 3035 (apply 'vc-status-create-fileinfo (pop entries))))))))
3035 (setq node (ewoc-enter-before vc-status node 3036
3036 (vc-status-create-fileinfo file state extra marked))) 3037(defun vc-status-busy ()
3037 (setq entry (pop entries)))))))))) 3038 (and (buffer-live-p vc-status-process-buffer)
3038 3039 (get-buffer-process vc-status-process-buffer)))
3039(defun vc-update-vc-status-buffer (entries buffer &optional more-to-come)
3040 ;; ENTRIES is a list of (FILE VC_STATE EXTRA) items.
3041 ;; BUFFER is the *vc-status* buffer to be updated with ENTRIES
3042 ;; If MORE-TO-COME is true, then more updates will come from the
3043 ;; asynchronous process.
3044 (with-current-buffer buffer
3045 (when entries
3046 (vc-status-add-entries entries buffer)
3047 (ewoc-goto-node vc-status (ewoc-nth vc-status 0)))
3048 ;; No more updates are expected from the asynchronous process.
3049 (unless more-to-come
3050 (setq vc-status-process-buffer nil)
3051 ;; We are done, turn off the mode-line "in progress" message.
3052 (setq mode-line-process nil))))
3053 3040
3054(defun vc-status-refresh () 3041(defun vc-status-refresh ()
3055 "Refresh the contents of the VC status buffer. 3042 "Refresh the contents of the VC status buffer.
3056Throw an error if another update process is in progress." 3043Throw an error if another update process is in progress."
3057 (interactive) 3044 (interactive)
3058 (if vc-status-process-buffer 3045 (if (vc-status-busy)
3059 (error "Another update process is in progress, cannot run two at a time") 3046 (error "Another update process is in progress, cannot run two at a time")
3060 ;; We clear the ewoc, but remember the marked files so that we can
3061 ;; mark them again after the refresh is done.
3062 ;; This is not very efficient; ewoc could use a new function here.
3063 (setq vc-status-crt-marked
3064 (mapcar
3065 (lambda (elem)
3066 (vc-status-fileinfo->name elem))
3067 (ewoc-collect
3068 vc-status
3069 (lambda (crt) (vc-status-fileinfo->marked crt)))))
3070 (ewoc-filter vc-status (lambda (node) nil))
3071
3072 (let ((backend (vc-responsible-backend default-directory)) 3047 (let ((backend (vc-responsible-backend default-directory))
3073 (status-buffer (current-buffer)) 3048 (status-buffer (current-buffer))
3074 (def-dir default-directory)) 3049 (def-dir default-directory))
@@ -3084,14 +3059,35 @@ Throw an error if another update process is in progress."
3084 ;; `vc-status-process-buffer' to remember this buffer, so that 3059 ;; `vc-status-process-buffer' to remember this buffer, so that
3085 ;; it can be used later to kill the update process in case it 3060 ;; it can be used later to kill the update process in case it
3086 ;; takes too long. 3061 ;; takes too long.
3087 (setq vc-status-process-buffer 3062 (unless (buffer-live-p vc-status-process-buffer)
3088 (get-buffer-create 3063 (setq vc-status-process-buffer
3089 (generate-new-buffer-name (format " *VC-%s* tmp status" backend)))) 3064 (generate-new-buffer (format " *VC-%s* tmp status" backend))))
3090 (with-current-buffer vc-status-process-buffer 3065 (lexical-let ((oldentries (ewoc-collect vc-status (lambda (_) t)))
3091 (cd def-dir) 3066 (buffer (current-buffer)))
3092 (erase-buffer) 3067 (with-current-buffer vc-status-process-buffer
3093 (vc-call-backend backend 'dir-status def-dir 3068 (cd def-dir)
3094 #'vc-update-vc-status-buffer status-buffer))))) 3069 (erase-buffer)
3070 (vc-call-backend
3071 backend 'dir-status def-dir
3072 (lambda (entries &optional more-to-come)
3073 ;; ENTRIES is a list of (FILE VC_STATE EXTRA) items.
3074 ;; If MORE-TO-COME is true, then more updates will come from
3075 ;; the asynchronous process.
3076 (with-current-buffer buffer
3077 (dolist (entry entries)
3078 (setq oldentries
3079 (delq (member (car entry) oldentries) oldentries)))
3080 (vc-status-update entries buffer)
3081 (ewoc-goto-node vc-status (ewoc-nth vc-status 0))
3082 ;; No more updates are expected from the asynchronous process.
3083 (unless more-to-come
3084 ;; We are done, turn off the mode-line "in progress" message.
3085 (setq mode-line-process nil)
3086 ;; Update old entries that were not mentioned, and were
3087 ;; hence implicitly given as uptodate.
3088 (dolist (entry oldentries)
3089 (setf (vc-status-fileinfo->state entry) 'up-to-date))
3090 (vc-status-update oldentries buffer 'noinsert))))))))))
3095 3091
3096(defun vc-status-kill-dir-status-process () 3092(defun vc-status-kill-dir-status-process ()
3097 "Kill the temporary buffer and associated process." 3093 "Kill the temporary buffer and associated process."
@@ -3236,10 +3232,9 @@ that share the same state."
3236(defun vc-status-register () 3232(defun vc-status-register ()
3237 "Register the marked files, or the current file if no marks." 3233 "Register the marked files, or the current file if no marks."
3238 (interactive) 3234 (interactive)
3239 (let ((files (or (vc-status-marked-files) 3235 ;; FIXME: Just pass the fileset to vc-register.
3240 (list (vc-status-current-file))))) 3236 (mapc 'vc-register (or (vc-status-marked-files)
3241 (dolist (file files) 3237 (list (vc-status-current-file)))))
3242 (vc-register file))))
3243 3238
3244(defun vc-status-find-file () 3239(defun vc-status-find-file ()
3245 "Find the file on the current line." 3240 "Find the file on the current line."
@@ -3260,11 +3255,8 @@ that share the same state."
3260(defun vc-status-marked-files () 3255(defun vc-status-marked-files ()
3261 "Return the list of marked files" 3256 "Return the list of marked files"
3262 (mapcar 3257 (mapcar
3263 (lambda (elem) 3258 (lambda (elem) (expand-file-name (vc-status-fileinfo->name elem)))
3264 (expand-file-name (vc-status-fileinfo->name elem))) 3259 (ewoc-collect vc-status 'vc-status-fileinfo->marked)))
3265 (ewoc-collect
3266 vc-status
3267 (lambda (crt) (vc-status-fileinfo->marked crt)))))
3268 3260
3269(defun vc-status-hide-up-to-date () 3261(defun vc-status-hide-up-to-date ()
3270 "Hide up-to-date items from display." 3262 "Hide up-to-date items from display."
@@ -3297,7 +3289,7 @@ that share the same state."
3297 (vc-call-backend backend 'status-fileinfo-extra file))) 3289 (vc-call-backend backend 'status-fileinfo-extra file)))
3298 (entry 3290 (entry
3299 (list file-short (if state state 'unregistered) extra))) 3291 (list file-short (if state state 'unregistered) extra)))
3300 (vc-status-add-entries (list entry) status-buf)))))) 3292 (vc-status-update (list entry) status-buf))))))
3301 ;; We didn't find any vc-status buffers, remove the hook, it is 3293 ;; We didn't find any vc-status buffers, remove the hook, it is
3302 ;; not needed. 3294 ;; not needed.
3303 (unless found-vc-status-buf (remove-hook 'after-save-hook 'vc-status-mark-buffer-changed))))) 3295 (unless found-vc-status-buf (remove-hook 'after-save-hook 'vc-status-mark-buffer-changed)))))