Mercurial > emacs
comparison lisp/dired-aux.el @ 89909:68c22ea6027c
Sync to HEAD
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Fri, 16 Apr 2004 12:51:06 +0000 |
parents | 375f2633d815 |
children | 4c90ffeb71c5 |
comparison
equal
deleted
inserted
replaced
89908:ee1402f7b568 | 89909:68c22ea6027c |
---|---|
1 ;;; dired-aux.el --- less commonly used parts of dired -*-byte-compile-dynamic: t;-*- | 1 ;;; dired-aux.el --- less commonly used parts of dired -*-byte-compile-dynamic: t;-*- |
2 | 2 |
3 ;; Copyright (C) 1985, 1986, 1992, 1994, 1998, 2000, 2001 | 3 ;; Copyright (C) 1985, 1986, 1992, 1994, 1998, 2000, 2001, 2004 |
4 ;; Free Software Foundation, Inc. | 4 ;; Free Software Foundation, Inc. |
5 | 5 |
6 ;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>. | 6 ;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>. |
7 ;; Maintainer: FSF | 7 ;; Maintainer: FSF |
8 ;; Keywords: files | 8 ;; Keywords: files |
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 Mark files with different names if PREDICATE is nil (or interactively | |
97 when the user enters empty input at the predicate prompt). | |
98 | |
99 PREDICATE is a Lisp expression that can refer to the following variables: | |
100 | |
101 size1, size2 - file size in bytes | |
102 mtime1, mtime2 - last modification time in seconds, as a float | |
103 fa1, fa2 - list of file attributes | |
104 returned by function `file-attributes' | |
105 | |
106 where 1 refers to attribute of file in the current dired buffer | |
107 and 2 to attribute of file in second dired buffer. | |
108 | |
109 Examples of PREDICATE: | |
110 | |
111 (> mtime1 mtime2) - mark newer files | |
112 (not (= size1 size2)) - mark files with different sizes | |
113 (not (string= (nth 8 fa1) (nth 8 fa2))) - mark files with different modes | |
114 (not (and (= (nth 2 fa1) (nth 2 fa2)) - mark files with different UID | |
115 (= (nth 3 fa1) (nth 3 fa2)))) and GID." | |
116 (interactive | |
117 (list (read-file-name (format "Compare %s with: " | |
118 (dired-current-directory)) | |
119 (dired-dwim-target-directory)) | |
120 (read-from-minibuffer "Mark if (lisp expr or RET): " nil nil t nil "nil"))) | |
121 (let* ((dir1 (dired-current-directory)) | |
122 (file-alist1 (dired-files-attributes dir1)) | |
123 (file-alist2 (dired-files-attributes dir2)) | |
124 (file-list1 (mapcar | |
125 'cadr | |
126 (dired-file-set-difference | |
127 file-alist1 file-alist2 | |
128 predicate))) | |
129 (file-list2 (mapcar | |
130 'cadr | |
131 (dired-file-set-difference | |
132 file-alist2 file-alist1 | |
133 predicate)))) | |
134 (dired-fun-in-all-buffers | |
135 dir1 nil | |
136 (lambda () | |
137 (dired-mark-if | |
138 (member (dired-get-filename nil t) file-list1) nil))) | |
139 (dired-fun-in-all-buffers | |
140 dir2 nil | |
141 (lambda () | |
142 (dired-mark-if | |
143 (member (dired-get-filename nil t) file-list2) nil))) | |
144 (message "Marked in dir1: %s files, in dir2: %s files" | |
145 (length file-list1) | |
146 (length file-list2)))) | |
147 | |
148 (defun dired-file-set-difference (list1 list2 predicate) | |
149 "Combine LIST1 and LIST2 using a set-difference operation. | |
150 The result list contains all file items that appear in LIST1 but not LIST2. | |
151 This is a non-destructive function; it makes a copy of the data if necessary | |
152 to avoid corrupting the original LIST1 and LIST2. | |
153 PREDICATE (see `dired-compare-directories') is an additional match | |
154 condition. Two file items are considered to match if they are equal | |
155 *and* PREDICATE evaluates to t." | |
156 (if (or (null list1) (null list2)) | |
157 list1 | |
158 (let (res) | |
159 (dolist (file1 list1) | |
160 (unless (let ((list list2)) | |
161 (while (and list | |
162 (not (let* ((file2 (car list)) | |
163 (fa1 (caddr file1)) | |
164 (fa2 (caddr file2)) | |
165 (size1 (nth 7 fa1)) | |
166 (size2 (nth 7 fa2)) | |
167 (mtime1 (float-time (nth 5 fa1))) | |
168 (mtime2 (float-time (nth 5 fa2)))) | |
169 (and | |
170 (equal (car file1) (car file2)) | |
171 (not (eval predicate)))))) | |
172 (setq list (cdr list))) | |
173 list) | |
174 (setq res (cons file1 res)))) | |
175 (nreverse res)))) | |
176 | |
177 (defun dired-files-attributes (dir) | |
178 "Return a list of all file names and attributes from DIR. | |
179 List has a form of (file-name full-file-name (attribute-list))" | |
180 (mapcar | |
181 (lambda (file-name) | |
182 (let ((full-file-name (expand-file-name file-name dir))) | |
183 (list file-name | |
184 full-file-name | |
185 (file-attributes full-file-name)))) | |
186 (directory-files dir))) | |
187 | |
91 (defun dired-do-chxxx (attribute-name program op-symbol arg) | 188 (defun dired-do-chxxx (attribute-name program op-symbol arg) |
92 ;; Change file attributes (mode, group, owner) of marked files and | 189 ;; Change file attributes (mode, group, owner, timestamp) of marked files and |
93 ;; refresh their file lines. | 190 ;; refresh their file lines. |
94 ;; ATTRIBUTE-NAME is a string describing the attribute to the user. | 191 ;; ATTRIBUTE-NAME is a string describing the attribute to the user. |
95 ;; PROGRAM is the program used to change the attribute. | 192 ;; PROGRAM is the program used to change the attribute. |
96 ;; OP-SYMBOL is the type of operation (for use in dired-mark-pop-up). | 193 ;; OP-SYMBOL is the type of operation (for use in dired-mark-pop-up). |
97 ;; ARG describes which files to use, as in dired-get-marked-files. | 194 ;; ARG describes which files to use, as in dired-get-marked-files. |
104 failures) | 201 failures) |
105 (setq failures | 202 (setq failures |
106 (dired-bunch-files 10000 | 203 (dired-bunch-files 10000 |
107 (function dired-check-process) | 204 (function dired-check-process) |
108 (append | 205 (append |
109 (list operation program new-attribute) | 206 (list operation program) |
207 (if (eq op-symbol 'touch) | |
208 '("-t") nil) | |
209 (list new-attribute) | |
110 (if (string-match "gnu" system-configuration) | 210 (if (string-match "gnu" system-configuration) |
111 '("--") nil)) | 211 '("--") nil)) |
112 files)) | 212 files)) |
113 (dired-do-redisplay arg);; moves point if ARG is an integer | 213 (dired-do-redisplay arg);; moves point if ARG is an integer |
114 (if failures | 214 (if failures |
136 "Change the owner of the marked (or next ARG) files." | 236 "Change the owner of the marked (or next ARG) files." |
137 (interactive "P") | 237 (interactive "P") |
138 (if (memq system-type '(ms-dos windows-nt)) | 238 (if (memq system-type '(ms-dos windows-nt)) |
139 (error "chown not supported on this system")) | 239 (error "chown not supported on this system")) |
140 (dired-do-chxxx "Owner" dired-chown-program 'chown arg)) | 240 (dired-do-chxxx "Owner" dired-chown-program 'chown arg)) |
241 | |
242 (defun dired-do-touch (&optional arg) | |
243 "Change the timestamp of the marked (or next ARG) files. | |
244 This calls touch." | |
245 (interactive "P") | |
246 (dired-do-chxxx "Timestamp" dired-touch-program 'touch arg)) | |
141 | 247 |
142 ;; Process all the files in FILES in batches of a convenient size, | 248 ;; Process all the files in FILES in batches of a convenient size, |
143 ;; by means of (FUNCALL FUNCTION ARGS... SOME-FILES...). | 249 ;; by means of (FUNCALL FUNCTION ARGS... SOME-FILES...). |
144 ;; Batches are chosen to need less than MAX chars for the file names, | 250 ;; Batches are chosen to need less than MAX chars for the file names, |
145 ;; allowing 3 extra characters of separator per file name. | 251 ;; allowing 3 extra characters of separator per file name. |
464 ;; Get a clean buffer for error output: | 570 ;; Get a clean buffer for error output: |
465 (setq err-buffer (get-buffer-create " *dired-check-process output*")) | 571 (setq err-buffer (get-buffer-create " *dired-check-process output*")) |
466 (set-buffer err-buffer) | 572 (set-buffer err-buffer) |
467 (erase-buffer) | 573 (erase-buffer) |
468 (setq default-directory dir ; caller's default-directory | 574 (setq default-directory dir ; caller's default-directory |
469 err (/= 0 | 575 err (not (eq 0 |
470 (apply (function dired-call-process) program nil arguments))) | 576 (apply (function dired-call-process) program nil arguments)))) |
471 (if err | 577 (if err |
472 (progn | 578 (progn |
473 (dired-log (concat program " " (prin1-to-string arguments) "\n")) | 579 (dired-log (concat program " " (prin1-to-string arguments) "\n")) |
474 (dired-log err-buffer) | 580 (dired-log err-buffer) |
475 (or arguments program t)) | 581 (or arguments program t)) |
562 ("\\.tgz\\'" ".tar" "gunzip") | 668 ("\\.tgz\\'" ".tar" "gunzip") |
563 ("\\.Z\\'" "" "uncompress") | 669 ("\\.Z\\'" "" "uncompress") |
564 ;; For .z, try gunzip. It might be an old gzip file, | 670 ;; For .z, try gunzip. It might be an old gzip file, |
565 ;; or it might be from compact? pack? (which?) but gunzip handles both. | 671 ;; or it might be from compact? pack? (which?) but gunzip handles both. |
566 ("\\.z\\'" "" "gunzip") | 672 ("\\.z\\'" "" "gunzip") |
673 ("\\.dz\\'" "" "dictunzip") | |
674 ("\\.tbz\\'" ".tar" "bunzip2") | |
567 ("\\.bz2\\'" "" "bunzip2") | 675 ("\\.bz2\\'" "" "bunzip2") |
568 ;; This item controls naming for compression. | 676 ;; This item controls naming for compression. |
569 ("\\.tar\\'" ".tgz" nil)) | 677 ("\\.tar\\'" ".tgz" nil)) |
570 "Control changes in file name suffixes for compression and uncompression. | 678 "Control changes in file name suffixes for compression and uncompression. |
571 Each element specifies one transformation rule, and has the form: | 679 Each element specifies one transformation rule, and has the form: |
2013 Third arg DELIMITED (prefix arg) means replace only word-delimited matches. | 2121 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 | 2122 If you exit (\\[keyboard-quit], RET or q), you can resume the query replace |
2015 with the command \\[tags-loop-continue]." | 2123 with the command \\[tags-loop-continue]." |
2016 (interactive | 2124 (interactive |
2017 "sQuery replace in marked files (regexp): \nsQuery replace %s by: \nP") | 2125 "sQuery replace in marked files (regexp): \nsQuery replace %s by: \nP") |
2126 (dolist (file (dired-get-marked-files nil nil 'dired-nondirectory-p)) | |
2127 (let ((buffer (get-file-buffer file))) | |
2128 (if (and buffer (with-current-buffer buffer | |
2129 buffer-read-only)) | |
2130 (error "File `%s' is visited read-only" file)))) | |
2018 (tags-query-replace from to delimited | 2131 (tags-query-replace from to delimited |
2019 '(dired-get-marked-files nil nil 'dired-nondirectory-p))) | 2132 '(dired-get-marked-files nil nil 'dired-nondirectory-p))) |
2020 | 2133 |
2021 (defun dired-nondirectory-p (file) | 2134 (defun dired-nondirectory-p (file) |
2022 (not (file-directory-p file))) | 2135 (not (file-directory-p file))) |
2035 (backward-delete-char 1)) | 2148 (backward-delete-char 1)) |
2036 (message "%s" (buffer-string)))) | 2149 (message "%s" (buffer-string)))) |
2037 | 2150 |
2038 (provide 'dired-aux) | 2151 (provide 'dired-aux) |
2039 | 2152 |
2153 ;;; arch-tag: 4b508de9-a153-423d-8d3f-a1bbd86f4f60 | |
2040 ;;; dired-aux.el ends here | 2154 ;;; dired-aux.el ends here |