Subject: Re: bug#40896: 27.0.91; Moving point fails sometimes in shell-command

From: Michael Albinus <[email-masked]>
Date: Tue, 28 Apr 2020 16:22:19 +0200

Eli Zaretskii <[email-masked]> writes:

>> From: Michael Albinus <[email-masked]>
>> Cc: [email-masked],  [email-masked]
>> Date: Mon, 27 Apr 2020 19:50:57 +0200
>> 
>> Hmm, maybe I have been biased with the Tramp behaviour. But still,
>> there's suspicious behaviour with shell-command:
>
> I think these also behave as intended.  In general, all the non-nil
> values of shell-command-dont-erase-buffer are set up to accumulate
> output of several consecutive commands.  Once again, perhaps the
> documentation needs to be clarified.

Whatever shell-command-dont-erase-buffer says, shell-command output in
non-interactive mode shall be inserted at point, possibly after erasing
the buffer first. The first example I gave shows that this doesn't happen:

--8<---------------cut here---------------start------------->8---
;; Don't erase if the buffer is not the current one and
;; `shell-command-dont-erase-buffer' is set to `save-point'.
;; Check point.
(let ((default-directory temporary-file-directory)
      (shell-command-dont-erase-buffer 'save-point)
      buffer point)
  (with-temp-buffer
    (setq buffer (current-buffer))
    (insert "foobar")
    (goto-char (- (point-max) 3))
    (setq point (point))
    (cl-assert (string-equal "foobar" (buffer-string)))
    (cl-assert (string-equal "foo" (buffer-substring (point-min) (point))))
    (cl-assert (string-equal "bar" (buffer-substring (point) (point-max))))
    (cl-assert (= (point) (- (point-max) 3)))
    (with-temp-buffer
      (shell-command "echo baz" buffer))
    ;; The shell command output should be inserted between "foo" and "bar".
    (cl-assert (string-equal "foobaz\nbar" (buffer-string)) 'show-args)
    (cl-assert (= point (point)) 'show-args)))
--8<---------------cut here---------------end--------------->8---

Note that in case the buffer the output has to be inserted in is the
current one, this test succeeds. You can achieve this be replacing
'(with-temp-buffer (shell-command "echo baz" buffer))' by
'(shell-command "echo baz" buffer)'. This is inconsistent, isn't it? And
I haven't found any indication, that in case the buffer is not the
current one, shell command is inserted at the end of the buffer instead
of being inserted at point.

The second test case I've shown indicates, that a random value of
shell-command-dont-erase-buffer (I use the symbol 'random' here) doesn't
behave as expected. The docstring of that user option is not clear to
me: could it be, that the special symbols 'beg-last-out', 'end-last-out'
and ‘save-point’ indicate only setting the point if the buffer is the
current one? Why that? It's inconsistent in my eyes.

Maybe all of this is irrelevant in real life. But I'm fighting with
Tramp, in order to let its shell-command implementation behave like in
the local case.

Best regards, Michael.