diff options
| author | Eric S. Raymond | 2008-05-04 13:17:33 +0000 |
|---|---|---|
| committer | Eric S. Raymond | 2008-05-04 13:17:33 +0000 |
| commit | cb625535b532afa1017ed5b6ff7ca0b25f1e3b0a (patch) | |
| tree | d22e7e112c2d1afc8ab3066920ec4b735dbffd59 | |
| parent | 67321a57fccfdbfa8fa88e1b4ddb3d206e1081fe (diff) | |
| download | emacs-cb625535b532afa1017ed5b6ff7ca0b25f1e3b0a.tar.gz emacs-cb625535b532afa1017ed5b6ff7ca0b25f1e3b0a.zip | |
Bug fix for vc-dispatcher split.
| -rw-r--r-- | lisp/vc-dispatcher.el | 100 | ||||
| -rw-r--r-- | lisp/vc.el | 132 |
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. | ||
| 1562 | Marking/Unmarking key bindings and actions: | ||
| 1563 | m - 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 | ||
| 1568 | u - marks a file/directory or if the region is active, unmark all the files | ||
| 1569 | in region. | ||
| 1570 | M - 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 | ||
| 1574 | U - 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. | ||
| 2059 | Marking/Unmarking key bindings and actions: | ||
| 2060 | m - 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 | ||
| 2065 | u - marks a file/directory or if the region is active, unmark all the files | ||
| 2066 | in region. | ||
| 2067 | M - 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 | ||
| 2071 | U - 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 | ||