Merge from origin/emacs-27

154cd116be (origin/emacs-27) * admin/release-process: Adapt bug numbe...
fd19282134 Fix shell-tests failures
891f7de8ed * test/lisp/simple-tests.el: Full path to Emacs binary (bu...
92f30d62c0 * lisp/tab-line.el (tab-line-auto-hscroll): Fix for long t...
dde313151d * lisp/menu-bar.el (menu-bar-options-menu): Add desktop-sa...
3543b9fad9 ; Fix a test (Bug#39067)
83f9fe44fa ; * etc/NEWS: Fix typo.
2eb0b7835d Fix shell-command-dont-erase-buffer feature
c134978a76 Remove reference to Emacs 19 from FAQ
fabf0065c5 Doc fixes in package.el

# Conflicts:
#	etc/NEWS
This commit is contained in:
Glenn Morris 2020-01-20 07:50:30 -08:00
commit 215ceadcc8
10 changed files with 169 additions and 44 deletions

View file

@ -46,18 +46,22 @@ See admin/gitmerge.el.
Emacs uses the "blocking" feature of Debbugs for bugs that need to be
addressed in the next release.
Currently, bug#21966 is the tracking bug for release of 25.2 and
bug#24655 is the tracking bug for release 26.1. Say bug#123 needs
to be fixed for Emacs 26.1. Send a message to control@debbugs.gnu.org
Currently, bug#39200 is the tracking bug for release of 27.1 and
bug#39202 is the tracking bug for release 28.1. Say bug#123 needs
to be fixed for Emacs 27.1. Send a message to control@debbugs.gnu.org
that says:
block 24655 by 123
block 39200 by 123
Change "block" to "unblock" to remove a bug from the list. Closed
bugs are not listed as blockers, so you do not need to explicitly
unblock one that has been closed. You may need to force an update of
the tracking bug with ctrl-f5/shift-reload to see the latest version.
If you use the debbugs package from GNU ELPA, you can apply the
following form to see all bugs which block a given release:
(debbugs-gnu-emacs-release-blocking-reports "27.1")
* TO BE DONE SHORTLY BEFORE RELEASE

View file

@ -826,12 +826,14 @@ the output buffer. But if you change the value of the variable
inserted into a buffer of that name.
@vindex shell-command-dont-erase-buffer
By default, the output buffer is erased between shell commands.
If you change the value of the variable
@code{shell-command-dont-erase-buffer} to a non-@code{nil} value,
the output buffer is not erased. This variable also controls where to
set the point in the output buffer after the command completes; see the
documentation of the variable for details.
By default, the output buffer is erased between shell commands, except
when the output goes to the current buffer. If you change the value
of the option @code{shell-command-dont-erase-buffer} to @code{erase},
then the output buffer is always erased. Any other non-@code{nil}
value prevents to erase the output buffer.
This option also controls where to set the point in the output buffer
after the command completes; see the documentation of the option for details.
@node Interactive Shell
@subsection Interactive Subshell

View file

@ -3068,8 +3068,8 @@ begun}.
@cindex Ignored X resources
@cindex @file{.Xdefaults}
As of version 19, Emacs searches for X resources in the files specified
by the following environment variables:
Emacs searches for X resources in the files specified by the following
environment variables:
@itemize @bullet

View file

@ -2037,6 +2037,14 @@ variable for remote shells. It still defaults to "/bin/sh".
** Single shell commands
+++
*** 'shell-command-dont-erase-buffer' accepts the value 'erase' to
force to erase the output buffer before execution of the command.
*** The new functions 'shell-command-save-pos-or-erase' and
'shell-command-set-point-after-cmd' control how point is handled
between two consecutive shell commands in the same buffer.
+++
*** 'async-shell-command-width' defines the number of display columns
available for output of asynchronous shell commands.

View file

@ -606,8 +606,10 @@ EXP should be a form read from a foo-pkg.el file.
Convert EXP into a `package-desc' object using the
`package-desc-from-define' constructor before pushing it to
`package-alist'.
If there already exists a package by that name in
`package-alist', replace that definition with the new one."
If there already exists a package by the same name in
`package-alist', insert this object there such that the packages
are sorted with the highest version first."
(when (eq (car-safe exp) 'define-package)
(let* ((new-pkg-desc (apply #'package-desc-from-define (cdr exp)))
(name (package-desc-name new-pkg-desc))
@ -952,7 +954,7 @@ untar into a directory named DIR; otherwise, signal an error."
pkg-dir))
(defun package-generate-description-file (pkg-desc pkg-file)
"Create the foo-pkg.el file for single-file packages."
"Create the foo-pkg.el file PKG-FILE for single-file package PKG-DESC."
(let* ((name (package-desc-name pkg-desc)))
(let ((print-level nil)
(print-quoted t)
@ -996,6 +998,7 @@ untar into a directory named DIR; otherwise, signal an error."
(defvar version-control)
(defun package-generate-autoloads (name pkg-dir)
"Generate autoloads in PKG-DIR for package named NAME."
(let* ((auto-name (format "%s-autoloads.el" name))
;;(ignore-name (concat name "-pkg.el"))
(generated-autoload-file (expand-file-name auto-name pkg-dir))
@ -1176,12 +1179,14 @@ The return result is a `package-desc'."
;; signature checking.
(defun package--write-file-no-coding (file-name)
"Write file FILE-NAME without encoding using coding system."
(let ((buffer-file-coding-system 'no-conversion))
(write-region (point-min) (point-max) file-name nil 'silent)))
(declare-function url-http-file-exists-p "url-http" (url))
(defun package--archive-file-exists-p (location file)
"Return t if FILE exists in remote LOCATION."
(let ((http (string-match "\\`https?:" location)))
(if http
(progn
@ -2819,6 +2824,7 @@ of these dependencies, similar to the list returned by
(push dep out)))))))))))
(defun package-desc-status (pkg-desc)
"Return the status of `package-desc' object PKG-DESC."
(let* ((name (package-desc-name pkg-desc))
(dir (package-desc-dir pkg-desc))
(lle (assq name package-load-list))

View file

@ -1476,6 +1476,18 @@ mail status in mode line"))
(bindings--define-key menu [cursor-separator]
menu-bar-separator)
(bindings--define-key menu [save-desktop]
(menu-bar-make-toggle
toggle-save-desktop-globally desktop-save-mode
"Save State between Sessions"
"Saving desktop state %s"
"Visit desktop of previous session when restarting Emacs"
(require 'desktop)
;; Do it by name, to avoid a free-variable
;; warning during byte compilation.
(set-default
'desktop-save-mode (not (symbol-value 'desktop-save-mode)))))
(bindings--define-key menu [save-place]
(menu-bar-make-toggle
toggle-save-place-globally save-place-mode

View file

@ -3436,19 +3436,28 @@ This affects `shell-command' and `async-shell-command'."
:version "27.1")
(defcustom shell-command-dont-erase-buffer nil
"If non-nil, output buffer is not erased between shell commands.
Also, a non-nil value sets the point in the output buffer
once the command completes.
"Control if the output buffer is erased before the command.
A nil value erases the output buffer before execution of the
shell command, except when the output buffer is the current one.
The value `erase' ensures the output buffer is erased before
execution of the shell command.
Other non-nil values prevent the output buffer from being erased and
set the point after execution of the shell command.
The value `beg-last-out' sets point at the beginning of the output,
`end-last-out' sets point at the end of the buffer, `save-point'
restores the buffer position before the command."
:type '(choice
(const :tag "Erase buffer" nil)
(const :tag "Erase output buffer if not the current one" nil)
(const :tag "Always erase output buffer" erase)
(const :tag "Set point to beginning of last output" beg-last-out)
(const :tag "Set point to end of last output" end-last-out)
(const :tag "Save point" save-point))
:group 'shell
:version "26.1")
:version "27.1")
(defvar shell-command-saved-pos nil
"Record of point positions in output buffers after command completion.
@ -3457,8 +3466,11 @@ where BUFFER is the output buffer, and POS is the point position
in BUFFER once the command finishes.
This variable is used when `shell-command-dont-erase-buffer' is non-nil.")
(defun shell-command--save-pos-or-erase ()
(defun shell-command-save-pos-or-erase (&optional output-to-current-buffer)
"Store a buffer position or erase the buffer.
Optional argument OUTPUT-TO-CURRENT-BUFFER, if non-nil, means that the output
of the shell command goes to the caller current buffer.
See `shell-command-dont-erase-buffer'."
(let ((sym shell-command-dont-erase-buffer)
pos)
@ -3469,7 +3481,9 @@ See `shell-command-dont-erase-buffer'."
(setq pos
(cond ((eq sym 'save-point) (point))
((eq sym 'beg-last-out) (point-max))
((not sym)
;;((not sym)
((or (eq sym 'erase)
(and (null sym) (not output-to-current-buffer)))
(let ((inhibit-read-only t))
(erase-buffer) nil))))
(when pos
@ -3477,7 +3491,7 @@ See `shell-command-dont-erase-buffer'."
(push (cons (current-buffer) pos)
shell-command-saved-pos))))
(defun shell-command--set-point-after-cmd (&optional buffer)
(defun shell-command-set-point-after-cmd (&optional buffer)
"Set point in BUFFER after command complete.
BUFFER is the output buffer of the command; if nil, then defaults
to the current BUFFER.
@ -3492,12 +3506,19 @@ whose `car' is BUFFER."
(when (buffer-live-p buf)
(let ((win (car (get-buffer-window-list buf)))
(pmax (with-current-buffer buf (point-max))))
(unless (and pos (memq sym '(save-point beg-last-out)))
;; The first time we run a command in a fresh created buffer
;; we have not saved positions yet; advance to `point-max', so that
;; succesive commands knows the position where the new comman start.
;; (unless (and pos (memq sym '(save-point beg-last-out)))
(unless (and pos (memq sym '(save-point beg-last-out end-last-out)))
(setq pos pmax))
;; Set point in the window displaying buf, if any; otherwise
;; display buf temporary in selected frame and set the point.
(if win
(set-window-point win pos)
(when pos
(with-current-buffer buf (goto-char pos)))
(save-window-excursion
(let ((win (display-buffer
buf
@ -3625,7 +3646,9 @@ impose the use of a shell (with its need to quote arguments)."
(if handler
(funcall handler 'shell-command command output-buffer error-buffer)
(if (and output-buffer
(not (or (bufferp output-buffer) (stringp output-buffer))))
(or (eq output-buffer (current-buffer))
(and (stringp output-buffer) (eq (get-buffer output-buffer) (current-buffer)))
(not (or (bufferp output-buffer) (stringp output-buffer))))) ; Bug#39067
;; Output goes in current buffer.
(let ((error-file
(and error-buffer
@ -3635,6 +3658,7 @@ impose the use of a shell (with its need to quote arguments)."
temporary-file-directory))))))
(barf-if-buffer-read-only)
(push-mark nil t)
(shell-command-save-pos-or-erase 'output-to-current-buffer)
;; We do not use -f for csh; we will not support broken use of
;; .cshrcs. Even the BSD csh manual says to use
;; "if ($?prompt) exit" before things that are not useful
@ -3663,7 +3687,8 @@ impose the use of a shell (with its need to quote arguments)."
;; because we inserted text.
(goto-char (prog1 (mark t)
(set-marker (mark-marker) (point)
(current-buffer)))))
(current-buffer))))
(shell-command-set-point-after-cmd))
;; Output goes in a separate buffer.
;; Preserve the match data in case called from a program.
;; FIXME: It'd be ridiculous for an Elisp function to call
@ -3708,7 +3733,7 @@ impose the use of a shell (with its need to quote arguments)."
(rename-uniquely))
(setq buffer (get-buffer-create bname)))))
(with-current-buffer buffer
(shell-command--save-pos-or-erase)
(shell-command-save-pos-or-erase)
(setq default-directory directory)
(let ((process-environment
(if (natnump async-shell-command-width)
@ -3814,7 +3839,7 @@ and are used only if a pop-up buffer is displayed."
;; `shell-command-dont-erase-buffer' is non-nil.
(defun shell-command-sentinel (process signal)
(when (memq (process-status process) '(exit signal))
(shell-command--set-point-after-cmd (process-buffer process))
(shell-command-set-point-after-cmd (process-buffer process))
(message "%s: %s."
(car (cdr (cdr (process-command process))))
(substring signal 0 -1))))
@ -3933,7 +3958,7 @@ interactively, this is t."
(set-buffer-major-mode buffer) ; Enable globalized modes (bug#38111)
(unwind-protect
(if (and (eq buffer (current-buffer))
(or (not shell-command-dont-erase-buffer)
(or (memq shell-command-dont-erase-buffer '(nil erase))
(and (not (eq buffer (get-buffer "*Shell Command Output*")))
(not (region-active-p)))))
;; If the input is the same buffer as the output,
@ -3956,7 +3981,7 @@ interactively, this is t."
(with-current-buffer buffer
(if (not output-buffer)
(setq default-directory directory))
(shell-command--save-pos-or-erase)))
(shell-command-save-pos-or-erase)))
(setq exit-status
(call-shell-region start end command nil
(if error-file
@ -3975,7 +4000,7 @@ interactively, this is t."
;; There's some output, display it
(progn
(display-message-or-buffer buffer)
(shell-command--set-point-after-cmd buffer))
(shell-command-set-point-after-cmd buffer))
;; No output; error?
(let ((output
(if (and error-file

View file

@ -520,12 +520,14 @@ the selected tab visible."
(add-face-text-property (point-min) (point-max) 'tab-line)
(if (> (vertical-motion 1) 0)
(let* ((point (previous-single-property-change (point) 'tab))
(tab-prop (or (get-pos-property point 'tab)
(get-pos-property
(previous-single-property-change point 'tab) 'tab)))
(new-hscroll (seq-position strings tab-prop
(lambda (str tab)
(eq (get-pos-property 1 'tab str) tab)))))
(tab-prop (when point
(or (get-pos-property point 'tab)
(and (setq point (previous-single-property-change point 'tab))
(get-pos-property point 'tab)))))
(new-hscroll (when tab-prop
(seq-position strings tab-prop
(lambda (str tab)
(eq (get-pos-property 1 'tab str) tab))))))
(when new-hscroll
(setq hscroll (- new-hscroll))
(set-window-parameter nil 'tab-line-hscroll hscroll)))
@ -545,12 +547,14 @@ the selected tab visible."
(add-face-text-property (point-min) (point-max) 'tab-line)
(when (> (vertical-motion 1) 0)
(let* ((point (previous-single-property-change (point) 'tab))
(tab-prop (or (get-pos-property point 'tab)
(get-pos-property
(previous-single-property-change point 'tab) 'tab)))
(new-hscroll (seq-position strings tab-prop
(lambda (str tab)
(eq (get-pos-property 1 'tab str) tab)))))
(tab-prop (when point
(or (get-pos-property point 'tab)
(and (setq point (previous-single-property-change point 'tab))
(get-pos-property point 'tab)))))
(new-hscroll (when tab-prop
(seq-position strings tab-prop
(lambda (str tab)
(eq (get-pos-property 1 'tab str) tab))))))
(when new-hscroll
(setq hscroll (- new-hscroll))
(set-window-parameter nil 'tab-line-hscroll hscroll)))))))))

View file

@ -34,7 +34,15 @@
(with-temp-buffer
(shell-mode)
(insert "cd ba;")
(forward-char -1)
(should (equal (shell--parse-pcomplete-arguments)
'(("cd" "ba" "") 1 4)))))
'(("cd" "ba") 1 4)))))
(ert-deftest shell-tests-completion-after-semi ()
(with-temp-buffer
(shell-mode)
(insert "cd ba;")
(should (equal (shell--parse-pcomplete-arguments)
'(("cd" "ba" "") 1 4 7)))))
;;; shell-tests.el ends here

View file

@ -711,5 +711,61 @@ See Bug#21722."
(when process (delete-process process))
(when buffer (kill-buffer buffer)))))))
;;; Tests for shell-command-dont-erase-buffer
(defmacro with-shell-command-dont-erase-buffer (str output-buffer-is-current &rest body)
(declare (debug (form &body)) (indent 2))
(let ((expected (make-symbol "expected"))
(command (make-symbol "command"))
(caller-buf (make-symbol "caller-buf"))
(output-buf (make-symbol "output-buf")))
`(let* ((,caller-buf (generate-new-buffer "caller-buf"))
(,output-buf (if ,output-buffer-is-current ,caller-buf
(generate-new-buffer "output-buf")))
(emacs (expand-file-name invocation-name invocation-directory))
(,command (format "%s -Q --batch --eval '(princ \"%s\")'"
emacs ,str))
(inhibit-message t))
(unwind-protect
;; Feature must work the same regardless how we specify the 2nd arg of `shell-command', ie,
;; as a buffer, buffer name (or t, if the output must go to the current buffer).
(dolist (output (append (list ,output-buf (buffer-name ,output-buf))
(if ,output-buffer-is-current '(t) nil)))
(dolist (save-pos '(erase nil beg-last-out end-last-out save-point))
(let ((shell-command-dont-erase-buffer save-pos))
(with-current-buffer ,output-buf (erase-buffer))
(with-current-buffer ,caller-buf
(dotimes (_ 2) (shell-command ,command output)))
(with-current-buffer ,output-buf
,@body))))
(kill-buffer ,caller-buf)
(when (buffer-live-p ,output-buf)
(kill-buffer ,output-buf))))))
(ert-deftest simple-tests-shell-command-39067 ()
"The output buffer is erased or not according to `shell-command-dont-erase-buffer'."
(let ((str "foo\n"))
(dolist (output-current '(t nil))
(with-shell-command-dont-erase-buffer str output-current
(let ((expected (cond ((eq shell-command-dont-erase-buffer 'erase) str)
((null shell-command-dont-erase-buffer)
(if output-current (concat str str)
str))
(t (concat str str)))))
(should (string= expected (buffer-string))))))))
(ert-deftest simple-tests-shell-command-dont-erase-buffer ()
"The point is set at the expected position after execution of the command."
(let* ((str "foo\n")
(expected-point `((beg-last-out . ,(1+ (length str)))
(end-last-out . ,(1+ (* 2 (length str))))
(save-point . 1))))
(dolist (output-buffer-is-current '(t ni))
(with-shell-command-dont-erase-buffer str output-buffer-is-current
(when (memq shell-command-dont-erase-buffer '(beg-last-out end-last-out save-point))
(should (= (point) (alist-get shell-command-dont-erase-buffer expected-point))))))))
(provide 'simple-test)
;;; simple-test.el ends here