From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Roland Winkler" Newsgroups: gmane.emacs.bugs Subject: bug#10598: 24.0.92; run dired-do-async-shell-command on multiple files individually Date: Tue, 17 Jul 2012 02:17:37 -0500 Message-ID: <20485.4497.853929.507281@gargle.gargle.HOWL> References: <87liow9jdf.fsf@niu.edu> <87obtsqbiw.fsf@mail.jurta.org> <20255.60373.371008.208639@gargle.gargle.HOWL> <87394x8im1.fsf@mail.jurta.org> <20478.42579.593253.620476@lukas.physics.niu.edu> <871ukg9i6m.fsf@mail.jurta.org> <20479.59979.797807.988643@gargle.gargle.HOWL> <878vem8z9i.fsf@mail.jurta.org> <20482.30360.86756.671195@gargle.gargle.HOWL> <87k3y51l7m.fsf@mail.jurta.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1342509502 15672 80.91.229.3 (17 Jul 2012 07:18:22 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 17 Jul 2012 07:18:22 +0000 (UTC) Cc: 10598@debbugs.gnu.org To: Juri Linkov Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Jul 17 09:18:22 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Sr233-0005bg-24 for geb-bug-gnu-emacs@m.gmane.org; Tue, 17 Jul 2012 09:18:21 +0200 Original-Received: from localhost ([::1]:38185 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sr232-00059d-Aj for geb-bug-gnu-emacs@m.gmane.org; Tue, 17 Jul 2012 03:18:20 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:55558) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sr22w-00059N-LF for bug-gnu-emacs@gnu.org; Tue, 17 Jul 2012 03:18:18 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Sr22m-0001hc-AV for bug-gnu-emacs@gnu.org; Tue, 17 Jul 2012 03:18:14 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:35629) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sr22m-0001hL-6Z for bug-gnu-emacs@gnu.org; Tue, 17 Jul 2012 03:18:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1Sr28Y-0004eH-Fb for bug-gnu-emacs@gnu.org; Tue, 17 Jul 2012 03:24:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: "Roland Winkler" Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 17 Jul 2012 07:24:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 10598 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 10598-submit@debbugs.gnu.org id=B10598.134250982517844 (code B ref 10598); Tue, 17 Jul 2012 07:24:02 +0000 Original-Received: (at 10598) by debbugs.gnu.org; 17 Jul 2012 07:23:45 +0000 Original-Received: from localhost ([127.0.0.1]:45174 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1Sr28G-0004dl-5O for submit@debbugs.gnu.org; Tue, 17 Jul 2012 03:23:44 -0400 Original-Received: from fencepost.gnu.org ([208.118.235.10]:59366) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1Sr28C-0004dc-0N for 10598@debbugs.gnu.org; Tue, 17 Jul 2012 03:23:42 -0400 Original-Received: from pchdb00005.uni-regensburg.de ([132.199.129.10]:43255 helo=regnitz) by fencepost.gnu.org with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1Sr22O-0003Sr-7g; Tue, 17 Jul 2012 03:17:40 -0400 In-Reply-To: <87k3y51l7m.fsf@mail.jurta.org> X-Mailer: VM 8.2 trial under 24.1.1 (x86_64-unknown-linux-gnu) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:62029 Archived-At: On Sun Jul 15 2012 Juri Linkov wrote: > Yes, it seems this is what remains to do. > It's implemented in the following patch: Thanks a lot, this looks great to me (and also works for me as expected). In the slightly modified version of the patch below, I updated also the docstring for dired-do-shell-command and I unified the indentation. It would be good if the info node "(emacs)Shell Commands in Dired" will be updated, too. --- dired-aux.el~ 2012-07-15 01:08:08.000000000 -0500 +++ dired-aux.el 2012-07-17 02:03:33.000000000 -0500 @@ -539,8 +539,17 @@ (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))) @@ -549,18 +558,14 @@ (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. @@ -582,6 +587,15 @@ it, write `*\"\"' in place of just `*'. This is equivalent to just `*' in the shell, but avoids Dired's special handling. +If COMMAND ends in `&', `;', or `;&', execute the shell command +in the background asynchronously. When operating on multiple files +and COMMAND ends in `&', the shell command is executed 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 `;'. + If COMMAND produces output, it goes to a separate buffer. This feature does not try to redisplay Dired buffers afterward, as @@ -592,9 +606,9 @@ of the Dired buffer, so output files usually are created there instead of in a subdir. -In a noninteractive call (from Lisp code), you must specify -the list of file names explicitly with the FILE-LIST argument, which -can be produced by `dired-get-marked-files', for example." +In a noninteractive call, you must specify the list of file names explicitly +with the FILE-LIST argument, which can be produced by `dired-get-marked-files', +for example." ;;Functions dired-run-shell-command and dired-shell-stuff-it do the ;;actual work and can be redefined for customization. (interactive @@ -648,23 +662,34 @@ ;; 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