comparison lisp/dired/dired-trns.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 ;; dired-trns.el - file transformers for dired shell commands.
2
3 ;; Id: dired-trns.el,v 1.6 1991/07/05 13:36:01 sk RelBeta
4
5 ;; Code contributed by Hans Chalupsky <hans@cs.Buffalo.EDU>.
6 ;; Integrated with my dired.el sk@sparc0 11-Jan-1991 14:38.
7 ;; And hacked up a bit.
8
9 ;; LISPDIR ENTRY for the Elisp Archive ===============================
10 ;; LCD Archive Entry:
11 ;; dired-trns|Hans Chalupsky|hans@cs.Buffalo.EDU
12 ;; |Filename Transformation for Tree Dired Shell Commands
13 ;; |Date: 1991/07/05 13:36:01 |Revision: 1.6 |
14
15 ;; INSTALLATION ======================================================
16 ;; Put this file into your load-path and add (load "dired-trns") to
17 ;; your dired-load-hook, e.g.
18 ;;
19 ;; (setq dired-load-hook '(lambda ()
20 ;; ;; possibly more statements here
21 ;; (load "dired-trns")))
22
23 ;; Transformers are functions that take a file (a string) as an argument
24 ;; and transform it into some other string (e.g., a filename without an
25 ;; extension).
26 ;;
27 ;; Each transformer is associated with a dispatch character. The associations
28 ;; are stored in a keymap for fast and easy lookup. The dispatch character
29 ;; is used to activate the associated transformer function at a particular
30 ;; position in a shell command issued in dired.
31 ;;
32 ;; Transformers can be used to construct complicated shell commands that
33 ;; operate on a large number of files, for example, they allow to create
34 ;; functionality such as "mv *.lsp *.lisp" where each .lsp file is
35 ;; renamed into a a file with same name but new extension .lisp.
36
37 (defvar dired-trans-map (make-keymap)
38 "Array that associates keys with file transformer functions")
39
40 (defmacro dired-trans-define (char &rest body)
41 "Macro that assigns the transformer function (lambda (file) BODY) to
42 CHAR (a character or string). BODY must return a string (the transformed
43 file or whatever. This macro allows easy definition of user specific
44 transformation functions."
45 (if (not (stringp char)) (setq char (char-to-string char)))
46 (list 'define-key 'dired-trans-map char
47 (list 'function (append '(lambda (file)) body))))
48
49 (defun dired-trans-run (transformers file)
50 "Applies each transformer supplied in the string TRANSFORMERS in sequence
51 to FILE and returns the concatenation of the results."
52 (mapconcat (function
53 (lambda (transformer)
54 (setq transformer (char-to-string transformer))
55 (funcall (or (lookup-key dired-trans-map transformer)
56 (error "Undefined transfomer: %s" transformer))
57 file)))
58 transformers nil))
59
60 (defvar dired-trans-re-ext "\\.[^.]*\\(\\.\\(\\(g?z\\)\\|Z\\)\\)?$"
61 "The part of a filename matching this regexp will be viewed as extension")
62
63 (defun dired-trans-init ()
64 "Defines a basic set of useful transformers.
65
66 * is a noop that returns the unmodified filename (equivalent to [dbe]).
67 n returns the Name component of a filename without directory information
68 d returns the Directory component of a filename
69 b returns the Basename of a filename, i.e., the name of the file without
70 directory and extension (see dired-trans-re-ext)
71 A basename with directory component can be obtained by [db].
72 e returns the Extension of a filename (i.e., whatever
73 dired-trans-re-ext splits off)
74 v returns a file without directory and without ,v suffixes if any.
75 z returns a file without directory and without .Z .z .gz suffixes if any."
76 (dired-trans-define
77 "*" file)
78 (dired-trans-define
79 "n" (or (file-name-nondirectory file) ""))
80 (dired-trans-define
81 "d" (or (file-name-directory file) ""))
82 (dired-trans-define
83 "b" (setq file (dired-trans-run "n" file))
84 (substring file 0 (string-match dired-trans-re-ext file)))
85 (dired-trans-define
86 "e" (let ((e (string-match dired-trans-re-ext file)))
87 (if e
88 (substring file e)
89 "")))
90 (dired-trans-define
91 "v" (setq file (dired-trans-run "n" file))
92 (substring file 0 (string-match ",v$" file)))
93 (dired-trans-define
94 "z" (setq file (dired-trans-run "n" file))
95 (substring file 0 (string-match "\\.\\(\\(g?z\\)\\|Z\\)$" file)))
96 )
97
98 (dired-trans-init)
99
100 (defun dired-trans-mklist (files &optional transformers)
101 "Takes a list of FILES and applies the sequence of TRANSFORMERS to each
102 of them. The transformed results are concatenated, separated by
103 dired-mark-separator, prefixed by dired-mark-prefix and postfixed by
104 dired-mark-postfix to generate a file list suitable for a particular shell."
105 (if (not (consp files))(setq files (list files)))
106 (if (null transformers) (setq transformers "*"))
107 (let ((file-list
108 (mapconcat (function
109 (lambda (file)
110 (shell-quote
111 (dired-trans-run transformers file))))
112 files dired-mark-separator)))
113 (if (> (length files) 1)
114 (concat dired-mark-prefix file-list dired-mark-postfix)
115 file-list)))
116
117 ;; By default, transformations can be specified like this:
118 ;; [db] or [dv] or #z# or #dbe# or #dbe (blank at the end).
119
120 (defvar dired-trans-starters "[#[]"
121 "User definable set of characters to be used to indicate the start of a
122 transformer sequence")
123
124 (defvar dired-trans-enders "[]# ]"
125 "User definable set of characters to be used to indicate the end of a
126 transformer sequence")
127
128 (defun dired-trans-expand (command files)
129 "Takes a shell COMMAND and a list of FILES and substitutes each occurance
130 of a transformer sequence by an accordingly transformed file list. Special
131 characters such as [,] or * can be quoted with a backslash."
132 (let ((quoted nil)
133 (collect-transformers nil)
134 (transformers ""))
135 (mapconcat (function
136 (lambda (char)
137 (setq char (char-to-string char))
138 (cond (quoted (setq quoted nil) char)
139 ((equal char "\\") (setq quoted t) nil)
140 (collect-transformers
141 (cond ((string-match dired-trans-enders char)
142 (setq collect-transformers nil)
143 (prog1 (dired-trans-mklist
144 files transformers)
145 (setq transformers "")))
146 (t (setq transformers
147 (concat transformers char))
148 nil)))
149 ((string-match dired-trans-starters char)
150 (setq collect-transformers t) nil)
151 ;; for compatibility and as a special case that should
152 ;; not be redefinable by the user (used below)
153 ((equal char "*")
154 (dired-trans-mklist files "*"))
155 (t char))))
156 command nil)))
157
158 (defun dired-trans-make (command files &optional all-at-once)
159 "Takes a shell COMMAND and a list of FILES and returns a command operating
160 on the list of files (transformed if COMMAND contains transformers). If
161 ALL-AT-ONCE is t the resulting command will be of the form
162 cmd file1 file2 ... fileN
163 otherwise it will be
164 cmd file1; cmd file2; ... cmd fileN;
165 Both examples assume a single reference to the file list."
166 (let (fns expanded-command)
167 (cond (all-at-once
168 (setq expanded-command (dired-trans-expand command files))
169 (if (equal command expanded-command)
170 (concat command (dired-trans-expand " *" files))
171 expanded-command))
172 (t (mapconcat
173 (function
174 (lambda (file)
175 (dired-trans-make command file t)))
176 files ";")))))
177
178 ;; Redefine this function from dired.el:
179
180 (defun dired-shell-stuff-it (command file-list on-each &optional raw-arg)
181 "Make up a shell command line from COMMAND and FILE-LIST.
182 If ON-EACH is t, COMMAND should be applied to each file, else
183 simply concat all files.
184 The list of marked files is appended to the command string unless asterisks
185 `*' or transformer sequences enclosed in `[]' indicate the place(s) where
186 the (transformed) list should go. See documentation of function
187 dired-trans-init for a list of transformers.
188 With a zero argument the resulting command will be of the form
189 cmd file1; cmd file2; ... cmd fileN assuming only one reference to the
190 file list. E.g., to rename all .lsp files into .lisp files mark all the
191 .lsp files and issue the command `mv * [db].lisp' ."
192 (dired-trans-make command file-list (not on-each)))