Package: emacs;
Reported by: Michael Albinus <michael.albinus <at> gmx.de>
Date: Mon, 27 Apr 2020 08:29:01 UTC
Severity: normal
Found in version 27.0.91
Message #20 received at 40896 <at> debbugs.gnu.org (full text, mbox):
From: Michael Albinus <michael.albinus <at> gmx.de> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 40896 <at> debbugs.gnu.org, tino.calancha <at> gmail.com Subject: Re: bug#40896: 27.0.91; Moving point fails sometimes in shell-command Date: Thu, 30 Apr 2020 15:45:38 +0200
Michael Albinus <michael.albinus <at> gmx.de> writes: Hi Eli, > 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. In order to understand the situation better, I have enhanced my test code to cover all different values of shell-command-dont-erase-buffer, and whether the OUTPUT-BUFFER argument of shell-command is the current buffer, or not. Here's the code: --8<---------------cut here---------------start------------->8--- (progn (message " s-c-d-e-b current-buffer buffer-string point") (message "===============================================") (let ((default-directory temporary-file-directory) buffer) ;; These are the possible values of `shell-command-dont-erase-buffer'. ;; `random' is taken as non-nil value without special meaning. (dolist (shell-command-dont-erase-buffer '(nil erase beg-last-out end-last-out save-point random)) ;; `shell-command' might work over the current buffer, or not. (dolist (current '(t nil)) (with-temp-buffer ;; We insert the string "foobar" into an empty buffer. ;; Point is set between "foo" and "bar". (setq buffer (current-buffer)) (insert "foobar") (goto-char (- (point) 3)) ;; Apply `shell-command'. It shall output the string ;; "bazz". Messages in the *Messages* buffer are ;; suppressed. (let (message-log-max) (if current (shell-command "echo -n bazz" (current-buffer)) (with-temp-buffer (shell-command "echo -n bazz" buffer)))) ;; Print result. (message "%12s %14s %13s %5d" shell-command-dont-erase-buffer current (buffer-string) (point)))) (message "-----------------------------------------------")))) --8<---------------cut here---------------end--------------->8--- In a temporary buffer, the string "foobar" is inserted. Point is set between "foo" and "bar". Then, shell-command is called, which outputs the string "bazz". The result can be seen in the *Messages* buffer. Honestly, I cannot say whether this is conform to the docstring of shell-command (I have read it several times), because it describes too many cases, and it is not always clear how the combination of the cases is meant. But at least, I would say the results look inconsistent. A first observation is, that the output is inserted at (point) if OUTPUT-BUFFER is the current buffer, and it is appended at (point-max) if OUTPUT-BUFFER is not the current buffer. The fact, that the output is appended at the end of the buffer, isn't mentioned anywhere in the doc AFAICT. Now, let's see the details: --8<---------------cut here---------------start------------->8--- s-c-d-e-b current-buffer buffer-string point =============================================== nil t foobazzbar 4 nil nil bazz 5 --8<---------------cut here---------------end--------------->8--- shell-command-dont-erase-buffer is nil. In case OUTPUT-BUFFER is the current one, "bazz" is inserted at (point), and (point) is preserved. Fine. In case OUTPUT-BUFFER is not the current one, the buffer is erased, which as OK. However, (point) is NOT preserved, but moved to the end of the shell command output. That doesn't sound right. --8<---------------cut here---------------start------------->8--- erase t bazz 1 erase nil bazz 5 --8<---------------cut here---------------end--------------->8--- shell-command-dont-erase-buffer is erase. In both cases of OUTPUT-BUFFER, the buffer is erased (as expected), but again, in case OUTPUT-BUFFER is not the current one, (point) is moved after the shell command output. --8<---------------cut here---------------start------------->8--- beg-last-out t foobazzbar 4 beg-last-out nil foobarbazz 7 --8<---------------cut here---------------end--------------->8--- shell-command-dont-erase-buffer is beg-last-out. Shell command output is inserted in case OUTPUT-BUFFER is the current one, and it is appended otherwise. (point) is moved in both cases to the begin of the shell command output, which is consistent, but I don't still see why the output is either inserted, or appended. --8<---------------cut here---------------start------------->8--- end-last-out t foobazzbar 4 end-last-out nil foobazzbar 11 --8<---------------cut here---------------end--------------->8--- shell-command-dont-erase-buffer is end-last-out. In case OUTPUT-BUFFER is the current one everything looks as expected. But in the other case, OUTPUT-BUFFER is not the current buffer, the result is irritating. Shell command is inserted in this case at (point), and (point) is not moved to the end of the shell command output, but to the end of the buffer. Strange! --8<---------------cut here---------------start------------->8--- save-point t foobazzbar 4 save-point nil foobarbazz 4 --8<---------------cut here---------------end--------------->8--- shell-command-dont-erase-buffer is save-point. And indeed, (point) is saved in both cases. But again, shell command output is appended at the end of the buffer, instead of being inserted at (point). --8<---------------cut here---------------start------------->8--- random t foobazzbar 4 random nil foobazzbar 11 --8<---------------cut here---------------end--------------->8--- shell-command-dont-erase-buffer is random, which stands for a non-nil value which has no special meaning. It behaves like end-last-out. I don't know whether this is intended; if yes, it shall be documented. Best regards, Michael.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.