comparison lisp/dired-aux.el @ 42676:24e0ac83a078

(dired-shell-stuff-it): Substitute for * or ? only when they are surrounded by whitespace. Use dired-mark-separator when adding one file name to a command. (dired-do-shell-command): Verify that * is surrounded by whitespace. Ask for confirmation if * or ? is not surrounded by whitespace. (dired-bunch-files): Re-reverse the partial file list when it is used.
author Richard M. Stallman <rms@gnu.org>
date Sat, 12 Jan 2002 20:14:25 +0000
parents a8cf90908008
children d1778d61917a
comparison
equal deleted inserted replaced
42675:640c0fcaebf1 42676:24e0ac83a078
152 (rest (cdr files))) 152 (rest (cdr files)))
153 ;; If we have at least 1 pending file 153 ;; If we have at least 1 pending file
154 ;; and this file won't fit in the length limit, process now. 154 ;; and this file won't fit in the length limit, process now.
155 (if (and pending (> (+ thislength pending-length) max)) 155 (if (and pending (> (+ thislength pending-length) max))
156 (setq failures 156 (setq failures
157 (nconc (apply function (append args pending)) 157 (nconc (apply function (append args (nreverse pending)))
158 failures) 158 failures)
159 pending nil 159 pending nil
160 pending-length 0)) 160 pending-length 0))
161 ;; Do (setq pending (cons thisfile pending)) 161 ;; Do (setq pending (cons thisfile pending))
162 ;; but reuse the cons that was in `files'. 162 ;; but reuse the cons that was in `files'.
163 (setcdr files pending) 163 (setcdr files pending)
164 (setq pending files) 164 (setq pending files)
165 (setq pending-length (+ thislength pending-length)) 165 (setq pending-length (+ thislength pending-length))
166 (setq files rest))) 166 (setq files rest)))
167 (nconc (apply function (append args pending)) 167 (nconc (apply function (append args (nreverse pending)))
168 failures))) 168 failures)))
169 169
170 ;;;###autoload 170 ;;;###autoload
171 (defun dired-do-print (&optional arg) 171 (defun dired-do-print (&optional arg)
172 "Print the marked (or next ARG) files. 172 "Print the marked (or next ARG) files.
314 "Run a shell command COMMAND on the marked files. 314 "Run a shell command COMMAND on the marked files.
315 If no files are marked or a specific numeric prefix arg is given, 315 If no files are marked or a specific numeric prefix arg is given,
316 the next ARG files are used. Just \\[universal-argument] means the current file. 316 the next ARG files are used. Just \\[universal-argument] means the current file.
317 The prompt mentions the file(s) or the marker, as appropriate. 317 The prompt mentions the file(s) or the marker, as appropriate.
318 318
319 If there is output, it goes to a separate buffer. 319 If there is a `*' in COMMAND, surrounded by whitespace, this runs
320 320 COMMAND just once with the entire file list substituted there.
321 Normally the command is run on each file individually. 321
322 However, if there is a `*' in the command then it is run 322 If there is no `*', but there is a `?' in COMMAND, surrounded by
323 just once with the entire file list substituted there. 323 whitespace, this runs COMMAND on each file individually with the
324 324 file name substituted for `?'.
325 If there is no `*', but a `?' in the command then it is still run 325
326 on each file individually but with the filename substituted there 326 Otherwise, this runs COMMAND on each file individually with the
327 instead of at the end of the command. 327 file name added at the end of COMMAND (separated by a space).
328 328
329 No automatic redisplay of dired buffers is attempted, as there's no 329 `*' and `?' when not surrounded by whitespace have no special
330 telling what files the command may have changed. Type 330 significance for `dired-do-shell-command', and are passed through
331 \\[dired-do-redisplay] to redisplay the marked files. 331 normally to the shell, but you must confirm first. To pass `*' by
332 332 itself to the shell as a wildcard, type `*""'.
333 The shell command has the top level directory as working directory, so 333
334 output files usually are created there instead of in a subdir. 334 If COMMAND produces output, it goes to a separate buffer.
335
336 This feature does not try to redisplay Dired buffers afterward, as
337 there's no telling what files COMMAND may have changed.
338 Type \\[dired-do-redisplay] to redisplay the marked files.
339
340 When COMMAND runs, its working directory is the top-level directory of
341 the Dired buffer, so output files usually are created there instead of
342 in a subdir.
335 343
336 In a noninteractive call (from Lisp code), you must specify 344 In a noninteractive call (from Lisp code), you must specify
337 the list of file names explicitly with the FILE-LIST argument." 345 the list of file names explicitly with the FILE-LIST argument."
338 ;;Functions dired-run-shell-command and dired-shell-stuff-it do the 346 ;;Functions dired-run-shell-command and dired-shell-stuff-it do the
339 ;;actual work and can be redefined for customization. 347 ;;actual work and can be redefined for customization.
345 "%s: ") 353 "%s: ")
346 current-prefix-arg 354 current-prefix-arg
347 files) 355 files)
348 current-prefix-arg 356 current-prefix-arg
349 files))) 357 files)))
350 (let* ((on-each (not (string-match "\\*" command)))) 358 (let* ((on-each (not (string-match "\\(^\\|[ \t]\\)\\*\\([ \t]\\|$\\)" command)))
351 (if on-each 359 (subst (not (string-match "\\(^\\|[ \t]\\)\\?\\([ \t]\\|$\\)" command)))
352 (dired-bunch-files 360 (star (not (string-match "\\*" command)))
353 (- 10000 (length command)) 361 (qmark (not (string-match "\\?" command))))
354 (function (lambda (&rest files) 362 ;; Get confirmation for wildcards that may have been meant
355 (dired-run-shell-command 363 ;; to control substitution of a file name or the file name list.
356 (dired-shell-stuff-it command files t arg)))) 364 (if (cond ((and star (not on-each))
357 nil 365 (y-or-n-p "Confirm--do you mean to use `*' as a wildcard? "))
358 file-list) 366 ((and qmark (not subst))
359 ;; execute the shell command 367 (y-or-n-p "Confirm--do you mean to use `?' as a wildcard? "))
360 (dired-run-shell-command 368 (t))
361 (dired-shell-stuff-it command file-list nil arg))))) 369 (if on-each
370 (dired-bunch-files
371 (- 10000 (length command))
372 (function (lambda (&rest files)
373 (dired-run-shell-command
374 (dired-shell-stuff-it command files t arg))))
375 nil
376 file-list)
377 ;; execute the shell command
378 (dired-run-shell-command
379 (dired-shell-stuff-it command file-list nil arg))))))
362 380
363 ;; Might use {,} for bash or csh: 381 ;; Might use {,} for bash or csh:
364 (defvar dired-mark-prefix "" 382 (defvar dired-mark-prefix ""
365 "Prepended to marked files in dired shell commands.") 383 "Prepended to marked files in dired shell commands.")
366 (defvar dired-mark-postfix "" 384 (defvar dired-mark-postfix ""
374 ;; simply concat all files and apply COMMAND to this. 392 ;; simply concat all files and apply COMMAND to this.
375 ;; FILE-LIST's elements will be quoted for the shell." 393 ;; FILE-LIST's elements will be quoted for the shell."
376 ;; Might be redefined for smarter things and could then use RAW-ARG 394 ;; Might be redefined for smarter things and could then use RAW-ARG
377 ;; (coming from interactive P and currently ignored) to decide what to do. 395 ;; (coming from interactive P and currently ignored) to decide what to do.
378 ;; Smart would be a way to access basename or extension of file names. 396 ;; Smart would be a way to access basename or extension of file names.
379 ;; See dired-trns.el for an approach to this.
380 ;; Bug: There is no way to quote a * or a ?
381 ;; On the other hand, you can never accidentally get a * or a ? into
382 ;; your cmd.
383 (let ((stuff-it 397 (let ((stuff-it
384 (cond ((string-match "\\*" command) 398 (cond ((string-match "\\(^\\|[ \t]\\)\\*\\([ \t]\\|$\\)" command)
385 (function (lambda (x) 399 (lambda (x)
386 (dired-replace-in-string "\\*" x command)))) 400 (string-match "\\(^\\|[ \t]\\)\\(\\*\\)\\([ \t]\\|$\\)" command)
387 ((string-match "\\?" command) 401 (replace-match x t t command 2)))
388 (function (lambda (x) 402 ((string-match "\\(^\\|[ \t]\\)\\?\\([ \t]\\|$\\)" command)
389 (dired-replace-in-string "\\?" x command)))) 403 (lambda (x)
390 (t (function (lambda (x) (concat command " " x))))))) 404 (string-match "\\(^\\|[ \t]\\)\\(\\?\\)\\([ \t]\\|$\\)" command)
405 (replace-match x t t command 2)))
406 (t (lambda (x) (concat command dired-mark-separator x))))))
391 (if on-each 407 (if on-each
392 (mapconcat stuff-it (mapcar 'shell-quote-argument file-list) ";") 408 (mapconcat stuff-it (mapcar 'shell-quote-argument file-list) ";")
393 (let ((fns (mapconcat 'shell-quote-argument 409 (let ((files (mapconcat 'shell-quote-argument
394 file-list dired-mark-separator))) 410 file-list dired-mark-separator)))
395 (if (> (length file-list) 1) 411 (if (> (length file-list) 1)
396 (setq fns (concat dired-mark-prefix fns dired-mark-postfix))) 412 (setq files (concat dired-mark-prefix files dired-mark-postfix)))
397 (funcall stuff-it fns))))) 413 (funcall stuff-it files)))))
398 414
399 ;; This is an extra function so that it can be redefined by ange-ftp. 415 ;; This is an extra function so that it can be redefined by ange-ftp.
400 (defun dired-run-shell-command (command) 416 (defun dired-run-shell-command (command)
401 (let ((handler 417 (let ((handler
402 (find-file-name-handler (directory-file-name default-directory) 418 (find-file-name-handler (directory-file-name default-directory)