From 6dafa0d5352ada03f9a6db6ba8d3eec8f7884642 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Tue, 17 Jul 2012 21:40:15 +0300 Subject: [PATCH] * lisp/dired-aux.el (dired-do-async-shell-command): Doc fix. (dired-do-async-shell-command): Don't add `*' at the end of the command (Bug#11815). (dired-do-shell-command): Doc fix. (dired-shell-stuff-it): Strip the trailing "&" and ";" if any. Join the individual commands using either "&" or ";" as the separator depending on the values of these trailing characters. At the end re-add the trailing "&". (Bug#10598) * lisp/simple.el (async-shell-command): Sync the interactive spec with `shell-command'. Doc fix. (shell-command): Doc fix. --- etc/NEWS | 12 +++++-- lisp/ChangeLog | 15 +++++++++ lisp/dired-aux.el | 81 ++++++++++++++++++++++++++++++----------------- lisp/simple.el | 19 +++++++---- 4 files changed, 89 insertions(+), 38 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index bf7880bd1ac..3435a839a74 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -274,13 +274,13 @@ The variable `diff-use-changed-face' defines whether to use the face `diff-changed', or `diff-removed' and `diff-added' to highlight changes in context diffs. +** Ediff now uses the same color scheme as Diff mode +on high color displays. + ** Flymake uses fringe bitmaps to indicate errors and warnings. See flymake-fringe-indicator-position, flymake-error-bitmap and flymake-warning-bitmap. -** Ediff now uses the same color scheme as Diff mode -on high color displays. - ** `sh-script' *** Pairing of parens/quotes uses electric-pair-mode instead of skeleton-pair. *** `sh-electric-here-document-mode' now controls auto-insertion of here-docs. @@ -348,6 +348,12 @@ these commands now). ** erc will look up server/channel names via auth-source and use the channel keys found, if any. +** Dired + +*** `dired-do-async-shell-command' executes each file sequentially +if the command ends in `;' (when operating on multiple files). +Othwerwise, it executes the command on each file in parallel. + ** FFAP *** The option `ffap-url-unwrap-remote' can now be a list of strings, diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 2320a16a26e..cbc233079a7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,18 @@ +2012-07-17 Juri Linkov + + * dired-aux.el (dired-do-async-shell-command): Doc fix. + (dired-do-async-shell-command): Don't add `*' at the end of the + command (Bug#11815). + (dired-do-shell-command): Doc fix. + (dired-shell-stuff-it): Strip the trailing "&" and ";" if any. + Join the individual commands using either "&" or ";" as the + separator depending on the values of these trailing characters. + At the end re-add the trailing "&". (Bug#10598) + + * simple.el (async-shell-command): Sync the interactive spec with + `shell-command'. Doc fix. + (shell-command): Doc fix. + 2012-07-17 Juri Linkov * descr-text.el (describe-char): Fix format args. (Bug#10129) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index ffd93a85ee8..6186f762e0a 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -545,8 +545,17 @@ offer a smarter default choice of shell command." (defun dired-do-async-shell-command (command &optional arg file-list) "Run a shell command COMMAND on the marked files asynchronously. -Like `dired-do-shell-command' but if COMMAND doesn't end in ampersand, -adds `* &' surrounded by whitespace and executes the command asynchronously. +Like `dired-do-shell-command', but adds `&' at the end of COMMAND +to execute it asynchronously. + +When operating on multiple files, asynchronous commands +are executed in the background on each file in parallel. +In shell syntax this means separating the individual commands +with `&'. However, when COMMAND ends in `;' or `;&' then commands +are executed in the background on each file sequentially waiting +for each command to terminate before running the next command. +In shell syntax this means separating the individual commands with `;'. + The output appears in the buffer `*Async Shell Command*'." (interactive (let ((files (dired-get-marked-files t current-prefix-arg))) @@ -555,18 +564,14 @@ The output appears in the buffer `*Async Shell Command*'." (dired-read-shell-command "& on %s: " current-prefix-arg files) current-prefix-arg files))) - (unless (string-match "[*?][ \t]*\\'" command) - (setq command (concat command " *"))) (unless (string-match "&[ \t]*\\'" command) (setq command (concat command " &"))) (dired-do-shell-command command arg file-list)) -;; The in-background argument is only needed in Emacs 18 where -;; shell-command doesn't understand an appended ampersand `&'. ;;;###autoload (defun dired-do-shell-command (command &optional arg file-list) "Run a shell command COMMAND on the marked files. -If no files are marked or a specific numeric prefix arg is given, +If no files are marked or a numeric prefix arg is given, the next ARG files are used. Just \\[universal-argument] means the current file. The prompt mentions the file(s) or the marker, as appropriate. @@ -588,7 +593,17 @@ If you want to use `*' as a shell wildcard with whitespace around it, write `*\"\"' in place of just `*'. This is equivalent to just `*' in the shell, but avoids Dired's special handling. -If COMMAND produces output, it goes to a separate buffer. +If COMMAND ends in `&', `;', or `;&', it is executed in the +background asynchronously, and the output appears in the buffer +`*Async Shell Command*'. When operating on multiple files and COMMAND +ends in `&', the shell command is executed on each file in parallel. +However, when COMMAND ends in `;' or `;&' then commands are executed +in the background on each file sequentially waiting for each command +to terminate before running the next command. You can also use +`dired-do-async-shell-command' that automatically adds `&'. + +Otherwise, COMMAND is executed synchronously, and the output +appears in the buffer `*Shell Command Output*'. This feature does not try to redisplay Dired buffers afterward, as there's no telling what files COMMAND may have changed. @@ -607,10 +622,7 @@ can be produced by `dired-get-marked-files', for example." (let ((files (dired-get-marked-files t current-prefix-arg))) (list ;; Want to give feedback whether this file or marked files are used: - (dired-read-shell-command (concat "! on " - "%s: ") - current-prefix-arg - files) + (dired-read-shell-command "! on %s: " current-prefix-arg files) current-prefix-arg files))) (let* ((on-each (not (string-match dired-star-subst-regexp command))) @@ -654,23 +666,34 @@ can be produced by `dired-get-marked-files', for example." ;; Might be redefined for smarter things and could then use RAW-ARG ;; (coming from interactive P and currently ignored) to decide what to do. ;; Smart would be a way to access basename or extension of file names. - (let ((stuff-it - (if (or (string-match dired-star-subst-regexp command) - (string-match dired-quark-subst-regexp command)) - (lambda (x) - (let ((retval command)) - (while (string-match - "\\(^\\|[ \t]\\)\\([*?]\\)\\([ \t]\\|$\\)" retval) - (setq retval (replace-match x t t retval 2))) - retval)) - (lambda (x) (concat command dired-mark-separator x))))) - (if on-each - (mapconcat stuff-it (mapcar 'shell-quote-argument file-list) ";") - (let ((files (mapconcat 'shell-quote-argument - file-list dired-mark-separator))) - (if (> (length file-list) 1) - (setq files (concat dired-mark-prefix files dired-mark-postfix))) - (funcall stuff-it files))))) + (let* ((in-background (string-match "[ \t]*&[ \t]*\\'" command)) + (command (if in-background + (substring command 0 (match-beginning 0)) + command)) + (sequentially (string-match "[ \t]*;[ \t]*\\'" command)) + (command (if sequentially + (substring command 0 (match-beginning 0)) + command)) + (stuff-it + (if (or (string-match dired-star-subst-regexp command) + (string-match dired-quark-subst-regexp command)) + (lambda (x) + (let ((retval command)) + (while (string-match + "\\(^\\|[ \t]\\)\\([*?]\\)\\([ \t]\\|$\\)" retval) + (setq retval (replace-match x t t retval 2))) + retval)) + (lambda (x) (concat command dired-mark-separator x))))) + (concat + (if on-each + (mapconcat stuff-it (mapcar 'shell-quote-argument file-list) + (if (and in-background (not sequentially)) "&" ";")) + (let ((files (mapconcat 'shell-quote-argument + file-list dired-mark-separator))) + (if (> (length file-list) 1) + (setq files (concat dired-mark-prefix files dired-mark-postfix))) + (funcall stuff-it files))) + (if in-background "&" "")))) ;; This is an extra function so that it can be redefined by ange-ftp. ;;;###autoload diff --git a/lisp/simple.el b/lisp/simple.el index 37e0b48d31d..c958c460f98 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2247,9 +2247,11 @@ to `shell-command-history'." (defun async-shell-command (command &optional output-buffer error-buffer) "Execute string COMMAND asynchronously in background. -Like `shell-command' but if COMMAND doesn't end in ampersand, adds `&' -surrounded by whitespace and executes the command asynchronously. +Like `shell-command', but adds `&' at the end of COMMAND +to execute it asynchronously. + The output appears in the buffer `*Async Shell Command*'. +That buffer is in shell mode. In Elisp, you will often be better served by calling `start-process' directly, since it offers more control and does not impose the use of a @@ -2257,8 +2259,12 @@ shell (with its need to quote arguments)." (interactive (list (read-shell-command "Async shell command: " nil nil - (and buffer-file-name - (file-relative-name buffer-file-name))) + (let ((filename + (cond + (buffer-file-name) + ((eq major-mode 'dired-mode) + (dired-get-filename nil t))))) + (and filename (file-relative-name filename)))) current-prefix-arg shell-command-default-error-buffer)) (unless (string-match "&[ \t]*\\'" command) @@ -2269,9 +2275,10 @@ shell (with its need to quote arguments)." "Execute string COMMAND in inferior shell; display output, if any. With prefix argument, insert the COMMAND's output at point. -If COMMAND ends in ampersand, execute it asynchronously. +If COMMAND ends in `&', execute it asynchronously. The output appears in the buffer `*Async Shell Command*'. -That buffer is in shell mode. +That buffer is in shell mode. You can also use +`async-shell-command' that automatically adds `&'. Otherwise, COMMAND is executed synchronously. The output appears in the buffer `*Shell Command Output*'. If the output is short enough to -- 2.39.2