From a4aa32bdfff7aaf54efbacbb04b7f2b52fef92a7 Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Thu, 9 Feb 2023 01:09:10 +0000 Subject: [PATCH 01/42] Fix 'save-restriction' for narrowing locks * src/editfns.c (narrowing_locks_save): (narrowing_locks_restore): Make them non-static. * src/lisp.h: Make them externally visible. * src/bytecode.c (exec_byte_code): Save and restore narrowing locks. * lisp/emacs-lisp/bytecomp.el (byte-compile-save-restriction): Increment unbinding count. * src/comp.c (helper_save_restriction): Save and restore narrowing locks. --- lisp/emacs-lisp/bytecomp.el | 2 +- src/bytecode.c | 2 ++ src/comp.c | 2 ++ src/editfns.c | 4 ++-- src/lisp.h | 2 ++ 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 5df1205869c..c6cda6b588a 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -4900,7 +4900,7 @@ binding slots have been popped." (defun byte-compile-save-restriction (form) (byte-compile-out 'byte-save-restriction 0) (byte-compile-body-do-effect (cdr form)) - (byte-compile-out 'byte-unbind 1)) + (byte-compile-out 'byte-unbind 2)) (defun byte-compile-save-current-buffer (form) (byte-compile-out 'byte-save-current-buffer 0) diff --git a/src/bytecode.c b/src/bytecode.c index 124348e5b35..8e214560f30 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -942,6 +942,8 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, CASE (Bsave_restriction): record_unwind_protect (save_restriction_restore, save_restriction_save ()); + record_unwind_protect (narrowing_locks_restore, + narrowing_locks_save ()); NEXT; CASE (Bcatch): /* Obsolete since 25. */ diff --git a/src/comp.c b/src/comp.c index 10cf7962ba1..0e2dfd3913b 100644 --- a/src/comp.c +++ b/src/comp.c @@ -5063,6 +5063,8 @@ helper_save_restriction (void) { record_unwind_protect (save_restriction_restore, save_restriction_save ()); + record_unwind_protect (narrowing_locks_restore, + narrowing_locks_save ()); } static bool diff --git a/src/editfns.c b/src/editfns.c index 78d2c73ecbf..21e22181b82 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2787,7 +2787,7 @@ reset_outermost_narrowings (void) /* Helper functions to save and restore the narrowing locks of the current buffer in Fsave_restriction. */ -static Lisp_Object +Lisp_Object narrowing_locks_save (void) { Lisp_Object buf = Fcurrent_buffer (); @@ -2798,7 +2798,7 @@ narrowing_locks_save (void) return Fcons (buf, Fcopy_sequence (locks)); } -static void +void narrowing_locks_restore (Lisp_Object buf_and_saved_locks) { if (NILP (buf_and_saved_locks)) diff --git a/src/lisp.h b/src/lisp.h index 1276285e2f2..93197d38176 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4684,6 +4684,8 @@ extern void save_excursion_save (union specbinding *); extern void save_excursion_restore (Lisp_Object, Lisp_Object); extern Lisp_Object save_restriction_save (void); extern void save_restriction_restore (Lisp_Object); +extern Lisp_Object narrowing_locks_save (void); +extern void narrowing_locks_restore (Lisp_Object); extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); From 97314447e609e673be060bcdf0f244f396a70a3a Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Thu, 9 Feb 2023 01:09:10 +0000 Subject: [PATCH 02/42] Make 'narrowing-lock' and 'narrowing-unlock' internal * src/editfns.c (Finternal__lock_narrowing): Renamed from 'narrowing-lock'. (Finternal__unlock_narrowing): Renamed from 'narrowing-unlock'. (unwind_narrow_to_region_locked): (narrow_to_region_locked): (syms_of_editfns): Use the new names. * lisp/subr.el (internal--with-narrowing): Use the new name. --- lisp/subr.el | 2 +- src/editfns.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index 32c997425cf..5cc0c94ba48 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3963,7 +3963,7 @@ detailed description. (save-restriction (progn (narrow-to-region start end) - (if tag (narrowing-lock tag)) + (if tag (internal--lock-narrowing tag)) (funcall body)))) (defun find-tag-default-bounds () diff --git a/src/editfns.c b/src/editfns.c index 21e22181b82..e1c57502805 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2812,7 +2812,7 @@ narrowing_locks_restore (Lisp_Object buf_and_saved_locks) static void unwind_narrow_to_region_locked (Lisp_Object tag) { - Fnarrowing_unlock (tag); + Finternal__unlock_narrowing (tag); Fwiden (); } @@ -2821,7 +2821,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); } @@ -2932,7 +2932,8 @@ limit of the locked restriction is used instead of the argument. */) return Qnil; } -DEFUN ("narrowing-lock", Fnarrowing_lock, Snarrowing_lock, 1, 1, 0, +DEFUN ("internal--lock-narrowing", Finternal__lock_narrowing, + Sinternal__lock_narrowing, 1, 1, 0, doc: /* Lock the current narrowing with TAG. When restrictions are locked, `narrow-to-region' and `widen' can be @@ -2967,7 +2968,8 @@ not be used as a stronger variant of normal restrictions. */) return Qnil; } -DEFUN ("narrowing-unlock", Fnarrowing_unlock, Snarrowing_unlock, 1, 1, 0, +DEFUN ("internal--unlock-narrowing", Finternal__unlock_narrowing, + Sinternal__unlock_narrowing, 1, 1, 0, doc: /* Unlock a narrowing locked with (narrowing-lock TAG). Unlocking restrictions locked with `narrowing-lock' should be used @@ -4903,8 +4905,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); } From d8438e2bb44f448d1a0653321a8f262a1b6a3f2b Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Thu, 9 Feb 2023 01:09:10 +0000 Subject: [PATCH 03/42] Add 'without-narrowing' macro * lisp/subr.el (without-narrowing): New macro, companion (and almost identical) to 'with-narrowing'. --- lisp/subr.el | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index 5cc0c94ba48..af3f1f1abd5 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3952,18 +3952,37 @@ and END limits, unless the restrictions are unlocked by calling `narrowing-unlock' with TAG. See `narrowing-lock' for a more detailed description. -\(fn START END [:locked TAG] BODY)" - (if (eq (car rest) :locked) +\(fn START END [:label LABEL] BODY)" + (if (eq (car rest) :label) `(internal--with-narrowing ,start ,end (lambda () ,@(cddr rest)) ,(cadr rest)) `(internal--with-narrowing ,start ,end (lambda () ,@rest)))) -(defun internal--with-narrowing (start end body &optional tag) +(defun internal--with-narrowing (start end body &optional label) "Helper function for `with-narrowing', which see." (save-restriction (progn (narrow-to-region start end) - (if tag (internal--lock-narrowing tag)) + (if label (internal--lock-narrowing label)) + (funcall body)))) + +(defmacro without-narrowing (&rest rest) + "Execute BODY without restrictions. + +The current restrictions, if any, are restored upon return. + +\(fn [:label LABEL] BODY)" + (if (eq (car rest) :label) + `(internal--without-narrowing (lambda () ,@(cddr rest)) + ,(cadr rest)) + `(internal--without-narrowing (lambda () ,@rest)))) + +(defun internal--without-narrowing (body &optional label) + "Helper function for `without-narrowing', which see." + (save-restriction + (progn + (if label (internal--unlock-narrowing label)) + (widen) (funcall body)))) (defun find-tag-default-bounds () From 0d73e4aa261d1d751a7469a6274b2e1b9fa210e6 Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Thu, 9 Feb 2023 01:09:10 +0000 Subject: [PATCH 04/42] Add specific symbols for narrowings * src/xdisp.c (syms_of_xdisp): Define symbol. (handle_fontified_prop): Use it. * src/keyboard.c (syms_of_keyboard): Define symbol. (safe_run_hooks_maybe_narrowed): Use it. --- src/keyboard.c | 5 ++++- src/xdisp.c | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/keyboard.c b/src/keyboard.c index 6f0f075e54e..243767aff53 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1915,7 +1915,8 @@ safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w) 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"); diff --git a/src/xdisp.c b/src/xdisp.c index a19c9908616..f777d2899b4 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -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' @@ -36266,6 +36266,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. */ From a6cd4553d48aff1d241d54d62dc1b39b3ff541e0 Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Thu, 9 Feb 2023 01:09:10 +0000 Subject: [PATCH 05/42] Rename two long line optimizations variables * src/buffer.c (syms_of_buffer): Rename two variables. * src/xdisp.c (get_locked_narrowing_begv): (get_locked_narrowing_zv): (handle_fontified_prop): Use the new names. * src/keyboard.c (safe_run_hooks_maybe_narrowed): Use the new names. --- src/buffer.c | 12 ++++++------ src/keyboard.c | 2 +- src/xdisp.c | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 38648519ba0..07723a7c6ff 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5916,8 +5916,8 @@ 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, + DEFVAR_INT ("long-line-optimizations-region-size", + long_line_optimizations_region_size, doc: /* Region size for locked narrowing in buffers with long lines. This variable has effect only in buffers which contain one or more @@ -5932,10 +5932,10 @@ To disable that narrowing, set this variable to 0. See also `long-line-locked-narrowing-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 @@ -5949,7 +5949,7 @@ 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/keyboard.c b/src/keyboard.c index 243767aff53..4417aa97d28 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1910,7 +1910,7 @@ 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); diff --git a/src/xdisp.c b/src/xdisp.c index f777d2899b4..8034b20d5f8 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; From 79ce185ad1373845781646812638d4872b8aee69 Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Thu, 9 Feb 2023 01:09:10 +0000 Subject: [PATCH 06/42] Update the documentation about labeled (locked) narrowing * src/xdisp.c (syms_of_xdisp) : Update docstring. * src/keyboard.c (syms_of_keyboard) : (syms_of_keyboard) : Update docstring. * src/editfns.c: (narrowing_locks): Explain why an alist is used instead of a buffer-local variable. (reset_outermost_narrowings): Point to recipes that demonstrate why it is necessary to restore the user narrowing bounds when redisplay starts. (Fwiden): Update docstring. (Fnarrow_to_region): Update docstring. (Finternal__lock_narrowing): Update docstring. (Finternal__unlock_narrowing): Update docstring. (Fsave_restriction): Update docstring. * src/buffer.c (syms_of_buffer) : Update docstring. (syms_of_buffer) : Update docstring. * lisp/subr.el (with-narrowing): Update docstring. (without-narrowing): Update docstring. * etc/NEWS: Mention the 'long-line-optimizations-region-size' and 'long-line-optimizations-bol-search-limit' options. Announce the 'with-narrowing' and 'without-narrowing' forms. * doc/lispref/positions.texi (Narrowing): Update the documentation of 'narrow-to-region', 'widen' and 'save-restriction'. Document the 'with-narrowing' and 'without-narrowing' special forms. * doc/lispref/display.texi (Auto Faces): Update the documentation. * doc/lispref/commands.texi (Command Overview): Document the fact that the buffer is narrowed around 'pre-command-hook' and 'post-command-hook' when the buffer text includes very long lines. --- doc/lispref/commands.texi | 6 +++ doc/lispref/display.texi | 10 ++--- doc/lispref/positions.texi | 82 +++++++++++++++++++++++++++++++++----- etc/NEWS | 16 +++++++- lisp/subr.el | 14 ++++--- src/buffer.c | 35 ++++++++-------- src/editfns.c | 70 ++++++++++++++------------------ src/keyboard.c | 24 +++++------ src/xdisp.c | 11 +++-- 9 files changed, 168 insertions(+), 100 deletions(-) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index dc78adc4520..be34027d21d 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-narrowing} form (see +@ref{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..1b7ef006634 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-narrowing} form +(see @ref{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/positions.texi b/doc/lispref/positions.texi index f3824436246..e7d5c610d67 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-narrowing} 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-narrowing} is used instead. To gain access to other +portions of the buffer, use @code{without-narrowing} 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-narrowing} with a +label argument (see below), the limits set by @code{with-narrowing} +are restored, instead of canceling the narrowing. To gain access to +other portions of the buffer, use @code{without-narrowing} 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-narrowing} 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,58 @@ This is the contents of foo@point{} @end group @end example @end defspec + +@defspec with-narrowing 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 + +When the optional @var{label} symbol argument is present however, the +narrowing is 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-narrowing} and gain +access to other portions of the buffer, use @code{without-narrowing} +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 +@end defspec + +@defspec without-narrowing [: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 @var{label} argument is present however, the +narrowing set by @code{with-narrowing} with the same @var{label} +argument are lifted. +@end defspec diff --git a/etc/NEWS b/etc/NEWS index 2d15e39036a..01e7f2cfb09 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -615,8 +615,12 @@ 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 options 'long-line-optimizations-region-size' and +'long-line-optimizations-bol-search-limit'. This may, in particular, +cause occasional mis-fontifications in these buffers. The new function 'long-line-optimizations-p' returns non-nil when these optimizations are in effect in the current buffer. @@ -3814,6 +3818,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-narrowing' and 'without-narrowing'. +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/subr.el b/lisp/subr.el index af3f1f1abd5..7ed0cb02a70 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3946,11 +3946,11 @@ See also `locate-user-emacs-file'.") 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-narrowing' with the +same LABEL argument. \(fn START END [:label LABEL] BODY)" (if (eq (car rest) :label) @@ -3971,6 +3971,10 @@ detailed description. The current restrictions, if any, are restored upon return. +When the optional :label LABEL argument is present, the +restrictions set by `with-narrowing' with the same LABEL argument +are lifted. + \(fn [:label LABEL] BODY)" (if (eq (car rest) :label) `(internal--without-narrowing (lambda () ,@(cddr rest)) diff --git a/src/buffer.c b/src/buffer.c index 07723a7c6ff..755061d0dee 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5918,18 +5918,18 @@ There is no reason to change that value except for debugging purposes. */); DEFVAR_INT ("long-line-optimizations-region-size", long_line_optimizations_region_size, - doc: /* Region size for locked narrowing in buffers with long lines. + 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-narrowing' 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_optimizations_region_size = 500000; @@ -5938,15 +5938,16 @@ There is no reason to change that value except for debugging purposes. */); 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-narrowing' 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_optimizations_bol_search_limit = 128; diff --git a/src/editfns.c b/src/editfns.c index e1c57502805..64906671be7 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) { @@ -2829,10 +2836,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-narrowing' with a +label, `widen' restores the narrowing limits set by `with-narrowing'. +To gain access to other portions of the buffer, use +`without-narrowing' with the same label. */) (void) { Fset (Qoutermost_narrowing, Qnil); @@ -2879,11 +2888,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-narrowing' 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-narrowing' is used instead of the +argument. To gain access to other portions of the buffer, use +`without-narrowing' with the same label. */) (Lisp_Object start, Lisp_Object end) { EMACS_INT s = fix_position (start), e = fix_position (end); @@ -2912,7 +2922,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 ())); @@ -2934,30 +2944,16 @@ limit of the locked restriction is used instead of the argument. */) DEFUN ("internal--lock-narrowing", Finternal__lock_narrowing, Sinternal__lock_narrowing, 1, 1, 0, - doc: /* Lock the current narrowing with TAG. + 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-narrowing'. */) (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))) @@ -2970,15 +2966,9 @@ not be used as a stronger variant of normal restrictions. */) DEFUN ("internal--unlock-narrowing", Finternal__unlock_narrowing, Sinternal__unlock_narrowing, 1, 1, 0, - doc: /* Unlock a narrowing locked with (narrowing-lock TAG). + 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-narrowing'. */) (Lisp_Object tag) { Lisp_Object buf = Fcurrent_buffer (); @@ -3085,8 +3075,8 @@ DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0 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-narrowing' 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). diff --git a/src/keyboard.c b/src/keyboard.c index 4417aa97d28..1d0b907bd8e 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -12731,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-narrowing' 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; @@ -12753,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-narrowing' 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 8034b20d5f8..1450b869d20 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -36777,12 +36777,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-narrowing' 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); From 2956e54b1dda1647a9399211c7d09b208b85dcfa Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Thu, 9 Feb 2023 01:09:10 +0000 Subject: [PATCH 07/42] Add an extensive test for labeled (locked) narrowing * test/src/buffer-tests.el (test-labeled-narrowing): New test. --- test/src/buffer-tests.el | 106 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el index 9d4bbf3e040..0ae78c8d9d9 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-narrowing' and `without-narrowing'." + (with-current-buffer (generate-new-buffer " foo" t) + (insert (make-string 5000 ?a)) + (should (= (point-min) 1)) + (should (= (point-max) 5001)) + (with-narrowing + 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-narrowing + :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 500))) + (without-narrowing + :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-narrowing + 50 250 :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 250)) + (widen) + (should (= (point-min) 100)) + (should (= (point-max) 250)) + (without-narrowing + :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (without-narrowing + :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-narrowing + 50 250 :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 250)) + (with-narrowing + 150 500 :label 'baz + (should (= (point-min) 150)) + (should (= (point-max) 250)) + (without-narrowing + :label 'bar + (should (= (point-min) 150)) + (should (= (point-max) 250))) + (without-narrowing + :label 'foo + (should (= (point-min) 150)) + (should (= (point-max) 250))) + (without-narrowing + :label 'baz + (should (= (point-min) 100)) + (should (= (point-max) 250)) + (without-narrowing + :label 'foo + (should (= (point-min) 100)) + (should (= (point-max) 250))) + (without-narrowing + :label 'bar + (should (= (point-min) 100)) + (should (= (point-max) 500)) + (without-narrowing + :label 'foobar + (should (= (point-min) 100)) + (should (= (point-max) 500))) + (without-narrowing + :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 From 4297039bd1325166eac82d950951716ec122d465 Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Fri, 10 Feb 2023 20:55:47 +0000 Subject: [PATCH 08/42] Save and restore the absence of narrowing locks * src/editfns.c (narrowing_locks_save): Return the buffer with a empty locks list when the current buffer has no narrowing locks. (narrowing_locks_restore): Remove the narrowing locks if the buffer had no narrowing locks. --- src/editfns.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/editfns.c b/src/editfns.c index 64906671be7..f9879662168 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2799,21 +2799,19 @@ 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)); } 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 From dcb2379a463678bdadd05ee39d61e7da84c71c5e Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Mon, 13 Feb 2023 10:23:39 +0000 Subject: [PATCH 09/42] Minor improvements to labeled narrowing * lisp/subr.el (internal--with-narrowing): (internal--without-narrowing): Remove unnecessary 'progn'. * etc/NEWS: Mention 'with-narrowing' in the entry about long lines. * doc/lispref/positions.texi (Narrowing): Fix typo. * doc/lispref/display.texi (Auto Faces): Use @pxref. * doc/lispref/commands.texi (Command Overview): Use @pxref. --- doc/lispref/commands.texi | 4 ++-- doc/lispref/display.texi | 2 +- doc/lispref/positions.texi | 2 +- etc/NEWS | 5 +++-- lisp/subr.el | 14 ++++++-------- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index be34027d21d..9723c279a45 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -100,8 +100,8 @@ 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-narrowing} form (see -@ref{Narrowing}), with a +hooks are called as if they were in a @code{with-narrowing} form +(@pxref{Narrowing}), with a @code{long-line-optimizations-in-command-hooks} label and with the buffer narrowed to a portion around point. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 1b7ef006634..f0ca7440c60 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -3503,7 +3503,7 @@ usually assign faces to around 400 to 600 characters at each call. Note that, when the buffer text includes very long lines, these functions are called as if they were in a @code{with-narrowing} form -(see @ref{Narrowing}), with a +(@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 diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index e7d5c610d67..bad83e1be2d 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -1193,5 +1193,5 @@ restores the saved bounds. In that case it is equivalent to When the optional @var{label} argument is present however, the narrowing set by @code{with-narrowing} with the same @var{label} -argument are lifted. +argument is lifted. @end defspec diff --git a/etc/NEWS b/etc/NEWS index 01e7f2cfb09..de4f65ebe62 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -619,8 +619,9 @@ 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 options 'long-line-optimizations-region-size' and -'long-line-optimizations-bol-search-limit'. This may, in particular, -cause occasional mis-fontifications in these buffers. +'long-line-optimizations-bol-search-limit', as if they were in a +'with-narrowing' form. This may, in particular, cause occasional +mis-fontifications in these buffers. The new function 'long-line-optimizations-p' returns non-nil when these optimizations are in effect in the current buffer. diff --git a/lisp/subr.el b/lisp/subr.el index 7ed0cb02a70..d280c7fef13 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3961,10 +3961,9 @@ same LABEL argument. (defun internal--with-narrowing (start end body &optional label) "Helper function for `with-narrowing', which see." (save-restriction - (progn - (narrow-to-region start end) - (if label (internal--lock-narrowing label)) - (funcall body)))) + (narrow-to-region start end) + (if label (internal--lock-narrowing label)) + (funcall body))) (defmacro without-narrowing (&rest rest) "Execute BODY without restrictions. @@ -3984,10 +3983,9 @@ are lifted. (defun internal--without-narrowing (body &optional label) "Helper function for `without-narrowing', which see." (save-restriction - (progn - (if label (internal--unlock-narrowing label)) - (widen) - (funcall body)))) + (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. From 865758130a1126fd38603c445baba7b74fb35329 Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Mon, 13 Feb 2023 11:50:28 +0100 Subject: [PATCH 10/42] ; * admin/git-bisect-start: Update failing commits --- admin/git-bisect-start | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) 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 From 10f2aedea9a47a9a12b194344504e418a12b26e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Mon, 13 Feb 2023 14:53:48 +0100 Subject: [PATCH 11/42] ; * lisp/progmodes/c-ts-mode.el (c-ts-base-mode): delete duplicate --- lisp/progmodes/c-ts-mode.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index af7aa1c3a0e..04f68881945 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -772,8 +772,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") From 909bd04cf5fd42744ca5f1f34cb42b48b363ee62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20M=C3=BCller?= Date: Mon, 13 Feb 2023 15:50:47 +0100 Subject: [PATCH 12/42] ; * lisp/calendar/lunar.el: Add comments. (bug#61460) --- lisp/calendar/lunar.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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") From dd8b720ee74e72359eb174aa5a27ab1770a349bd Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Mon, 13 Feb 2023 16:44:57 +0100 Subject: [PATCH 13/42] ; * etc/NEWS: Fix typos. --- etc/NEWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index de4f65ebe62..f2f059119fd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -570,7 +570,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. @@ -618,7 +618,7 @@ and the major mode with 'M-x so-long-mode', or visit the file with 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 options 'long-line-optimizations-region-size' and +controlled by the variables 'long-line-optimizations-region-size' and 'long-line-optimizations-bol-search-limit', as if they were in a 'with-narrowing' form. This may, in particular, cause occasional mis-fontifications in these buffers. From d806b0e33cf9dcc108b932226e84eaa0b6378eb9 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Mon, 13 Feb 2023 19:46:22 +0200 Subject: [PATCH 14/42] * lisp/repeat.el: Rename internal function and variable (bug#60980) (repeat--transient-exitfun): Rename internal variable from 'repeat-exit-function'. (repeat--clear-prev): Rename internal function from 'repeat--exit'. --- lisp/repeat.el | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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." From 3d572ae0d507bba07f3cfc5ae2d2c7dd4937472c Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 13 Feb 2023 20:11:28 +0200 Subject: [PATCH 15/42] Rename with/without-narrowing to with/without-restriction * doc/lispref/commands.texi: * doc/lispref/display.texi: * doc/lispref/positions.texi: * etc/NEWS: * lisp/subr.el: * src/buffer.c: * src/editfns.c: * src/keyboard.c: * src/xdisp.c: * test/src/buffer-tests.el: Rename with-narrowing and without-narrowing to with-restriction and without-restriction. Likewise with internal--with-narrowing and internal--without-narrowing. All callers and documentation changed. --- doc/lispref/commands.texi | 2 +- doc/lispref/display.texi | 2 +- doc/lispref/positions.texi | 24 ++++++++++++------------ etc/NEWS | 4 ++-- lisp/subr.el | 24 ++++++++++++------------ src/buffer.c | 4 ++-- src/editfns.c | 18 +++++++++--------- src/keyboard.c | 4 ++-- src/xdisp.c | 2 +- test/src/buffer-tests.el | 32 ++++++++++++++++---------------- 10 files changed, 58 insertions(+), 58 deletions(-) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 9723c279a45..6fd9377e1de 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -100,7 +100,7 @@ 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-narrowing} form +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. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index f0ca7440c60..a8311f5c9a2 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -3502,7 +3502,7 @@ For efficiency, we recommend writing these functions so that they usually assign faces to around 400 to 600 characters at each call. Note that, when the buffer text includes very long lines, these -functions are called as if they were in a @code{with-narrowing} form +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}. diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index bad83e1be2d..f6a0cf14476 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -1037,12 +1037,12 @@ 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). -However, when the narrowing has been set by @code{with-narrowing} with +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-narrowing} is used instead. To gain access to other -portions of the buffer, use @code{without-narrowing} with the same +@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 @@ -1068,10 +1068,10 @@ It is equivalent to the following expression: (narrow-to-region 1 (1+ (buffer-size))) @end example -However, when a narrowing has been set by @code{with-narrowing} with a -label argument (see below), the limits set by @code{with-narrowing} +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-narrowing} with the +other portions of the buffer, use @code{without-restriction} with the same label. @end deffn @@ -1089,7 +1089,7 @@ 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-narrowing} with a label argument (see below). +@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. @@ -1141,7 +1141,7 @@ This is the contents of foo@point{} @end example @end defspec -@defspec with-narrowing start end [:label label] body +@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 @@ -1164,8 +1164,8 @@ and @code{widen} can be used only within the @var{start} and @var{end} limits. @item -To lift the restriction introduced by @code{with-narrowing} and gain -access to other portions of the buffer, use @code{without-narrowing} +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}).) @@ -1180,7 +1180,7 @@ user. @end itemize @end defspec -@defspec without-narrowing [:label label] body +@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 @@ -1192,6 +1192,6 @@ restores the saved bounds. In that case it is equivalent to @end example When the optional @var{label} argument is present however, the -narrowing set by @code{with-narrowing} with the same @var{label} +narrowing set by @code{with-restriction} with the same @var{label} argument is lifted. @end defspec diff --git a/etc/NEWS b/etc/NEWS index f2f059119fd..db77fdfbb42 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -620,7 +620,7 @@ In buffers in which these display optimizations are in effect, the 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-narrowing' form. This may, in particular, cause occasional +'with-restriction form. This may, in particular, cause occasional mis-fontifications in these buffers. The new function 'long-line-optimizations-p' returns non-nil when @@ -3820,7 +3820,7 @@ The default timeout value can be defined by the new variable 'set-transient-map-timeout'. +++ -** New forms 'with-narrowing' and 'without-narrowing'. +** 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 diff --git a/lisp/subr.el b/lisp/subr.el index 58a8e85b61d..c26cbb9a56c 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3941,7 +3941,7 @@ 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. @@ -3949,39 +3949,39 @@ The current restrictions, if any, are restored upon return. 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-narrowing' with the +to other portions of the buffer, use `without-restriction' with the same LABEL argument. \(fn START END [:label LABEL] BODY)" (if (eq (car rest) :label) - `(internal--with-narrowing ,start ,end (lambda () ,@(cddr rest)) + `(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 label) - "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 (narrow-to-region start end) (if label (internal--lock-narrowing label)) (funcall body))) -(defmacro without-narrowing (&rest rest) +(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-narrowing' with the same LABEL argument +restrictions set by `with-restriction' with the same LABEL argument are lifted. \(fn [:label LABEL] BODY)" (if (eq (car rest) :label) - `(internal--without-narrowing (lambda () ,@(cddr rest)) + `(internal--without-restriction (lambda () ,@(cddr rest)) ,(cadr rest)) - `(internal--without-narrowing (lambda () ,@rest)))) + `(internal--without-restriction (lambda () ,@rest)))) -(defun internal--without-narrowing (body &optional label) - "Helper function for `without-narrowing', which see." +(defun internal--without-restriction (body &optional label) + "Helper function for `without-restriction', which see." (save-restriction (if label (internal--unlock-narrowing label)) (widen) diff --git a/src/buffer.c b/src/buffer.c index 755061d0dee..df1f5206668 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5924,7 +5924,7 @@ 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-narrowing' form with a label. +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. @@ -5942,7 +5942,7 @@ 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-narrowing' form with a label. +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 diff --git a/src/editfns.c b/src/editfns.c index f9879662168..ce133785e0b 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2836,10 +2836,10 @@ DEFUN ("widen", Fwiden, Swiden, 0, 0, "", This allows the buffer's full text to be seen and edited. -However, when restrictions have been set by `with-narrowing' with a -label, `widen' restores the narrowing limits set by `with-narrowing'. +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-narrowing' with the same label. */) +`without-restriction' with the same label. */) (void) { Fset (Qoutermost_narrowing, Qnil); @@ -2886,12 +2886,12 @@ When calling from Lisp, pass two arguments START and END: positions (integers or markers) bounding the text that should remain visible. -However, when restrictions have been set by `with-narrowing' with a +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-narrowing' is used instead of the +the corresponding limit set by `with-restriction' is used instead of the argument. To gain access to other portions of the buffer, use -`without-narrowing' with the same label. */) +`without-restriction' with the same label. */) (Lisp_Object start, Lisp_Object end) { EMACS_INT s = fix_position (start), e = fix_position (end); @@ -2944,7 +2944,7 @@ DEFUN ("internal--lock-narrowing", Finternal__lock_narrowing, Sinternal__lock_narrowing, 1, 1, 0, doc: /* Lock the current narrowing with LABEL. -This is an internal function used by `with-narrowing'. */) +This is an internal function used by `with-restriction'. */) (Lisp_Object tag) { Lisp_Object buf = Fcurrent_buffer (); @@ -2966,7 +2966,7 @@ DEFUN ("internal--unlock-narrowing", Finternal__unlock_narrowing, Sinternal__unlock_narrowing, 1, 1, 0, doc: /* Unlock a narrowing locked with LABEL. -This is an internal function used by `without-narrowing'. */) +This is an internal function used by `without-restriction'. */) (Lisp_Object tag) { Lisp_Object buf = Fcurrent_buffer (); @@ -3073,7 +3073,7 @@ DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0 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, including those that were set by `with-narrowing' with a +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 diff --git a/src/keyboard.c b/src/keyboard.c index 1d0b907bd8e..b2816f8270b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -12732,7 +12732,7 @@ which the error occurred is unconditionally removed, since otherwise the error might happen repeatedly and make Emacs nonfunctional. Note that, when `long-line-optimizations-p' is non-nil in the buffer, -these functions are called as if they were in a `with-narrowing' form, +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'. @@ -12752,7 +12752,7 @@ unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to avoid making Emacs unresponsive while the user types. Note that, when `long-line-optimizations-p' is non-nil in the buffer, -these functions are called as if they were in a `with-narrowing' form, +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'. diff --git a/src/xdisp.c b/src/xdisp.c index 1450b869d20..5c5ecaa2bcb 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -36778,7 +36778,7 @@ 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 `long-line-optimizations-p' is non-nil in the buffer, -these functions are called as if they were in a `with-narrowing' form, +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'. */); diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el index 0ae78c8d9d9..45914b2b6b0 100644 --- a/test/src/buffer-tests.el +++ b/test/src/buffer-tests.el @@ -8540,12 +8540,12 @@ Finally, kill the buffer and its temporary file." ))) (ert-deftest test-labeled-narrowing () - "Test `with-narrowing' and `without-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-narrowing + (with-restriction 100 500 :label 'foo (should (= (point-min) 100)) (should (= (point-max) 500)) @@ -8564,11 +8564,11 @@ Finally, kill the buffer and its temporary file." (narrow-to-region 400 1000) (should (= (point-min) 400)) (should (= (point-max) 500)) - (without-narrowing + (without-restriction :label 'bar (should (= (point-min) 100)) (should (= (point-max) 500))) - (without-narrowing + (without-restriction :label 'foo (should (= (point-min) 1)) (should (= (point-max) 5001))) @@ -8577,18 +8577,18 @@ Finally, kill the buffer and its temporary file." (widen) (should (= (point-min) 100)) (should (= (point-max) 500)) - (with-narrowing + (with-restriction 50 250 :label 'bar (should (= (point-min) 100)) (should (= (point-max) 250)) (widen) (should (= (point-min) 100)) (should (= (point-max) 250)) - (without-narrowing + (without-restriction :label 'bar (should (= (point-min) 100)) (should (= (point-max) 500)) - (without-narrowing + (without-restriction :label 'foo (should (= (point-min) 1)) (should (= (point-max) 5001))) @@ -8598,39 +8598,39 @@ Finally, kill the buffer and its temporary file." (should (= (point-max) 250))) (should (= (point-min) 100)) (should (= (point-max) 500)) - (with-narrowing + (with-restriction 50 250 :label 'bar (should (= (point-min) 100)) (should (= (point-max) 250)) - (with-narrowing + (with-restriction 150 500 :label 'baz (should (= (point-min) 150)) (should (= (point-max) 250)) - (without-narrowing + (without-restriction :label 'bar (should (= (point-min) 150)) (should (= (point-max) 250))) - (without-narrowing + (without-restriction :label 'foo (should (= (point-min) 150)) (should (= (point-max) 250))) - (without-narrowing + (without-restriction :label 'baz (should (= (point-min) 100)) (should (= (point-max) 250)) - (without-narrowing + (without-restriction :label 'foo (should (= (point-min) 100)) (should (= (point-max) 250))) - (without-narrowing + (without-restriction :label 'bar (should (= (point-min) 100)) (should (= (point-max) 500)) - (without-narrowing + (without-restriction :label 'foobar (should (= (point-min) 100)) (should (= (point-max) 500))) - (without-narrowing + (without-restriction :label 'foo (should (= (point-min) 1)) (should (= (point-max) 5001))) From 4bb27a5ca93f8269d9cd4b85fd948176304236eb Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 13 Feb 2023 20:37:15 +0200 Subject: [PATCH 16/42] ; Minor docs copyedits * etc/NEWS: Add text about adapting to long-line optimizations. * doc/lispref/positions.texi (Narrowing): Improve documentation of labeled narrowing. --- doc/lispref/positions.texi | 18 ++++++++++++------ etc/NEWS | 10 ++++++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index f6a0cf14476..1b32f18922c 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -1153,9 +1153,10 @@ saved bounds. In that case it is equivalent to body) @end example -When the optional @var{label} symbol argument is present however, the -narrowing is labeled. A labeled narrowing differs from a non-labeled -one in several ways: +@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 @@ -1178,6 +1179,11 @@ 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 @@ -1191,7 +1197,7 @@ restores the saved bounds. In that case it is equivalent to body) @end example -When the optional @var{label} argument is present however, the -narrowing set by @code{with-restriction} with the same @var{label} -argument is lifted. +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/etc/NEWS b/etc/NEWS index db77fdfbb42..35063678f58 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -620,8 +620,14 @@ In buffers in which these display optimizations are in effect, the 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. +'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. From 4f099a721730b3c5e75133f75d34ff8b379522a1 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Tue, 14 Feb 2023 07:47:06 -0800 Subject: [PATCH 17/42] ; Remove failing erc-reuse-buffers test * test/lisp/erc/erc-scenarios-base-reuse-buffers.el (erc-scenarios-base-reuse-buffers-server-buffers--enabled): Delete test. --- .../erc/erc-scenarios-base-reuse-buffers.el | 36 ------------------- 1 file changed, 36 deletions(-) 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) From 4eac80fcc39917c4dbb7d66c9c85003bfd994409 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Tue, 29 Nov 2022 22:53:44 -0800 Subject: [PATCH 18/42] ; Prepare to update ERC version to 5.5 * doc/misc/erc.texi: Mention in various places that ERC is also available from GNU ELPA. * etc/ERC-NEWS: Mention Compat dependency and shorten title for auth-source section. * lisp/erc/erc-backend.el: (erc-server-reconnect-function, erc-tags-format): Update package version to 5.5. (erc--parse-message-tags): Downcase warning "type" to remain consistent with all other ERC warnings. * lisp/erc/erc-button.el: (erc-button-alist): Change package-version to 5.5. * lisp/erc/erc-match.el (erc-match-quote-when-adding): Update package version to 5.5. * lisp/erc/erc-sasl.el: Mention actual info node in Commentary. (erc-sasl): Update package version to 5.5. (erc-sasl-password): Reword doc string. (erc-sasl-auth-source-function): Capitalize "info" in doc string. * lisp/erc/erc-services.el (erc-auth-source-services-function): Update package version to 5.5. Capitalize "info" in doc string. Change choice type from const to function-item. * lisp/erc/erc.el (erc-password): Capitalize "info" in doc string. (erc-inhibit-multiline-input, erc-ask-about-multiline-input, erc-prompt-hidden, erc-hide-prompt, erc-unhide-query-prompt, erc-join-buffer, erc-reconnect-display, erc-kill-server-hook, erc-kill-channel-hook, erc-kill-buffer-hook, erc-url-connect-function): Update package version to 5.5. (erc-auth-source-server-function, erc-auth-source-join-function): Update package version to 5.5. Change choice type from const to function-item. Capitalize "info" in doc string. (erc-tls): Capitalize "info" in doc string. --- doc/misc/erc.texi | 12 +++++++++-- etc/ERC-NEWS | 20 +++++++++++------- lisp/erc/erc-backend.el | 6 +++--- lisp/erc/erc-button.el | 2 +- lisp/erc/erc-match.el | 2 +- lisp/erc/erc-sasl.el | 37 ++++++++++++++++----------------- lisp/erc/erc-services.el | 6 +++--- lisp/erc/erc.el | 44 ++++++++++++++++++++-------------------- 8 files changed, 71 insertions(+), 58 deletions(-) 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/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 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. +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 will forgo sending a traditional +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) From 6a32ba8b69c9d7a9c356611bb8033a0a83b4e8b8 Mon Sep 17 00:00:00 2001 From: Philip Kaludercic Date: Tue, 14 Feb 2023 19:48:01 +0100 Subject: [PATCH 19/42] ; Fix the installation of dependencies for VC packages * lisp/emacs-lisp/package-vc.el (package-vc-install-dependencies): Work with package-desc objects instead of (PACKAGE-NAME VERSION) pairs. --- lisp/emacs-lisp/package-vc.el | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index bf49f274bfd..4a987052949 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -435,24 +435,29 @@ 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))) + (equal a (car 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) + (cl-callf seq-uniq to-install) (cl-callf sort to-install #'dependent-order)) (mapc #'package-install-from-archive to-install) missing)) From a3751b5d0c1a6aa4edaa16504012fb4a0e6302f9 Mon Sep 17 00:00:00 2001 From: Philip Kaludercic Date: Tue, 14 Feb 2023 19:49:51 +0100 Subject: [PATCH 20/42] ; Raise an error if a VC package checkout is empty * lisp/emacs-lisp/package-vc.el (package-vc--unpack): Check if PKG-DIR is empty before proceeding with the installation. --- lisp/emacs-lisp/package-vc.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index 4a987052949..bad59aa6c0f 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -611,7 +611,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) @@ -620,6 +620,9 @@ 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)) ;; When nothing is specified about a `lisp-dir', then should ;; heuristically check if there is a sub-directory with lisp From 420d2cae846e7f0b18765bfd59420dde23bd7ead Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Tue, 14 Feb 2023 20:40:55 +0100 Subject: [PATCH 21/42] Update to Transient v0.3.7-209-gdab1dfa --- lisp/transient.el | 240 +++++++++++++++++++++------------------------- 1 file changed, 111 insertions(+), 129 deletions(-) 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'.") +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 + "" #'transient-scroll-up + "" #'transient-scroll-down) -(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. +(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'.") +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 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-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 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.") +(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 "") #'transient-noop) - (define-key map (kbd "") #'transient-backward-button) - (define-key map (kbd "") #'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-keymap transient-popup-navigation-map + :doc "One of the keymaps used when popup navigation is enabled. +See `transient-enable-popup-navigation'." + "" #'transient-noop + "" #'transient-backward-button + "" #'transient-forward-button + "C-r" #'transient-isearch-backward + "C-s" #'transient-isearch-forward + "M-RET" #'transient-push-button) -(defvar transient-button-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "") #'transient-push-button) - (define-key map (kbd "") #'transient-push-button) - map) - "One of the keymaps used when popup navigation is enabled. -See `transient-enable-popup-navigation'.") +(defvar-keymap transient-button-map + :doc "One of the keymaps used when popup navigation is enabled. +See `transient-enable-popup-navigation'." + "" #'transient-push-button + "" #'transient-push-button) -(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-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--do-suspend + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-minus + "" #'transient--do-stay + "" #'transient--do-quit-all + "" #'transient--do-quit-all + "" #'transient--do-quit-one + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-call + "" #'transient--do-call + "" #'transient--do-call + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-stay + "" #'transient--do-noop + "" #'transient--do-move + "" #'transient--do-push-button + "" #'transient--do-move + "" #'transient--do-move + "" #'transient--do-move + "" #'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. + "" #'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 "" b)) + (when-let ((b (keymap-lookup map "="))) (keymap-set map "" b)) + (when-let ((b (keymap-lookup map "+"))) (keymap-set map "" 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 "" #'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." + " " #'transient-resume + " " #'transient-resume + " " #'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 + " " #'transient-isearch-exit + " " #'transient-isearch-cancel + " " #'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)) From d97a38399678269e01e32e5b3da4d3d91144c433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20Kj=C3=B8nigsen?= Date: Tue, 14 Feb 2023 20:04:19 +0100 Subject: [PATCH 22/42] csharp-ts-mode: fontify compiler directives (bug#61512) lisp/progmodes/csharp-mode.el: Add tree-sitter-queries for known C# compiler-directives. --- lisp/progmodes/csharp-mode.el | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) 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))) From accd88d55455b8c585b162242e6e4ede742afa99 Mon Sep 17 00:00:00 2001 From: Theodor Thornhill Date: Tue, 14 Feb 2023 20:53:55 +0100 Subject: [PATCH 23/42] Don't indent template_string contents (bug#61503) * lisp/progmodes/js.el (js--treesit-indent-rules): Add new rule. * lisp/progmodes/typescript-ts-mode.el (typescript-ts-mode--indent-rules): Add new rule. --- lisp/progmodes/js.el | 1 + lisp/progmodes/typescript-ts-mode.el | 1 + 2 files changed, 2 insertions(+) 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/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) From 5206a551c166fc1908edff4fdf1695f7cef3600a Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Tue, 14 Feb 2023 20:22:50 +0000 Subject: [PATCH 24/42] Improve backward compatibility of save-restriction * src/editfns.c (save_restriction_save_1): Renamed from 'save_restrictions_save'. Make it static. (save_restriction_restore_1): Renamed from 'save_restriction_restore'. Make it static. (save_restriction_restore): New function, combining 'save_restriction_save_1' and 'narrowing_locks_save'. (save_restriction_save): New function, combining 'save_restriction_restore_1' and 'narrowing_locks_restore'. (Fsave_restriction): Restore the previous code. (narrowing_locks_save, narrowing_locks_restore): Make them static. * src/lisp.h: Remove two functions that are not externally visible anymore. * src/comp.c (helper_save_restriction): Restore the previous code. * src/bytecode.c (exec_byte_code): Restore the previous code. * lisp/emacs-lisp/bytecomp.el (byte-compile-save-restriction): Decrement unbinding count. --- lisp/emacs-lisp/bytecomp.el | 2 +- src/bytecode.c | 2 -- src/comp.c | 2 -- src/editfns.c | 28 +++++++++++++++++++++------- src/lisp.h | 2 -- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index c6cda6b588a..5df1205869c 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -4900,7 +4900,7 @@ binding slots have been popped." (defun byte-compile-save-restriction (form) (byte-compile-out 'byte-save-restriction 0) (byte-compile-body-do-effect (cdr form)) - (byte-compile-out 'byte-unbind 2)) + (byte-compile-out 'byte-unbind 1)) (defun byte-compile-save-current-buffer (form) (byte-compile-out 'byte-save-current-buffer 0) diff --git a/src/bytecode.c b/src/bytecode.c index 8e214560f30..124348e5b35 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -942,8 +942,6 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, CASE (Bsave_restriction): record_unwind_protect (save_restriction_restore, save_restriction_save ()); - record_unwind_protect (narrowing_locks_restore, - narrowing_locks_save ()); NEXT; CASE (Bcatch): /* Obsolete since 25. */ diff --git a/src/comp.c b/src/comp.c index 0e2dfd3913b..10cf7962ba1 100644 --- a/src/comp.c +++ b/src/comp.c @@ -5063,8 +5063,6 @@ helper_save_restriction (void) { record_unwind_protect (save_restriction_restore, save_restriction_save ()); - record_unwind_protect (narrowing_locks_restore, - narrowing_locks_save ()); } static bool diff --git a/src/editfns.c b/src/editfns.c index ce133785e0b..f83c5c7259b 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2794,7 +2794,7 @@ reset_outermost_narrowings (void) /* Helper functions to save and restore the narrowing locks of the current buffer in Fsave_restriction. */ -Lisp_Object +static Lisp_Object narrowing_locks_save (void) { Lisp_Object buf = Fcurrent_buffer (); @@ -2804,7 +2804,7 @@ narrowing_locks_save (void) return Fcons (buf, Fcopy_sequence (locks)); } -void +static void narrowing_locks_restore (Lisp_Object buf_and_saved_locks) { Lisp_Object buf = XCAR (buf_and_saved_locks); @@ -2975,8 +2975,8 @@ This is an internal function used by `without-restriction'. */) 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. @@ -2999,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) @@ -3068,6 +3068,21 @@ 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. @@ -3092,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); } diff --git a/src/lisp.h b/src/lisp.h index 93197d38176..1276285e2f2 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4684,8 +4684,6 @@ extern void save_excursion_save (union specbinding *); extern void save_excursion_restore (Lisp_Object, Lisp_Object); extern Lisp_Object save_restriction_save (void); extern void save_restriction_restore (Lisp_Object); -extern Lisp_Object narrowing_locks_save (void); -extern void narrowing_locks_restore (Lisp_Object); extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); From 477aa047ee73d2b93c04a88700263e58cf7bab70 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Tue, 14 Feb 2023 19:29:30 +0200 Subject: [PATCH 25/42] rust-ts-mode: Highlight variable reassignments * lisp/progmodes/rust-ts-mode.el (rust-ts-mode): New treesit font-lock feature: 'assignment' (bug#61302). (rust-ts-mode--fontify-pattern): Remove the node lookup step. (rust-ts-mode--font-lock-settings): Update variable declaration queries to match the 'pattern' child node right away. Add highlights for 'assignment. --- lisp/progmodes/rust-ts-mode.el | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lisp/progmodes/rust-ts-mode.el b/lisp/progmodes/rust-ts-mode.el index 5c71a8ad461..f709b16ff39 100644 --- a/lisp/progmodes/rust-ts-mode.el +++ b/lisp/progmodes/rust-ts-mode.el @@ -163,11 +163,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 @@ -261,7 +266,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 +347,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))) From a3a1ef7bd5eb7a3b74b0fd80ce78ef234c25f573 Mon Sep 17 00:00:00 2001 From: Randy Taylor Date: Wed, 8 Feb 2023 21:43:04 -0500 Subject: [PATCH 26/42] Fix rust-ts-mode type and module highlighting (Bug#61302) * lisp/progmodes/rust-ts-mode.el (rust-ts-mode--font-lock-settings): Specify import queries to avoid clashing with scoped identifiers in the code. Highlight attributes with font-lock-preprocessor-face. --- lisp/progmodes/rust-ts-mode.el | 88 +++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/lisp/progmodes/rust-ts-mode.el b/lisp/progmodes/rust-ts-mode.el index f709b16ff39..f510b7bb6c9 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 @@ -147,12 +147,6 @@ :feature 'comment '(([(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) @@ -211,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 @@ -225,25 +266,40 @@ (:match "^[A-Z]" @font-lock-type-face)) ((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 consants. + :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 From 7678b7e46f2e394447f39c3a6cf02bc285e5a5a4 Mon Sep 17 00:00:00 2001 From: ~kby Date: Tue, 14 Feb 2023 23:25:05 +0000 Subject: [PATCH 27/42] Eglot: check server capability before sending didSave (bug#61478) * lisp/progmodes/eglot.el (eglot--signal-textDocument/didSave): check server capability. Copyright-paperwork-exempt: Yes --- lisp/progmodes/eglot.el | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) 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. From fdac69b45e608f9f3610066ed873dacfd971119a Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Wed, 15 Feb 2023 05:08:01 +0100 Subject: [PATCH 28/42] ; Auto-commit of loaddefs files. --- lisp/ldefs-boot.el | 110 ++++++++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 40 deletions(-) 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 "{\\|<[^/>]*?" "}\\|]*[^/]>" "