diff options
42 files changed, 913 insertions, 514 deletions
diff --git a/admin/git-bisect-start b/admin/git-bisect-start index a439ee7fe15..65bfffc0ad6 100755 --- a/admin/git-bisect-start +++ b/admin/git-bisect-start @@ -82,7 +82,7 @@ done # SKIP-BRANCH 58cc931e92ece70c3e64131ee12a799d65409100 ## The list below is the exhaustive list of all commits between Dec 1 -## 2016 and Dec 31 2022 on which building Emacs with the default +## 2016 and Jan 31 2023 on which building Emacs with the default ## options, on a GNU/Linux computer and with GCC, fails. It is ## possible (though unlikely) that building Emacs with non-default ## options, with other compilers, or on other platforms, would succeed @@ -1674,3 +1674,36 @@ $REAL_GIT bisect skip $(cat $0 | grep '^# SKIP-SINGLE ' | sed 's/^# SKIP-SINGLE # SKIP-SINGLE 8c13e8497821881b5197a1717e9e53b9991859d0 # SKIP-SINGLE a6db8464e150c49724c71c5969b97f205ee2dec5 # SKIP-SINGLE cfbfd393b450d4eb7ac0b7922b44208688553c9e +# SKIP-SINGLE 382e018856a884a96a94ad551dbc1d7b0317b2e5 +# SKIP-SINGLE 8360e12f0ea3a3ccf0305adab3c7ea7e38af36c1 +# SKIP-SINGLE 56e8607dc99b90c43f82001cbf073e58a4698298 +# SKIP-SINGLE 956889d8ff1c79db45ca9b1711f406961e71c272 +# SKIP-SINGLE e2e937300f5a68ce1e2a349a583859a29394ac5f +# SKIP-SINGLE 176830fe2bb1c80ee128e515f6223cddc8b0a2ca +# SKIP-SINGLE 3f069bd796b0024033640051b5f74ba9834985f8 +# SKIP-SINGLE 435ba92ccc4c46914c261de57f71ac6d92c20178 +# SKIP-SINGLE ad6d8f7df180a9563d3f064f29c6366f114b8de0 +# SKIP-SINGLE 8d7ad65665833ae99b7e7119dae37afa438968a4 +# SKIP-SINGLE 10032f424ccf611783f5b92742e91e70595587c4 +# SKIP-SINGLE 4b1714571c8c6cf7ae2ee2602c66b7c903c45a4a +# SKIP-SINGLE f27a330b99eebbe7f4690163358b4cacbd4e17a1 +# SKIP-SINGLE b73539832d9c4e802925cb8f261a13473da383b3 +# SKIP-SINGLE f50cb7d7c4b37cd8e4bb1ffa5d3f9273c7e19e10 +# SKIP-SINGLE 96015c9c8cc1720e8ee7cd9cea4de48126dd9122 +# SKIP-SINGLE 2bd0b9475384adfb4dd2cc794bbe1d8621546717 +# SKIP-SINGLE d9a2673ee95cf7172a622dc0229ddf72aec8e8c1 +# SKIP-SINGLE 0116e27b26cb4a98f2de8dca12d8e9d90d222992 +# SKIP-SINGLE 96601cd90ba1b8a650d0e41dad2a58cb9e270f1b +# SKIP-SINGLE 99e40959f4036debe099f144ed2664a38e23563d +# SKIP-SINGLE 207a0d9408cb97b9ae78469e2487e3075ade03f8 +# SKIP-SINGLE 64fee21d5f85db465198970a4d636cb17d500f26 +# SKIP-SINGLE 48bd17923a98f49a30bdce2f3a52e03fe45d63f0 +# SKIP-SINGLE 9058601308db4892fbc3e599b83fe4326fef9886 +# SKIP-SINGLE a3003492ace0571e5179500b42bbe44cb9763dbb +# SKIP-SINGLE 197f994384cb37ae4ae7a771815bbe565d4ae242 +# SKIP-SINGLE 1970726e26a979243925fabe32686ba2ee757c6b +# SKIP-SINGLE 1de6ebf2878485a0ef6b778df7d6a14d5b22a01c +# SKIP-SINGLE 013ab7e2a83afa7fb577c356ae686439a2906f34 +# SKIP-SINGLE 1c3ca3bb649b7e812a84b4a559463462d4357080 +# SKIP-SINGLE 48ed4228a75907ae1bb7a2d4314ffb3277c75e3a +# SKIP-SINGLE b9025c507a3a7dae4de19b18cafaa09b18183832 diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index e9268ff2a0d..69b4f56bee1 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -540,15 +540,18 @@ declaration (@code{c-indent-defun} in CC mode, @kindex C-M-q @r{(C mode)} @findex c-indent-exp @findex prog-indent-sexp -Reindent each line in the balanced expression that follows point. In -CC mode, this invokes @code{c-indent-exp}; in tree-sitter based -@code{c-ts-mode} this invokes a more general @code{prog-indent-sexp}. -A prefix argument inhibits warning messages about invalid syntax. +Reindent each line in the balanced expression (@pxref{Expressions}), +also known as ``sexp'', that follows point. In CC mode, this invokes +@code{c-indent-exp}; in tree-sitter based @code{c-ts-mode} this +invokes a more general @code{prog-indent-sexp}. A prefix argument +inhibits warning messages about invalid syntax. @item @key{TAB} @findex c-indent-line-or-region Reindent the current line, active region, or block starting on this -line (@code{c-indent-line-or-region}). +line (@code{c-indent-line-or-region}). With prefix argument, rigidly +reindent the balanced expression which starts on the current line, if +the current line needs reindentation. @vindex c-tab-always-indent If @code{c-tab-always-indent} is @code{t}, this command always reindents diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index dc78adc4520..6fd9377e1de 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -99,6 +99,12 @@ is removed from the hook. emacs, The GNU Emacs Manual}) runs these two hooks just as a keyboard command does. + Note that, when the buffer text includes very long lines, these two +hooks are called as if they were in a @code{with-restriction} form +(@pxref{Narrowing}), with a +@code{long-line-optimizations-in-command-hooks} label and with the +buffer narrowed to a portion around point. + @node Defining Commands @section Defining Commands @cindex defining commands diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index c5374e1481a..a8311f5c9a2 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -3501,11 +3501,11 @@ function finishes are the ones that really matter. For efficiency, we recommend writing these functions so that they usually assign faces to around 400 to 600 characters at each call. -When the buffer text includes very long lines, these functions are -called with the buffer narrowed to a relatively small region around -@var{pos}, and with narrowing locked, so the functions cannot use -@code{widen} to gain access to the rest of the buffer. -@xref{Narrowing}. +Note that, when the buffer text includes very long lines, these +functions are called as if they were in a @code{with-restriction} form +(@pxref{Narrowing}), with a +@code{long-line-optimizations-in-fontification-functions} label and +with the buffer narrowed to a portion around @var{pos}. @end defvar @node Basic Faces diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 68f31e500bb..638b759ff13 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -1474,19 +1474,24 @@ in this frame. Its value is @code{color}, @code{grayscale} or @vindex title@r{, a frame parameter} @item title -If a frame has a non-@code{nil} title, it appears in the window +If a frame has a non-@code{nil} title, that title appears in the window system's title bar at the top of the frame, and also in the mode line of windows in that frame if @code{mode-line-frame-identification} uses @samp{%F} (@pxref{%-Constructs}). This is normally the case when Emacs is not using a window system, and can only display one frame at -a time. @xref{Frame Titles}. +a time. When Emacs is using a window system, this parameter, if +non-@code{nil}, overrides the title determined by the @code{name} +parameter and the implicit title calculated according to +@code{frame-title-format}. It also overrides the title determined by +@code{icon-title-format} for iconified frames. @xref{Frame Titles}. @vindex name@r{, a frame parameter} @item name -The name of the frame. The frame name serves as a default for the frame -title, if the @code{title} parameter is unspecified or @code{nil}. If -you don't specify a name, Emacs sets the frame name automatically -(@pxref{Frame Titles}). +The name of the frame. If you don't specify a name via this +parameter, Emacs sets the frame name automatically, as specified by +@code{frame-title-format} and @code{icon-title-format}, and that is +the frame's title that will appear on display when Emacs uses a window +system (unless the @code{title} parameter overrides it). If you specify the frame name explicitly when you create the frame, the name is also used (instead of the name of the Emacs executable) when @@ -2630,17 +2635,26 @@ frame name automatically based on a template stored in the variable frame is redisplayed. @defvar frame-title-format -This variable specifies how to compute a name for a frame when you have -not explicitly specified one. The variable's value is actually a mode +This variable specifies how to compute a name for a frame when you +have not explicitly specified one (via the frame's parameters; +@pxref{Basic Parameters}). The variable's value is actually a mode line construct, just like @code{mode-line-format}, except that the -@samp{%c}, @samp{%C}, and @samp{%l} constructs are ignored. @xref{Mode Line -Data}. +@samp{%c}, @samp{%C}, and @samp{%l} constructs are ignored. +@xref{Mode Line Data}. @end defvar @defvar icon-title-format -This variable specifies how to compute the name for an iconified frame, -when you have not explicitly specified the frame title. This title -appears in the icon itself. +This variable specifies how to compute the name for an iconified frame +when you have not explicitly specified the frame's name via the +frame's parameters. The resulting title appears in the frame's icon +itself. If the value is a string, is should be a mode line construct +like that of @code{frame-title-format}. The value can also be +@code{t}, which means to use @code{frame-title-format} instead; this +avoids problems with some window managers and desktop environments, +where a change in a frame's title (when a frame is iconified) is +interpreted as a request to raise the frame and/or give it input +focus. The default is a string identical to the default value of +@code{frame-title-format}. @end defvar @defvar multiple-frames diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index f3824436246..1b32f18922c 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -1037,11 +1037,13 @@ positions. In an interactive call, @var{start} and @var{end} are set to the bounds of the current region (point and the mark, with the smallest first). -Note that, in rare circumstances, Emacs may decide to leave, for -performance reasons, the accessible portion of the buffer unchanged -after a call to @code{narrow-to-region}. This can happen when a Lisp -program is called via low-level hooks, such as -@code{jit-lock-functions}, @code{post-command-hook}, etc. +However, when the narrowing has been set by @code{with-restriction} with +a label argument (see below), @code{narrow-to-region} can be used only +within the limits of that narrowing. If @var{start} or @var{end} are +outside these limits, the corresponding limit set by +@code{with-restriction} is used instead. To gain access to other +portions of the buffer, use @code{without-restriction} with the same +label. @end deffn @deffn Command narrow-to-page &optional move-count @@ -1065,13 +1067,13 @@ It is equivalent to the following expression: @example (narrow-to-region 1 (1+ (buffer-size))) @end example -@end deffn -Note that, in rare circumstances, Emacs may decide to leave, for -performance reasons, the accessible portion of the buffer unchanged -after a call to @code{widen}. This can happen when a Lisp program is -called via low-level hooks, such as @code{jit-lock-functions}, -@code{post-command-hook}, etc. +However, when a narrowing has been set by @code{with-restriction} with a +label argument (see below), the limits set by @code{with-restriction} +are restored, instead of canceling the narrowing. To gain access to +other portions of the buffer, use @code{without-restriction} with the +same label. +@end deffn @defun buffer-narrowed-p This function returns non-@code{nil} if the buffer is narrowed, and @@ -1086,6 +1088,9 @@ in effect. The state of narrowing is restored even in the event of an abnormal exit via @code{throw} or error (@pxref{Nonlocal Exits}). Therefore, this construct is a clean way to narrow a buffer temporarily. +This construct also saves and restores the narrowings that were set by +@code{with-restriction} with a label argument (see below). + The value returned by @code{save-restriction} is that returned by the last form in @var{body}, or @code{nil} if no body forms were given. @@ -1135,3 +1140,64 @@ This is the contents of foo@point{} @end group @end example @end defspec + +@defspec with-restriction start end [:label label] body +This special form saves the current bounds of the accessible portion +of the buffer, sets the accessible portion to start at @var{start} and +end at @var{end}, evaluates the @var{body} forms, and restores the +saved bounds. In that case it is equivalent to + +@example +(save-restriction + (narrow-to-region start end) + body) +@end example + +@cindex labeled narrowing +When the optional argument @var{label}, a symbol, is present, the +narrowing is @dfn{labeled}. A labeled narrowing differs from a +non-labeled one in several ways: + +@itemize @bullet +@item +During the evaluation of the @var{body} form, @code{narrow-to-region} +and @code{widen} can be used only within the @var{start} and @var{end} +limits. + +@item +To lift the restriction introduced by @code{with-restriction} and gain +access to other portions of the buffer, use @code{without-restriction} +with the same @var{label} argument. (Another way to gain access to +other portions of the buffer is to use an indirect buffer +(@pxref{Indirect Buffers}).) + +@item +Labeled narrowings can be nested. + +@item +Labeled narrowings can only be used in Lisp programs: they are never +visible on display, and never interfere with narrowings set by the +user. +@end itemize + +If you use @code{with-restriction} with the optional @var{label} +argument, we recommend documenting the @var{label} in the doc strings +of the functions which use it, so that other Lisp programs your code +calls could lift the labeled narrowing if and when it needs. +@end defspec + +@defspec without-restriction [:label label] body +This special form saves the current bounds of the accessible portion +of the buffer, widens the buffer, evaluates the @var{body} forms, and +restores the saved bounds. In that case it is equivalent to + +@example +(save-restriction + (widen) + body) +@end example + +When the optional argument @var{label} is present, the narrowing set +by @code{with-restriction} with the same @var{label} argument is +lifted. +@end defspec diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi index 8030dfa4bb7..d5ec0f48e1c 100644 --- a/doc/misc/erc.texi +++ b/doc/misc/erc.texi @@ -90,7 +90,8 @@ Advanced Usage @chapter Introduction ERC is a powerful, modular, and extensible IRC client for Emacs. -It is distributed with Emacs since version 22.1. +It has been included in Emacs since 2006 (@pxref{History}) and is also +available on GNU ELPA. IRC is short for Internet Relay Chat. When using IRC, you can communicate with other users on the same IRC network. There are many @@ -1463,6 +1464,7 @@ or if you have bugs to report, there are several places you can go. @item @uref{https://www.emacswiki.org/emacs/ERC} is the emacswiki.org page for ERC@. Anyone may add tips, hints, etc.@: to it. +If you do so, please help keep it up to date. @item You can ask questions about using ERC on the Emacs mailing list, @@ -1471,7 +1473,13 @@ You can ask questions about using ERC on the Emacs mailing list, @item You can visit the IRC Libera.Chat channel @samp{#emacs}. Many of the contributors are frequently around and willing to answer your -questions. +questions. You can also try the relatively quiet @samp{#erc}, on the +same network, for more involved questions. + +@item +You can check GNU ELPA between Emacs releases to see if a newer +version is available that might contain a fix for your issue: +@uref{https://elpa.gnu.org/packages/erc.html}. @item To report a bug in ERC, use @kbd{M-x erc-bug}. diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index 1769b70c9bc..486171a080a 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -3853,15 +3853,6 @@ The dribble file will be saved, though (@pxref{Auto Save}). @code{gnus-after-exiting-gnus-hook} is called as the final item when exiting Gnus. -Note: - -@quotation -Miss Lisa Cannifax, while sitting in English class, felt her feet go -numbly heavy and herself fall into a hazy trance as the boy sitting -behind her drew repeated lines with his pencil across the back of her -plastic chair. -@end quotation - @node Group Topics @section Group Topics diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index 9d09172401f..d5e256d9d33 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -47,18 +47,18 @@ From now on, only the most essential operations will be officially supported in its absence, and users will see a warning upon entry-point invocation when it's not present. -** Tighter auth-source integration with bigger changes on the horizon. +** Tighter auth-source integration. The days of hit-and-miss auth-source queries are hopefully behind us. With the overhaul of the services module temporarily shelved and the transition to SASL-based authentication still underway, users may feel left in the lurch to endure yet another release cycle of backtick hell. For some, auth-source may provide a workaround in the form of -nonstandard server passwords. See the section titled "auth-source" in -the Integrations chapter of ERC's manual. +nonstandard server passwords. See the section entitled "auth-source" +in the Integrations chapter of ERC's manual. ** Rudimentary SASL support has arrived. -A new module, 'erc-sasl', now ships with ERC 5.5. See the SASL -section in the manual for details. +A new module, 'erc-sasl', now ships with ERC. See Info node "(erc) +SASL" in the manual for details. ** Username argument for entry-point commands. Commands 'erc' and 'erc-tls' now accept a ':user' keyword argument, @@ -88,8 +88,8 @@ off by default, new users are encouraged to enable them. Clicking on 'irc://' and 'ircs://' links elsewhere in Emacs now does the right thing most of the time. However, for security reasons, users are now prompted to confirm connection parameters prior to lift -off. See the new '(erc) Integrations' section in the Info manual to -override this. +off. See the new '(erc) Integrations' section in the Info manual for +details. ** Miscellaneous behavioral changes impacting the user experience. A bug has been fixed that saw prompts being mangled, doubled, or @@ -117,6 +117,12 @@ file called erc-common.el. This was done to further lessen the various complications arising from the mutual dependency between 'erc' and 'erc-backend'. +ERC now relies on the Compat library from GNU ELPA to supply forward +compatibility shims for users running older versions of Emacs. The +required Compat version resides atop ERC's main library file, in the +'Package-Requires' header. Third-party ERC modules will benefit +automatically from this adoption. + The function 'erc-network' always returns non-nil in server and target buffers belonging to a successfully established IRC connection, even after that connection has been closed. (Also see the note in the @@ -563,7 +563,7 @@ documented from day one; it just didn't behave according to documentation. It turns out some Lisp programs were using this coding-system on the wrong assumption that the "auto" part means some automagic handling of the end-of-line (EOL) format conversion; those -program will now start to fail, because BOM signature in UTF-8 encoded +programs will now start to fail, because BOM signature in UTF-8 encoded text is rarely expected. That is the reason we mention this bugfix here. @@ -608,8 +608,19 @@ with 'C-x x t', or try disabling all known slow minor modes with and the major mode with 'M-x so-long-mode', or visit the file with 'M-x find-file-literally' instead of the usual 'C-x C-f'. -Note that the display optimizations in these cases may cause the -buffer to be occasionally mis-fontified. +In buffers in which these display optimizations are in effect, the +'fontification-functions', 'pre-command-hook' and 'post-command-hook' +hooks are executed on a narrowed portion of the buffer, whose size is +controlled by the variables 'long-line-optimizations-region-size' and +'long-line-optimizations-bol-search-limit', as if they were in a +'with-restriction' form. This may, in particular, cause occasional +mis-fontifications in these buffers. Modes which are affected by +these optimizations and by the fact that the buffer is narrowed, +should adapt and either modify their algorithm so as not to expect the +entire buffer to be accessible, or, if accessing outside of the +narrowed region doesn't hurt performance, use the +'without-restriction' form to temporarily lift the restriction and +access portions of the buffer outside of the narrowed region. The new function 'long-line-optimizations-p' returns non-nil when these optimizations are in effect in the current buffer. @@ -1184,6 +1195,13 @@ the most recently deleted frame. With a numerical prefix argument between 1 and 16, where 1 is the most recently deleted frame, undelete the corresponding deleted frame. ++++ +*** The variable 'icon-title-format' can now have the value t. +That value means to use 'frame-title-format' for iconified frames. +This is useful with some window managers and desktop environments +which treat changes in frame's title as requests to raise the frame +and/or give it input focus. + ** Tab Bars and Tab Lines --- @@ -3807,6 +3825,14 @@ TIMEOUT is the idle time after which to deactivate the transient map. The default timeout value can be defined by the new variable 'set-transient-map-timeout'. ++++ +** New forms 'with-restriction' and 'without-restriction'. +These forms can be used as enhanced alternatives to the +'save-restriction' form combined with, respectively, +'narrow-to-region' and 'widen'. They also accept an optional label +argument, with which labeled narrowings can be created and lifted. +See the "(elisp) Narrowing" node for details. + ** Connection Local Variables +++ diff --git a/lisp/calendar/lunar.el b/lisp/calendar/lunar.el index 70681f42c90..8ced4144105 100644 --- a/lisp/calendar/lunar.el +++ b/lisp/calendar/lunar.el @@ -85,6 +85,9 @@ remainder mod 4 gives the phase: 0 new moon, 1 first quarter, 2 full moon, (* 0.0107306 time time) (* 0.00001236 time time time)) 360.0)) + ;; moon-lat is the argument of latitude, which is the angle + ;; of the moon measured from the ascending node of its orbit + ;; (i.e. argument of perigee + true anomaly). (moon-lat (mod (+ 21.2964 (* 390.67050646 index) @@ -153,9 +156,11 @@ remainder mod 4 gives the phase: 0 new moon, 1 first quarter, 2 full moon, ;; Line 7000 Peter Duffett-Smith Cambridge University Press 1990 (defun eclipse-check (moon-lat phase) (let* ((moon-lat (* (/ float-pi 180) moon-lat)) + ;; For positions near the ascending or descending node, + ;; calculate the absolute angular distance from that node. (moon-lat (abs (- moon-lat (* (floor (/ moon-lat float-pi)) float-pi)))) - (moon-lat (if (> moon-lat 0.37) + (moon-lat (if (> moon-lat 0.37) ; FIXME (* 0.5 float-pi) (- float-pi moon-lat) moon-lat)) (phase-name (cond ((= phase 0) "Solar") diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index bf49f274bfd..b753adcb8a0 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -435,21 +435,26 @@ version of that package." (push pkg missing)))))) (version-order (a b) "Predicate to sort packages in order." - (version-list-< (cadr b) (cadr a))) + (version-list-< + (package-desc-version b) + (package-desc-version a))) (duplicate-p (a b) "Are A and B the same package?" - (eq (car a) (car b))) + (eq (package-desc-name a) (package-desc-name b))) (depends-on-p (target package) "Does PACKAGE depend on TARGET?" (or (eq target package) (let* ((pac package-archive-contents) (desc (cadr (assoc package pac)))) - (seq-some - (apply-partially #'depends-on-p target) - (package-desc-reqs desc))))) + (and desc (seq-some + (apply-partially #'depends-on-p target) + (package-desc-reqs desc)))))) (dependent-order (a b) - (or (not (depends-on-p (car b) (car a))) - (depends-on-p (car a) (car b))))) + (let ((desc-a (package-desc-name a)) + (desc-b (package-desc-name b))) + (or (not desc-a) (not desc-b) + (not (depends-on-p desc-b desc-a)) + (depends-on-p desc-a desc-b))))) (mapc #'search requirements) (cl-callf sort to-install #'version-order) (cl-callf seq-uniq to-install #'duplicate-p) @@ -597,6 +602,13 @@ attribute in PKG-SPEC." (vc-retrieve-tag dir release-rev) (message "No release revision was found, continuing..."))))) +(defvar package-vc-non-code-file-names + '(".dir-locals.el" ".dir-locals-2.el") + "List of file names that do not contain Emacs Lisp code. +This list is used by `package-vc--unpack' to better check if the +user is fetching code from a repository that does not contain any +Emacs Lisp files.") + (defun package-vc--unpack (pkg-desc pkg-spec &optional rev) "Install the package described by PKG-DESC. PKG-SPEC is a package specification, a property list describing @@ -606,7 +618,7 @@ checkout. This overrides the `:branch' attribute in PKG-SPEC." (pcase-let* (((map :lisp-dir) pkg-spec) (name (package-desc-name pkg-desc)) (dirname (package-desc-full-name pkg-desc)) - (pkg-dir (expand-file-name dirname package-user-dir))) + (pkg-dir (file-name-as-directory (expand-file-name dirname package-user-dir)))) (when (string-empty-p name) (user-error "Empty package name")) (setf (package-desc-dir pkg-desc) pkg-dir) @@ -615,6 +627,17 @@ checkout. This overrides the `:branch' attribute in PKG-SPEC." (package--delete-directory pkg-dir) (error "There already exists a checkout for %s" name))) (package-vc--clone pkg-desc pkg-spec pkg-dir rev) + (when (directory-empty-p pkg-dir) + (delete-directory pkg-dir) + (error "Empty checkout for %s" name)) + (unless (seq-remove + (lambda (file) + (member (file-name-nondirectory file) package-vc-non-code-file-names)) + (directory-files-recursively pkg-dir "\\.el\\'" nil)) + (when (yes-or-no-p (format "No Emacs Lisp files found when fetching \"%s\", \ +abort installation?" name)) + (delete-directory pkg-dir t) + (user-error "Installation aborted"))) ;; When nothing is specified about a `lisp-dir', then should ;; heuristically check if there is a sub-directory with lisp diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 1da701aebc4..cf0b734bd28 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -425,7 +425,7 @@ Called with a server buffer as its only argument. Potential uses include exponential backoff and probing for connectivity prior to dialing. Use `erc-schedule-reconnect' to instead try again later and optionally alter the attempts tally." - :package-version '(ERC . "5.4.1") ; FIXME on next release + :package-version '(ERC . "5.5") :type '(choice (function-item erc-server-delayed-reconnect) function)) @@ -1167,7 +1167,7 @@ Note that future bundled modules providing IRCv3 functionality will not be compatible with the legacy format. User code should eventually transition to expecting this \"5.5+ variant\" and set this option to nil." - :package-version '(ERC . "5.4.1") ; FIXME increment on next release + :package-version '(ERC . "5.5") :type '(choice (const nil) (const legacy) (const overridable))) @@ -1201,7 +1201,7 @@ instead, leave them as a single string." (get 'erc-parse-tags 'erc-v3-warned-p)) (put 'erc-parse-tags 'erc-v3-warned-p t) (display-warning - 'ERC + 'erc (concat "Legacy ERC tags behavior is currently in effect, but other modules," " including those bundled with ERC, may override this in future" diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el index 1be47c3e665..c28dddefa0e 100644 --- a/lisp/erc/erc-button.el +++ b/lisp/erc/erc-button.el @@ -176,7 +176,7 @@ PAR is a number of a regexp grouping whose text will be passed to CALLBACK. There can be several PAR arguments. If REGEXP is `nicknames', these are ignored, and CALLBACK will be called with the nickname matched as the argument." - :version "29.1" + :package-version '(ERC . "5.5") :type '(repeat (list :tag "Button" (choice :tag "Matches" diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el index 499bcaf5724..52ee5c855f3 100644 --- a/lisp/erc/erc-match.el +++ b/lisp/erc/erc-match.el @@ -244,7 +244,7 @@ server and other miscellaneous functions." "Whether to `regexp-quote' when adding to a match list interactively. When the value is a boolean, the opposite behavior will be made available via universal argument." - :package-version '(ERC . "5.4.1") ; FIXME increment on next release + :package-version '(ERC . "5.5") :type '(choice (const ask) (const t) (const nil))) diff --git a/lisp/erc/erc-sasl.el b/lisp/erc/erc-sasl.el index 97c7c54a517..ed91f412255 100644 --- a/lisp/erc/erc-sasl.el +++ b/lisp/erc/erc-sasl.el @@ -24,13 +24,13 @@ ;; ;; https://lists.gnu.org/archive/html/erc-discuss/2012-02/msg00001.html ;; -;; See options and Info manual for usage. +;; See M-x customize-group RET erc-sasl RET and (info "(erc) SASL") +;; for usage. ;; ;; TODO: ;; -;; - Find a way to obfuscate the password in memory (via something -;; like `auth-source--obfuscate'); it's currently visible in -;; backtraces. +;; - Obfuscate non-auth-source passwords in memory. They're currently +;; visible in backtraces. ;; ;; - Implement a proxy mechanism that chooses the strongest available ;; mechanism for you. Requires CAP 3.2 (see bug#49860). @@ -52,7 +52,7 @@ (defgroup erc-sasl nil "SASL for ERC." :group 'erc - :package-version '(ERC . "5.4.1")) ; FIXME increment on next release + :package-version '(ERC . "5.5")) (defcustom erc-sasl-mechanism 'plain "SASL mechanism to connect with. @@ -76,19 +76,19 @@ commands, `erc' and `erc-tls'." (defcustom erc-sasl-password :password "Optional account password to send when authenticating. -When `erc-sasl-auth-source-function' is a function, ERC will -attempt an auth-source query and prompt for input if it fails. -Otherwise, when the value is a nonempty string, ERC will use it -unconditionally for most mechanisms. Likewise with `:password', -except ERC will instead use the \"session password\" on file, if -any, which often originates from the entry-point commands `erc' -or `erc-tls'. As with auth-source, ERC will prompt for input as -a fallback. - -Note that, with `:password', ERC will forgo sending a traditional +When `erc-sasl-auth-source-function' is a function, ERC attempts +an auth-source query and prompts for input if it fails. +Otherwise, when the value of this option is a nonempty string, +ERC uses it unconditionally for most mechanisms. Likewise with a +value of `:password', except ERC instead uses the \"session +password\" on file, if any, which often originates from the +entry-point commands `erc' or `erc-tls'. As with auth-source, +ERC prompts for input as a fallback. + +Note that, with `:password', ERC forgoes sending a traditional server password via the IRC \"PASS\" command. Also, when -`erc-sasl-mechanism' is set to `ecdsa-nist256p-challenge', this -option should hold the file name of the key." +`erc-sasl-mechanism' is set to `ecdsa-nist256p-challenge', ERC +expects this option to hold the file name of the key." :type '(choice (const nil) (const :password) string symbol)) (defcustom erc-sasl-auth-source-function nil @@ -100,9 +100,8 @@ though ERC itself only specifies `:user' paired with a ERC binds all options defined in this library, such as `erc-sasl-password', to their values from entry-point invocation. In return, ERC expects a string to send as the SASL password, or -nil, in which case, ERC will prompt the for input. See info -node `(erc) auth-source' for details on ERC's auth-source -integration." +nil, in which case, ERC prompts for input. See Info node `(erc) +auth-source' for details on ERC's auth-source integration." :type '(choice (function-item erc-sasl-auth-source-password-as-host) (function-item erc-auth-source-search) (const nil) diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el index 1c2fc2fcdc8..2e6959cc3f0 100644 --- a/lisp/erc/erc-services.el +++ b/lisp/erc/erc-services.el @@ -180,9 +180,9 @@ Called with a subset of keyword parameters known to `auth-source-search' and relevant to authenticating to nickname services. In return, ERC expects a string to send as the password, or nil, to fall through to the next method, such as -prompting. See info node `(erc) auth-source' for details." - :package-version '(ERC . "5.4.1") ; FIXME update when publishing to ELPA - :type '(choice (const erc-auth-source-search) +prompting. See Info node `(erc) auth-source' for details." + :package-version '(ERC . "5.5") + :type '(choice (function-item erc-auth-source-search) (const nil) function)) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index ff1820cfaf2..d35907a1677 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -217,8 +217,8 @@ parameters and authentication." This variable only exists for legacy reasons. It's not customizable and is limited to a single server password. Users looking for similar -functionality should consider auth-source instead. See info -node `(auth) Top' and info node `(erc) auth-source'.") +functionality should consider auth-source instead. See Info +node `(auth) Top' and Info node `(erc) auth-source'.") (make-obsolete-variable 'erc-password "use auth-source instead" "29.1") @@ -250,19 +250,19 @@ node `(auth) Top' and info node `(erc) auth-source'.") Issue an error when the number of input lines submitted for sending exceeds this value. The value t means disallow more than 1 line of input." - :package-version '(ERC . "5.4.1") ; FIXME match to next release + :package-version '(ERC . "5.5") :group 'erc :type '(choice integer boolean)) (defcustom erc-ask-about-multiline-input nil "Whether to ask to ignore `erc-inhibit-multiline-input' when tripped." - :package-version '(ERC . "5.4.1") ; FIXME match to next release + :package-version '(ERC . "5.5") :group 'erc :type 'boolean) (defcustom erc-prompt-hidden ">" "Text to show in lieu of the prompt when hidden." - :package-version '(ERC . "5.4.1") ; FIXME increment on next ELPA release + :package-version '(ERC . "5.5") :group 'erc-display :type 'string) @@ -272,7 +272,7 @@ To unhide, type something in the input area. Once revealed, a prompt remains unhidden until the next disconnection. Channel prompts are unhidden upon rejoining. See `erc-unhide-query-prompt' for behavior concerning query prompts." - :package-version '(ERC . "5.4.1") ; FIXME increment on next ELPA release + :package-version '(ERC . "5.5") :group 'erc-display :type '(choice (const :tag "Always hide prompt" t) (set (const server) @@ -284,7 +284,7 @@ prompts are unhidden upon rejoining. See Otherwise, prompts in a connection's query buffers remain hidden until the user types in the input area or a new message arrives from the target." - :package-version '(ERC . "5.4.1") ; FIXME increment on next ELPA release + :package-version '(ERC . "5.5") :group 'erc-display ;; Extensions may one day offer a way to discover whether a target ;; is online. When that happens, this can be expanded accordingly. @@ -1479,7 +1479,7 @@ The available choices are: `bury' - bury it in a new buffer, `buffer' - in place of the current buffer, any other value - in place of the current buffer." - :package-version '(ERC . "5.4.1") ; FIXME increment upon publishing to ELPA + :package-version '(ERC . "5.5") :group 'erc-buffers :type '(choice (const :tag "Split window and select" window) (const :tag "Split window, don't select" window-noselect) @@ -1495,7 +1495,7 @@ This only affects automatic reconnections and is ignored when issuing a /reconnect command or reinvoking `erc-tls' with the same args (assuming success, of course). See `erc-join-buffer' for a description of possible values." - :package-version '(ERC . "5.4.1") ; FIXME increment upon publishing to ELPA + :package-version '(ERC . "5.5") :group 'erc-buffers :type '(choice (const :tag "Use value of `erc-join-buffer'" nil) (const :tag "Split window and select" window) @@ -2319,7 +2319,7 @@ Example usage: When present, ID should be a symbol or a string to use for naming the server buffer and identifying the connection unequivocally. -See info node `(erc) Network Identifier' for details. Like USER +See Info node `(erc) Network Identifier' for details. Like USER and CLIENT-CERTIFICATE, this parameter cannot be specified interactively." (interactive (let ((erc-default-port erc-default-port-tls)) @@ -3258,10 +3258,10 @@ if any. In return, ERC expects a string to send as the server password, or nil, to skip the \"PASS\" command completely. An explicit `:password' argument to entry-point commands `erc' and `erc-tls' also inhibits lookup, as does setting this option to -nil. See info node `(erc) auth-source' for details." - :package-version '(ERC . "5.4.1") ; FIXME update when publishing to ELPA +nil. See Info node `(erc) auth-source' for details." + :package-version '(ERC . "5.5") :group 'erc - :type '(choice (const erc-auth-source-search) + :type '(choice (function-item erc-auth-source-search) (const nil) function)) @@ -3272,11 +3272,11 @@ Called with a subset of keyword arguments known to channel. In return, ERC expects a string to use as the channel \"key\", or nil to just join the channel normally. Setting the option itself to nil tells ERC to always forgo consulting -auth-source for channel keys. For more information, see info +auth-source for channel keys. For more information, see Info node `(erc) auth-source'." - :package-version '(ERC . "5.4.1") ; FIXME update when publishing to ELPA + :package-version '(ERC . "5.5") :group 'erc - :type '(choice (const erc-auth-source-search) + :type '(choice (function-item erc-auth-source-search) (const nil) function)) @@ -6837,8 +6837,8 @@ shortened server name instead." ;; erc-goodies is required at end of this file. -;; FIXME when 29.1 is cut and `format-spec' is added to ELPA Compat, -;; remove the function invocations from the spec form below. +;; TODO when ERC drops Emacs 28, replace the expressions in the format +;; spec below with functions. (defun erc-update-mode-line-buffer (buffer) "Update the mode line in a single ERC buffer BUFFER." (with-current-buffer buffer @@ -7213,7 +7213,7 @@ See also `format-spec'." (defcustom erc-kill-server-hook '(erc-kill-server erc-networks-shrink-ids-and-buffer-names) "Invoked whenever a live server buffer is killed via `kill-buffer'." - :package-version '(ERC . "5.4.1") ; FIXME increment upon publishing to ELPA + :package-version '(ERC . "5.5") :group 'erc-hooks :type 'hook) @@ -7222,7 +7222,7 @@ See also `format-spec'." erc-networks-shrink-ids-and-buffer-names erc-networks-rename-surviving-target-buffer) "Invoked whenever a channel-buffer is killed via `kill-buffer'." - :package-version '(ERC . "5.4.1") ; FIXME increment upon publishing to ELPA + :package-version '(ERC . "5.5") :group 'erc-hooks :type 'hook) @@ -7232,7 +7232,7 @@ See also `format-spec'." "Hook run whenever a query buffer is killed. See also `kill-buffer'." - :package-version '(ERC . "5.4.1") ; FIXME increment upon publishing to ELPA + :package-version '(ERC . "5.5") :group 'erc-hooks :type 'hook) @@ -7311,7 +7311,7 @@ Called with a string meant to represent a URL scheme, like \"ircs\", followed by any number of keyword arguments recognized by `erc' and `erc-tls'." :group 'erc - :package-version '(ERC . "5.4.1") ; FIXME increment on release + :package-version '(ERC . "5.5") :type '(choice (const nil) function)) (defun erc--url-default-connect-function (scheme &rest plist) diff --git a/lisp/faces.el b/lisp/faces.el index 4933b495a6c..d1a7881e396 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -191,7 +191,7 @@ For internal use only." (let ((face-id (car (gethash face face--new-frame-defaults)))) (push `(,face-id ,face . ,spec) faces))) (frame--face-hash-table frame)) - (mapcar #'cdr (sort faces (lambda (f1 f2) (< (car f1) (car f2))))))) + (mapcar #'cdr (sort faces (lambda (f1 f2) (> (car f1) (car f2))))))) (defun face-list () "Return a list of all defined faces." @@ -199,7 +199,7 @@ For internal use only." (maphash (lambda (face spec) (push `(,(car spec) . ,face) faces)) face--new-frame-defaults) - (mapcar #'cdr (sort faces (lambda (f1 f2) (< (car f1) (car f2))))))) + (mapcar #'cdr (sort faces (lambda (f1 f2) (> (car f1) (car f2))))))) (defun make-face (face) "Define a new face with name FACE, a symbol. diff --git a/lisp/international/mule.el b/lisp/international/mule.el index 52019697ad7..25b90b49c8f 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el @@ -2544,6 +2544,7 @@ This function is intended to be added to `auto-coding-functions'." ;; coding-system-equal, since it isn't a ;; coding-system. So test that up front. (not (equal sym-type 'charset)) + (not (equal bfcs-type 'charset)) (coding-system-equal 'utf-8 sym-type) (coding-system-equal 'utf-8 bfcs-type)) buffer-file-coding-system diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index dfb076e52df..dfa14140b4e 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -2921,7 +2921,7 @@ and corresponding effects. ;;; Generated autoloads from progmodes/c-ts-common.el -(register-definition-prefixes "c-ts-common" '("c-ts-")) +(register-definition-prefixes "c-ts-common" '("c-ts-common-")) ;;; Generated autoloads from progmodes/c-ts-mode.el @@ -7881,36 +7881,53 @@ Display-Line-Numbers mode. (fn &optional ARG)" t) (defvar header-line-indent "" "\ -String to indent at the start if the header line. -This is used in `header-line-indent-mode', and buffers that have -this switched on should have a `header-line-format' that look like: +String of spaces to indent the beginning of header-line due to line numbers. +This is intended to be used in `header-line-format', and requires +the `header-line-indent-mode' to be turned on, in order for the width +of this string to be kept updated when the line-number width changes +on display. An example of a `header-line-format' that uses this +variable might look like this: (\"\" header-line-indent THE-REST...) +where THE-REST is the format string which produces the actual text +of the header-line. Also see `header-line-indent-width'.") (defvar header-line-indent-width 0 "\ -The width of the current line numbers displayed. -This is updated when `header-line-indent-mode' is switched on. - +The width of the current line number display in the window. +This is measured in units of the frame's canonical columns. +This is updated when `header-line-indent-mode' is switched on, +and is intended for use in `:align-to' display specifications +that are part of `header-line-format', when portions of header-line +text should be aligned to respective parts of buffer text. Also see `header-line-indent'.") (autoload 'header-line-indent-mode "display-line-numbers" "\ -Mode to indent the header line in `display-line-numbers-mode' buffers. +Minor mode to help with alignment of header line when line numbers are shown. -This means that the header line will be kept indented so that it -has blank space that's as wide as the displayed line numbers in -the buffer. +This minor mode should be turned on in buffers which display header-line +that needs to be aligned with buffer text when `display-line-numbers-mode' +is turned on in the buffer. -Buffers that have this switched on should have a -`header-line-format' that look like: +Buffers that have this switched on should have a `header-line-format' +that uses the `header-line-indent' or the `header-line-indent-width' +variables, which this mode will keep up-to-date with the current +display of line numbers. For example, a `header-line-format' that +looks like this: (\"\" header-line-indent THE-REST...) -The `header-line-indent-width' variable is also kept updated, and -has the width of `header-line-format'. This can be used, for -instance, in `:align-to' specs, like: +will make sure the text produced by THE-REST (which should be +a header-line format string) is always indented to be aligned on +display with the first column of buffer text. + +The `header-line-indent-width' variable is also kept updated, +and can be used, for instance, in `:align-to' specs as part +of `header-line-format', like this: (space :align-to (+ header-line-indent-width 10)) +See also `line-number-display-width'. + This is a minor mode. If called interactively, toggle the `Header-Line-Indent mode' mode. If the prefix argument is positive, enable the mode, and if it is zero or negative, disable @@ -9763,6 +9780,10 @@ If called from Lisp, return the name as a string; return nil if the name is not known. (fn GLYPH &optional INTERACTIVE)" t) +(autoload 'emoji--init "emoji" "\ + + +(fn &optional FORCE INHIBIT-ADJUST)") (autoload 'emoji-zoom-increase "emoji" "\ Increase the size of the character under point. FACTOR is the multiplication factor for the size. @@ -10219,7 +10240,7 @@ Example usage: When present, ID should be a symbol or a string to use for naming the server buffer and identifying the connection unequivocally. -See info node `(erc) Network Identifier' for details. Like USER +See Info node `(erc) Network Identifier' for details. Like USER and CLIENT-CERTIFICATE, this parameter cannot be specified interactively. @@ -15815,7 +15836,7 @@ it is disabled. ;;; Generated autoloads from progmodes/hideshow.el -(defvar hs-special-modes-alist (mapcar #'purecopy '((c-mode "{" "}" "/[*/]" nil nil) (c++-mode "{" "}" "/[*/]" nil nil) (bibtex-mode ("@\\S(*\\(\\s(\\)" 1)) (java-mode "{" "}" "/[*/]" nil nil) (js-mode "{" "}" "/[*/]" nil) (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil))) "\ +(defvar hs-special-modes-alist (mapcar #'purecopy '((c-mode "{" "}" "/[*/]" nil nil) (c-ts-mode "{" "}" "/[*/]" nil nil) (c++-mode "{" "}" "/[*/]" nil nil) (c++-ts-mode "{" "}" "/[*/]" nil nil) (bibtex-mode ("@\\S(*\\(\\s(\\)" 1)) (java-mode "{" "}" "/[*/]" nil nil) (java-ts-mode "{" "}" "/[*/]" nil nil) (js-mode "{" "}" "/[*/]" nil) (js-ts-mode "{" "}" "/[*/]" nil) (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil))) "\ Alist for initializing the hideshow variables for different modes. Each element has the form (MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC @@ -17306,12 +17327,12 @@ Return non-nil if there is an image at point.") ;;; Generated autoloads from image/image-converter.el (autoload 'image-converter-add-handler "image-converter" "\ -Make Emacs use CONVERTER to parse image files that end with SUFFIX. -CONVERTER is a function with two parameters, where the first is -the file name or a string with the image data, and the second is -non-nil if the first parameter is image data. The converter -should output the image in the current buffer, converted to -`image-convert-to-format'. +Make Emacs use CONVERTER to parse image files whose names end with SUFFIX. +CONVERTER is a function with two arguments, the file name or a string +with the image data, and a non-nil value if the first argument is image data. +The converter should produce the image in the current buffer, converted to +the format given by `image-convert-to-format'. +SUFFIX should not include the leading dot. (fn SUFFIX CONVERTER)") (register-definition-prefixes "image-converter" '("image-convert")) @@ -17355,9 +17376,9 @@ Open directory DIR and create a default window configuration. Convenience command that: - - Opens Dired in folder DIR - - Splits windows in most useful (?) way - - Sets `truncate-lines' to t + - opens Dired in folder DIR; + - splits windows in most useful (?) way; and + - sets `truncate-lines' to t After the command has finished, you would typically mark some image files in Dired and type @@ -17415,11 +17436,12 @@ Default bookmark handler for Image-Dired buffers. ;;; Generated autoloads from image/image-dired-dired.el (autoload 'image-dired-dired-toggle-marked-thumbs "image-dired-dired" "\ -Toggle thumbnails in front of file names in the Dired buffer. -If no marked file could be found, insert or hide thumbnails on the -current line. ARG, if non-nil, specifies the files to use instead -of the marked files. If ARG is an integer, use the next ARG (or -previous -ARG, if ARG<0) files. +Toggle thumbnails in front of marked file names in the Dired buffer. +If no file is marked, toggle display of thumbnail on the current file's line. +ARG, if non-nil (interactively, the prefix argument), specifies the files +whose thumbnail display to toggle instead of the marked files: if ARG is an +integer, use the next ARG (or previous -ARG, if ARG<0) files; any other +value of ARG means toggle thumbnail display of the current line's file. (fn &optional ARG)" '(dired-mode)) (autoload 'image-dired-jump-thumbnail-buffer "image-dired-dired" "\ @@ -17471,7 +17493,8 @@ Append thumbnails to `image-dired-thumbnail-buffer'." '(dired-mode)) (autoload 'image-dired-display-thumb "image-dired-dired" "\ Shorthand for `image-dired-display-thumbs' with prefix argument." '(dired-mode)) (autoload 'image-dired-dired-display-external "image-dired-dired" "\ -Display file at point using an external viewer." '(dired-mode)) +Display file at point using an external viewer. +The viewer is specified by the value of `image-dired-external-viewer'." '(dired-mode)) (autoload 'image-dired-dired-display-image "image-dired-dired" "\ Display current image file. See documentation for `image-dired-display-image' for more information. @@ -17479,11 +17502,11 @@ See documentation for `image-dired-display-image' for more information. (fn &optional _)" '(dired-mode)) (set-advertised-calling-convention 'image-dired-dired-display-image 'nil '"29.1") (autoload 'image-dired-mark-tagged-files "image-dired-dired" "\ -Use REGEXP to mark files with matching tag. +Mark files whose tag matches REGEXP. A `tag' is a keyword, a piece of meta data, associated with an image file and stored in image-dired's database file. This command -lets you input a regexp and this will be matched against all tags -on all image files in the database file. The files that have a +prompts for a regexp, and then matches it against all the tags +of all the image files in the database file. The files that have a matching tag will be marked in the Dired buffer. (fn REGEXP)" '(dired-mode)) @@ -17498,7 +17521,8 @@ matching tag will be marked in the Dired buffer. ;;; Generated autoloads from image/image-dired-tags.el (autoload 'image-dired-tag-files "image-dired-tags" "\ -Tag marked file(s) in Dired. With prefix ARG, tag file at point. +Tag file(s) which are marked in a Dired buffer. +With prefix ARG, tag the file at point. (fn ARG)" '(dired-mode)) (autoload 'image-dired-delete-tag "image-dired-tags" "\ @@ -18311,7 +18335,9 @@ Add submenus to the File menu, to convert to and from various formats." t) (put 'ispell-check-comments 'safe-local-variable (lambda (a) (memq a '(nil t exclusive)))) (defvar ispell-personal-dictionary nil "\ File name of your personal spelling dictionary, or nil. -If nil, the default personal dictionary for your spelling checker is used.") +If nil, the default personal dictionary for your spelling checker is used. +Due to a misfeature of Hunspell, if the value is an absolute file name, the +file by that name must already exist for Hunspell to be able to use it.") (custom-autoload 'ispell-personal-dictionary "ispell" t) (put 'ispell-local-dictionary 'safe-local-variable 'string-or-null-p) (defconst ispell-menu-map (let ((map (make-sparse-keymap "Spell"))) (define-key map [ispell-change-dictionary] `(menu-item ,(purecopy "Change Dictionary...") ispell-change-dictionary :help ,(purecopy "Supply explicit dictionary file name"))) (define-key map [ispell-kill-ispell] `(menu-item ,(purecopy "Kill Process") (lambda nil (interactive) (ispell-kill-ispell nil 'clear)) :enable (and (boundp 'ispell-process) ispell-process (eq (ispell-process-status) 'run)) :help ,(purecopy "Terminate Ispell subprocess"))) (define-key map [ispell-pdict-save] `(menu-item ,(purecopy "Save Dictionary") (lambda nil (interactive) (ispell-pdict-save t t)) :help ,(purecopy "Save personal dictionary"))) (define-key map [ispell-customize] `(menu-item ,(purecopy "Customize...") (lambda nil (interactive) (customize-group 'ispell)) :help ,(purecopy "Customize spell checking options"))) (define-key map [ispell-help] `(menu-item ,(purecopy "Help") (lambda nil (interactive) (describe-function 'ispell-help)) :help ,(purecopy "Show standard Ispell keybindings and commands"))) (define-key map [flyspell-mode] `(menu-item ,(purecopy "Automatic spell checking (Flyspell)") flyspell-mode :help ,(purecopy "Check spelling while you edit the text") :button (:toggle bound-and-true-p flyspell-mode))) (define-key map [ispell-complete-word] `(menu-item ,(purecopy "Complete Word") ispell-complete-word :help ,(purecopy "Complete word at cursor using dictionary"))) (define-key map [ispell-complete-word-interior-frag] `(menu-item ,(purecopy "Complete Word Fragment") ispell-complete-word-interior-frag :help ,(purecopy "Complete word fragment at cursor"))) (define-key map [ispell-continue] `(menu-item ,(purecopy "Continue Spell-Checking") ispell-continue :enable (and (boundp 'ispell-region-end) (marker-position ispell-region-end) (equal (marker-buffer ispell-region-end) (current-buffer))) :help ,(purecopy "Continue spell checking last region"))) (define-key map [ispell-word] `(menu-item ,(purecopy "Spell-Check Word") ispell-word :help ,(purecopy "Spell-check word at cursor"))) (define-key map [ispell-comments-and-strings] `(menu-item ,(purecopy "Spell-Check Comments") ispell-comments-and-strings :help ,(purecopy "Spell-check only comments and strings"))) (define-key map [ispell-region] `(menu-item ,(purecopy "Spell-Check Region") ispell-region :enable mark-active :help ,(purecopy "Spell-check text in marked region"))) (define-key map [ispell-message] `(menu-item ,(purecopy "Spell-Check Message") ispell-message :visible (eq major-mode 'mail-mode) :help ,(purecopy "Skip headers and included message text"))) (define-key map [ispell-buffer] `(menu-item ,(purecopy "Spell-Check Buffer") ispell-buffer :help ,(purecopy "Check spelling of selected buffer"))) map) "\ @@ -26541,8 +26567,12 @@ or call the function `repeat-mode'.") (autoload 'repeat-mode "repeat" "\ Toggle Repeat mode. -When Repeat mode is enabled, and the command symbol has the property named -`repeat-map', this map is activated temporarily for the next command. +When Repeat mode is enabled, certain commands bound to multi-key +sequences can be repeated by typing a single key, after typing the +full key sequence once. +The commands which can be repeated like that are those whose symbol + has the property `repeat-map' which specifies a keymap of single +keys for repeating. See `describe-repeat-maps' for a list of all repeatable commands. This is a global minor mode. If called interactively, toggle the diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index af7aa1c3a0e..a60c464093e 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -219,6 +219,7 @@ delimiters < and >'s." MODE is either `c' or `cpp'." (let ((common `(((parent-is "translation_unit") point-min 0) + ((query "(ERROR (ERROR)) @indent") point-min 0) ((node-is ")") parent 1) ((node-is "]") parent-bol 0) ((node-is "else") parent-bol 0) @@ -267,15 +268,15 @@ MODE is either `c' or `cpp'." ((query "(for_statement update: (_) @indent)") parent-bol 5) ((query "(call_expression arguments: (_) @indent)") parent c-ts-mode-indent-offset) ((parent-is "call_expression") parent 0) + ;; Closing bracket. This should be before initializer_list + ;; (and probably others) rule because that rule (and other + ;; similar rules) will match the closing bracket. (Bug#61398) + ((node-is "}") point-min c-ts-common-statement-offset) ,@(when (eq mode 'cpp) '(((node-is "access_specifier") parent-bol 0) ;; Indent the body of namespace definitions. ((parent-is "declaration_list") parent-bol c-ts-mode-indent-offset))) - ;; Closing bracket. This should be before initializer_list - ;; (and probably others) rule because that rule (and other - ;; similar rules) will match the closing bracket. (Bug#61398) - ((node-is "}") point-min c-ts-common-statement-offset) ;; int[5] a = { 0, 0, 0, 0 }; ((parent-is "initializer_list") parent-bol c-ts-mode-indent-offset) @@ -738,7 +739,8 @@ the semicolon. This function skips the semicolon." :doc "Keymap for C and C-like languages with tree-sitter" :parent prog-mode-map "C-c C-q" #'c-ts-mode-indent-defun - "C-c ." #'c-ts-mode-set-style) + "C-c ." #'c-ts-mode-set-style + "C-c C-c" #'comment-region) ;;;###autoload (define-derived-mode c-ts-base-mode prog-mode "C" @@ -772,8 +774,7 @@ the semicolon. This function skips the semicolon." `((block . ,(rx (or "compound_statement" "field_declaration_list" "enumerator_list" - "initializer_list" - "field_declaration_list"))) + "initializer_list"))) (if . "if_statement") (else . ("if_statement" . "alternative")) (do . "do_statement") @@ -785,7 +786,7 @@ the semicolon. This function skips the semicolon." ;; Electric (setq-local electric-indent-chars - (append "{}():;," electric-indent-chars)) + (append "{}():;,#" electric-indent-chars)) ;; Imenu. (setq-local treesit-simple-imenu-settings diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el index 852e893dc25..b6b842d7fd4 100644 --- a/lisp/progmodes/csharp-mode.el +++ b/lisp/progmodes/csharp-mode.el @@ -862,7 +862,30 @@ compilation and evaluation time conflicts." :language 'c-sharp :feature 'escape-sequence :override t - '((escape_sequence) @font-lock-escape-face))) + '((escape_sequence) @font-lock-escape-face) + + :language 'c-sharp + :feature 'directives + :override t + '((if_directive + "if" @font-lock-preprocessor-face + (identifier) @font-lock-variable-name-face) + (elif_directive + "elif" @font-lock-preprocessor-face + (identifier) @font-lock-variable-name-face) + (else_directive) @font-lock-preprocessor-face + (endif_directive) @font-lock-preprocessor-face + (define_directive + "define" @font-lock-preprocessor-face + (identifier) @font-lock-variable-name-face) + (nullable_directive) @font-lock-preprocessor-face + (pragma_directive) @font-lock-preprocessor-face + (region_directive) @font-lock-preprocessor-face + (endregion_directive) @font-lock-preprocessor-face + (region_directive + (preproc_message) @font-lock-variable-name-face) + (endregion_directive + (preproc_message) @font-lock-variable-name-face)))) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode)) @@ -925,7 +948,7 @@ Key bindings: (setq-local treesit-font-lock-settings csharp-ts-mode--font-lock-settings) (setq-local treesit-font-lock-feature-list '(( comment definition) - ( keyword string type) + ( keyword string type directives) ( constant escape-sequence expression literal property) ( function bracket delimiter error))) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 58d519548e0..82401b685ce 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -2496,13 +2496,14 @@ When called interactively, use the currently active server" (defun eglot--signal-textDocument/didSave () "Send textDocument/didSave to server." (eglot--signal-textDocument/didChange) - (jsonrpc-notify - (eglot--current-server-or-lose) - :textDocument/didSave - (list - ;; TODO: Handle TextDocumentSaveRegistrationOptions to control this. - :text (buffer-substring-no-properties (point-min) (point-max)) - :textDocument (eglot--TextDocumentIdentifier)))) + (when (eglot--server-capable :textDocumentSync :save) + (jsonrpc-notify + (eglot--current-server-or-lose) + :textDocument/didSave + (list + ;; TODO: Handle TextDocumentSaveRegistrationOptions to control this. + :text (buffer-substring-no-properties (point-min) (point-max)) + :textDocument (eglot--TextDocumentIdentifier))))) (defun eglot-flymake-backend (report-fn &rest _more) "A Flymake backend for Eglot. diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index e15da7110f1..6948ebba631 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -162,7 +162,8 @@ :override t :feature 'keyword `([,@java-ts-mode--keywords - (this)] @font-lock-keyword-face + (this) + (super)] @font-lock-keyword-face (labeled_statement (identifier) @font-lock-keyword-face)) :language 'java diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 05d69c314bb..1f08f09935b 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3442,6 +3442,7 @@ This function is intended for use in `after-change-functions'." ((parent-is "arguments") parent-bol js-indent-level) ((parent-is "array") parent-bol js-indent-level) ((parent-is "formal_parameters") parent-bol js-indent-level) + ((parent-is "template_string") no-indent) ; Don't indent the string contents. ((parent-is "template_substitution") parent-bol js-indent-level) ((parent-is "object_pattern") parent-bol js-indent-level) ((parent-is "object") parent-bol js-indent-level) diff --git a/lisp/progmodes/rust-ts-mode.el b/lisp/progmodes/rust-ts-mode.el index 5c71a8ad461..ec823d09d8c 100644 --- a/lisp/progmodes/rust-ts-mode.el +++ b/lisp/progmodes/rust-ts-mode.el @@ -124,8 +124,8 @@ (treesit-font-lock-rules :language 'rust :feature 'attribute - '((attribute_item) @font-lock-constant-face - (inner_attribute_item) @font-lock-constant-face) + '((attribute_item) @font-lock-preprocessor-face + (inner_attribute_item) @font-lock-preprocessor-face) :language 'rust :feature 'bracket @@ -148,12 +148,6 @@ '(([(block_comment) (line_comment)]) @font-lock-comment-face) :language 'rust - :feature 'constant - `((boolean_literal) @font-lock-constant-face - ((identifier) @font-lock-constant-face - (:match "^[A-Z][A-Z\\d_]*$" @font-lock-constant-face))) - - :language 'rust :feature 'delimiter '((["," "." ";" ":" "::"]) @font-lock-delimiter-face) @@ -163,11 +157,16 @@ (macro_definition "macro_rules!" @font-lock-constant-face) (macro_definition (identifier) @font-lock-preprocessor-face) (field_declaration name: (field_identifier) @font-lock-property-face) - (parameter) @rust-ts-mode--fontify-pattern - (let_declaration) @rust-ts-mode--fontify-pattern - (for_expression) @rust-ts-mode--fontify-pattern - (let_condition) @rust-ts-mode--fontify-pattern - (match_arm) @rust-ts-mode--fontify-pattern) + (parameter pattern: (_) @rust-ts-mode--fontify-pattern) + (let_declaration pattern: (_) @rust-ts-mode--fontify-pattern) + (for_expression pattern: (_) @rust-ts-mode--fontify-pattern) + (let_condition pattern: (_) @rust-ts-mode--fontify-pattern) + (match_arm pattern: (_) @rust-ts-mode--fontify-pattern)) + + :language 'rust + :feature 'assignment + '((assignment_expression left: (_) @rust-ts-mode--fontify-pattern) + (compound_assignment_expr left: (_) @rust-ts-mode--fontify-pattern)) :language 'rust :feature 'function @@ -206,7 +205,54 @@ :language 'rust :feature 'type - `((enum_variant name: (identifier) @font-lock-type-face) + `((scoped_use_list path: (identifier) @font-lock-constant-face) + (scoped_use_list path: (scoped_identifier + name: (identifier) @font-lock-constant-face)) + + ((use_as_clause alias: (identifier) @font-lock-type-face) + (:match "^[A-Z]" @font-lock-type-face)) + ((use_as_clause path: (identifier) @font-lock-type-face) + (:match "^[A-Z]" @font-lock-type-face)) + ((use_as_clause path: + (scoped_identifier path: (_) + name: (identifier) @font-lock-type-face)) + (:match "^[A-Z]" @font-lock-type-face)) + (use_as_clause path: (scoped_identifier name: (identifier) @default)) + + ((use_declaration + argument: (scoped_identifier + path: (_) @font-lock-constant-face + name: (identifier) @font-lock-type-face)) + (:match "^[A-Z]" @font-lock-type-face)) + (use_declaration + argument: (scoped_identifier + name: (identifier) @default)) + + (use_declaration + argument: (scoped_identifier + path: (scoped_identifier + path: (_) @font-lock-constant-face + name: (identifier) @font-lock-constant-face) + name: (identifier) @default)) + + (use_declaration + argument: (scoped_use_list + path: (scoped_identifier + path: (_) @font-lock-constant-face + name: (identifier) @font-lock-constant-face))) + + ((use_list (identifier) @font-lock-type-face) + (:match "^[A-Z]" @font-lock-type-face)) + (use_list (identifier) @default) + ((use_list (scoped_identifier path: (_) + name: (identifier) @font-lock-type-face)) + (:match "^[A-Z]" @font-lock-type-face)) + (use_list (scoped_identifier path: (_) + name: (identifier) @default)) + (use_wildcard (scoped_identifier + name: (identifier) @font-lock-constant-face)) + + (enum_variant name: (identifier) @font-lock-type-face) (match_arm pattern: (match_pattern (_ type: (identifier) @font-lock-type-face))) (match_arm @@ -221,24 +267,39 @@ ((scoped_identifier path: (identifier) @font-lock-type-face) (:match "^[A-Z]" @font-lock-type-face)) ((scoped_identifier - (scoped_identifier - path: (identifier) @font-lock-type-face)) - (:match "^[A-Z]" @font-lock-type-face)) - ((scoped_identifier path: [(identifier) @font-lock-type-face (scoped_identifier name: (identifier) @font-lock-type-face)]) (:match "^[A-Z]" @font-lock-type-face)) - (scoped_type_identifier path: (identifier) @font-lock-type-face) + ((scoped_identifier path: (identifier) @font-lock-type-face) + (:match + "^\\(u8\\|u16\\|u32\\|u64\\|u128\\|usize\\|i8\\|i16\\|i32\\|i64\\|i128\\|isize\\|char\\|str\\)$" + @font-lock-type-face)) + (scoped_identifier path: (_) @font-lock-constant-face + name: (identifier) @font-lock-type-face) + (scoped_identifier path: (scoped_identifier + name: (identifier) @font-lock-constant-face)) + (scoped_type_identifier path: (_) @font-lock-constant-face) + (scoped_type_identifier + path: (scoped_identifier + path: (_) @font-lock-constant-face + name: (identifier) @font-lock-constant-face)) (type_identifier) @font-lock-type-face - (use_as_clause alias: (identifier) @font-lock-type-face) - (use_list (identifier) @font-lock-type-face)) + ;; Ensure function calls aren't highlighted as types. + (call_expression function: (scoped_identifier name: (identifier) @default))) :language 'rust :feature 'property '((field_identifier) @font-lock-property-face (shorthand_field_initializer (identifier) @font-lock-property-face)) + ;; Must be under type, otherwise some imports can be highlighted as constants. + :language 'rust + :feature 'constant + `((boolean_literal) @font-lock-constant-face + ((identifier) @font-lock-constant-face + (:match "^[A-Z][A-Z\\d_]*$" @font-lock-constant-face))) + :language 'rust :feature 'variable '((identifier) @font-lock-variable-name-face @@ -261,7 +322,7 @@ (treesit-available-p) `(lambda (node override start end &rest _) (let ((captures (treesit-query-capture - (treesit-node-child-by-field-name node "pattern") + node ,(treesit-query-compile 'rust '((identifier) @id (shorthand_field_identifier) @id))))) (pcase-dolist (`(_name . ,id) captures) @@ -342,7 +403,7 @@ delimiters < and >'s." (setq-local treesit-font-lock-feature-list '(( comment definition) ( keyword string) - ( attribute builtin constant escape-sequence + ( assignment attribute builtin constant escape-sequence number type) ( bracket delimiter error function operator property variable))) diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el index 561b90deedd..88a1ff3e202 100644 --- a/lisp/progmodes/typescript-ts-mode.el +++ b/lisp/progmodes/typescript-ts-mode.el @@ -86,6 +86,7 @@ Argument LANGUAGE is either `typescript' or `tsx'." ((parent-is "arguments") parent-bol typescript-ts-mode-indent-offset) ((parent-is "array") parent-bol typescript-ts-mode-indent-offset) ((parent-is "formal_parameters") parent-bol typescript-ts-mode-indent-offset) + ((parent-is "template_string") no-indent) ; Don't indent the string contents. ((parent-is "template_substitution") parent-bol typescript-ts-mode-indent-offset) ((parent-is "object_pattern") parent-bol typescript-ts-mode-indent-offset) ((parent-is "object") parent-bol typescript-ts-mode-indent-offset) diff --git a/lisp/repeat.el b/lisp/repeat.el index 37d4aaec985..2fcac4d2ce3 100644 --- a/lisp/repeat.el +++ b/lisp/repeat.el @@ -359,8 +359,8 @@ This property can override the value of this variable." :group 'repeat :version "28.1") -(defvar repeat-exit-function nil - "Function that exits the repeating sequence.") +(defvar repeat--transient-exitfun nil + "Function returned by `set-transient-map'.") (defvar repeat-exit-timer nil "Timer activated after the last key typed in the repeating key sequence.") @@ -517,9 +517,9 @@ See `describe-repeat-maps' for a list of all repeatable commands." 'ignore)) (setq repeat-in-progress t) - (repeat--exit) + (repeat--clear-prev) (let ((exitfun (set-transient-map map))) - (setq repeat-exit-function exitfun) + (setq repeat--transient-exitfun exitfun) (let* ((prop (repeat--command-property 'repeat-exit-timeout)) (timeout (unless (eq prop 'no) (or prop repeat-exit-timeout)))) @@ -538,17 +538,17 @@ See `describe-repeat-maps' for a list of all repeatable commands." This function can be used to force exit of repetition while it's active." (interactive) (setq repeat-in-progress nil) - (repeat--exit) + (repeat--clear-prev) (funcall repeat-echo-function nil)) -(defun repeat--exit () +(defun repeat--clear-prev () "Internal function to clean up previously set exit function and timer." (when repeat-exit-timer (cancel-timer repeat-exit-timer) (setq repeat-exit-timer nil)) - (when repeat-exit-function - (funcall repeat-exit-function) - (setq repeat-exit-function nil))) + (when repeat--transient-exitfun + (funcall repeat--transient-exitfun) + (setq repeat--transient-exitfun nil))) (defun repeat-echo-message-string (keymap) "Return a string with the list of repeating keys in KEYMAP." diff --git a/lisp/subr.el b/lisp/subr.el index db33483f509..a0a22072a18 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3946,30 +3946,51 @@ See also `locate-user-emacs-file'.") "Return non-nil if the current buffer is narrowed." (/= (- (point-max) (point-min)) (buffer-size))) -(defmacro with-narrowing (start end &rest rest) +(defmacro with-restriction (start end &rest rest) "Execute BODY with restrictions set to START and END. The current restrictions, if any, are restored upon return. -With the optional :locked TAG argument, inside BODY, -`narrow-to-region' and `widen' can be used only within the START -and END limits, unless the restrictions are unlocked by calling -`narrowing-unlock' with TAG. See `narrowing-lock' for a more -detailed description. +When the optional :label LABEL argument is present, in which +LABEL is a symbol, inside BODY, `narrow-to-region' and `widen' +can be used only within the START and END limits. To gain access +to other portions of the buffer, use `without-restriction' with the +same LABEL argument. -\(fn START END [:locked TAG] BODY)" - (if (eq (car rest) :locked) - `(internal--with-narrowing ,start ,end (lambda () ,@(cddr rest)) +\(fn START END [:label LABEL] BODY)" + (if (eq (car rest) :label) + `(internal--with-restriction ,start ,end (lambda () ,@(cddr rest)) ,(cadr rest)) - `(internal--with-narrowing ,start ,end (lambda () ,@rest)))) + `(internal--with-restriction ,start ,end (lambda () ,@rest)))) -(defun internal--with-narrowing (start end body &optional tag) - "Helper function for `with-narrowing', which see." +(defun internal--with-restriction (start end body &optional label) + "Helper function for `with-restriction', which see." (save-restriction - (progn - (narrow-to-region start end) - (if tag (narrowing-lock tag)) - (funcall body)))) + (narrow-to-region start end) + (if label (internal--lock-narrowing label)) + (funcall body))) + +(defmacro without-restriction (&rest rest) + "Execute BODY without restrictions. + +The current restrictions, if any, are restored upon return. + +When the optional :label LABEL argument is present, the +restrictions set by `with-restriction' with the same LABEL argument +are lifted. + +\(fn [:label LABEL] BODY)" + (if (eq (car rest) :label) + `(internal--without-restriction (lambda () ,@(cddr rest)) + ,(cadr rest)) + `(internal--without-restriction (lambda () ,@rest)))) + +(defun internal--without-restriction (body &optional label) + "Helper function for `without-restriction', which see." + (save-restriction + (if label (internal--unlock-narrowing label)) + (widen) + (funcall body))) (defun find-tag-default-bounds () "Determine the boundaries of the default tag, based on text at point. diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el index b844955e1be..c5e7b8f4bc6 100644 --- a/lisp/textmodes/emacs-news-mode.el +++ b/lisp/textmodes/emacs-news-mode.el @@ -53,13 +53,28 @@ :parent emacs-news-common-map "C-c C-s" #'emacs-news-next-untagged-entry "C-c C-r" #'emacs-news-previous-untagged-entry - "C-c C-t" #'emacs-news-toggle-tag + "C-c C-t" #'emacs-news-cycle-tag + "C-c C-d" #'emacs-news-delete-temporary-markers "C-c C-g" #'emacs-news-goto-section "C-c C-j" #'emacs-news-find-heading "C-c C-e" #'emacs-news-count-untagged-entries "C-x C-q" #'emacs-news-view-mode "<remap> <open-line>" #'emacs-news-open-line) +(easy-menu-define emacs-news-mode-menu emacs-news-mode-map + "Menu for `emacs-news-mode'." + '("News" + ["Next Untagged" emacs-news-next-untagged-entry :help "Go to next untagged entry"] + ["Previous Untagged" emacs-news-previous-untagged-entry :help "Go to previous untagged entry"] + ["Count Untagged" emacs-news-count-untagged-entries :help "Count the number of untagged entries"] + ["Cycle Tag" emacs-news-cycle-tag :help "Cycle documentation tag of current entry"] + ["Delete Tags" emacs-news-delete-temporary-markers :help "Delete all documentation tags in buffer"] + "--" + ["Goto Section" emacs-news-goto-section :help "Prompt for section and go to it"] + ["Goto Heading" emacs-news-find-heading :help "Prompt for heading and go to it"] + "--" + ["Enter View Mode" emacs-news-view-mode :help "Enter view-only mode"])) + (defvar emacs-news-view-mode-map ;; This is defined this way instead of inheriting because we're ;; deriving the mode from `special-mode' and want the keys from there. @@ -173,8 +188,8 @@ untagged NEWS entry." (interactive nil emacs-news-mode) (emacs-news-next-untagged-entry t)) -(defun emacs-news-toggle-tag () - "Toggle documentation tag of current headline in the Emacs NEWS file." +(defun emacs-news-cycle-tag () + "Cycle documentation tag of current headline in the Emacs NEWS file." (interactive nil emacs-news-mode) (save-excursion (goto-char (line-beginning-position)) @@ -191,7 +206,7 @@ untagged NEWS entry." (insert "+++")) ((looking-at (rx bol "+++" eol)) (delete-char 4)) - (t (user-error "Invalid headline tag; can't toggle"))))) + (t (user-error "Invalid headline tag; can't cycle"))))) (defun emacs-news-count-untagged-entries () "Say how many untagged entries there are in the current NEWS buffer." diff --git a/lisp/transient.el b/lisp/transient.el index 73ea6fa940e..c0ecd2950d7 100644 --- a/lisp/transient.el +++ b/lisp/transient.el @@ -965,7 +965,7 @@ keyword. Only use this alias to define an infix command that actually sets an infix argument. To define a infix command that, for -example, sets a variable use `transient-define-infix' instead. +example, sets a variable, use `transient-define-infix' instead. \(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)") @@ -1509,18 +1509,8 @@ then just return it. Otherwise return the symbol whose ;;; Keymaps -(defvar transient-base-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "ESC ESC ESC") #'transient-quit-all) - (define-key map (kbd "C-g") #'transient-quit-one) - (define-key map (kbd "C-q") #'transient-quit-all) - (define-key map (kbd "C-z") #'transient-suspend) - (define-key map (kbd "C-v") #'transient-scroll-up) - (define-key map (kbd "C-M-v") #'transient-scroll-down) - (define-key map [next] #'transient-scroll-up) - (define-key map [prior] #'transient-scroll-down) - map) - "Parent of other keymaps used by Transient. +(defvar-keymap transient-base-map + :doc "Parent of other keymaps used by Transient. This is the parent keymap of all the keymaps that are used in all transients: `transient-map' (which in turn is the parent @@ -1533,40 +1523,42 @@ the latter isn't a proper transient prefix command, it can be edited using the same functions as used for transients. If you add a new command here, then you must also add a binding -to `transient-predicate-map'.") - -(defvar transient-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map transient-base-map) - (define-key map (kbd "C-u") #'universal-argument) - (define-key map (kbd "C--") #'negative-argument) - (define-key map (kbd "C-t") #'transient-show) - (define-key map (kbd "?") #'transient-help) - (define-key map (kbd "C-h") #'transient-help) - ;; Also bound to "C-x p" and "C-x n" in transient-common-commands. - (define-key map (kbd "C-M-p") #'transient-history-prev) - (define-key map (kbd "C-M-n") #'transient-history-next) - map) - "Top-level keymap used by all transients. +to `transient-predicate-map'." + "ESC ESC ESC" #'transient-quit-all + "C-g" #'transient-quit-one + "C-q" #'transient-quit-all + "C-z" #'transient-suspend + "C-v" #'transient-scroll-up + "C-M-v" #'transient-scroll-down + "<next>" #'transient-scroll-up + "<prior>" #'transient-scroll-down) + +(defvar-keymap transient-map + :doc "Top-level keymap used by all transients. If you add a new command here, then you must also add a binding -to `transient-predicate-map'. Also see `transient-base-map'.") - -(defvar transient-edit-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map transient-base-map) - (define-key map (kbd "?") #'transient-help) - (define-key map (kbd "C-h") #'transient-help) - (define-key map (kbd "C-x l") #'transient-set-level) - map) - "Keymap that is active while a transient in is in \"edit mode\".") - -(defvar transient-sticky-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map transient-base-map) - (define-key map (kbd "C-g") #'transient-quit-seq) - map) - "Keymap that is active while an incomplete key sequence is active.") +to `transient-predicate-map'. Also see `transient-base-map'." + :parent transient-base-map + "C-u" #'universal-argument + "C--" #'negative-argument + "C-t" #'transient-show + "?" #'transient-help + "C-h" #'transient-help + ;; Also bound to "C-x p" and "C-x n" in transient-common-commands. + "C-M-p" #'transient-history-prev + "C-M-n" #'transient-history-next) + +(defvar-keymap transient-edit-map + :doc "Keymap that is active while a transient in is in \"edit mode\"." + :parent transient-base-map + "?" #'transient-help + "C-h" #'transient-help + "C-x l" #'transient-set-level) + +(defvar-keymap transient-sticky-map + :doc "Keymap that is active while an incomplete key sequence is active." + :parent transient-base-map + "C-g" #'transient-quit-seq) (defvar transient--common-command-prefixes '(?\C-x)) @@ -1606,70 +1598,28 @@ to `transient-predicate-map'. Also see `transient-base-map'.") "Show common permanently"))) (list "C-x l" "Show/hide suffixes" #'transient-set-level)))))))) -(defvar transient-popup-navigation-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "<down-mouse-1>") #'transient-noop) - (define-key map (kbd "<up>") #'transient-backward-button) - (define-key map (kbd "<down>") #'transient-forward-button) - (define-key map (kbd "C-r") #'transient-isearch-backward) - (define-key map (kbd "C-s") #'transient-isearch-forward) - (define-key map (kbd "M-RET") #'transient-push-button) - map) - "One of the keymaps used when popup navigation is enabled. -See `transient-enable-popup-navigation'.") - -(defvar transient-button-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "<mouse-1>") #'transient-push-button) - (define-key map (kbd "<mouse-2>") #'transient-push-button) - map) - "One of the keymaps used when popup navigation is enabled. -See `transient-enable-popup-navigation'.") - -(defvar transient-predicate-map - (let ((map (make-sparse-keymap))) - (define-key map [transient-suspend] #'transient--do-suspend) - (define-key map [transient-help] #'transient--do-stay) - (define-key map [transient-set-level] #'transient--do-stay) - (define-key map [transient-history-prev] #'transient--do-stay) - (define-key map [transient-history-next] #'transient--do-stay) - (define-key map [universal-argument] #'transient--do-stay) - (define-key map [negative-argument] #'transient--do-minus) - (define-key map [digit-argument] #'transient--do-stay) - (define-key map [top-level] #'transient--do-quit-all) - (define-key map [transient-quit-all] #'transient--do-quit-all) - (define-key map [transient-quit-one] #'transient--do-quit-one) - (define-key map [transient-quit-seq] #'transient--do-stay) - (define-key map [transient-show] #'transient--do-stay) - (define-key map [transient-update] #'transient--do-stay) - (define-key map [transient-toggle-common] #'transient--do-stay) - (define-key map [transient-set] #'transient--do-call) - (define-key map [transient-save] #'transient--do-call) - (define-key map [transient-reset] #'transient--do-call) - (define-key map [describe-key-briefly] #'transient--do-stay) - (define-key map [describe-key] #'transient--do-stay) - (define-key map [transient-scroll-up] #'transient--do-stay) - (define-key map [transient-scroll-down] #'transient--do-stay) - (define-key map [mwheel-scroll] #'transient--do-stay) - (define-key map [scroll-bar-toolkit-scroll] #'transient--do-stay) - (define-key map [transient-noop] #'transient--do-noop) - (define-key map [transient-mouse-push-button] #'transient--do-move) - (define-key map [transient-push-button] #'transient--do-push-button) - (define-key map [transient-backward-button] #'transient--do-move) - (define-key map [transient-forward-button] #'transient--do-move) - (define-key map [transient-isearch-backward] #'transient--do-move) - (define-key map [transient-isearch-forward] #'transient--do-move) - ;; If a valid but incomplete prefix sequence is followed by - ;; an unbound key, then Emacs calls the `undefined' command - ;; but does not set `this-command', `this-original-command' - ;; or `real-this-command' accordingly. Instead they are nil. - (define-key map [nil] #'transient--do-warn) - map) - "Base keymap used to map common commands to their transient behavior. +(defvar-keymap transient-popup-navigation-map + :doc "One of the keymaps used when popup navigation is enabled. +See `transient-enable-popup-navigation'." + "<down-mouse-1>" #'transient-noop + "<up>" #'transient-backward-button + "<down>" #'transient-forward-button + "C-r" #'transient-isearch-backward + "C-s" #'transient-isearch-forward + "M-RET" #'transient-push-button) + +(defvar-keymap transient-button-map + :doc "One of the keymaps used when popup navigation is enabled. +See `transient-enable-popup-navigation'." + "<mouse-1>" #'transient-push-button + "<mouse-2>" #'transient-push-button) + +(defvar-keymap transient-predicate-map + :doc "Base keymap used to map common commands to their transient behavior. The \"transient behavior\" of a command controls, among other things, whether invoking the command causes the transient to be -exited or not and whether infix arguments are exported before +exited or not, and whether infix arguments are exported before doing so. Each \"key\" is a command that is common to all transients and @@ -1681,7 +1631,43 @@ transient behavior of the respective command. For transient commands that are bound in individual transients, the transient behavior is specified using the `:transient' slot -of the corresponding object.") +of the corresponding object." + "<transient-suspend>" #'transient--do-suspend + "<transient-help>" #'transient--do-stay + "<transient-set-level>" #'transient--do-stay + "<transient-history-prev>" #'transient--do-stay + "<transient-history-next>" #'transient--do-stay + "<universal-argument>" #'transient--do-stay + "<negative-argument>" #'transient--do-minus + "<digit-argument>" #'transient--do-stay + "<top-level>" #'transient--do-quit-all + "<transient-quit-all>" #'transient--do-quit-all + "<transient-quit-one>" #'transient--do-quit-one + "<transient-quit-seq>" #'transient--do-stay + "<transient-show>" #'transient--do-stay + "<transient-update>" #'transient--do-stay + "<transient-toggle-common>" #'transient--do-stay + "<transient-set>" #'transient--do-call + "<transient-save>" #'transient--do-call + "<transient-reset>" #'transient--do-call + "<describe-key-briefly>" #'transient--do-stay + "<describe-key>" #'transient--do-stay + "<transient-scroll-up>" #'transient--do-stay + "<transient-scroll-down>" #'transient--do-stay + "<mwheel-scroll>" #'transient--do-stay + "<scroll-bar-toolkit-scroll>" #'transient--do-stay + "<transient-noop>" #'transient--do-noop + "<transient-mouse-push-button>" #'transient--do-move + "<transient-push-button>" #'transient--do-push-button + "<transient-backward-button>" #'transient--do-move + "<transient-forward-button>" #'transient--do-move + "<transient-isearch-backward>" #'transient--do-move + "<transient-isearch-forward>" #'transient--do-move + ;; If a valid but incomplete prefix sequence is followed by + ;; an unbound key, then Emacs calls the `undefined' command + ;; but does not set `this-command', `this-original-command' + ;; or `real-this-command' accordingly. Instead they are nil. + "<nil>" #'transient--do-warn) (defvar transient--transient-map nil) (defvar transient--predicate-map nil) @@ -1725,9 +1711,9 @@ of the corresponding object.") (string-trim key) cmd conflict))) (define-key map kbd cmd)))) - (when-let ((b (lookup-key map "-"))) (define-key map [kp-subtract] b)) - (when-let ((b (lookup-key map "="))) (define-key map [kp-equal] b)) - (when-let ((b (lookup-key map "+"))) (define-key map [kp-add] b)) + (when-let ((b (keymap-lookup map "-"))) (keymap-set map "<kp-subtract>" b)) + (when-let ((b (keymap-lookup map "="))) (keymap-set map "<kp-equal>" b)) + (when-let ((b (keymap-lookup map "+"))) (keymap-set map "<kp-add>" b)) (when transient-enable-popup-navigation ;; `transient--make-redisplay-map' maps only over bindings that are ;; directly in the base keymap, so that cannot be a composed keymap. @@ -1742,7 +1728,7 @@ of the corresponding object.") (set-keymap-parent map transient-predicate-map) (when (memq (oref transient--prefix transient-non-suffix) '(nil transient--do-warn transient--do-noop)) - (define-key map [handle-switch-frame] #'transient--do-suspend)) + (keymap-set map "<handle-switch-frame>" #'transient--do-suspend)) (dolist (obj transient--suffixes) (let* ((cmd (oref obj command)) (sub-prefix (and (symbolp cmd) (get cmd 'transient--prefix) t)) @@ -1810,8 +1796,8 @@ of the corresponding object.") This function is called by transient prefix commands to setup the transient. In that case NAME is mandatory, LAYOUT and EDIT must -be nil and PARAMS may be (but usually is not) used to set e.g. the -\"scope\" of the transient (see `transient-define-prefix'). +be nil and PARAMS may be (but usually is not) used to set, e.g., +the \"scope\" of the transient (see `transient-define-prefix'). This function is also called internally in which case LAYOUT and EDIT may be non-nil." @@ -2587,10 +2573,10 @@ transient is active." (defvar transient-resume-mode) -(defun transient-help () - "Show help for the active transient or one of its suffixes." - (interactive) - (if (called-interactively-p 'any) +(defun transient-help (&optional interactive) + "Show help for the active transient or one of its suffixes.\n\n(fn)" + (interactive (list t)) + (if interactive (setq transient--helpp t) (with-demoted-errors "transient-help: %S" (when (lookup-key transient--transient-map @@ -3831,17 +3817,15 @@ Suffixes on levels %s and %s are unavailable.\n" (propertize (format ">=%s" (1+ level)) 'face 'transient-disabled-suffix)))))) -(defvar transient-resume-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [remap Man-quit] #'transient-resume) - (define-key map [remap Info-exit] #'transient-resume) - (define-key map [remap quit-window] #'transient-resume) - map) - "Keymap for `transient-resume-mode'. +(defvar-keymap transient-resume-mode-map + :doc "Keymap for `transient-resume-mode'. This keymap remaps every command that would usually just quit the documentation buffer to `transient-resume', which additionally -resumes the suspended transient.") +resumes the suspended transient." + "<remap> <Man-quit>" #'transient-resume + "<remap> <Info-exit>" #'transient-resume + "<remap> <quit-window>" #'transient-resume) (define-minor-mode transient-resume-mode "Auxiliary minor-mode used to resume a transient after viewing help.") @@ -3901,13 +3885,11 @@ See `forward-button' for information about N." ;;; Compatibility ;;;; Popup Isearch -(defvar transient--isearch-mode-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map isearch-mode-map) - (define-key map [remap isearch-exit] #'transient-isearch-exit) - (define-key map [remap isearch-cancel] #'transient-isearch-cancel) - (define-key map [remap isearch-abort] #'transient-isearch-abort) - map)) +(defvar-keymap transient--isearch-mode-map + :parent isearch-mode-map + "<remap> <isearch-exit>" #'transient-isearch-exit + "<remap> <isearch-cancel>" #'transient-isearch-cancel + "<remap> <isearch-abort>" #'transient-isearch-abort) (defun transient-isearch-backward (&optional regexp-p) "Do incremental search backward. @@ -4034,8 +4016,8 @@ that does that. Of course \"Q\" may already be bound to something else, so that function binds \"M-q\" to that command instead. Of course \"M-q\" may already be bound to something else, but we stop there." - (define-key transient-base-map "q" #'transient-quit-one) - (define-key transient-sticky-map "q" #'transient-quit-seq) + (keymap-set transient-base-map "q" #'transient-quit-one) + (keymap-set transient-sticky-map "q" #'transient-quit-seq) (setq transient-substitute-key-function #'transient-rebind-quit-commands)) diff --git a/src/buffer.c b/src/buffer.c index 38648519ba0..df1f5206668 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5916,40 +5916,41 @@ If nil, these display shortcuts will always remain disabled. There is no reason to change that value except for debugging purposes. */); XSETFASTINT (Vlong_line_threshold, 50000); - DEFVAR_INT ("long-line-locked-narrowing-region-size", - long_line_locked_narrowing_region_size, - doc: /* Region size for locked narrowing in buffers with long lines. + DEFVAR_INT ("long-line-optimizations-region-size", + long_line_optimizations_region_size, + doc: /* Region size for narrowing in buffers with long lines. -This variable has effect only in buffers which contain one or more -lines whose length is above `long-line-threshold', which see. For -performance reasons, in such buffers, low-level hooks such as -`fontification-functions' or `post-command-hook' are executed on a -narrowed buffer, with a narrowing locked with `narrowing-lock'. This -variable specifies the size of the narrowed region around point. +This variable has effect only in buffers in which +`long-line-optimizations-p' is non-nil. For performance reasons, in +such buffers, the `fontification-functions', `pre-command-hook' and +`post-command-hook' hooks are executed on a narrowed buffer around +point, as if they were called in a `with-restriction' form with a label. +This variable specifies the size of the narrowed region around point. To disable that narrowing, set this variable to 0. -See also `long-line-locked-narrowing-bol-search-limit'. +See also `long-line-optimizations-bol-search-limit'. There is no reason to change that value except for debugging purposes. */); - long_line_locked_narrowing_region_size = 500000; + long_line_optimizations_region_size = 500000; - DEFVAR_INT ("long-line-locked-narrowing-bol-search-limit", - long_line_locked_narrowing_bol_search_limit, + DEFVAR_INT ("long-line-optimizations-bol-search-limit", + long_line_optimizations_bol_search_limit, doc: /* Limit for beginning of line search in buffers with long lines. -This variable has effect only in buffers which contain one or more -lines whose length is above `long-line-threshold', which see. For -performance reasons, in such buffers, low-level hooks such as -`fontification-functions' or `post-command-hook' are executed on a -narrowed buffer, with a narrowing locked with `narrowing-lock'. The -variable `long-line-locked-narrowing-region-size' specifies the size -of the narrowed region around point. This variable, which should be a -small integer, specifies the number of characters by which that region -can be extended backwards to make it start at the beginning of a line. +This variable has effect only in buffers in which +`long-line-optimizations-p' is non-nil. For performance reasons, in +such buffers, the `fontification-functions', `pre-command-hook' and +`post-command-hook' hooks are executed on a narrowed buffer around +point, as if they were called in a `with-restriction' form with a label. +The variable `long-line-optimizations-region-size' specifies the +size of the narrowed region around point. This variable, which should +be a small integer, specifies the number of characters by which that +region can be extended backwards to make it start at the beginning of +a line. There is no reason to change that value except for debugging purposes. */); - long_line_locked_narrowing_bol_search_limit = 128; + long_line_optimizations_bol_search_limit = 128; DEFVAR_INT ("large-hscroll-threshold", large_hscroll_threshold, doc: /* Horizontal scroll of truncated lines above which to use redisplay shortcuts. diff --git a/src/editfns.c b/src/editfns.c index 78d2c73ecbf..f83c5c7259b 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2659,7 +2659,11 @@ DEFUN ("delete-and-extract-region", Fdelete_and_extract_region, the (uninterned) Qoutermost_narrowing tag and records the narrowing bounds that were set by the user and that are visible on display. This alist is used internally by narrow-to-region, widen, - narrowing-lock, narrowing-unlock and save-restriction. */ + internal--lock-narrowing, internal--unlock-narrowing and + save-restriction. For efficiency reasons, an alist is used instead + of a buffer-local variable: otherwise reset_outermost_narrowings, + which is called during each redisplay cycle, would have to loop + through all live buffers. */ static Lisp_Object narrowing_locks; /* Add BUF with its LOCKS in the narrowing_locks alist. */ @@ -2763,7 +2767,10 @@ unwind_reset_outermost_narrowing (Lisp_Object buf) In particular, this function is called when redisplay starts, so that if a Lisp function executed during redisplay calls (redisplay) while a locked narrowing is in effect, the locked narrowing will - not be visible on display. */ + not be visible on display. + See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57207#140 and + https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57207#254 for example + recipes that demonstrate why this is necessary. */ void reset_outermost_narrowings (void) { @@ -2792,27 +2799,25 @@ narrowing_locks_save (void) { Lisp_Object buf = Fcurrent_buffer (); Lisp_Object locks = assq_no_quit (buf, narrowing_locks); - if (NILP (locks)) - return Qnil; - locks = XCAR (XCDR (locks)); + if (!NILP (locks)) + locks = XCAR (XCDR (locks)); return Fcons (buf, Fcopy_sequence (locks)); } static void narrowing_locks_restore (Lisp_Object buf_and_saved_locks) { - if (NILP (buf_and_saved_locks)) - return; Lisp_Object buf = XCAR (buf_and_saved_locks); Lisp_Object saved_locks = XCDR (buf_and_saved_locks); narrowing_locks_remove (buf); - narrowing_locks_add (buf, saved_locks); + if (!NILP (saved_locks)) + narrowing_locks_add (buf, saved_locks); } static void unwind_narrow_to_region_locked (Lisp_Object tag) { - Fnarrowing_unlock (tag); + Finternal__unlock_narrowing (tag); Fwiden (); } @@ -2821,7 +2826,7 @@ void narrow_to_region_locked (Lisp_Object begv, Lisp_Object zv, Lisp_Object tag) { Fnarrow_to_region (begv, zv); - Fnarrowing_lock (tag); + Finternal__lock_narrowing (tag); record_unwind_protect (restore_point_unwind, Fpoint_marker ()); record_unwind_protect (unwind_narrow_to_region_locked, tag); } @@ -2829,10 +2834,12 @@ narrow_to_region_locked (Lisp_Object begv, Lisp_Object zv, Lisp_Object tag) DEFUN ("widen", Fwiden, Swiden, 0, 0, "", doc: /* Remove restrictions (narrowing) from current buffer. -This allows the buffer's full text to be seen and edited, unless -restrictions have been locked with `narrowing-lock', which see, in -which case the narrowing that was current when `narrowing-lock' was -called is restored. */) +This allows the buffer's full text to be seen and edited. + +However, when restrictions have been set by `with-restriction' with a +label, `widen' restores the narrowing limits set by `with-restriction'. +To gain access to other portions of the buffer, use +`without-restriction' with the same label. */) (void) { Fset (Qoutermost_narrowing, Qnil); @@ -2879,11 +2886,12 @@ When calling from Lisp, pass two arguments START and END: positions (integers or markers) bounding the text that should remain visible. -When restrictions have been locked with `narrowing-lock', which see, -`narrow-to-region' can be used only within the limits of the -restrictions that were current when `narrowing-lock' was called. If -the START or END arguments are outside these limits, the corresponding -limit of the locked restriction is used instead of the argument. */) +However, when restrictions have been set by `with-restriction' with a +label, `narrow-to-region' can be used only within the limits of these +restrictions. If the START or END arguments are outside these limits, +the corresponding limit set by `with-restriction' is used instead of the +argument. To gain access to other portions of the buffer, use +`without-restriction' with the same label. */) (Lisp_Object start, Lisp_Object end) { EMACS_INT s = fix_position (start), e = fix_position (end); @@ -2912,7 +2920,7 @@ limit of the locked restriction is used instead of the argument. */) /* Record the accessible range of the buffer when narrow-to-region is called, that is, before applying the narrowing. It is used - only by narrowing-lock. */ + only by internal--lock-narrowing. */ Fset (Qoutermost_narrowing, list3 (Qoutermost_narrowing, Fpoint_min_marker (), Fpoint_max_marker ())); @@ -2932,31 +2940,18 @@ limit of the locked restriction is used instead of the argument. */) return Qnil; } -DEFUN ("narrowing-lock", Fnarrowing_lock, Snarrowing_lock, 1, 1, 0, - doc: /* Lock the current narrowing with TAG. +DEFUN ("internal--lock-narrowing", Finternal__lock_narrowing, + Sinternal__lock_narrowing, 1, 1, 0, + doc: /* Lock the current narrowing with LABEL. -When restrictions are locked, `narrow-to-region' and `widen' can be -used only within the limits of the restrictions that were current when -`narrowing-lock' was called, unless the lock is removed by calling -`narrowing-unlock' with TAG. - -Locking restrictions should be used sparingly, after carefully -considering the potential adverse effects on the code that will be -executed within locked restrictions. It is typically meant to be used -around portions of code that would become too slow, and make Emacs -unresponsive, if they were executed in a large buffer. For example, -restrictions are locked by Emacs around low-level hooks such as -`fontification-functions' or `post-command-hook'. - -Locked restrictions are never visible on display, and can therefore -not be used as a stronger variant of normal restrictions. */) +This is an internal function used by `with-restriction'. */) (Lisp_Object tag) { Lisp_Object buf = Fcurrent_buffer (); Lisp_Object outermost_narrowing = buffer_local_value (Qoutermost_narrowing, buf); - /* If narrowing-lock is called without being preceded by - narrow-to-region, do nothing. */ + /* If internal--lock-narrowing is ever called without being preceded + by narrow-to-region, do nothing. */ if (NILP (outermost_narrowing)) return Qnil; if (NILP (narrowing_lock_peek_tag (buf))) @@ -2967,16 +2962,11 @@ not be used as a stronger variant of normal restrictions. */) return Qnil; } -DEFUN ("narrowing-unlock", Fnarrowing_unlock, Snarrowing_unlock, 1, 1, 0, - doc: /* Unlock a narrowing locked with (narrowing-lock TAG). +DEFUN ("internal--unlock-narrowing", Finternal__unlock_narrowing, + Sinternal__unlock_narrowing, 1, 1, 0, + doc: /* Unlock a narrowing locked with LABEL. -Unlocking restrictions locked with `narrowing-lock' should be used -sparingly, after carefully considering the reasons why restrictions -were locked. Restrictions are typically locked around portions of -code that would become too slow, and make Emacs unresponsive, if they -were executed in a large buffer. For example, restrictions are locked -by Emacs around low-level hooks such as `fontification-functions' or -`post-command-hook'. */) +This is an internal function used by `without-restriction'. */) (Lisp_Object tag) { Lisp_Object buf = Fcurrent_buffer (); @@ -2985,8 +2975,8 @@ by Emacs around low-level hooks such as `fontification-functions' or return Qnil; } -Lisp_Object -save_restriction_save (void) +static Lisp_Object +save_restriction_save_1 (void) { if (BEGV == BEG && ZV == Z) /* The common case that the buffer isn't narrowed. @@ -3009,8 +2999,8 @@ save_restriction_save (void) } } -void -save_restriction_restore (Lisp_Object data) +static void +save_restriction_restore_1 (Lisp_Object data) { struct buffer *cur = NULL; struct buffer *buf = (CONSP (data) @@ -3078,13 +3068,28 @@ save_restriction_restore (Lisp_Object data) set_buffer_internal (cur); } +Lisp_Object +save_restriction_save (void) +{ + Lisp_Object restr = save_restriction_save_1 (); + Lisp_Object locks = narrowing_locks_save (); + return Fcons (restr, locks); +} + +void +save_restriction_restore (Lisp_Object data) +{ + narrowing_locks_restore (XCDR (data)); + save_restriction_restore_1 (XCAR (data)); +} + DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0, doc: /* Execute BODY, saving and restoring current buffer's restrictions. The buffer's restrictions make parts of the beginning and end invisible. \(They are set up with `narrow-to-region' and eliminated with `widen'.) This special form, `save-restriction', saves the current buffer's -restrictions, as well as their locks if they have been locked with -`narrowing-lock', when it is entered, and restores them when it is exited. +restrictions, including those that were set by `with-restriction' with a +label argument, when it is entered, and restores them when it is exited. So any `narrow-to-region' within BODY lasts only until the end of the form. The old restrictions settings are restored even in case of abnormal exit \(throw or error). @@ -3102,7 +3107,6 @@ usage: (save-restriction &rest BODY) */) specpdl_ref count = SPECPDL_INDEX (); record_unwind_protect (save_restriction_restore, save_restriction_save ()); - record_unwind_protect (narrowing_locks_restore, narrowing_locks_save ()); val = Fprogn (body); return unbind_to (count, val); } @@ -4903,8 +4907,8 @@ it to be non-nil. */); defsubr (&Sdelete_and_extract_region); defsubr (&Swiden); defsubr (&Snarrow_to_region); - defsubr (&Snarrowing_lock); - defsubr (&Snarrowing_unlock); + defsubr (&Sinternal__lock_narrowing); + defsubr (&Sinternal__unlock_narrowing); defsubr (&Ssave_restriction); defsubr (&Stranspose_regions); } diff --git a/src/keyboard.c b/src/keyboard.c index 6f0f075e54e..b2816f8270b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1910,12 +1910,13 @@ safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w) specbind (Qinhibit_quit, Qt); if (current_buffer->long_line_optimizations_p - && long_line_locked_narrowing_region_size > 0) + && long_line_optimizations_region_size > 0) { ptrdiff_t begv = get_locked_narrowing_begv (PT); ptrdiff_t zv = get_locked_narrowing_zv (PT); if (begv != BEG || zv != Z) - narrow_to_region_locked (make_fixnum (begv), make_fixnum (zv), hook); + narrow_to_region_locked (make_fixnum (begv), make_fixnum (zv), + Qlong_line_optimizations_in_command_hooks); } run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), @@ -12168,6 +12169,8 @@ syms_of_keyboard (void) /* Hooks to run before and after each command. */ DEFSYM (Qpre_command_hook, "pre-command-hook"); DEFSYM (Qpost_command_hook, "post-command-hook"); + DEFSYM (Qlong_line_optimizations_in_command_hooks, + "long-line-optimizations-in-command-hooks"); /* Hook run after the region is selected. */ DEFSYM (Qpost_select_region_hook, "post-select-region-hook"); @@ -12728,13 +12731,11 @@ If an unhandled error happens in running this hook, the function in which the error occurred is unconditionally removed, since otherwise the error might happen repeatedly and make Emacs nonfunctional. -Note that, when the current buffer contains one or more lines whose -length is above `long-line-threshold', these hook functions are called -with the buffer narrowed to a small portion around point (whose size -is specified by `long-line-locked-narrowing-region-size'), and the -narrowing is locked (see `narrowing-lock'), so that these hook -functions cannot use `widen' to gain access to other portions of -buffer text. +Note that, when `long-line-optimizations-p' is non-nil in the buffer, +these functions are called as if they were in a `with-restriction' form, +with a `long-line-optimizations-in-command-hooks' label and with the +buffer narrowed to a portion around point whose size is specified by +`long-line-optimizations-region-size'. See also `post-command-hook'. */); Vpre_command_hook = Qnil; @@ -12750,13 +12751,11 @@ It is a bad idea to use this hook for expensive processing. If unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to avoid making Emacs unresponsive while the user types. -Note that, when the current buffer contains one or more lines whose -length is above `long-line-threshold', these hook functions are called -with the buffer narrowed to a small portion around point (whose size -is specified by `long-line-locked-narrowing-region-size'), and the -narrowing is locked (see `narrowing-lock'), so that these hook -functions cannot use `widen' to gain access to other portions of -buffer text. +Note that, when `long-line-optimizations-p' is non-nil in the buffer, +these functions are called as if they were in a `with-restriction' form, +with a `long-line-optimizations-in-command-hooks' label and with the +buffer narrowed to a portion around point whose size is specified by +`long-line-optimizations-region-size'. See also `pre-command-hook'. */); Vpost_command_hook = Qnil; diff --git a/src/xdisp.c b/src/xdisp.c index a19c9908616..1f630de7586 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -3536,11 +3536,11 @@ get_closer_narrowed_begv (struct window *w, ptrdiff_t pos) ptrdiff_t get_locked_narrowing_begv (ptrdiff_t pos) { - if (long_line_locked_narrowing_region_size <= 0) + if (long_line_optimizations_region_size <= 0) return BEGV; - int len = long_line_locked_narrowing_region_size / 2; + int len = long_line_optimizations_region_size / 2; int begv = max (pos - len, BEGV); - int limit = long_line_locked_narrowing_bol_search_limit; + int limit = long_line_optimizations_bol_search_limit; while (limit > 0) { if (begv == BEGV || FETCH_BYTE (CHAR_TO_BYTE (begv) - 1) == '\n') @@ -3554,9 +3554,9 @@ get_locked_narrowing_begv (ptrdiff_t pos) ptrdiff_t get_locked_narrowing_zv (ptrdiff_t pos) { - if (long_line_locked_narrowing_region_size <= 0) + if (long_line_optimizations_region_size <= 0) return ZV; - int len = long_line_locked_narrowing_region_size / 2; + int len = long_line_optimizations_region_size / 2; return min (pos + len, ZV); } @@ -4394,7 +4394,7 @@ handle_fontified_prop (struct it *it) eassert (it->end_charpos == ZV); if (current_buffer->long_line_optimizations_p - && long_line_locked_narrowing_region_size > 0) + && long_line_optimizations_region_size > 0) { ptrdiff_t begv = it->locked_narrowing_begv; ptrdiff_t zv = it->locked_narrowing_zv; @@ -4406,7 +4406,7 @@ handle_fontified_prop (struct it *it) } if (begv != BEG || zv != Z) narrow_to_region_locked (make_fixnum (begv), make_fixnum (zv), - Qfontification_functions); + Qlong_line_optimizations_in_fontification_functions); } /* Don't allow Lisp that runs from 'fontification-functions' @@ -13424,7 +13424,8 @@ gui_consider_frame_title (Lisp_Object frame) Fselect_window (f->selected_window, Qt); set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->contents)); - fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; + fmt = (FRAME_ICONIFIED_P (f) && !EQ (Vicon_title_format, Qt) + ? Vicon_title_format : Vframe_title_format); mode_line_target = MODE_LINE_TITLE; title_start = MODE_LINE_NOPROP_LEN (0); @@ -36266,6 +36267,8 @@ be let-bound around code that needs to disable messages temporarily. */); DEFSYM (QCfile, ":file"); DEFSYM (Qfontified, "fontified"); DEFSYM (Qfontification_functions, "fontification-functions"); + DEFSYM (Qlong_line_optimizations_in_fontification_functions, + "long-line-optimizations-in-fontification-functions"); /* Name of the symbol which disables Lisp evaluation in 'display' properties. This is used by enriched.el. */ @@ -36606,9 +36609,11 @@ which no explicit name has been set (see `modify-frame-parameters'). */); DEFVAR_LISP ("icon-title-format", Vicon_title_format, doc: /* Template for displaying the title bar of an iconified frame. \(Assuming the window manager supports this feature.) -This variable has the same structure as `mode-line-format' (which see), -and is used only on frames for which no explicit name has been set -\(see `modify-frame-parameters'). */); +If the value is a string, it should have the same structure +as `mode-line-format' (which see), and is used only on frames +for which no explicit name has been set \(see `modify-frame-parameters'). +If the value is t, that means use `frame-title-format' for +iconified frames. */); /* Do not nest calls to pure_list. This works around a bug in Oracle Developer Studio 12.6. */ Lisp_Object icon_title_name_format @@ -36775,12 +36780,11 @@ Each function is called with one argument POS. Functions must fontify a region starting at POS in the current buffer, and give fontified regions the property `fontified' with a non-nil value. -Note that, when the buffer contains one or more lines whose length is -above `long-line-threshold', these functions are called with the -buffer narrowed to a small portion around POS (whose size is specified -by `long-line-locked-narrowing-region-size'), and the narrowing is -locked (see `narrowing-lock'), so that these functions cannot use -`widen' to gain access to other portions of buffer text. */); +Note that, when `long-line-optimizations-p' is non-nil in the buffer, +these functions are called as if they were in a `with-restriction' form, +with a `long-line-optimizations-in-fontification-functions' label and +with the buffer narrowed to a portion around POS whose size is +specified by `long-line-optimizations-region-size'. */); Vfontification_functions = Qnil; Fmake_variable_buffer_local (Qfontification_functions); diff --git a/test/lisp/erc/erc-scenarios-base-reuse-buffers.el b/test/lisp/erc/erc-scenarios-base-reuse-buffers.el index d23a0b35904..71027a0c138 100644 --- a/test/lisp/erc/erc-scenarios-base-reuse-buffers.el +++ b/test/lisp/erc/erc-scenarios-base-reuse-buffers.el @@ -63,42 +63,6 @@ collisions involving bouncers in ERC. Run EXTRA." (should (cdr (erc-scenarios-common-buflist "127.0.0.1")))) (when more (funcall more port)))) -;; XXX maybe remove: already covered many times over by other scenarios -(ert-deftest erc-scenarios-base-reuse-buffers-server-buffers--enabled () - :tags '(:expensive-test) - (with-suppressed-warnings ((obsolete erc-reuse-buffers)) - (should erc-reuse-buffers)) - (let ((erc-scenarios-common-dialog "base/reuse-buffers/server")) - (erc-scenarios-common-with-cleanup - ((dumb-server (erc-d-run "localhost" t 'foonet 'barnet)) - (port (process-contact dumb-server :service)) - erc-autojoin-channels-alist) - - (ert-info ("Connect to foonet") - (with-current-buffer (erc :server "127.0.0.1" - :port port - :nick "tester" - :password "foonet:changeme" - :full-name "tester") - (should (string= (buffer-name) (format "127.0.0.1:%d" port))) - (erc-d-t-search-for 12 "marked as being away"))) - - (ert-info ("Connect to barnet") - (with-current-buffer (erc :server "127.0.0.1" - :port port - :nick "tester" - :password "barnet:changeme" - :full-name "tester") - (should (string= (buffer-name) (format "127.0.0.1:%d" port))) - (erc-d-t-search-for 45 "marked as being away"))) - - (erc-d-t-wait-for 2 (get-buffer "foonet")) - (erc-d-t-wait-for 2 (get-buffer "barnet")) - - (ert-info ("Server buffers are unique, no IP-based names") - (should-not (eq (get-buffer "foonet") (get-buffer "barnet"))) - (should-not (erc-scenarios-common-buflist "127.0.0.1")))))) - ;; FIXME no sense in running this twice (JOIN variant includes this) (ert-deftest erc-scenarios-base-reuse-buffers-server-buffers--disabled () :tags '(:expensive-test) diff --git a/test/lisp/erc/erc-scenarios-internal.el b/test/lisp/erc/erc-scenarios-internal.el index 8d38c2dde49..18eb94e24b0 100644 --- a/test/lisp/erc/erc-scenarios-internal.el +++ b/test/lisp/erc/erc-scenarios-internal.el @@ -21,6 +21,9 @@ (require 'ert-x) (eval-and-compile + (when (and (getenv "EMACS_TEST_DIRECTORY") + (getenv "EMACS_TEST_JUNIT_REPORT")) + (setq ert-load-file-name (or (macroexp-file-name) buffer-file-name))) (let ((load-path (cons (expand-file-name "erc-d" (ert-resource-directory)) load-path))) (load "erc-d-tests" nil 'silent))) diff --git a/test/lisp/international/mule-tests.el b/test/lisp/international/mule-tests.el index 6e23d8c5421..6b76e35ae22 100644 --- a/test/lisp/international/mule-tests.el +++ b/test/lisp/international/mule-tests.el @@ -99,7 +99,7 @@ provide HTML fragments. Some tests override those variables." (ert-deftest sgml-html-meta-utf-8 () "Baseline: UTF-8." - (should (eq 'utf-8 (sgml-html-meta-run "utf-8")))) + (should (eq 'utf-8 (coding-system-base (sgml-html-meta-run "utf-8"))))) (ert-deftest sgml-html-meta-windows-hebrew () "A non-Unicode charset." diff --git a/test/lisp/textmodes/emacs-news-mode-resources/toggle-tag.erts b/test/lisp/textmodes/emacs-news-mode-resources/cycle-tag.erts index 63c3b1b7d8a..63c3b1b7d8a 100644 --- a/test/lisp/textmodes/emacs-news-mode-resources/toggle-tag.erts +++ b/test/lisp/textmodes/emacs-news-mode-resources/cycle-tag.erts diff --git a/test/lisp/textmodes/emacs-news-mode-tests.el b/test/lisp/textmodes/emacs-news-mode-tests.el index e1152265a45..676a3270da6 100644 --- a/test/lisp/textmodes/emacs-news-mode-tests.el +++ b/test/lisp/textmodes/emacs-news-mode-tests.el @@ -23,10 +23,10 @@ (require 'ert-x) (require 'emacs-news-mode) -(ert-deftest emacs-news-toggle-tag () - (ert-test-erts-file (ert-resource-file "toggle-tag.erts") +(ert-deftest emacs-news-cycle-tag () + (ert-test-erts-file (ert-resource-file "cycle-tag.erts") (lambda () (emacs-news-mode) - (emacs-news-toggle-tag)))) + (emacs-news-cycle-tag)))) ;;; emacs-news-mode-tests.el ends here diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el index 9d4bbf3e040..45914b2b6b0 100644 --- a/test/src/buffer-tests.el +++ b/test/src/buffer-tests.el @@ -8539,4 +8539,110 @@ Finally, kill the buffer and its temporary file." (if f2 (delete-file f2)) ))) +(ert-deftest test-labeled-narrowing () + "Test `with-restriction' and `without-restriction'." + (with-current-buffer (generate-new-buffer " foo" t) + (insert (make-string 5000 ?a)) + (should (= (point-min) 1)) + (should (= (point-max) 5001)) + (with-restriction + 100 500 :label 'foo + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (widen) + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (narrow-to-region 1 5000) + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (narrow-to-region 50 150) + (should (= (point-min) 100)) + (should (= (point-max) 150)) + (widen) + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (narrow-to-region 400 1000) + (should (= (point-min) 400)) + (should (= (point-max) 500)) + (without-restriction + :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 500))) + (without-restriction + :label 'foo + (should (= (point-min) 1)) + (should (= (point-max) 5001))) + (should (= (point-min) 400)) + (should (= (point-max) 500)) + (widen) + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (with-restriction + 50 250 :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 250)) + (widen) + (should (= (point-min) 100)) + (should (= (point-max) 250)) + (without-restriction + :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (without-restriction + :label 'foo + (should (= (point-min) 1)) + (should (= (point-max) 5001))) + (should (= (point-min) 100)) + (should (= (point-max) 500))) + (should (= (point-min) 100)) + (should (= (point-max) 250))) + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (with-restriction + 50 250 :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 250)) + (with-restriction + 150 500 :label 'baz + (should (= (point-min) 150)) + (should (= (point-max) 250)) + (without-restriction + :label 'bar + (should (= (point-min) 150)) + (should (= (point-max) 250))) + (without-restriction + :label 'foo + (should (= (point-min) 150)) + (should (= (point-max) 250))) + (without-restriction + :label 'baz + (should (= (point-min) 100)) + (should (= (point-max) 250)) + (without-restriction + :label 'foo + (should (= (point-min) 100)) + (should (= (point-max) 250))) + (without-restriction + :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (without-restriction + :label 'foobar + (should (= (point-min) 100)) + (should (= (point-max) 500))) + (without-restriction + :label 'foo + (should (= (point-min) 1)) + (should (= (point-max) 5001))) + (should (= (point-min) 100)) + (should (= (point-max) 500))) + (should (= (point-min) 100)) + (should (= (point-max) 250))) + (should (= (point-min) 150)) + (should (= (point-max) 250))) + (should (= (point-min) 100)) + (should (= (point-max) 250)))) + (should (= (point-min) 1)) + (should (= (point-max) 5001)))) + ;;; buffer-tests.el ends here |