commit cdd37ba4e853dcb31d8a85e12526b509720b37cd (HEAD, refs/remotes/origin/master) Author: Juri Linkov Date: Tue Apr 16 09:40:15 2024 +0300 Support prefix argument for switching tabs in tab-line-mode * lisp/tab-line.el (tab-line-select-tab-buffer): Optimize. (tab-line-switch-cycling): Enable by default like in tab-bar-mode. (tab-line-switch-to-prev-tab, tab-line-switch-to-next-tab): Add a prefix argument ARG and support it for switching tabs. Improve docstring. diff --git a/lisp/tab-line.el b/lisp/tab-line.el index 54e9ee16243..48272b7b4b3 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -843,29 +843,27 @@ using the `previous-buffer' command." (force-mode-line-update)))))))) (defun tab-line-select-tab-buffer (buffer &optional window) - (let* ((window-buffer (window-buffer window)) - (next-buffers (seq-remove (lambda (b) (eq b window-buffer)) - (window-next-buffers window))) - (prev-buffers (seq-remove (lambda (b) (eq b window-buffer)) - (mapcar #'car (window-prev-buffers window)))) - ;; Remove next-buffers from prev-buffers - (prev-buffers (seq-difference prev-buffers next-buffers))) - (cond - ((and (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) - (memq buffer next-buffers)) - (dotimes (_ (1+ (seq-position next-buffers buffer))) - (switch-to-next-buffer window))) - ((and (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) - (memq buffer prev-buffers)) - (dotimes (_ (1+ (seq-position prev-buffers buffer))) - (switch-to-prev-buffer window))) - (t - (with-selected-window window - (let ((switch-to-buffer-obey-display-actions nil)) - (switch-to-buffer buffer))))))) - -(defcustom tab-line-switch-cycling nil - "Enable cycling tab switch. + (if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) + (let* ((window-buffer (window-buffer window)) + (next-buffers (seq-remove (lambda (b) (eq b window-buffer)) + (window-next-buffers window))) + (prev-buffers (seq-remove (lambda (b) (eq b window-buffer)) + (mapcar #'car (window-prev-buffers window)))) + ;; Remove next-buffers from prev-buffers + (prev-buffers (seq-difference prev-buffers next-buffers))) + (cond + ((memq buffer next-buffers) + (dotimes (_ (1+ (seq-position next-buffers buffer))) + (switch-to-next-buffer window))) + ((memq buffer prev-buffers) + (dotimes (_ (1+ (seq-position prev-buffers buffer))) + (switch-to-prev-buffer window))))) + (with-selected-window window + (let ((switch-to-buffer-obey-display-actions nil)) + (switch-to-buffer buffer))))) + +(defcustom tab-line-switch-cycling t + "Wrap tabs on tab switch while cycling. If non-nil, `tab-line-switch-to-prev-tab' in the first tab switches to the last tab and `tab-line-switch-to-next-tab' in the last tab switches to the first tab. This variable is not consulted @@ -874,47 +872,62 @@ when `tab-line-tabs-function' is `tab-line-tabs-window-buffers'." :group 'tab-line :version "28.1") -(defun tab-line-switch-to-prev-tab (&optional event) - "Switch to the previous tab's buffer. -Its effect is the same as using the `previous-buffer' command -(\\[previous-buffer])." - (interactive (list last-nonmenu-event)) +(defun tab-line-switch-to-prev-tab (&optional event arg) + "Switch to the ARGth previous tab's buffer. +When `tab-line-tabs-function' is `tab-line-tabs-window-buffers', +its effect is the same as using the `previous-buffer' command +\(\\[previous-buffer]). +For other values of `tab-line-tabs-function' this command +switches to the previous buffer in the sequence defined by +`tab-line-tabs-function'. To wrap buffer cycling in this case +is possible when `tab-line-switch-cycling' is non-nil." + (interactive (list last-nonmenu-event + (prefix-numeric-value current-prefix-arg))) (let ((window (and (listp event) (posn-window (event-start event))))) - (if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) - (switch-to-prev-buffer window) - (with-selected-window (or window (selected-window)) + (with-selected-window (or window (selected-window)) + (if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) + (previous-buffer arg t) (let* ((buffers (seq-keep (lambda (tab) (or (and (bufferp tab) tab) (alist-get 'buffer tab))) (funcall tab-line-tabs-function))) - (pos (seq-position buffers (current-buffer))) - (buffer (when pos - (if (and tab-line-switch-cycling (<= pos 0)) - (nth (1- (length buffers)) buffers) - (nth (1- pos) buffers))))) + (old-pos (seq-position buffers (current-buffer))) + (new-pos (when old-pos (- old-pos (or arg 1)))) + (new-pos (when new-pos + (if tab-line-switch-cycling + (mod new-pos (length buffers)) + (max new-pos 0)))) + (buffer (when new-pos (nth new-pos buffers)))) (when (bufferp buffer) (let ((switch-to-buffer-obey-display-actions nil)) (switch-to-buffer buffer)))))))) -(defun tab-line-switch-to-next-tab (&optional event) - "Switch to the next tab's buffer. -Its effect is the same as using the `next-buffer' command -(\\[next-buffer])." - (interactive (list last-nonmenu-event)) +(defun tab-line-switch-to-next-tab (&optional event arg) + "Switch to the next ARGth tab's buffer. +When `tab-line-tabs-function' is `tab-line-tabs-window-buffers', +its effect is the same as using the `next-buffer' command +\(\\[next-buffer]). +For other values of `tab-line-tabs-function' this command +switches to the next buffer in the sequence defined by +`tab-line-tabs-function'. To wrap buffer cycling in this case +is possible when `tab-line-switch-cycling' is non-nil." + (interactive (list last-nonmenu-event + (prefix-numeric-value current-prefix-arg))) (let ((window (and (listp event) (posn-window (event-start event))))) - (if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) - (switch-to-next-buffer window) - (with-selected-window (or window (selected-window)) + (with-selected-window (or window (selected-window)) + (if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) + (next-buffer arg t) (let* ((buffers (seq-keep (lambda (tab) (or (and (bufferp tab) tab) (alist-get 'buffer tab))) (funcall tab-line-tabs-function))) - (pos (seq-position buffers (current-buffer))) - (buffer (when pos - (if (and tab-line-switch-cycling - (<= (length buffers) (1+ pos))) - (car buffers) - (nth (1+ pos) buffers))))) + (old-pos (seq-position buffers (current-buffer))) + (new-pos (when old-pos (+ old-pos (or arg 1)))) + (new-pos (when new-pos + (if tab-line-switch-cycling + (mod new-pos (length buffers)) + (min new-pos (1- (length buffers)))))) + (buffer (when new-pos (nth new-pos buffers)))) (when (bufferp buffer) (let ((switch-to-buffer-obey-display-actions nil)) (switch-to-buffer buffer)))))))) commit b33fb3b69cb9d4bce3a8cd12771649b3c3945fb0 Author: Noah Peart Date: Fri Apr 12 22:09:17 2024 -0700 Add font-locking for operators in go-ts-mode (bug#70361) * lisp/progmodes/go-ts-mode.el (go-ts-mode--font-lock-settings): Add font-locking rule for Go operators. diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index ad4b6baf205..b82bc2364dc 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -142,6 +142,10 @@ :feature 'delimiter '((["," "." ";" ":"]) @font-lock-delimiter-face) + :language 'go + :feature 'operator + `([,@go-ts-mode--operators] @font-lock-operator-face) + :language 'go :feature 'definition `((function_declaration commit 930c578c1042e6372e5433e31b2ea801315c01c9 Author: Eric Abrahamsen Date: Mon Apr 15 20:14:50 2024 -0700 ; Improvements to PEG documentation * doc/lispref/peg.texi: Make more use of defmac/defmacro, and try to clarify the relationships between the various macros and functions. * lisp/progmodes/peg.el (peg-parse): Remove claim that PEXS can also be a single list of rules. diff --git a/doc/lispref/peg.texi b/doc/lispref/peg.texi index fbf57852ee0..90aa76988db 100644 --- a/doc/lispref/peg.texi +++ b/doc/lispref/peg.texi @@ -1,78 +1,31 @@ -@c -*-texinfo-*- -@c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2023 Free Software -@c Foundation, Inc. -@c See the file elisp.texi for copying conditions. -@node Parsing Expression Grammars -@chapter Parsing Expression Grammars -@cindex text parsing -@cindex parsing expression grammar -@cindex PEG - - Emacs Lisp provides several tools for parsing and matching text, -from regular expressions (@pxref{Regular Expressions}) to full -left-to-right (a.k.a.@: @acronym{LL}) grammar parsers (@pxref{Top,, -Bovine parser development,bovine}). @dfn{Parsing Expression Grammars} -(@acronym{PEG}) are another approach to text parsing that offer more -structure and composibility than regular expressions, but less -complexity than context-free grammars. - -A Parsing Expression Grammar (@acronym{PEG}) describes a formal language -in terms of a set of rules for recognizing strings in the language. In -Emacs, a @acronym{PEG} parser is defined as a list of named rules, each -of which matches text patterns and/or contains references to other -rules. Parsing is initiated with the function @code{peg-run} or the -macro @code{peg-parse} (see below), and parses text after point in the -current buffer, using a given set of rules. - -@cindex parsing expression -@cindex root, of parsing expression grammar -@cindex entry-point, of parsing expression grammar -Each rule in a @acronym{PEG} is referred to as a @dfn{parsing -expression} (@acronym{PEX}), and can be specified a a literal string, a -regexp-like character range or set, a peg-specific construct resembling -an Emacs Lisp function call, a reference to another rule, or a -combination of any of these. A grammar is expressed as a tree of rules -in which one rule is typically treated as a ``root'' or ``entry-point'' -rule. For instance: - -@example -@group -((number sign digit (* digit)) - (sign (or "+" "-" "")) - (digit [0-9])) -@end group -@end example - -Once defined, grammars can be used to parse text after point in the -current buffer, in the following ways: - -@defmac peg-parse &rest pexs -Match @var{pexs} at point. If @var{pexs} is a list of PEG rules, the -first rule is considered the ``entry-point'': +struct makes a set of rules available within its +body. The actual parsing is initiated with @code{peg-run}: + +@defun peg-run peg-matcher &optional failure-function success-function +This function accepts a single @var{peg-matcher}, which is the result of +calling @code{peg} (see below) on a named rule, usually the entry-point +of a larger grammar. + +At the end of parsing, one of @var{failure-function} or +@var{success-function} is called, depending on whether the parsing +succeeded or not. If @var{success-function} is called, it is passed a +lambda form that runs all the actions collected on the stack during +parsing -- by default this lambda form is simply executed. If parsing +fails, the @var{failure-function} is called with a list of @acronym{PEG} +expressions that failed during parsing; by default this list is +discarded. +@end defun + +The @var{peg-matcher} passed to @code{peg-run} is produced by a call to +@code{peg}: + +@defmac peg &rest pexs +Convert @var{pexs} into a single peg-matcher suitable for passing to +@code{peg-run}. @end defmac -@example -@group -(peg-parse - ((number sign digit (* digit)) - (sign (or "+" "-" "")) - (digit [0-9]))) -@end group -@end example - -@c FIXME: These two should be formally defined using @defmac and @defun. -@findex with-peg-rules -@findex peg-run -The @code{peg-parse} macro represents the simplest use of the -@acronym{PEG} library, but also the least flexible, as the rules must be -written directly into the source code. A more flexible approach -involves use of three macros in conjunction: @code{with-peg-rules}, a -@code{let}-like construct that makes a set of rules available within the -macro body; @code{peg-run}, which initiates parsing given a single rule; -and @code{peg}, which is used to wrap the entry-point rule name. In -fact, a call to @code{peg-parse} expands to just this set of calls. The -above example could be written as: +The @code{peg-parse} example above expands to just this set of calls, +and could be written as: @example @group @@ -84,14 +37,19 @@ above example could be written as: @end group @end example -This allows more explicit control over the ``entry-point'' of parsing, -and allows the combination of rules from different sources. +This approach allows more explicit control over the ``entry-point'' of +parsing, and allows the combination of rules from different sources. -@c FIXME: Use @defmac. -@findex define-peg-rule Individual rules can also be defined using a more @code{defun}-like syntax, using the macro @code{define-peg-rule}: +@defmac define-peg-rule name args &rest pexs +Define @var{name} as a PEG rule that accepts @var{args} and matches +@var{pexs} at point. +@end defmac + +For instance: + @example @group (define-peg-rule digit () @@ -99,14 +57,16 @@ syntax, using the macro @code{define-peg-rule}: @end group @end example -This also allows for rules that accept an argument (supplied by the -@code{funcall} PEG rule, @pxref{PEX Definitions}). +Arguments can be supplied to rules by the @code{funcall} PEG rule +(@pxref{PEX Definitions}). -@c FIXME: Use @defmac. -@findex define-peg-ruleset Another possibility is to define a named set of rules with @code{define-peg-ruleset}: +@defmac define-peg-ruleset name &rest rules +Define @var{name} as an identifier for @var{rules}. +@end defmac + @example @group (define-peg-ruleset number-grammar @@ -240,10 +200,10 @@ Returns non-@code{nil} if parsing @acronym{PEX} @var{e} from point fails Treats the value of the Lisp expression @var{exp} as a boolean. @end table -@c FIXME: peg-char-classes should be mentioned in the text below. @vindex peg-char-classes -Character class matching can use the same named character classes as -in regular expressions (@pxref{Top,, Character Classes,elisp}) +Character-class matching can refer to the classes named in +@code{peg-char-classes}, equivalent to character classes in regular +expressions (@pxref{Top,, Character Classes,elisp}) @node Parsing Actions @section Parsing Actions diff --git a/lisp/progmodes/peg.el b/lisp/progmodes/peg.el index bb57650d883..938f8da910d 100644 --- a/lisp/progmodes/peg.el +++ b/lisp/progmodes/peg.el @@ -316,13 +316,14 @@ EXPS is a list of rules/expressions that failed.") "Match PEXS at point. PEXS is a sequence of PEG expressions, implicitly combined with `and'. Returns STACK if the match succeed and signals an error on failure, -moving point along the way. -PEXS can also be a list of PEG rules, in which case the first rule is used." +moving point along the way." (if (and (consp (car pexs)) (symbolp (caar pexs)) (not (ignore-errors (not (eq 'call (car (peg-normalize (car pexs)))))))) - ;; `pexs' is a list of rules: use the first rule as entry point. + ;; The first of `pexs' has not been defined as a rule, so assume + ;; that none of them have been and they should be fed to + ;; `with-peg-rules' `(with-peg-rules ,pexs (peg-run (peg ,(caar pexs)) #'peg-signal-failure)) `(peg-run (peg ,@pexs) #'peg-signal-failure))) commit 98b90fc853f05e3d94545c48851e59ace33b50cb Author: Basil L. Contovounesios Date: Mon Apr 15 23:56:00 2024 +0200 ; Fix last change to secrets-tests.el. diff --git a/test/lisp/net/secrets-tests.el b/test/lisp/net/secrets-tests.el index 1d9c1446e26..b7dd0b8f7ef 100644 --- a/test/lisp/net/secrets-tests.el +++ b/test/lisp/net/secrets-tests.el @@ -175,7 +175,7 @@ ;; Create another item with a non-latin password. (Bug#70301) (should (secrets-create-item "session" "parola" "парола")) - (string-equal (secrets-get-secret "session" "parola") "парола") + (should (string-equal (secrets-get-secret "session" "parola") "парола")) ;; Create an item with attributes. (should commit 3ac1a7b6fe6d324339ca5c36ffdce3985f6c55a1 Author: Stefan Monnier Date: Mon Apr 15 16:06:54 2024 -0400 (track-changes-fetch): Fix nested use case * lisp/emacs-lisp/track-changes.el (track-changes-fetch): Don't presume that if there's nothing to do we're on `track-changes--clean-trackers`. diff --git a/lisp/emacs-lisp/track-changes.el b/lisp/emacs-lisp/track-changes.el index df4aad0d596..9e62b8bdf30 100644 --- a/lisp/emacs-lisp/track-changes.el +++ b/lisp/emacs-lisp/track-changes.el @@ -335,23 +335,27 @@ and re-enable the TRACKER corresponding to ID." (substring before (- (length before) (- endb prevend))))) (setq lenbefore (length before))))))) - (if (null beg) - (progn - (cl-assert (null states)) - (cl-assert (memq id track-changes--clean-trackers)) - (cl-assert (eq (track-changes--tracker-state id) - track-changes--state)) - ;; Nothing to do. - nil) - (cl-assert (not (memq id track-changes--clean-trackers))) - (cl-assert (<= (point-min) beg end (point-max))) - ;; Update the tracker's state *before* running `func' so we don't risk - ;; mistakenly replaying the changes in case `func' exits non-locally. - (setf (track-changes--tracker-state id) track-changes--state) - (unwind-protect (funcall func beg end (or before lenbefore)) - ;; Re-enable the tracker's signal only after running `func', so - ;; as to avoid recursive invocations. - (cl-pushnew id track-changes--clean-trackers))))) + (unwind-protect + (if (null beg) + (progn + (cl-assert (null states)) + ;; We may have been called in the middle of another + ;; `track-changes-fetch', in which case we may be in a clean + ;; state but not yet on `track-changes--clean-trackers' + ;;(cl-assert (memq id track-changes--clean-trackers)) + (cl-assert (eq (track-changes--tracker-state id) + track-changes--state)) + ;; Nothing to do. + nil) + (cl-assert (not (memq id track-changes--clean-trackers))) + (cl-assert (<= (point-min) beg end (point-max))) + ;; Update the tracker's state *before* running `func' so we don't risk + ;; mistakenly replaying the changes in case `func' exits non-locally. + (setf (track-changes--tracker-state id) track-changes--state) + (funcall func beg end (or before lenbefore))) + ;; Re-enable the tracker's signal only after running `func', so + ;; as to avoid recursive invocations. + (cl-pushnew id track-changes--clean-trackers)))) ;;;; Auxiliary functions. commit 5fda398fb3bbda43dab37a0c187c90ad4bc4d1b0 Author: Stefan Monnier Date: Mon Apr 15 15:53:48 2024 -0400 (track-changes--before): Fix bug#70396 * lisp/emacs-lisp/track-changes.el (track-changes--before): Widen the buffer before accessing it with positions potentially outside the beg..end region. diff --git a/lisp/emacs-lisp/track-changes.el b/lisp/emacs-lisp/track-changes.el index 1bab7ca38fd..df4aad0d596 100644 --- a/lisp/emacs-lisp/track-changes.el +++ b/lisp/emacs-lisp/track-changes.el @@ -481,42 +481,42 @@ Details logged to `track-changes--error-log'") (funcall signal-if-disjoint end track-changes--before-beg) (funcall signal-if-disjoint track-changes--before-end beg))) (funcall reset)) - (cl-assert (save-restriction - (widen) - (<= (point-min) + (save-restriction + (widen) + (cl-assert (<= (point-min) track-changes--before-beg track-changes--before-end - (point-max)))) - (when (< beg track-changes--before-beg) - (if (and track-changes--disjoint-trackers - (funcall signal-if-disjoint end track-changes--before-beg)) - (funcall reset) - (let* ((old-bbeg track-changes--before-beg) - ;; To avoid O(N²) behavior when faced with many small changes, - ;; we copy more than needed. - (new-bbeg (min (max (point-min) - (- old-bbeg - (length track-changes--before-string))) - beg))) - (setf track-changes--before-beg new-bbeg) - (cl-callf (lambda (old new) (concat new old)) - track-changes--before-string - (buffer-substring-no-properties new-bbeg old-bbeg))))) - - (when (< track-changes--before-end end) - (if (and track-changes--disjoint-trackers - (funcall signal-if-disjoint track-changes--before-end beg)) - (funcall reset) - (let* ((old-bend track-changes--before-end) - ;; To avoid O(N²) behavior when faced with many small changes, - ;; we copy more than needed. - (new-bend (max (min (point-max) - (+ old-bend - (length track-changes--before-string))) - end))) - (setf track-changes--before-end new-bend) - (cl-callf concat track-changes--before-string - (buffer-substring-no-properties old-bend new-bend)))))))) + (point-max))) + (when (< beg track-changes--before-beg) + (if (and track-changes--disjoint-trackers + (funcall signal-if-disjoint end track-changes--before-beg)) + (funcall reset) + (let* ((old-bbeg track-changes--before-beg) + ;; To avoid O(N²) behavior when faced with many small + ;; changes, we copy more than needed. + (new-bbeg + (min beg (max (point-min) + (- old-bbeg + (length track-changes--before-string)))))) + (setf track-changes--before-beg new-bbeg) + (cl-callf (lambda (old new) (concat new old)) + track-changes--before-string + (buffer-substring-no-properties new-bbeg old-bbeg))))) + + (when (< track-changes--before-end end) + (if (and track-changes--disjoint-trackers + (funcall signal-if-disjoint track-changes--before-end beg)) + (funcall reset) + (let* ((old-bend track-changes--before-end) + ;; To avoid O(N²) behavior when faced with many small + ;; changes, we copy more than needed. + (new-bend + (max end (min (point-max) + (+ old-bend + (length track-changes--before-string)))))) + (setf track-changes--before-end new-bend) + (cl-callf concat track-changes--before-string + (buffer-substring-no-properties old-bend new-bend))))))))) (defun track-changes--after (beg end len) (cl-assert track-changes--state) commit 9b755244bf0b9cd5f820ae45a4db14913a587c7b Author: Eli Zaretskii Date: Mon Apr 15 16:50:59 2024 +0300 Fix resetting the frame's 'frozen_window_starts' flag * src/window.c (grow_mini_window, shrink_mini_window): Reimplement how the frame's 'frozen_window_starts' flag is set and reset, to make sure it is always reset when the mini-window gets to its normal one-line height. Patch by Martin Rudalics (Bug#70038) diff --git a/src/window.c b/src/window.c index fe26311fbb2..6c0fce4119f 100644 --- a/src/window.c +++ b/src/window.c @@ -5376,7 +5376,6 @@ grow_mini_window (struct window *w, int delta) struct window *r = XWINDOW (root); Lisp_Object grow; - FRAME_WINDOWS_FROZEN (f) = true; grow = call3 (Qwindow__resize_root_window_vertically, root, make_fixnum (- delta), Qt); @@ -5390,6 +5389,8 @@ grow_mini_window (struct window *w, int delta) && window_resize_check (r, false)) resize_mini_window_apply (w, -XFIXNUM (grow)); } + FRAME_WINDOWS_FROZEN (f) + = window_body_height (w, WINDOW_BODY_IN_PIXELS) > FRAME_LINE_HEIGHT (f); } /** @@ -5413,7 +5414,6 @@ shrink_mini_window (struct window *w) struct window *r = XWINDOW (root); Lisp_Object grow; - FRAME_WINDOWS_FROZEN (f) = false; grow = call3 (Qwindow__resize_root_window_vertically, root, make_fixnum (delta), Qt); @@ -5425,6 +5425,8 @@ shrink_mini_window (struct window *w) bar. */ grow_mini_window (w, -delta); + FRAME_WINDOWS_FROZEN (f) + = window_body_height (w, WINDOW_BODY_IN_PIXELS) > FRAME_LINE_HEIGHT (f); } DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, commit a80a5d42d3a5f095c9d52ef5f5fe18d2e500d875 Author: Eli Zaretskii Date: Mon Apr 15 15:47:39 2024 +0300 Fix display of @xref documentation in Info * lisp/info.el (Info--dont-hide-references): New variable. (Info-fontify-node): Use 'Info--dont-hide-references' to disable hiding "*Note" or showing "See" instead of it in select nodes. (Bug#70382) diff --git a/lisp/info.el b/lisp/info.el index b459406959e..b1b9d48855a 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -4876,6 +4876,19 @@ first line or header line, and for breadcrumb links.") ;; 'font-lock-face 'header-line line) line)) +(defvar Info--dont-hide-references + '(("texinfo" "Cross Reference Commands")) + "Manuals and nodes where `Info-hide-note-references' should be ignored. +This is an alist whose elements should be of the form + + (MANUAL NODE...) + +where MANUAL is the basename of an Info manual's main file, and NODEs +are one or more nodes in MANUAL where info.el should not hide +cross-references even in `Info-hide-note-references' is non-nil. +This is because some rare nodes describe how cross-references work, +and so should be rendered as makeinfo produced them.") + (defun Info-fontify-node () "Fontify the node." (save-excursion @@ -4893,6 +4906,16 @@ first line or header line, and for breadcrumb links.") (or (eq Info-fontify-maximum-menu-size t) (< (- (point-max) (point-min)) Info-fontify-maximum-menu-size)))) + ;; Disable Info-hide-note-references in nodes that are + ;; incompatible with that feature. + (Info-hide-note-references + (if (member Info-current-node + (assoc-string + (file-name-sans-extension + (file-name-nondirectory Info-current-file)) + Info--dont-hide-references)) + nil + Info-hide-note-references)) rbeg rend) ;; Fontify header line commit deef12c15d8c9444a583fffa9254cc4fc44ebfa3 Author: Po Lu Date: Mon Apr 15 19:54:20 2024 +0800 Rewrite Android description of Android window management * doc/emacs/android.texi (Android Environment): Rewrite several paragraphs to better reflect recent changes and emphasize behavior on modern OS releases. diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi index 3f784bc9637..15c5fbcce3a 100644 --- a/doc/emacs/android.texi +++ b/doc/emacs/android.texi @@ -823,69 +823,73 @@ example, the permission to access contacts may be useful for EUDC. @node Android Windowing @section The Android Window System - Android's window system is unusual, in that all windows are -maximized or full-screen, and only one window can be displayed at a -time. On larger devices, the system permits simultaneously tiling up -to four windows on the screen. - - Windows on Android do not exist indefinitely after they are created. -Instead, the system may choose to close windows that are not on screen -in order to conserve memory, with the assumption that the program will -save its contents to disk and restore them later, when the user asks -for it to be opened again. As this is obviously not possible with -Emacs, Emacs separates the resources associated with a frame from its -system window. - - Each system window created (including the initial window created -during Emacs startup) is appended to a list of windows that do not -have associated frames. When a frame is created, Emacs looks up any -window within that list, and displays the contents of the frame -within; if there is no window at all, then one is created. Likewise, -when a new window is created by the system, Emacs places the contents -of any frame that is not already displayed within a window inside. -When a frame is closed, the corresponding system window is also -closed. Upon startup, the system creates a window itself (within -which Emacs displays the first window system frame shortly -thereafter.) Emacs differentiates between that window and windows -created on behalf of other frames to determine what to do when the -system window associated with a frame is closed: + Android's window system is unusual in that all windows are reported to +applications as maximized or full-screen, and, in the general case, only +one window can be displayed at a time. On larger devices, the system +permits simultaneously tiling up to four windows on the screen, though +in emulators or installations configured for ``desktop'' system stacks +freely resizable windows as other desktop window managers do. + + Windows, or, in system nomenclature, activities, do not exist +indefinitely after creation, as the system may choose to pause windows +that are not visible in order to conserve memory, on the assumption that +the program will save its contents to disk, to be restored when the user +selects those windows from the task switcher. Furthermore, a window is +created by the operating system at Emacs startup that is afforded +special treatment, which Emacs is expected to adopt. + + Emacs approaches window management with the general objective of +minimizing differences in frame behavior exposed to Lisp from that of +frames on ordinary window systems, such as X Windows; the degree to +which this goal is actually attained varies by the availability of +facilities for window management in the version of Android where it is +installed, and operating system policy towards inactive windows. When +it is unavoidable that concessions should be made to such policy, Emacs +prefers destroying frames to retaining ones with no activities to +display them, unless such a frame is the initial frame and therefore +displayed in the activity created at startup, which it is possible to +open and identify so long as Emacs is yet executing. + +@cindex frames and windows, Android 5.0 + Android 5.0 and later support an accurate implementation of window +management where frames hold a one-to-one relation to the activities in +which they are displayed, enabling deletion of activities in the task +switcher to directly affect the frames concerned, and vice versa. There +are just two exceptions: @itemize @bullet @item -When the system closes the window created during application startup -in order to save memory, Emacs retains the frame for when that window -is created later. - -@item -When the user closes the window created during application startup, -and the window was not previously closed by the system in order to -save resources, Emacs deletes any frame displayed within that window. - -However, on Android 7.0 and later, such frames are not deleted if the -window is closed four or more hours after the window moves into the -background, as the system automatically removes open windows once a -certain period of inactivity elapses when the number of windows retained -by the window manager surpasses a specific threshold, and window -deletion by this mechanism is indistinguishable from window deletion by -the user. Emacs begins to ignore window deletion after two hours less -than the default value of this threshold both to err on the side of -caution, in case the system's record of inactivity and Emacs's disagree, -and for the reason that this threshold is open to customization by OS -distributors. - -@item -When the user or the system closes any window created by Emacs on behalf -of a specific frame, Emacs deletes the frame displayed within that -window, unless the system is Android 5.0 or later, where such windows -are treated identically to the window created at startup, albeit with no -proviso regarding window inactivity. +After the system pauses an activity that remains in the task switcher in +response to inactivity, removing it from the task switcher while it +remains in its inactive state will not delete the frame inside, as Emacs +is not notified of the deletion of its activities in such circumstances. +The frame will be deleted upon the next window management operation that +prompts an examination of the list of live windows. Likewise, an +inactive activity displaying a frame will not be immediately deleted +with its frame, but will be if it is selected from the window list or +upon another examination of the window list. + +@item +Any frame besides the initial frame might be deleted after 4 to 6 hours +of inactivity in the background, if it is removed by the system in +``trimming'' the task switcher of excess, and presumably unwanted, +tasks; the initial frame is exempt from this treatment because it can be +reopened otherwise than from the task switcher, but as deletion by this +mechanism is indistinguishable from legitimate user action to remove +activities from the task switcher, the latter will also be ignored by +the initial frame after a 4-hour interval elapses from the time of last +activity. @end itemize - When the system predates Android 5.0, the window manager will not -accept more than one user-created Emacs window. If frame creation gives -rise to windows in excess of this limit, the window manager will -arbitrarily select one of their number to display, with the rest -remaining invisible until that window is destroyed with its frame. +@cindex frames and windows, Android 4.4 +@cindex frames and windows, Android 2.2 + Android 4.4 and earlier provide considerably inferior interfaces +inadequate for a complete implementation of window management. On such +systems, Emacs substitutes a fairly primitive mechanism where all but +the initial frame are deleted when their activities are paused, only a +single activity (not counting the activity created at startup) is +visible at a time, and unattached frames are displayed in the first +unoccupied activity available. @cindex windowing limitations, android @cindex frame parameters, android commit 9a79db506e39c02daa81629f0b224a86fad2b3c6 Author: Martin Rudalics Date: Mon Apr 15 11:17:51 2024 +0200 Make 'buffer-last-name' work better after 'find-alternate-file' (Bug#68235) * lisp/files.el (find-alternate-file): Before killing the previous buffer, try to restore its name and filenames (Bug#68235). diff --git a/lisp/files.el b/lisp/files.el index 20d63d33fef..1e11dd44bad 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2113,6 +2113,15 @@ killed." (rename-buffer oname))) (unless (eq (current-buffer) obuf) (with-current-buffer obuf + (unless (get-buffer oname) + ;; Restore original's buffer name so 'kill-buffer' can use it + ;; to assign its last name (Bug#68235). + (rename-buffer oname)) + ;; Restore original buffer's file names so they can be still + ;; used when referencing the now defunct buffer (Bug#68235). + (setq buffer-file-name ofile) + (setq buffer-file-number onum) + (setq buffer-file-truename otrue) ;; We already ran these; don't run them again. (let (kill-buffer-query-functions kill-buffer-hook) (kill-buffer obuf))))))