0
|
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)))
|