diff options
| author | Dan Nicolaescu | 2008-05-26 23:49:35 +0000 |
|---|---|---|
| committer | Dan Nicolaescu | 2008-05-26 23:49:35 +0000 |
| commit | af71bb11ac7c0145af8cd7d8533adb4a582b60cb (patch) | |
| tree | 535a6dda5f9165faf6bc9f51b72e2dd1edffe43b | |
| parent | 4ff615b49ff936fef63b0cf4f14f7e1bf53e456d (diff) | |
| download | emacs-af71bb11ac7c0145af8cd7d8533adb4a582b60cb.tar.gz emacs-af71bb11ac7c0145af8cd7d8533adb4a582b60cb.zip | |
(vc-dir-child-files): New function.
(vc-dir-node-directory): New function.
(vc-dir-update, vc-dir-parent-marked-p)
(vc-dir-children-marked-p, vc-dir-mark-all-files)
(vc-dir-marked-only-files, vc-dispatcher-selection-set): Use it.
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/vc-dispatcher.el | 121 |
2 files changed, 70 insertions, 56 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f48bfb2f1de..1d84ff07cbc 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -4,6 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | * vc-dispatcher.el (vc-resynch-window): Fix mode-line updating. | 5 | * vc-dispatcher.el (vc-resynch-window): Fix mode-line updating. |
| 6 | (vc-dir-menu-map): Fix menu title for the menu bar and the popup menu. | 6 | (vc-dir-menu-map): Fix menu title for the menu bar and the popup menu. |
| 7 | (vc-dir-child-files): New function. | ||
| 8 | (vc-dir-node-directory): New function. | ||
| 9 | (vc-dir-update, vc-dir-parent-marked-p) | ||
| 10 | (vc-dir-children-marked-p, vc-dir-mark-all-files) | ||
| 11 | (vc-dir-marked-only-files, vc-dispatcher-selection-set): Use it. | ||
| 7 | 12 | ||
| 8 | 2008-05-26 Stefan Monnier <monnier@iro.umontreal.ca> | 13 | 2008-05-26 Stefan Monnier <monnier@iro.umontreal.ca> |
| 9 | 14 | ||
diff --git a/lisp/vc-dispatcher.el b/lisp/vc-dispatcher.el index 2c9b93192a2..8e9cf21d3c7 100644 --- a/lisp/vc-dispatcher.el +++ b/lisp/vc-dispatcher.el | |||
| @@ -699,7 +699,7 @@ See `run-hooks'." | |||
| 699 | (current-buffer))))) | 699 | (current-buffer))))) |
| 700 | 700 | ||
| 701 | (defvar vc-dir-menu-map | 701 | (defvar vc-dir-menu-map |
| 702 | (let ((map (make-sparse-keymap))) | 702 | (let ((map (make-sparse-keymap "VC-dir"))) |
| 703 | (define-key map [quit] | 703 | (define-key map [quit] |
| 704 | '(menu-item "Quit" quit-window | 704 | '(menu-item "Quit" quit-window |
| 705 | :help "Quit")) | 705 | :help "Quit")) |
| @@ -800,7 +800,7 @@ See `run-hooks'." | |||
| 800 | `(menu-item | 800 | `(menu-item |
| 801 | ;; This is used so that client modes can add mode-specific | 801 | ;; This is used so that client modes can add mode-specific |
| 802 | ;; menu items to vc-dir-menu-map. | 802 | ;; menu items to vc-dir-menu-map. |
| 803 | "*vc-dispatcher*" ,vc-dir-menu-map :filter vc-dir-menu-map-filter)) | 803 | "VC-dir" ,vc-dir-menu-map :filter vc-dir-menu-map-filter)) |
| 804 | map) | 804 | map) |
| 805 | "Keymap for directory buffer.") | 805 | "Keymap for directory buffer.") |
| 806 | 806 | ||
| @@ -845,6 +845,16 @@ If `body' uses `event', it should be a variable, | |||
| 845 | map vc-dir-mode-map) | 845 | map vc-dir-mode-map) |
| 846 | map)) | 846 | map)) |
| 847 | 847 | ||
| 848 | (defun vc-dir-node-directory (node) | ||
| 849 | ;; Compute the directory for NODE. | ||
| 850 | ;; If it's a directory node, get it from the the node. | ||
| 851 | (let ((data (ewoc-data node))) | ||
| 852 | (or (vc-dir-fileinfo->directory data) | ||
| 853 | ;; Otherwise compute it from the file name. | ||
| 854 | (file-name-directory | ||
| 855 | (expand-file-name | ||
| 856 | (vc-dir-fileinfo->name data)))))) | ||
| 857 | |||
| 848 | (defun vc-dir-update (entries buffer &optional noinsert) | 858 | (defun vc-dir-update (entries buffer &optional noinsert) |
| 849 | "Update BUFFER's ewoc from the list of ENTRIES. | 859 | "Update BUFFER's ewoc from the list of ENTRIES. |
| 850 | If NOINSERT, ignore elements on ENTRIES which are not in the ewoc." | 860 | If NOINSERT, ignore elements on ENTRIES which are not in the ewoc." |
| @@ -875,15 +885,11 @@ If NOINSERT, ignore elements on ENTRIES which are not in the ewoc." | |||
| 875 | vc-ewoc (vc-dir-create-fileinfo | 885 | vc-ewoc (vc-dir-create-fileinfo |
| 876 | rd nil nil nil (expand-file-name default-directory)))) | 886 | rd nil nil nil (expand-file-name default-directory)))) |
| 877 | (setq node (ewoc-nth vc-ewoc 0))) | 887 | (setq node (ewoc-nth vc-ewoc 0))) |
| 878 | 888 | ||
| 879 | (while (and entry node) | 889 | (while (and entry node) |
| 880 | (let* ((entryfile (car entry)) | 890 | (let* ((entryfile (car entry)) |
| 881 | (entrydir (file-name-directory (expand-file-name entryfile))) | 891 | (entrydir (file-name-directory (expand-file-name entryfile))) |
| 882 | (nodedir | 892 | (nodedir (vc-dir-node-directory node))) |
| 883 | (or (vc-dir-fileinfo->directory (ewoc-data node)) | ||
| 884 | (file-name-directory | ||
| 885 | (expand-file-name | ||
| 886 | (vc-dir-fileinfo->name (ewoc-data node))))))) | ||
| 887 | (cond | 893 | (cond |
| 888 | ;; First try to find the directory. | 894 | ;; First try to find the directory. |
| 889 | ((string-lessp nodedir entrydir) | 895 | ((string-lessp nodedir entrydir) |
| @@ -899,29 +905,30 @@ If NOINSERT, ignore elements on ENTRIES which are not in the ewoc." | |||
| 899 | (setf (vc-dir-fileinfo->extra (ewoc-data node)) (nth 2 entry)) | 905 | (setf (vc-dir-fileinfo->extra (ewoc-data node)) (nth 2 entry)) |
| 900 | (setf (vc-dir-fileinfo->needs-update (ewoc-data node)) nil) | 906 | (setf (vc-dir-fileinfo->needs-update (ewoc-data node)) nil) |
| 901 | (ewoc-invalidate vc-ewoc node) | 907 | (ewoc-invalidate vc-ewoc node) |
| 902 | (setq entries (cdr entries) entry (car entries)) | 908 | (setq entries (cdr entries)) |
| 909 | (setq entry (car entries)) | ||
| 903 | (setq node (ewoc-next vc-ewoc node))) | 910 | (setq node (ewoc-next vc-ewoc node))) |
| 904 | (t | 911 | (t |
| 905 | (ewoc-enter-before vc-ewoc node | 912 | (ewoc-enter-before vc-ewoc node |
| 906 | (apply 'vc-dir-create-fileinfo entry)) | 913 | (apply 'vc-dir-create-fileinfo entry)) |
| 907 | (setq entries (cdr entries) entry (car entries)))))) | 914 | (setq entries (cdr entries)) |
| 915 | (setq entry (car entries)))))) | ||
| 908 | (t | 916 | (t |
| 909 | ;; We need to insert a directory node | 917 | ;; We might need to insert a directory node if the |
| 910 | (let ((rd (file-relative-name entrydir))) | 918 | ;; previous node was in a different directory. |
| 911 | (ewoc-enter-last | 919 | (let* ((rd (file-relative-name entrydir)) |
| 912 | vc-ewoc (vc-dir-create-fileinfo rd nil nil nil entrydir))) | 920 | (prev-node (ewoc-prev vc-ewoc node)) |
| 921 | (prev-dir (vc-dir-node-directory prev-node))) | ||
| 922 | (unless (string-equal entrydir prev-dir) | ||
| 923 | (ewoc-enter-before | ||
| 924 | vc-ewoc node (vc-dir-create-fileinfo rd nil nil nil entrydir)))) | ||
| 913 | ;; Now insert the node itself. | 925 | ;; Now insert the node itself. |
| 914 | (ewoc-enter-before vc-ewoc node | 926 | (ewoc-enter-before vc-ewoc node |
| 915 | (apply 'vc-dir-create-fileinfo entry)) | 927 | (apply 'vc-dir-create-fileinfo entry)) |
| 916 | (setq entries (cdr entries) entry (car entries)))))) | 928 | (setq entries (cdr entries) entry (car entries)))))) |
| 917 | ;; We're past the last node, all remaining entries go to the end. | 929 | ;; We're past the last node, all remaining entries go to the end. |
| 918 | (unless (or node noinsert) | 930 | (unless (or node noinsert) |
| 919 | (let* ((lastnode (ewoc-nth vc-ewoc -1)) | 931 | (let ((lastdir (vc-dir-node-directory (ewoc-nth vc-ewoc -1)))) |
| 920 | (lastdir | ||
| 921 | (or (vc-dir-fileinfo->directory (ewoc-data lastnode)) | ||
| 922 | (file-name-directory | ||
| 923 | (expand-file-name | ||
| 924 | (vc-dir-fileinfo->name (ewoc-data lastnode))))))) | ||
| 925 | (dolist (entry entries) | 932 | (dolist (entry entries) |
| 926 | (let ((entrydir (file-name-directory (expand-file-name (car entry))))) | 933 | (let ((entrydir (file-name-directory (expand-file-name (car entry))))) |
| 927 | ;; Insert a directory node if needed. | 934 | ;; Insert a directory node if needed. |
| @@ -1019,13 +1026,7 @@ If a prefix argument is given, move by that many lines." | |||
| 1019 | 1026 | ||
| 1020 | (defun vc-dir-parent-marked-p (arg) | 1027 | (defun vc-dir-parent-marked-p (arg) |
| 1021 | ;; Return nil if none of the parent directories of arg is marked. | 1028 | ;; Return nil if none of the parent directories of arg is marked. |
| 1022 | (let* ((argdata (ewoc-data arg)) | 1029 | (let* ((argdir (vc-dir-node-directory arg)) |
| 1023 | (argdir | ||
| 1024 | (let ((crtdir (vc-dir-fileinfo->directory argdata))) | ||
| 1025 | (if crtdir | ||
| 1026 | crtdir | ||
| 1027 | (file-name-directory (expand-file-name | ||
| 1028 | (vc-dir-fileinfo->name argdata)))))) | ||
| 1029 | (arglen (length argdir)) | 1030 | (arglen (length argdir)) |
| 1030 | (crt arg) | 1031 | (crt arg) |
| 1031 | data dir) | 1032 | data dir) |
| @@ -1033,41 +1034,29 @@ If a prefix argument is given, move by that many lines." | |||
| 1033 | ;; a parent is marked. | 1034 | ;; a parent is marked. |
| 1034 | (while (setq crt (ewoc-prev vc-ewoc crt)) | 1035 | (while (setq crt (ewoc-prev vc-ewoc crt)) |
| 1035 | (setq data (ewoc-data crt)) | 1036 | (setq data (ewoc-data crt)) |
| 1036 | (setq dir | 1037 | (setq dir (vc-dir-node-directory crt)) |
| 1037 | (let ((crtdir (vc-dir-fileinfo->directory data))) | ||
| 1038 | (if crtdir | ||
| 1039 | crtdir | ||
| 1040 | (file-name-directory (expand-file-name | ||
| 1041 | (vc-dir-fileinfo->name data)))))) | ||
| 1042 | |||
| 1043 | (when (and (vc-dir-fileinfo->directory data) | 1038 | (when (and (vc-dir-fileinfo->directory data) |
| 1044 | (string-equal (substring argdir 0 (length dir)) dir)) | 1039 | (string-equal (substring argdir 0 (length dir)) dir)) |
| 1045 | (when (vc-dir-fileinfo->marked data) | 1040 | (when (vc-dir-fileinfo->marked data) |
| 1046 | (error "Cannot mark `%s', parent directory `%s' marked" | 1041 | (error "Cannot mark `%s', parent directory `%s' marked" |
| 1047 | (vc-dir-fileinfo->name argdata) | 1042 | (vc-dir-fileinfo->name (ewoc-data arg)) |
| 1048 | (vc-dir-fileinfo->name data))))) | 1043 | (vc-dir-fileinfo->name data))))) |
| 1049 | nil)) | 1044 | nil)) |
| 1050 | 1045 | ||
| 1051 | (defun vc-dir-children-marked-p (arg) | 1046 | (defun vc-dir-children-marked-p (arg) |
| 1052 | ;; Return nil if none of the children of arg is marked. | 1047 | ;; Return nil if none of the children of arg is marked. |
| 1053 | (let* ((argdata (ewoc-data arg)) | 1048 | (let* ((argdir (vc-dir-node-directory arg)) |
| 1054 | (argdir (vc-dir-fileinfo->directory argdata)) | ||
| 1055 | (arglen (length argdir)) | 1049 | (arglen (length argdir)) |
| 1056 | (is-child t) | 1050 | (is-child t) |
| 1057 | (crt arg) | 1051 | (crt arg) |
| 1058 | data dir) | 1052 | data dir) |
| 1059 | (while (and is-child (setq crt (ewoc-next vc-ewoc crt))) | 1053 | (while (and is-child (setq crt (ewoc-next vc-ewoc crt))) |
| 1060 | (setq data (ewoc-data crt)) | 1054 | (setq data (ewoc-data crt)) |
| 1061 | (setq dir | 1055 | (setq dir (vc-dir-node-directory crt)) |
| 1062 | (let ((crtdir (vc-dir-fileinfo->directory data))) | ||
| 1063 | (if crtdir | ||
| 1064 | crtdir | ||
| 1065 | (file-name-directory (expand-file-name | ||
| 1066 | (vc-dir-fileinfo->name data)))))) | ||
| 1067 | (if (string-equal argdir (substring dir 0 arglen)) | 1056 | (if (string-equal argdir (substring dir 0 arglen)) |
| 1068 | (when (vc-dir-fileinfo->marked data) | 1057 | (when (vc-dir-fileinfo->marked data) |
| 1069 | (error "Cannot mark `%s', child `%s' marked" | 1058 | (error "Cannot mark `%s', child `%s' marked" |
| 1070 | (vc-dir-fileinfo->name argdata) | 1059 | (vc-dir-fileinfo->name (ewoc-data arg)) |
| 1071 | (vc-dir-fileinfo->name data))) | 1060 | (vc-dir-fileinfo->name data))) |
| 1072 | ;; We are done, we got to an entry that is not a child of `arg'. | 1061 | ;; We are done, we got to an entry that is not a child of `arg'. |
| 1073 | (setq is-child nil))) | 1062 | (setq is-child nil))) |
| @@ -1110,7 +1099,7 @@ share the same state." | |||
| 1110 | (ewoc-map | 1099 | (ewoc-map |
| 1111 | (lambda (filearg) | 1100 | (lambda (filearg) |
| 1112 | (when (and (vc-dir-fileinfo->directory filearg) | 1101 | (when (and (vc-dir-fileinfo->directory filearg) |
| 1113 | (vc-dir-fileinfo->directory filearg)) | 1102 | (vc-dir-fileinfo->marked filearg)) |
| 1114 | (error "Cannot mark all files, directory `%s' marked" | 1103 | (error "Cannot mark all files, directory `%s' marked" |
| 1115 | (vc-dir-fileinfo->name filearg)))) | 1104 | (vc-dir-fileinfo->name filearg)))) |
| 1116 | vc-ewoc) | 1105 | vc-ewoc) |
| @@ -1245,12 +1234,13 @@ that share the same state." | |||
| 1245 | (ewoc-collect vc-ewoc 'vc-dir-fileinfo->marked))) | 1234 | (ewoc-collect vc-ewoc 'vc-dir-fileinfo->marked))) |
| 1246 | 1235 | ||
| 1247 | (defun vc-dir-marked-only-files () | 1236 | (defun vc-dir-marked-only-files () |
| 1248 | "Return the list of marked files, For marked directories return child files." | 1237 | "Return the list of marked files, for marked directories return child files." |
| 1249 | (let ((crt (ewoc-nth vc-ewoc 0)) | 1238 | (let ((crt (ewoc-nth vc-ewoc 0)) |
| 1250 | result) | 1239 | result) |
| 1251 | (while crt | 1240 | (while crt |
| 1252 | (let ((crt-data (ewoc-data crt))) | 1241 | (let ((crt-data (ewoc-data crt))) |
| 1253 | (if (vc-dir-fileinfo->marked crt-data) | 1242 | (if (vc-dir-fileinfo->marked crt-data) |
| 1243 | ;; FIXME: use vc-dir-child-files here instead of duplicating it. | ||
| 1254 | (if (vc-dir-fileinfo->directory crt-data) | 1244 | (if (vc-dir-fileinfo->directory crt-data) |
| 1255 | (let* ((dir (vc-dir-fileinfo->directory crt-data)) | 1245 | (let* ((dir (vc-dir-fileinfo->directory crt-data)) |
| 1256 | (dirlen (length dir)) | 1246 | (dirlen (length dir)) |
| @@ -1261,21 +1251,40 @@ that share the same state." | |||
| 1261 | (substring | 1251 | (substring |
| 1262 | (progn | 1252 | (progn |
| 1263 | (setq data (ewoc-data crt)) | 1253 | (setq data (ewoc-data crt)) |
| 1264 | (let ((crtdir (vc-dir-fileinfo->directory data))) | 1254 | (vc-dir-node-directory crt)) |
| 1265 | (if crtdir | ||
| 1266 | crtdir | ||
| 1267 | (file-name-directory | ||
| 1268 | (expand-file-name | ||
| 1269 | (vc-dir-fileinfo->name data)))))) | ||
| 1270 | 0 dirlen) | 1255 | 0 dirlen) |
| 1271 | dir)) | 1256 | dir)) |
| 1272 | (unless (vc-dir-fileinfo->directory data) | 1257 | (unless (vc-dir-fileinfo->directory data) |
| 1273 | (push (vc-dir-fileinfo->name data) result)))) | 1258 | (push (expand-file-name (vc-dir-fileinfo->name data)) result)))) |
| 1274 | (push (expand-file-name (vc-dir-fileinfo->name crt-data)) result) | 1259 | (push (expand-file-name (vc-dir-fileinfo->name crt-data)) result) |
| 1275 | (setq crt (ewoc-next vc-ewoc crt))) | 1260 | (setq crt (ewoc-next vc-ewoc crt))) |
| 1276 | (setq crt (ewoc-next vc-ewoc crt))))) | 1261 | (setq crt (ewoc-next vc-ewoc crt))))) |
| 1277 | result)) | 1262 | result)) |
| 1278 | 1263 | ||
| 1264 | (defun vc-dir-child-files () | ||
| 1265 | "Return the list of child files for the current entry if it's a directory. | ||
| 1266 | If it is a file, return the file itself." | ||
| 1267 | (let* ((crt (ewoc-locate vc-ewoc)) | ||
| 1268 | (crt-data (ewoc-data crt)) | ||
| 1269 | result) | ||
| 1270 | (if (vc-dir-fileinfo->directory crt-data) | ||
| 1271 | (let* ((dir (vc-dir-fileinfo->directory crt-data)) | ||
| 1272 | (dirlen (length dir)) | ||
| 1273 | data) | ||
| 1274 | (while | ||
| 1275 | (and (setq crt (ewoc-next vc-ewoc crt)) | ||
| 1276 | (string-equal | ||
| 1277 | (substring | ||
| 1278 | (progn | ||
| 1279 | (setq data (ewoc-data crt)) | ||
| 1280 | (vc-dir-node-directory crt)) | ||
| 1281 | 0 dirlen) | ||
| 1282 | dir)) | ||
| 1283 | (unless (vc-dir-fileinfo->directory data) | ||
| 1284 | (push (expand-file-name (vc-dir-fileinfo->name data)) result)))) | ||
| 1285 | (push (expand-file-name (vc-dir-fileinfo->name crt-data)) result)) | ||
| 1286 | result)) | ||
| 1287 | |||
| 1279 | (defun vc-directory-resynch-file (&optional fname) | 1288 | (defun vc-directory-resynch-file (&optional fname) |
| 1280 | "Update the entries for FILE in any directory buffers that list it." | 1289 | "Update the entries for FILE in any directory buffers that list it." |
| 1281 | (let ((file (or fname (expand-file-name buffer-file-name)))) | 1290 | (let ((file (or fname (expand-file-name buffer-file-name)))) |
| @@ -1398,9 +1407,9 @@ containing that file. Otherwise, throw an error." | |||
| 1398 | ;; We assume, in order to avoid unpleasant surprises to the user, | 1407 | ;; We assume, in order to avoid unpleasant surprises to the user, |
| 1399 | ;; that a fileset is not in good shape to be handed to the user if the | 1408 | ;; that a fileset is not in good shape to be handed to the user if the |
| 1400 | ;; buffers visiting the fileset don't match the on-disk contents. | 1409 | ;; buffers visiting the fileset don't match the on-disk contents. |
| 1401 | (if (not observer) | 1410 | (unless observer |
| 1402 | (save-some-buffers | 1411 | (save-some-buffers |
| 1403 | nil (lambda () (vc-dispatcher-in-fileset-p (cdr selection))))) | 1412 | nil (lambda () (vc-dispatcher-in-fileset-p (cdr selection))))) |
| 1404 | selection)) | 1413 | selection)) |
| 1405 | 1414 | ||
| 1406 | (provide 'vc-dispatcher) | 1415 | (provide 'vc-dispatcher) |