Mercurial > emacs
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) |