Subject: Re: bug#79067: 31.0.50; Cannot async-shell-command anymore

From: Stephen Berman <[email-masked]>
Date: Mon, 21 Jul 2025 12:27:38 +0200

On Mon, 21 Jul 2025 11:51:38 +0200 Manuel Giraud <[email-masked]> wrote:

> Manuel Giraud <[email-masked]> writes:
>
>> Hi,
>>
>>>From a current build, I can't call `async-shell-command' anymore.  Here
>> is my recipe:
>>
>>   - emacs -Q
>>   - M-& ls <RET>
>>
>> I get the following error:
>>
>> shell-command: Asynchronous shell commands cannot output to current
>> buffer
>
> I'm not quite sure about the logic at play here but the following patch
> fixes my issue:
>
> diff --git a/lisp/simple.el b/lisp/simple.el
> index 88886de05c4..f7f059793ca 100644
> --- a/lisp/simple.el
> +++ b/lisp/simple.el
> @@ -4715,7 +4715,8 @@ shell-command
>  	;; Output goes in a separate buffer.
>  	(if (string-match "[ \t]*&[ \t]*\\'" command)
>  	    ;; Command ending with ampersand means asynchronous.
> -            (let* ((_ (or (bufferp output-buffer)
> +            (let* ((_ (or (null output-buffer)
> +                          (bufferp output-buffer)
>                            (stringp output-buffer)
>                            (error "Asynchronous shell commands cannot output to current buffer")))
>                     (buffer (get-buffer-create

The commit message of 852009b4f1c9, which added the bufferp and stringp
checks and the error message, says 'Improve error message for "C-u M-!
something &"'.  An alternative is to ignore the prefix argument when the
command is asynchronous, just like `async-shell-command' ignores the
prefix argument:

diff --git a/lisp/simple.el b/lisp/simple.el
index 88886de05c4..c64d3e5285b 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -4715,9 +4715,12 @@ shell-command
 	;; Output goes in a separate buffer.
 	(if (string-match "[ \t]*&[ \t]*\\'" command)
 	    ;; Command ending with ampersand means asynchronous.
-            (let* ((_ (or (bufferp output-buffer)
-                          (stringp output-buffer)
-                          (error "Asynchronous shell commands cannot output to current buffer")))
+            (let* ((output-buffer (unless (consp output-buffer)
+                                    ;; Output of asynchronous commands
+                                    ;; cannot be inserted into current
+                                    ;; buffer, so if OUTPUT-BUFFER is a
+                                    ;; prefix argument, ignore it.
+                                    output-buffer))
                    (buffer (get-buffer-create
                             (or output-buffer shell-command-buffer-name-async)))
                    (bname (buffer-name buffer))

Steve Berman