aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric S. Raymond2008-05-04 13:17:33 +0000
committerEric S. Raymond2008-05-04 13:17:33 +0000
commitcb625535b532afa1017ed5b6ff7ca0b25f1e3b0a (patch)
treed22e7e112c2d1afc8ab3066920ec4b735dbffd59
parent67321a57fccfdbfa8fa88e1b4ddb3d206e1081fe (diff)
downloademacs-cb625535b532afa1017ed5b6ff7ca0b25f1e3b0a.tar.gz
emacs-cb625535b532afa1017ed5b6ff7ca0b25f1e3b0a.zip
Bug fix for vc-dispatcher split.
-rw-r--r--lisp/vc-dispatcher.el100
-rw-r--r--lisp/vc.el132
2 files changed, 137 insertions, 95 deletions
diff --git a/lisp/vc-dispatcher.el b/lisp/vc-dispatcher.el
index 78ff34496bb..d89142445ca 100644
--- a/lisp/vc-dispatcher.el
+++ b/lisp/vc-dispatcher.el
@@ -540,11 +540,9 @@ editing!"
540 (when buffer 540 (when buffer
541 (with-current-buffer buffer 541 (with-current-buffer buffer
542 (vc-resynch-window file keep noquery))))) 542 (vc-resynch-window file keep noquery)))))
543 ;; FIME: Call into vc.el
544 (vc-directory-resynch-file file) 543 (vc-directory-resynch-file file)
545 (when (memq 'vc-dir-mark-buffer-changed after-save-hook) 544 (when (memq 'vc-dir-mark-buffer-changed after-save-hook)
546 (let ((buffer (get-file-buffer file))) 545 (let ((buffer (get-file-buffer file)))
547 ;; FIME: Call into vc.el
548 (vc-dir-mark-buffer-changed file)))) 546 (vc-dir-mark-buffer-changed file))))
549 547
550;; Command closures 548;; Command closures
@@ -888,6 +886,24 @@ See `run-hooks'."
888 ;; To distinguish files and directories. 886 ;; To distinguish files and directories.
889 directory) 887 directory)
890 888
889;; Used to describe a dispatcher client mode.
890(defstruct (vc-client-object
891 (:copier nil)
892 (:constructor
893 vc-create-client-object (name
894 headers
895 file-to-info
896 file-to-state
897 file-to-extra
898 updater))
899 (:conc-name vc-client-object->))
900 name
901 headers
902 file-to-info
903 file-to-state
904 file-to-extra
905 updater)
906
891(defvar vc-ewoc nil) 907(defvar vc-ewoc nil)
892(defvar vc-dir-process-buffer nil 908(defvar vc-dir-process-buffer nil
893 "The buffer used for the asynchronous call that computes the VC status.") 909 "The buffer used for the asynchronous call that computes the VC status.")
@@ -1027,25 +1043,17 @@ See `run-hooks'."
1027 (define-key map "\t" 'vc-dir-next-line) 1043 (define-key map "\t" 'vc-dir-next-line)
1028 (define-key map "p" 'vc-dir-previous-line) 1044 (define-key map "p" 'vc-dir-previous-line)
1029 (define-key map [backtab] 'vc-dir-previous-line) 1045 (define-key map [backtab] 'vc-dir-previous-line)
1030 ;; VC commands.
1031 ;; FIXME: These need to be in a client-local keymap
1032 (define-key map "=" 'vc-diff) ;; C-x v =
1033 (define-key map "a" 'vc-dir-register)
1034 (define-key map "+" 'vc-update) ;; C-x v +
1035 (define-key map "R" 'vc-revert) ;; u is taken by unmark.
1036 (define-key map "A" 'vc-annotate);; Can't be "g" (as in vc map)
1037 (define-key map "l" 'vc-print-log) ;; C-x v l
1038 ;; The remainder. 1046 ;; The remainder.
1039 (define-key map "f" 'vc-dir-find-file) 1047 (define-key map "f" 'vc-dir-find-file)
1040 (define-key map "\C-m" 'vc-dir-find-file) 1048 (define-key map "\C-m" 'vc-dir-find-file)
1041 (define-key map "o" 'vc-dir-find-file-other-window) 1049 (define-key map "o" 'vc-dir-find-file-other-window)
1042 (define-key map "x" 'vc-dir-hide-up-to-date)
1043 (define-key map "q" 'quit-window) 1050 (define-key map "q" 'quit-window)
1044 (define-key map "g" 'vc-dir-refresh) 1051 (define-key map "g" 'vc-dir-refresh)
1045 (define-key map "\C-c\C-c" 'vc-dir-kill-dir-status-process) 1052 (define-key map "\C-c\C-c" 'vc-dir-kill-dir-status-process)
1046 (define-key map [(down-mouse-3)] 'vc-dir-menu) 1053 (define-key map [(down-mouse-3)] 'vc-dir-menu)
1047 (define-key map [(mouse-2)] 'vc-dir-toggle-mark) 1054 (define-key map [(mouse-2)] 'vc-dir-toggle-mark)
1048 1055
1056 ;; FIXME: Calls back into vc.el
1049 ;; Hook up the menu. 1057 ;; Hook up the menu.
1050 (define-key map [menu-bar vc-dir-mode] 1058 (define-key map [menu-bar vc-dir-mode]
1051 '(menu-item 1059 '(menu-item
@@ -1493,8 +1501,7 @@ that share the same state."
1493 (ewoc-collect vc-ewoc 'vc-dir-fileinfo->marked))) 1501 (ewoc-collect vc-ewoc 'vc-dir-fileinfo->marked)))
1494 1502
1495(defun vc-dir-marked-only-files () 1503(defun vc-dir-marked-only-files ()
1496 "Return the list of marked files, for marked directories, return child files." 1504 "Return the list of marked files, For marked directories return child files."
1497
1498 (let ((crt (ewoc-nth vc-ewoc 0)) 1505 (let ((crt (ewoc-nth vc-ewoc 0))
1499 result) 1506 result)
1500 (while crt 1507 (while crt
@@ -1525,4 +1532,71 @@ that share the same state."
1525 (setq crt (ewoc-next vc-ewoc crt))))) 1532 (setq crt (ewoc-next vc-ewoc crt)))))
1526 result)) 1533 result))
1527 1534
1535(defun vc-dir-mark-buffer-changed (&optional fname)
1536 (let* ((file (or fname (expand-file-name buffer-file-name)))
1537 (found-vc-dir-buf nil))
1538 (save-excursion
1539 (dolist (status-buf (buffer-list))
1540 (set-buffer status-buf)
1541 ;; look for a vc-dir buffer that might show this file.
1542 (when (eq major-mode 'vc-dir-mode)
1543 (setq found-vc-dir-buf t)
1544 (let ((ddir (expand-file-name default-directory)))
1545 ;; This test is cvs-string-prefix-p
1546 (when (eq t (compare-strings file nil (length ddir) ddir nil nil))
1547 (let*
1548 ((file-short (substring file (length ddir)))
1549 (state
1550 (apply (client-mode->file-to-state client-mode) fname))
1551 (extra
1552 (apply (client-mode->file-to-extra client-mode) fname))
1553 (entry
1554 (list file-short state extra)))
1555 (vc-dir-update (list entry) status-buf))))))
1556 ;; We didn't find any vc-dir buffers, remove the hook, it is
1557 ;; not needed.
1558 (unless found-vc-dir-buf (remove-hook 'after-save-hook 'vc-dir-mark-buffer-changed)))))
1559
1560(defun vc-dir-mode (client-object)
1561 "Major mode for showing the VC status for a directory.
1562Marking/Unmarking key bindings and actions:
1563m - marks a file/directory or if the region is active, mark all the files
1564 in region.
1565 Restrictions: - a file cannot be marked if any parent directory is marked
1566 - a directory cannot be marked if any child file or
1567 directory is marked
1568u - marks a file/directory or if the region is active, unmark all the files
1569 in region.
1570M - if the cursor is on a file: mark all the files with the same VC state as
1571 the current file
1572 - if the cursor is on a directory: mark all child files
1573 - with a prefix argument: mark all files
1574U - if the cursor is on a file: unmark all the files with the same VC state
1575 as the current file
1576 - if the cursor is on a directory: unmark all child files
1577 - with a prefix argument: unmark all files
1578
1579
1580\\{vc-dir-mode-map}"
1581 (setq mode-name (vc-client-object->name client-object))
1582 (setq major-mode 'vc-dir-mode)
1583 (setq buffer-read-only t)
1584 (use-local-map vc-dir-mode-map)
1585 (set (make-local-variable 'tool-bar-map) vc-dir-tool-bar-map)
1586 (set (make-local-variable 'client-mode) client-object)
1587 (let ((buffer-read-only nil))
1588 (erase-buffer)
1589 (set (make-local-variable 'vc-dir-process-buffer) nil)
1590 (set (make-local-variable 'vc-ewoc)
1591 (ewoc-create (vc-client-object->file-to-info client-object)
1592 (vc-client-object->headers client-object)))
1593 (add-hook 'after-save-hook 'vc-dir-mark-buffer-changed)
1594 ;; Make sure that if the VC status buffer is killed, the update
1595 ;; process running in the background is also killed.
1596 (add-hook 'kill-buffer-query-functions 'vc-dir-kill-query nil t)
1597 (funcall (vc-client-object->updater client-object)))
1598 (run-hooks 'vc-dir-mode-hook))
1599
1600(put 'vc-dir-mode 'mode-class 'special)
1601
1528;;; vc-dispatcher.el ends here 1602;;; vc-dispatcher.el ends here
diff --git a/lisp/vc.el b/lisp/vc.el
index ed0ddc154cf..dcb2a8bf13f 100644
--- a/lisp/vc.el
+++ b/lisp/vc.el
@@ -2054,63 +2054,6 @@ specific headers."
2054(defun vc-default-extra-status-menu (backend) 2054(defun vc-default-extra-status-menu (backend)
2055 nil) 2055 nil)
2056 2056
2057(defun vc-dir-mode (entry-printer header-printer updater marker)
2058 "Major mode for showing the VC status for a directory.
2059Marking/Unmarking key bindings and actions:
2060m - marks a file/directory or ff the region is active, mark all the files
2061 in region.
2062 Restrictions: - a file cannot be marked if any parent directory is marked
2063 - a directory cannot be marked if any child file or
2064 directory is marked
2065u - marks a file/directory or if the region is active, unmark all the files
2066 in region.
2067M - if the cursor is on a file: mark all the files with the same VC state as
2068 the current file
2069 - if the cursor is on a directory: mark all child files
2070 - with a prefix argument: mark all files
2071U - if the cursor is on a file: unmark all the files with the same VC state
2072 as the current file
2073 - if the cursor is on a directory: unmark all child files
2074 - with a prefix argument: unmark all files
2075
2076
2077\\{vc-dir-mode-map}"
2078 (setq mode-name "VC Status")
2079 (setq major-mode 'vc-dir-mode)
2080 (setq buffer-read-only t)
2081 (use-local-map vc-dir-mode-map)
2082 (set (make-local-variable 'tool-bar-map) vc-dir-tool-bar-map)
2083 (let ((buffer-read-only nil)
2084 entries)
2085 (erase-buffer)
2086 (set (make-local-variable 'vc-dir-process-buffer) nil)
2087 (set (make-local-variable 'vc-ewoc)
2088 (ewoc-create entry-printer
2089 header-printer))
2090 (add-hook 'after-save-hook marker)
2091 ;; Make sure that if the VC status buffer is killed, the update
2092 ;; process running in the background is also killed.
2093 (add-hook 'kill-buffer-query-functions 'vc-dir-kill-query nil t)
2094 (eval updater))
2095 (run-hooks 'vc-dir-mode-hook))
2096
2097(put 'vc-dir-mode 'mode-class 'special)
2098
2099;;;###autoload
2100(defun vc-dir (dir)
2101 "Show the VC status for DIR."
2102 (interactive "DVC status for directory: ")
2103 (pop-to-buffer (vc-dir-prepare-status-buffer dir))
2104 (if (eq major-mode 'vc-dir-mode)
2105 (vc-dir-refresh)
2106 (let ((backend (vc-responsible-backend default-directory)))
2107 (vc-dir-mode (lambda (fileentry)
2108 (vc-call-backend backend 'status-printer fileentry))
2109 (lambda (dir)
2110 (vc-dir-headers backend default-directory))
2111 #'vc-dir-mark-buffer-changed
2112 #'vc-dir-refresh))))
2113
2114;; This is used to that VC backends could add backend specific menu 2057;; This is used to that VC backends could add backend specific menu
2115;; items to vc-dir-menu-map. 2058;; items to vc-dir-menu-map.
2116(defun vc-dir-menu-map-filter (orig-binding) 2059(defun vc-dir-menu-map-filter (orig-binding)
@@ -2231,33 +2174,58 @@ outside of VC) and one wants to do some operation on it."
2231 (or (vc-dir-marked-files) (list (vc-dir-current-file))))) 2174 (or (vc-dir-marked-files) (list (vc-dir-current-file)))))
2232 2175
2233(defun vc-default-status-fileinfo-extra (backend file) 2176(defun vc-default-status-fileinfo-extra (backend file)
2177 "Default absence of extra information returned for a file."
2234 nil) 2178 nil)
2235 2179
2236(defun vc-dir-mark-buffer-changed (&optional fname) 2180;; FIXME: Replace these with a more efficient dispatch
2237 (let* ((file (or fname (expand-file-name buffer-file-name))) 2181
2238 (found-vc-dir-buf nil)) 2182(defun vc-generic-status-printer (fileentry)
2239 (save-excursion 2183 (let ((backend (vc-responsible-backend (vc-dir-fileinfo->name fileentry))))
2240 (dolist (status-buf (buffer-list)) 2184 (vc-call-backend backend 'status-printer fileentry)))
2241 (set-buffer status-buf) 2185
2242 ;; look for a vc-dir buffer that might show this file. 2186(defun vc-generic-state (file)
2243 (when (eq major-mode 'vc-dir-mode) 2187 (let ((backend (vc-responsible-backend file)))
2244 (setq found-vc-dir-buf t) 2188 (vc-call-backend backend 'state)))
2245 (let ((ddir (expand-file-name default-directory))) 2189
2246 ;; This test is cvs-string-prefix-p 2190(defun vc-generic-status-fileinfo-extra (file)
2247 (when (eq t (compare-strings file nil (length ddir) ddir nil nil)) 2191 (let ((backend (vc-responsible-backend file)))
2248 (let* 2192 (vc-call-backend backend 'status-fileinfo-extra)))
2249 ((file-short (substring file (length ddir))) 2193
2250 (backend (vc-backend file)) 2194(defun vc-generic-dir-headers (dir)
2251 (state (and backend (vc-state file))) 2195 (let ((backend (vc-responsible-backend dir)))
2252 (extra 2196 (vc-dir-headers backend dir)))
2253 (and backend 2197
2254 (vc-call-backend backend 'status-fileinfo-extra file))) 2198(defun vc-make-backend-object (file-or-dir)
2255 (entry 2199 (vc-create-client-object
2256 (list file-short (if state state 'unregistered) extra))) 2200 "VC status"
2257 (vc-dir-update (list entry) status-buf)))))) 2201 (let ((backend (vc-responsible-backend file-or-dir)))
2258 ;; We didn't find any vc-dir buffers, remove the hook, it is 2202 (vc-dir-headers backend file-or-dir))
2259 ;; not needed. 2203 #'vc-generic-status-printer
2260 (unless found-vc-dir-buf (remove-hook 'after-save-hook 'vc-dir-mark-buffer-changed))))) 2204 #'vc-generic-state
2205 #'vc-generic-status-fileinfo-extra
2206 #'vc-dir-refresh))
2207
2208;;;###autoload
2209(defun vc-dir (dir)
2210 "Show the VC status for DIR."
2211 (interactive "DVC status for directory: ")
2212 (pop-to-buffer (vc-dir-prepare-status-buffer dir))
2213 (if (eq major-mode 'vc-dir-mode)
2214 (vc-dir-refresh)
2215 ;; Otherwise, initialize a new view using the dispatcher layer
2216 (progn
2217 ;; Build a capability object and hand it to the dispatcher initializer
2218 (vc-dir-mode (vc-make-backend-object backend))
2219 ;; Add VC-specific keybindings
2220 (let ((map (current-local-map)))
2221 (define-key map "=" 'vc-diff) ;; C-x v =
2222 (define-key map "a" 'vc-dir-register)
2223 (define-key map "+" 'vc-update) ;; C-x v +
2224 (define-key map "R" 'vc-revert) ;; u is taken by dispatcher unmark.
2225 (define-key map "A" 'vc-annotate) ;; g is taken by dispatcher referesh
2226 (define-key map "l" 'vc-print-log) ;; C-x v l
2227 (define-key map "x" 'vc-dir-hide-up-to-date)
2228 ))))
2261 2229
2262;; Named-configuration entry points 2230;; Named-configuration entry points
2263 2231