Mercurial > emacs
comparison lisp/dired-aux.el @ 53215:99f19d6d7aeb
(dired-do-query-replace-regexp): Report files visited read-only.
(dired-compare-directories): New command.
(dired-file-set-difference, dired-files-attributes): New functions.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 01 Dec 2003 01:56:19 +0000 |
parents | 695cf19ef79e |
children | 79093b308520 |
comparison
equal
deleted
inserted
replaced
53214:931e46b73703 | 53215:99f19d6d7aeb |
---|---|
86 diff-switches | 86 diff-switches |
87 (mapconcat 'identity diff-switches " ")))) | 87 (mapconcat 'identity diff-switches " ")))) |
88 nil)) | 88 nil)) |
89 (diff-backup (dired-get-filename) switches)) | 89 (diff-backup (dired-get-filename) switches)) |
90 | 90 |
91 (defun dired-compare-directories (dir2 predicate) | |
92 "Mark files with different file attributes in two dired buffers. | |
93 Compare file attributes of files in the current directory | |
94 with file attributes in directory DIR2 using PREDICATE on pairs of files | |
95 with the same name. Mark files for which PREDICATE returns non-nil. | |
96 | |
97 PREDICATE is a Lisp expression that can refer to the following variables: | |
98 | |
99 size1, size2 - file size in bytes | |
100 mtime1, mtime2 - last modification time in seconds, as a float | |
101 fa1, fa2 - list of file attributes | |
102 returned by function `file-attributes' | |
103 | |
104 where 1 refers to attribute of file in the current dired buffer | |
105 and 2 to attribute of file in second dired buffer. | |
106 | |
107 Examples of PREDICATE: | |
108 | |
109 (> mtime1 mtime2) - mark newer files | |
110 (not (= size1 size2)) - mark files with different sizes | |
111 (not (string= (nth 8 fa1) (nth 8 fa2))) - mark files with different modes | |
112 (not (and (= (nth 2 fa1) (nth 2 fa2)) - mark files with different UID | |
113 (= (nth 3 fa1) (nth 3 fa2)))) and GID." | |
114 (interactive | |
115 (list (read-file-name (format "Compare %s with: " | |
116 (dired-current-directory)) | |
117 (dired-dwim-target-directory)) | |
118 (read-minibuffer "Mark if (lisp expr): "))) | |
119 (let* ((dir1 (dired-current-directory)) | |
120 (file-alist1 (dired-files-attributes dir1)) | |
121 (file-alist2 (dired-files-attributes dir2)) | |
122 (file-list1 (mapcar | |
123 'cadr | |
124 (dired-file-set-difference | |
125 file-alist1 file-alist2 | |
126 predicate))) | |
127 (file-list2 (mapcar | |
128 'cadr | |
129 (dired-file-set-difference | |
130 file-alist2 file-alist1 | |
131 predicate)))) | |
132 (dired-fun-in-all-buffers | |
133 dir1 nil | |
134 (lambda () | |
135 (dired-mark-if | |
136 (member (dired-get-filename nil t) file-list1) nil))) | |
137 (dired-fun-in-all-buffers | |
138 dir2 nil | |
139 (lambda () | |
140 (dired-mark-if | |
141 (member (dired-get-filename nil t) file-list2) nil))) | |
142 (message "Marked in dir1: %s files, in dir2: %s files" | |
143 (length file-list1) | |
144 (length file-list2)))) | |
145 | |
146 (defun dired-file-set-difference (list1 list2 predicate) | |
147 "Combine LIST1 and LIST2 using a set-difference operation. | |
148 The result list contains all file items that appear in LIST1 but not LIST2. | |
149 This is a non-destructive function; it makes a copy of the data if necessary | |
150 to avoid corrupting the original LIST1 and LIST2. | |
151 PREDICATE (see `dired-compare-directories') is an additional match | |
152 condition. Two file items are considered to match if they are equal | |
153 *and* PREDICATE evaluates to t." | |
154 (if (or (null list1) (null list2)) | |
155 list1 | |
156 (let (res) | |
157 (dolist (file1 list1) | |
158 (unless (let ((list list2)) | |
159 (while (and list | |
160 (not (let* ((file2 (car list)) | |
161 (fa1 (caddr file1)) | |
162 (fa2 (caddr file2)) | |
163 (size1 (nth 7 fa1)) | |
164 (size2 (nth 7 fa2)) | |
165 (mtime1 (float-time (nth 5 fa1))) | |
166 (mtime2 (float-time (nth 5 fa2)))) | |
167 (and | |
168 (equal (car file1) (car file2)) | |
169 (not (eval predicate)))))) | |
170 (setq list (cdr list))) | |
171 list) | |
172 (setq res (cons file1 res)))) | |
173 (nreverse res)))) | |
174 | |
175 (defun dired-files-attributes (dir) | |
176 "Return a list of all file names and attributes from DIR. | |
177 List has a form of (file-name full-file-name (attribute-list))" | |
178 (mapcar | |
179 (lambda (file-name) | |
180 (let ((full-file-name (expand-file-name file-name dir))) | |
181 (list file-name | |
182 full-file-name | |
183 (file-attributes full-file-name)))) | |
184 (directory-files dir))) | |
185 | |
91 (defun dired-do-chxxx (attribute-name program op-symbol arg) | 186 (defun dired-do-chxxx (attribute-name program op-symbol arg) |
92 ;; Change file attributes (mode, group, owner) of marked files and | 187 ;; Change file attributes (mode, group, owner) of marked files and |
93 ;; refresh their file lines. | 188 ;; refresh their file lines. |
94 ;; ATTRIBUTE-NAME is a string describing the attribute to the user. | 189 ;; ATTRIBUTE-NAME is a string describing the attribute to the user. |
95 ;; PROGRAM is the program used to change the attribute. | 190 ;; PROGRAM is the program used to change the attribute. |
2013 Third arg DELIMITED (prefix arg) means replace only word-delimited matches. | 2108 Third arg DELIMITED (prefix arg) means replace only word-delimited matches. |
2014 If you exit (\\[keyboard-quit], RET or q), you can resume the query replace | 2109 If you exit (\\[keyboard-quit], RET or q), you can resume the query replace |
2015 with the command \\[tags-loop-continue]." | 2110 with the command \\[tags-loop-continue]." |
2016 (interactive | 2111 (interactive |
2017 "sQuery replace in marked files (regexp): \nsQuery replace %s by: \nP") | 2112 "sQuery replace in marked files (regexp): \nsQuery replace %s by: \nP") |
2113 (dolist (file (dired-get-marked-files nil nil 'dired-nondirectory-p)) | |
2114 (let ((buffer (get-file-buffer file))) | |
2115 (if (and buffer (with-current-buffer buffer | |
2116 buffer-read-only)) | |
2117 (error "File `%s' is visited read-only")))) | |
2018 (tags-query-replace from to delimited | 2118 (tags-query-replace from to delimited |
2019 '(dired-get-marked-files nil nil 'dired-nondirectory-p))) | 2119 '(dired-get-marked-files nil nil 'dired-nondirectory-p))) |
2020 | 2120 |
2021 (defun dired-nondirectory-p (file) | 2121 (defun dired-nondirectory-p (file) |
2022 (not (file-directory-p file))) | 2122 (not (file-directory-p file))) |