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

From: Michael Albinus <[email-masked]>
Date: Mon, 27 Apr 2020 19:50:57 +0200

Eli Zaretskii <[email-masked]> writes:

Hi Eli,

>> `shell-command' shall move the point after the output of the command,
>> unless indicated otherwise by `shell-command-dont-erase-buffer'.
>
> Which part(s) of the documentation caused this interpretation?  AFAIK,
> the truth is that the output is inserted at point (i.e. point is left
> _before_ the output), unless indicated otherwise by
> shell-command-dont-erase-buffer.  So if something we say tricks you to
> think otherwise, we need to fix that text.

Hmm, maybe I have been biased with the Tramp behaviour. But still,
there's suspicious behaviour with shell-command:

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

;; Don't erase if the buffer is not the current one and
;; `shell-command-dont-erase-buffer' is set to a non-nil value.
;; Point should be before shell command output.
(let ((default-directory temporary-file-directory)
      (shell-command-dont-erase-buffer 'random)
      buffer point)
  (with-temp-buffer
    (setq buffer (current-buffer))
    (insert "foobar")
    (setq point (point))
    (cl-assert (string-equal "foobar" (buffer-string)))
    (cl-assert (= (point) (point-max)))
    (with-temp-buffer
      (shell-command "echo baz" buffer))
    (cl-assert (string-equal "foobarbaz\n" (buffer-string)) 'show-args)
    ;; Point should be the same.
    (cl-assert (= point (point)) 'show-args)))
--8<---------------cut here---------------end--------------->8---

Unless I still misunderstand something, these cases should be checked. I
will work on Tramp when clarified.

> Thanks.

Best regards, Michael.