commit 116f69d741afb312c826647f303ad8488d355bee (HEAD, refs/remotes/origin/master) Author: Juanma Barranquero Date: Fri Nov 4 07:04:39 2022 +0100 ; * lisp/subr.el (setq-local): Doc fix. diff --git a/lisp/subr.el b/lisp/subr.el index 83e2e75c41..b60bc11079 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -161,10 +161,10 @@ of previous VARs. `(progn . ,(nreverse exps)))) (defmacro setq-local (&rest pairs) - "Make variables in PAIRS buffer-local and assign them the corresponding values. + "Make VARIABLEs buffer-local and assign them the corresponding VALUEs. -PAIRS is a list of variable/value pairs. For each variable, make -it buffer-local and assign it the corresponding value. The +The args are a list of variable/value pairs. For each VARIABLE, +make it buffer-local and assign it the corresponding VALUE. The variables are literal symbols and should not be quoted. The second VALUE is not computed until after the first VARIABLE commit 55a31836fb2e6fbfedbca993d1855c366b8b0a6b Author: Juanma Barranquero Date: Fri Nov 4 06:54:07 2022 +0100 ; * etc/NEWS.27, etc/NEWS.28: Fix typos. diff --git a/etc/NEWS.27 b/etc/NEWS.27 index f67a8c70d4..f4fb4e3121 100644 --- a/etc/NEWS.27 +++ b/etc/NEWS.27 @@ -2763,7 +2763,7 @@ not waiting for a process to be set up. This variable determines how many bytes can be read from a sub-process in one read operation. The default, 4096 bytes, was previously a hard-coded constant. Setting it to a larger value might enhance -throughput of reading from sub-processes that produces vast +throughput of reading from sub-processes that produce vast (megabytes) amounts of data in one go. ** The new user option 'quit-window-hook' is now run first when diff --git a/etc/NEWS.28 b/etc/NEWS.28 index 1edf4e85b0..8eab05a763 100644 --- a/etc/NEWS.28 +++ b/etc/NEWS.28 @@ -199,7 +199,7 @@ lacks the terminfo database, you can instruct Emacs to support 24-bit true color by setting 'COLORTERM=truecolor' in the environment. This is useful on systems such as FreeBSD which ships only with "etc/termcap". -** File names given on the command line are now be pushed onto history. +** File names given on the command line are now pushed onto history. The file names will be pushed onto 'file-name-history', like the names of files visited via 'C-x C-f' and other commands. commit 96436a125dad5cbae888e8385be2a79ef48d5d03 Merge: 5e7d08ae13 8cae9d8bd8 Author: Stefan Kangas Date: Fri Nov 4 06:31:49 2022 +0100 Merge from origin/emacs-28 8cae9d8bd8 ; * doc/emacs/search.texi (Lax Search): Improve wording. ... e01e8a8f84 ; * lisp/dired-aux.el (dired-show-file-type): Doc fix. commit 5e7d08ae1378771f44f1e3a6840bd81a3bbb7fa7 Author: Stefan Monnier Date: Thu Nov 3 23:16:12 2022 -0400 itree.c: Minor tightening * src/itree.c (iter): Initialize to NULL. (init_itree): Make sure it's not allocated before we overwrite it. (itree_insert_gap): Tweak the end-loop. diff --git a/src/itree.c b/src/itree.c index 611f6d4684..cd37da18b8 100644 --- a/src/itree.c +++ b/src/itree.c @@ -258,7 +258,7 @@ struct itree_iterator are limited by the fact we don't allow modifying the tree at the same time, making the use of nested iterations quite rare anyway. So we just use a single global iterator instead for now. */ -static struct itree_iterator *iter; +static struct itree_iterator *iter = NULL; static int interval_tree_max_height (const struct itree_tree *tree) @@ -290,6 +290,7 @@ itree_iterator_create (struct itree_tree *tree) void init_itree (void) { + eassert (!iter); iter = itree_iterator_create (NULL); } @@ -1205,6 +1206,9 @@ itree_insert_gap (struct itree_tree *tree, ITREE_FOREACH (node, tree, pos, pos + 1, PRE_ORDER) { if (node->begin == pos && node->front_advance + /* If we have front_advance and !rear_advance and + the overlay is empty, make sure we don't move + begin past end by pretending it's !front_advance. */ && (node->begin != node->end || node->rear_advance)) interval_stack_push (saved, node); } @@ -1213,7 +1217,7 @@ itree_insert_gap (struct itree_tree *tree, itree_remove (tree, nav_nodeptr (saved->nodes[i])); /* We can't use an iterator here, because we can't effectively - narrow AND shift some subtree at the same time. */ + narrow AND shift some subtree at the same time. */ if (tree->root != NULL) { const int size = interval_tree_max_height (tree) + 1; @@ -1229,7 +1233,7 @@ itree_insert_gap (struct itree_tree *tree, { if (node->begin > pos) { - /* All nodes in this subtree are shifted by length. */ + /* All nodes in this subtree are shifted by length. */ node->right->offset += length; ++tree->otick; } @@ -1255,16 +1259,17 @@ itree_insert_gap (struct itree_tree *tree, interval_stack_destroy (stack); } - /* Reinsert nodes starting at POS having front-advance. */ + /* Reinsert nodes starting at POS having front-advance. */ uintmax_t notick = tree->otick; nodeptr_and_flag nav; while ((nav = interval_stack_pop (saved), node = nav_nodeptr (nav))) { eassert (node->otick == ootick); + eassert (node->begin == pos); + eassert (node->end > pos || node->rear_advance); node->begin += length; - if (node->end != pos || node->rear_advance) - node->end += length; + node->end += length; node->otick = notick; interval_tree_insert (tree, node); } @@ -1273,7 +1278,7 @@ itree_insert_gap (struct itree_tree *tree, } /* Delete a gap at POS of length LENGTH, contracting all intervals - intersecting it. */ + intersecting it. */ void itree_delete_gap (struct itree_tree *tree, @@ -1282,10 +1287,10 @@ itree_delete_gap (struct itree_tree *tree, if (!tree || length <= 0 || tree->root == NULL) return; - /* FIXME: Don't allocate stack anew every time. */ + /* FIXME: Don't allocate stack anew every time. */ /* Can't use the iterator here, because by decrementing begin, we - might unintentionally bring shifted nodes back into our search space. */ + might unintentionally bring shifted nodes back into our search space. */ const int size = interval_tree_max_height (tree) + 1; struct interval_stack *stack = interval_stack_create (size); struct itree_node *node; commit ff679e16f8bf8a9876fc1a980c372d4e55f3745d Author: Stefan Monnier Date: Thu Nov 3 22:44:55 2022 -0400 itree: Reproduce markers's behavior more faithfully (bug#58928) The most obvious problem was the lack of support for `insert-before-markers`, but the behavior was also different in a few other cases. * src/itree.h (itree_insert_gap): * src/itree.c (itree_insert_gap): Add `before_markers` arg. * src/lisp.h (adjust_overlays_for_insert): * src/buffer.c (adjust_overlays_for_insert): Add `before_markers` arg. * src/insdel.c (adjust_markers_for_replace, adjust_markers_for_insert) (adjust_markers_for_delete): Adjust overlays directly from here. (insert_1_both, insert_from_string_1, insert_from_gap) (insert_from_buffer_1, adjust_after_replace, replace_range) (replace_range_2, del_range_2): Don't adjust overlays explicitly here any more. * test/src/buffer-tests.el (test-overlay-insert-before-markers-empty) (test-overlay-insert-before-markers-non-empty): New tests. diff --git a/src/buffer.c b/src/buffer.c index 3b0e6f1f9a..ee0b7e1350 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -3454,20 +3454,20 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) void -adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length) +adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length, bool before_markers) { if (!current_buffer->indirections) - itree_insert_gap (current_buffer->overlays, pos, length); + itree_insert_gap (current_buffer->overlays, pos, length, before_markers); else { struct buffer *base = current_buffer->base_buffer ? current_buffer->base_buffer : current_buffer; Lisp_Object tail, other; - itree_insert_gap (base->overlays, pos, length); + itree_insert_gap (base->overlays, pos, length, before_markers); FOR_EACH_LIVE_BUFFER (tail, other) if (XBUFFER (other)->base_buffer == base) - itree_insert_gap (XBUFFER (other)->overlays, pos, length); + itree_insert_gap (XBUFFER (other)->overlays, pos, length, before_markers); } } diff --git a/src/insdel.c b/src/insdel.c index 6d56a76c77..ef17f99d21 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -268,6 +268,7 @@ adjust_markers_for_delete (ptrdiff_t from, ptrdiff_t from_byte, m->bytepos = from_byte; } } + adjust_overlays_for_delete (from, to - from); } @@ -307,6 +308,7 @@ adjust_markers_for_insert (ptrdiff_t from, ptrdiff_t from_byte, m->charpos += nchars; } } + adjust_overlays_for_insert (from, to - from, before_markers); } /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters. @@ -358,6 +360,9 @@ adjust_markers_for_replace (ptrdiff_t from, ptrdiff_t from_byte, } check_markers (); + + adjust_overlays_for_insert (from + old_chars, new_chars, true); + adjust_overlays_for_delete (from, old_chars); } /* Starting at POS (BYTEPOS), find the byte position corresponding to @@ -917,7 +922,6 @@ insert_1_both (const char *string, if (Z - GPT < END_UNCHANGED) END_UNCHANGED = Z - GPT; - adjust_overlays_for_insert (PT, nchars); adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, before_markers); @@ -1043,7 +1047,6 @@ insert_from_string_1 (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, if (Z - GPT < END_UNCHANGED) END_UNCHANGED = Z - GPT; - adjust_overlays_for_insert (PT, nchars); adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + outgoing_nbytes, before_markers); @@ -1115,9 +1118,8 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail) insert_from_gap_1 (nchars, nbytes, text_at_gap_tail); - adjust_overlays_for_insert (ins_charpos, nchars); adjust_markers_for_insert (ins_charpos, ins_bytepos, - ins_charpos + nchars, ins_bytepos + nbytes, 0); + ins_charpos + nchars, ins_bytepos + nbytes, false); if (buffer_intervals (current_buffer)) { @@ -1257,10 +1259,9 @@ insert_from_buffer_1 (struct buffer *buf, if (Z - GPT < END_UNCHANGED) END_UNCHANGED = Z - GPT; - adjust_overlays_for_insert (PT, nchars); adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + outgoing_nbytes, - 0); + false); offset_intervals (current_buffer, PT, nchars); @@ -1316,17 +1317,12 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte, len, len_byte); else adjust_markers_for_insert (from, from_byte, - from + len, from_byte + len_byte, 0); + from + len, from_byte + len_byte, false); if (nchars_del > 0) record_delete (from, prev_text, false); record_insert (from, len); - if (len > nchars_del) - adjust_overlays_for_insert (from, len - nchars_del); - else if (len < nchars_del) - adjust_overlays_for_delete (from, nchars_del - len); - offset_intervals (current_buffer, from, len - nchars_del); if (from < PT) @@ -1507,14 +1503,9 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, which make the original byte positions of the markers invalid. */ adjust_markers_bytepos (from, from_byte, from + inschars, - from_byte + outgoing_insbytes, 1); + from_byte + outgoing_insbytes, true); } - /* Adjust the overlay center as needed. This must be done after - adjusting the markers that bound the overlays. */ - adjust_overlays_for_delete (from, nchars_del); - adjust_overlays_for_insert (from, inschars); - offset_intervals (current_buffer, from, inschars - nchars_del); /* Get the intervals for the part of the string we are inserting-- @@ -1640,18 +1631,10 @@ replace_range_2 (ptrdiff_t from, ptrdiff_t from_byte, sequences which make the original byte positions of the markers invalid. */ adjust_markers_bytepos (from, from_byte, from + inschars, - from_byte + insbytes, 1); + from_byte + insbytes, true); } } - /* Adjust the overlay center as needed. This must be done after - adjusting the markers that bound the overlays. */ - if (nchars_del != inschars) - { - adjust_overlays_for_insert (from, inschars); - adjust_overlays_for_delete (from + inschars, nchars_del); - } - offset_intervals (current_buffer, from, inschars - nchars_del); /* Relocate point as if it were a marker. */ @@ -1854,10 +1837,6 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, offset_intervals (current_buffer, from, - nchars_del); - /* Adjust the overlay center as needed. This must be done after - adjusting the markers that bound the overlays. */ - adjust_overlays_for_delete (from, nchars_del); - GAP_SIZE += nbytes_del; ZV_BYTE -= nbytes_del; Z_BYTE -= nbytes_del; diff --git a/src/itree.c b/src/itree.c index 3137cb6358..611f6d4684 100644 --- a/src/itree.c +++ b/src/itree.c @@ -1186,7 +1186,7 @@ itree_iterator_finish (struct itree_iterator *iter) void itree_insert_gap (struct itree_tree *tree, - ptrdiff_t pos, ptrdiff_t length) + ptrdiff_t pos, ptrdiff_t length, bool before_markers) { if (!tree || length <= 0 || tree->root == NULL) return; @@ -1195,14 +1195,19 @@ itree_insert_gap (struct itree_tree *tree, /* FIXME: Don't allocate iterator/stack anew every time. */ /* Nodes with front_advance starting at pos may mess up the tree - order, so we need to remove them first. */ + order, so we need to remove them first. This doesn't apply for + `before_markers` since in that case, all positions move identically + regardless of `front_advance` or `rear_advance`. */ struct interval_stack *saved = interval_stack_create (0); struct itree_node *node = NULL; - ITREE_FOREACH (node, tree, pos, pos + 1, PRE_ORDER) + if (!before_markers) { - if (node->begin == pos && node->front_advance - && (node->begin != node->end || node->rear_advance)) - interval_stack_push (saved, node); + ITREE_FOREACH (node, tree, pos, pos + 1, PRE_ORDER) + { + if (node->begin == pos && node->front_advance + && (node->begin != node->end || node->rear_advance)) + interval_stack_push (saved, node); + } } for (size_t i = 0; i < saved->length; ++i) itree_remove (tree, nav_nodeptr (saved->nodes[i])); @@ -1235,10 +1240,12 @@ itree_insert_gap (struct itree_tree *tree, && pos <= node->left->limit + node->left->offset) interval_stack_push (stack, node->left); - /* node->begin == pos implies no front-advance. */ - if (node->begin > pos) + if (before_markers + ? node->begin >= pos + : node->begin > pos) /* node->begin == pos => !front-advance */ node->begin += length; - if (node->end > pos || (node->end == pos && node->rear_advance)) + if (node->end > pos + || (node->end == pos && (before_markers || node->rear_advance))) { node->end += length; eassert (node != NULL); diff --git a/src/itree.h b/src/itree.h index 49a0333f34..d05bc7789a 100644 --- a/src/itree.h +++ b/src/itree.h @@ -120,7 +120,7 @@ extern void itree_insert (struct itree_tree *, struct itree_node *, ptrdiff_t, ptrdiff_t); extern struct itree_node *itree_remove (struct itree_tree *, struct itree_node *); -extern void itree_insert_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t); +extern void itree_insert_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t, bool); extern void itree_delete_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t); /* Iteration functions. Almost all code should use ITREE_FOREACH diff --git a/src/lisp.h b/src/lisp.h index eafa241adf..e240f86902 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4690,7 +4690,7 @@ extern void syms_of_editfns (void); extern bool mouse_face_overlay_overlaps (Lisp_Object); extern Lisp_Object disable_line_numbers_overlay_at_eob (void); extern AVOID nsberror (Lisp_Object); -extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t); +extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t, bool); extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t); extern void fix_start_end_in_overlays (ptrdiff_t, ptrdiff_t); extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool, diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el index b96a8dcacd..a39d7d51de 100644 --- a/test/src/buffer-tests.el +++ b/test/src/buffer-tests.el @@ -528,6 +528,28 @@ with parameters from the *Messages* buffer modification." (deftest-overlay-start/end-1 L (1 0) (1 1)) (deftest-overlay-start/end-1 M (0 0) (1 1)) +(ert-deftest test-overlay-insert-before-markers-empty () + (with-temp-buffer + (insert "1234") + (goto-char (1+ (point-min))) + (let ((overlay (make-overlay (point) (point)))) + (insert-before-markers "x") + (should (equal (point) (overlay-end overlay))) + (should (equal (point) (overlay-start overlay)))))) + +(ert-deftest test-overlay-insert-before-markers-non-empty () + (with-temp-buffer + (insert "1234") + (goto-char (+ 2 (point))) + (let ((overlay (make-overlay (1- (point)) (point)))) + (insert-before-markers "x") + (should (equal (point) (overlay-end overlay))) + (should (equal (- (point) 2) (overlay-start overlay))) + (forward-char -2) + (insert-before-markers "y") + (should (equal (+ 2 (point)) (overlay-end overlay))) + (should (equal (point) (overlay-start overlay)))))) + (ert-deftest test-overlay-start/end-2 () (should-not (overlay-start (with-temp-buffer (make-overlay 1 1)))) (should-not (overlay-end (with-temp-buffer (make-overlay 1 1))))) commit 7d47651d0168c863ad9e9b07921a42dc18029276 Author: Dmitry Gutov Date: Fri Nov 4 03:16:36 2022 +0200 project-buffers: Describe the default implementation * lisp/progmodes/project.el (project-buffers): Describe what the default implementation is doing (bug#58784). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index ec453baf72..6d062aa8fa 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -353,7 +353,10 @@ Also quote LOCAL-FILES if `default-directory' is quoted." local-files)))) (cl-defgeneric project-buffers (project) - "Return the list of all live buffers that belong to PROJECT." + "Return the list of all live buffers that belong to PROJECT. + +The default implementation matches the current open buffers to +PROJECT root using the value of `default-directory' in each one." (let ((root (expand-file-name (file-name-as-directory (project-root project)))) bufs) (dolist (buf (buffer-list)) commit ef45bfacb2157f6cb6e9d306b5ad8e3e219d03f8 Author: Dmitry Gutov Date: Fri Nov 4 03:03:29 2022 +0200 project-kill-buffer-conditions: Skip Gnus modes as well * lisp/progmodes/project.el (project-kill-buffer-conditions): Skip Gnus modes as well (bug#58839). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 9f386e7c92..ec453baf72 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1228,7 +1228,8 @@ displayed." (not "\\` ")) ;; non-text buffer such as xref, occur, vc, log, ... (and (derived-mode . special-mode) - (not (major-mode . help-mode))) + (not (major-mode . help-mode)) + (not (derived-mode . gnus-mode))) (derived-mode . compilation-mode) (derived-mode . dired-mode) (derived-mode . diff-mode) commit 44f23dac25f1a4f3194f760ddc733be4253f1ca0 Author: Dmitry Gutov Date: Fri Nov 4 02:58:58 2022 +0200 project-kill-buffer-conditions: Skip hidden ones * lisp/progmodes/project.el (project-kill-buffer-conditions): Make exception for "hidden" buffers (bug#58839). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 0aa7955c65..9f386e7c92 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1222,8 +1222,10 @@ displayed." (defcustom project-kill-buffer-conditions '(buffer-file-name ; All file-visiting buffers are included. - ;; Most of the temp buffers in the background: - (major-mode . fundamental-mode) + ;; Most of temp and logging buffers (aside from hidden ones): + (and + (major-mode . fundamental-mode) + (not "\\` ")) ;; non-text buffer such as xref, occur, vc, log, ... (and (derived-mode . special-mode) (not (major-mode . help-mode))) commit 8e7066babeac122c289b5b22c5a372bb67ddd8ef Author: Po Lu Date: Fri Nov 4 08:29:02 2022 +0800 Fix initialization of scroll valuator emacs_value * src/xterm.c (xi_handle_device_changed): Initialize emacs_value to 0, not DBL_MIN. (bug#58980) diff --git a/src/xterm.c b/src/xterm.c index 1b666fae7e..71ff69ece4 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -13083,7 +13083,7 @@ xi_handle_device_changed (struct x_display_info *dpyinfo, valuator->horizontal = (scroll->scroll_type == XIScrollTypeHorizontal); valuator->invalid_p = true; - valuator->emacs_value = DBL_MIN; + valuator->emacs_value = 0; valuator->increment = scroll->increment; valuator->number = scroll->number; break; commit d2a9dae40057ff16683d9c5f30a3b04500ebc4cf Author: Jim Porter Date: Sun Sep 18 17:42:09 2022 -0700 Only strip newlines when stringifying a value for Eshell * lisp/eshell/esh-util.el (eshell-stringify): Use 'string-trim-right' instead of stripping the last character of the result of 'pp-to-string' (bug#58810). * test/lisp/eshell/esh-util-tests.el: New file. diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index f47373c115..ecb6888651 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el @@ -350,16 +350,13 @@ Prepend remote identification of `default-directory', if any." "Convert OBJECT into a string value." (cond ((stringp object) object) - ((and (listp object) - (not (eq object nil))) - (let ((string (pp-to-string object))) - (substring string 0 (1- (length string))))) ((numberp object) (number-to-string object)) + ((and (eq object t) + (not eshell-stringify-t)) + nil) (t - (unless (and (eq object t) - (not eshell-stringify-t)) - (pp-to-string object))))) + (string-trim-right (pp-to-string object))))) (defsubst eshell-stringify-list (args) "Convert each element of ARGS into a string value." diff --git a/test/lisp/eshell/esh-util-tests.el b/test/lisp/eshell/esh-util-tests.el new file mode 100644 index 0000000000..1cbd015999 --- /dev/null +++ b/test/lisp/eshell/esh-util-tests.el @@ -0,0 +1,57 @@ +;;; esh-util-tests.el --- esh-util test suite -*- lexical-binding:t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(require 'ert) +(require 'esh-util) + +;;; Tests: + +(ert-deftest esh-util-test/eshell-stringify/string () + "Test that `eshell-stringify' preserves the value of strings." + (should (equal (eshell-stringify "hello") "hello"))) + +(ert-deftest esh-util-test/eshell-stringify/number () + "Test that `eshell-stringify' converts numbers to strings." + (should (equal (eshell-stringify 42) "42")) + (should (equal (eshell-stringify 4.2) "4.2"))) + +(ert-deftest esh-util-test/eshell-stringify/t () + "Test that `eshell-stringify' treats `t' according to `eshell-stringify-t'." + (let ((eshell-stringify-t t)) + (should (equal (eshell-stringify t) "t"))) + (let ((eshell-stringify-t nil)) + (should (equal (eshell-stringify t) nil)))) + +(ert-deftest esh-util-test/eshell-stringify/nil () + "Test that `eshell-stringify' converts nil to a string." + (should (equal (eshell-stringify nil) "nil"))) + +(ert-deftest esh-util-test/eshell-stringify/list () + "Test that `eshell-stringify' correctly stringifies lists." + (should (equal (eshell-stringify '(1 2 3)) "(1 2 3)")) + (should (equal (eshell-stringify '((1 2) (3 . 4))) + "((1 2)\n (3 . 4))"))) + +(ert-deftest esh-util-test/eshell-stringify/complex () + "Test that `eshell-stringify' correctly stringifies complex objects." + (should (equal (eshell-stringify (list 'quote 'hello)) "'hello"))) + +;;; esh-util-tests.el ends here commit 39f5696921c1618f46358a5c189244d3993a1fca Author: Paul Eggert Date: Thu Nov 3 11:09:53 2022 -0700 Improve suppression of bogus macOS warnings * configure.ac: On macOS, always use -Wno-deprecated-declarations, as the false alarms appear even if --disable-gcc-warnings is given (Bug#58966). diff --git a/configure.ac b/configure.ac index c9d1eb5709..b656dba4d9 100644 --- a/configure.ac +++ b/configure.ac @@ -1144,12 +1144,6 @@ AS_IF([test $gl_gcc_warnings = no], gl_WARN_ADD([-Wno-int-in-bool-context]) fi - # Suppress deprecation warnings from using sprintf variants, - # starting with Xcode 14.1 on macOS 13. - if test $opsys = darwin; then - gl_WARN_ADD([-Wno-deprecated-declarations]) - fi - # This causes too much noise in the MinGW build if test $opsys = mingw32; then gl_WARN_ADD([-Wno-pointer-sign]) @@ -1176,6 +1170,13 @@ if test "$emacs_cv_clang" = yes; then gl_WARN_ADD([-Wno-tautological-constant-out-of-range-compare]) fi +# Suppress deprecation warnings from using sprintf variants, +# starting with Xcode 14.1 on macOS 13. +# These warnings are false alarms, as Emacs usage of sprintf is safe. +if test $opsys = darwin; then + gl_WARN_ADD([-Wno-deprecated-declarations]) +fi + # Use a slightly smaller set of warning options for lib/. nw= nw="$nw -Wunused-macros" commit 8cae9d8bd843398010c41b1bf6d96c20937ab38f (refs/remotes/origin/emacs-28) Author: Eli Zaretskii Date: Thu Nov 3 20:02:00 2022 +0200 ; * doc/emacs/search.texi (Lax Search): Improve wording. (Bug#58992) diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index 269ea71aa8..c58cc363ad 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi @@ -1332,18 +1332,19 @@ tailor them to your needs. @kindex SPC @r{(Incremental search)} @findex isearch-toggle-lax-whitespace @vindex search-whitespace-regexp - By default, search commands perform @dfn{lax space matching}: -each space, or sequence of spaces, matches any sequence of one or more -whitespace characters in the text. (Incremental regexp search has a -separate default; see @ref{Regexp Search}.) Hence, @w{@samp{foo bar}} -matches @w{@samp{foo bar}}, @w{@samp{foo@ @ bar}}, -@w{@samp{foo@ @ @ bar}}, and so on (but not @samp{foobar}). More -precisely, Emacs matches each sequence of space characters in the -search string to a regular expression specified by the variable -@code{search-whitespace-regexp}. For example, to make spaces match -sequences of newlines as well as spaces, set it to the regular expression -@samp{[[:space:]\n]+}. The default value of this variable considers -any sequence of spaces and tab characters as whitespace. + By default, search commands perform @dfn{lax space matching}: each +space, or sequence of spaces, matches any sequence of one or more +whitespace characters in the text. More precisely, Emacs matches each +sequence of space characters in the search string to a regular +expression specified by the user option +@code{search-whitespace-regexp}. The default value of this option +considers any sequence of spaces and tab characters as whitespace. +Hence, @w{@samp{foo bar}} matches @w{@samp{foo bar}}, @w{@samp{foo@ @ +bar}}, @w{@samp{foo@ @ @ bar}}, and so on (but not @samp{foobar}). If +you want to make spaces match sequences of newlines as well as spaces +and tabs, customize the option to make its value be the regular +expression @samp{[[:space:]\n]+}. (The default behavior of the +incremental regexp search is different; see @ref{Regexp Search}.) If you want whitespace characters to match exactly, you can turn lax space matching off by typing @kbd{M-s @key{SPC}} commit 651bf0a99923e5eff279e9f9649aaed3d2f05c71 Author: Juri Linkov Date: Thu Nov 3 19:35:45 2022 +0200 Fix overlays order in Flyspell (bug#58970) Flyspell relies on the sorting order of overlays from 'overlays-in' that returned the overlays sorted by decreased 'overlay-start'. But after the recent merge of the noverlay branch, the order was reversed. So need to change the order back to the expected by Flyspell. * lisp/textmodes/flyspell.el (flyspell-auto-correct-previous-word): Sort overlays returned from 'overlays-in' descending by 'overlay-start'. diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index a66b72cfd0..11039f2963 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el @@ -2131,7 +2131,9 @@ But don't look beyond what's visible on the screen." ;; only reset if a new overlay exists (setq flyspell-auto-correct-previous-pos nil) - (let ((overlay-list (overlays-in (point-min) position)) + (let ((overlay-list (seq-sort-by + #'overlay-start #'> + (overlays-in (point-min) position))) (new-overlay 'dummy-value)) ;; search for previous (new) flyspell overlay commit a66280162f907a09be23922cc80ac352392adac6 Author: Basil L. Contovounesios Date: Wed Nov 2 03:50:38 2022 +0200 Port interval trees to --enable-checking=structs Some names under the interval_* namespace were renamed under the itree_* namespace in commits: 0. f421b58db5 of 2022-10-19 "Prefix all itree.h type names with itree_". 1. 37a1145410 of 2022-10-19 "Rename all exported itree.h functions with the itree_ prefix" Further, some values still referenced in commentary were removed in commits: 2. 258e618364 of 2022-10-17 "Delete the itree_null sentinel node, use NULL everywhere." 3. 2c4a3910b3 of 2022-10-02 "itree: Use a single iterator object" * src/emacs.c (main): Allocate global itree iterator once and for all. * src/alloc.c (mark_overlay): * src/buffer.c (set_overlays_multibyte): * src/itree.c (itree_destroy): Update commentary. (interval_stack_ensure_space, itree_insert_gap): Prefer unsigned-to-unsigned comparisons over signed-to-unsigned. (interval_stack_push_flagged, interval_tree_insert) (interval_tree_contains, itree_iterator_start) (itree_iterator_finish, itree_iterator_next, itree_iterator_narrow): Improve assertions. (itree_init): Rename... (init_itree): ...to this, for consistency with other global init functions. (itree_create): Stop leaking a global iterator allocation on each call. (interval_tree_init): Complete renames of interval_tree -> itree_tree and interval_tree_clear -> itree_clear. (interval_tree_remove_fix): Fix indentation. * src/itree.h: Declare init_itree. (ITREE_FOREACH): Fix typo in commentary. * src/pdumper.c [CHECK_STRUCTS] (dump_interval_node): Use the correct name in the HASH condition and #error message. (dump_overlay, dump_buffer): Update HASH (bug#58975). diff --git a/src/alloc.c b/src/alloc.c index f69c65dedc..6862cf916f 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -6508,7 +6508,7 @@ mark_char_table (struct Lisp_Vector *ptr, enum pvec_type pvectype) static void mark_overlay (struct Lisp_Overlay *ov) { - /* We don't mark the `interval_node` object, because it is managed manually + /* We don't mark the `itree_node` object, because it is managed manually rather than by the GC. */ eassert (BASE_EQ (ov->interval->data, make_lisp_ptr (ov, Lisp_Vectorlike))); set_vectorlike_marked (&ov->header); diff --git a/src/buffer.c b/src/buffer.c index 3129aa2890..3b0e6f1f9a 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -982,7 +982,7 @@ set_overlays_multibyte (bool multibyte) struct itree_tree *tree = current_buffer->overlays; const intmax_t size = itree_size (tree); - /* We can't use `interval_node_set_region` at the same time + /* We can't use `itree_node_set_region` at the same time as we iterate over the itree, so we need an auxiliary storage to keep the list of nodes. */ USE_SAFE_ALLOCA; diff --git a/src/emacs.c b/src/emacs.c index 8ad70fecd4..40ba0db340 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -82,6 +82,7 @@ along with GNU Emacs. If not, see . */ #endif /* HAVE_WINDOW_SYSTEM */ #include "bignum.h" +#include "itree.h" #include "intervals.h" #include "character.h" #include "buffer.h" @@ -1931,6 +1932,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem running_asynch_code = 0; init_random (); init_xfaces (); + init_itree (); #if defined HAVE_JSON && !defined WINDOWSNT init_json (); diff --git a/src/itree.c b/src/itree.c index bd4e8cc574..3137cb6358 100644 --- a/src/itree.c +++ b/src/itree.c @@ -191,7 +191,7 @@ interval_stack_clear (struct interval_stack *stack) } static inline void -interval_stack_ensure_space (struct interval_stack *stack, intmax_t nelements) +interval_stack_ensure_space (struct interval_stack *stack, uintmax_t nelements) { if (nelements > stack->size) { @@ -207,7 +207,7 @@ static inline void interval_stack_push_flagged (struct interval_stack *stack, struct itree_node *node, bool flag) { - eassert (node && node != NULL); + eassert (node); /* FIXME: While the stack used in the iterator is bounded by the tree depth and could be easily pre-allocated to a large enough size to avoid @@ -287,8 +287,8 @@ itree_iterator_create (struct itree_tree *tree) return g; } -static void -itree_init (void) +void +init_itree (void) { iter = itree_iterator_create (NULL); } @@ -555,16 +555,11 @@ itree_node_end (struct itree_tree *tree, return node->end; } -/* Allocate an interval_tree. Free with interval_tree_destroy. */ +/* Allocate an itree_tree. Free with itree_destroy. */ struct itree_tree * itree_create (void) { - /* FIXME? Maybe avoid the initialization of itree_null in the same - way that is used to call mem_init in alloc.c? It's not really - important though. */ - itree_init (); - struct itree_tree *tree = xmalloc (sizeof (*tree)); itree_clear (tree); return tree; @@ -584,10 +579,9 @@ itree_clear (struct itree_tree *tree) /* Initialize a pre-allocated tree (presumably on the stack). */ static void -interval_tree_init (struct interval_tree *tree) +interval_tree_init (struct itree_tree *tree) { - interval_tree_clear (tree); - /* tree->iter = itree_iterator_create (tree); */ + itree_clear (tree); } #endif @@ -596,8 +590,6 @@ void itree_destroy (struct itree_tree *tree) { eassert (tree->root == NULL); - /* if (tree->iter) - * itree_iterator_destroy (tree->iter); */ xfree (tree); } @@ -775,7 +767,7 @@ interval_tree_insert_fix (struct itree_tree *tree, static void interval_tree_insert (struct itree_tree *tree, struct itree_node *node) { - eassert (node->begin <= node->end && node != NULL); + eassert (node && node->begin <= node->end); /* FIXME: The assertion below fails because `delete_all_overlays` doesn't set left/right/parent to NULL. */ /* eassert (node->left == NULL && node->right == NULL @@ -868,7 +860,7 @@ itree_node_set_region (struct itree_tree *tree, static bool interval_tree_contains (struct itree_tree *tree, struct itree_node *node) { - eassert (node); + eassert (iter && node); struct itree_node *other; ITREE_FOREACH (other, tree, node->begin, PTRDIFF_MAX, ASCENDING) if (other == node) @@ -912,7 +904,7 @@ interval_tree_remove_fix (struct itree_tree *tree, if (parent == NULL) eassert (node == tree->root); else - eassert (node == NULL || node->parent == parent); + eassert (node == NULL || node->parent == parent); while (parent != NULL && null_safe_is_black (node)) { @@ -1151,7 +1143,7 @@ itree_iterator_start (struct itree_tree *tree, ptrdiff_t begin, ptrdiff_t end, enum itree_order order, const char *file, int line) { - /* struct itree_iterator *iter = tree->iter; */ + eassert (iter); if (iter->running) { fprintf (stderr, @@ -1179,7 +1171,7 @@ itree_iterator_start (struct itree_tree *tree, ptrdiff_t begin, void itree_iterator_finish (struct itree_iterator *iter) { - eassert (iter->running); + eassert (iter && iter->running); iter->running = false; } @@ -1212,7 +1204,7 @@ itree_insert_gap (struct itree_tree *tree, && (node->begin != node->end || node->rear_advance)) interval_stack_push (saved, node); } - for (int i = 0; i < saved->length; ++i) + for (size_t i = 0; i < saved->length; ++i) itree_remove (tree, nav_nodeptr (saved->nodes[i])); /* We can't use an iterator here, because we can't effectively @@ -1352,7 +1344,7 @@ interval_node_intersects (const struct itree_node *node, struct itree_node * itree_iterator_next (struct itree_iterator *g) { - eassert (g->running); + eassert (g && g->running); struct itree_node *const null = NULL; struct itree_node *node; @@ -1424,9 +1416,9 @@ void itree_iterator_narrow (struct itree_iterator *g, ptrdiff_t begin, ptrdiff_t end) { - eassert (g->running); + eassert (g && g->running); eassert (begin >= g->begin); eassert (end <= g->end); - g->begin = max (begin, g->begin); - g->end = min (end, g->end); + g->begin = max (begin, g->begin); + g->end = min (end, g->end); } diff --git a/src/itree.h b/src/itree.h index c6b68d3667..49a0333f34 100644 --- a/src/itree.h +++ b/src/itree.h @@ -106,6 +106,7 @@ enum itree_order ITREE_PRE_ORDER, }; +extern void init_itree (void); extern void itree_node_init (struct itree_node *, bool, bool, Lisp_Object); extern ptrdiff_t itree_node_begin (struct itree_tree *, struct itree_node *); extern ptrdiff_t itree_node_end (struct itree_tree *, struct itree_node *); @@ -147,7 +148,7 @@ extern struct itree_node *itree_iterator_next (struct itree_iterator *); BEWARE: - The expression T may be evaluated more than once, so make sure - it is cheap a pure. + it is cheap and pure. - Only a single iteration can happen at a time, so make sure none of the code within the loop can start another tree iteration, i.e. it shouldn't be able to run ELisp code, nor GC since GC can run ELisp by way diff --git a/src/pdumper.c b/src/pdumper.c index d6ae57afb2..0a5d96dbb7 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2137,8 +2137,8 @@ static dump_off dump_interval_node (struct dump_context *ctx, struct itree_node *node, dump_off parent_offset) { -#if CHECK_STRUCTS && !defined (HASH_interval_node_5765524F7E) -# error "interval_node changed. See CHECK_STRUCTS comment in config.h." +#if CHECK_STRUCTS && !defined (HASH_itree_node_50DE304F13) +# error "itree_node changed. See CHECK_STRUCTS comment in config.h." #endif struct itree_node out; dump_object_start (ctx, &out, sizeof (out)); @@ -2179,7 +2179,7 @@ dump_interval_node (struct dump_context *ctx, struct itree_node *node, static dump_off dump_overlay (struct dump_context *ctx, const struct Lisp_Overlay *overlay) { -#if CHECK_STRUCTS && !defined (HASH_Lisp_Overlay_1CD4249AEC) +#if CHECK_STRUCTS && !defined (HASH_Lisp_Overlay_EB4C05D8D2) # error "Lisp_Overlay changed. See CHECK_STRUCTS comment in config.h." #endif START_DUMP_PVEC (ctx, &overlay->header, struct Lisp_Overlay, out); @@ -2748,7 +2748,7 @@ dump_hash_table (struct dump_context *ctx, static dump_off dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer) { -#if CHECK_STRUCTS && !defined HASH_buffer_F0F08347A5 +#if CHECK_STRUCTS && !defined HASH_buffer_193CAA5E45 # error "buffer changed. See CHECK_STRUCTS comment in config.h." #endif struct buffer munged_buffer = *in_buffer; commit 8b8038494ce8354a3e2cfffebba40dbd1328ebb9 Author: Juanma Barranquero Date: Thu Nov 3 14:41:28 2022 +0100 * src/gnutls.c (Fgnutls_available_p): Avoid duplicating capabilities. diff --git a/src/gnutls.c b/src/gnutls.c index a0de0238c4..7f0aaf85a4 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -2790,6 +2790,10 @@ Any GnuTLS extension with ID up to 100 capabilities = Fcons (intern("gnutls"), capabilities); +# ifdef HAVE_GNUTLS_EXT__DUMBFW + capabilities = Fcons (intern("ClientHello Padding"), capabilities); +# endif + # ifdef HAVE_GNUTLS3 capabilities = Fcons (intern("gnutls3"), capabilities); capabilities = Fcons (intern("digests"), capabilities); @@ -2807,16 +2811,14 @@ Any GnuTLS extension with ID up to 100 const char* name = gnutls_ext_get_name(ext); if (name != NULL) { - capabilities = Fcons (intern(name), capabilities); + Lisp_Object cap = intern (name); + if (NILP (Fmemq (cap, capabilities))) + capabilities = Fcons (cap, capabilities); } } # endif # endif /* HAVE_GNUTLS3 */ -# ifdef HAVE_GNUTLS_EXT__DUMBFW - capabilities = Fcons (intern("ClientHello Padding"), capabilities); -# endif - # ifdef WINDOWSNT Vlibrary_cache = Fcons (Fcons (Qgnutls, capabilities), Vlibrary_cache); # endif /* WINDOWSNT */ commit d8bef573d6451d02a996d556dcd33b8e978b23d7 Author: Stefan Kangas Date: Wed Nov 2 15:43:35 2022 +0100 Prefer defvar-keymap in profiler.el * lisp/profiler.el (profiler-report-mode-map): Prefer defvar-keymap. diff --git a/lisp/profiler.el b/lisp/profiler.el index 8670e5786a..e66b1ff42a 100644 --- a/lisp/profiler.el +++ b/lisp/profiler.el @@ -534,72 +534,71 @@ RET: expand or collapse")) ;;; Report mode -(defvar profiler-report-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "n" 'profiler-report-next-entry) - (define-key map "p" 'profiler-report-previous-entry) - ;; I find it annoying more than helpful to not be able to navigate - ;; normally with the cursor keys. --Stef - ;; (define-key map [down] 'profiler-report-next-entry) - ;; (define-key map [up] 'profiler-report-previous-entry) - (define-key map "\r" 'profiler-report-toggle-entry) - (define-key map "\t" 'profiler-report-toggle-entry) - (define-key map "i" 'profiler-report-toggle-entry) - (define-key map "f" 'profiler-report-find-entry) - (define-key map "j" 'profiler-report-find-entry) - (define-key map [follow-link] 'mouse-face) - (define-key map [mouse-2] 'profiler-report-find-entry) - (define-key map "d" 'profiler-report-describe-entry) - (define-key map "C" 'profiler-report-render-calltree) - (define-key map "B" 'profiler-report-render-reversed-calltree) - (define-key map "A" 'profiler-report-ascending-sort) - (define-key map "D" 'profiler-report-descending-sort) - (define-key map "=" 'profiler-report-compare-profile) - (define-key map (kbd "C-x C-w") 'profiler-report-write-profile) - (easy-menu-define profiler-report-menu map "Menu for Profiler Report mode." - '("Profiler" - ["Next Entry" profiler-report-next-entry :active t - :help "Move to next entry"] - ["Previous Entry" profiler-report-previous-entry :active t - :help "Move to previous entry"] - "--" - ["Toggle Entry" profiler-report-toggle-entry - :active (profiler-report-calltree-at-point) - :help "Expand or collapse the current entry"] - ["Find Entry" profiler-report-find-entry - ;; FIXME should deactivate if not on a known function. - :active (profiler-report-calltree-at-point) - :help "Find the definition of the current entry"] - ["Describe Entry" profiler-report-describe-entry - :active (profiler-report-calltree-at-point) - :help "Show the documentation of the current entry"] - "--" - ["Show Calltree" profiler-report-render-calltree - :active profiler-report-reversed - :help "Show calltree view"] - ["Show Reversed Calltree" profiler-report-render-reversed-calltree - :active (not profiler-report-reversed) - :help "Show reversed calltree view"] - ["Sort Ascending" profiler-report-ascending-sort - :active (not (eq profiler-report-order 'ascending)) - :help "Sort calltree view in ascending order"] - ["Sort Descending" profiler-report-descending-sort - :active (not (eq profiler-report-order 'descending)) - :help "Sort calltree view in descending order"] - "--" - ["Compare Profile..." profiler-report-compare-profile :active t - :help "Compare current profile with another"] - ["Write Profile..." profiler-report-write-profile :active t - :help "Write current profile to a file"] - "--" - ["Start Profiler" profiler-start :active (not (profiler-running-p)) - :help "Start profiling"] - ["Stop Profiler" profiler-stop :active (profiler-running-p) - :help "Stop profiling"] - ["New Report" profiler-report :active (profiler-running-p) - :help "Make a new report"])) - map) - "Keymap for `profiler-report-mode'.") +(defvar-keymap profiler-report-mode-map + :doc "Keymap for `profiler-report-mode'." + "n" #'profiler-report-next-entry + "p" #'profiler-report-previous-entry + ;; I find it annoying more than helpful to not be able to navigate + ;; normally with the cursor keys. --Stef + ;; "" #'profiler-report-next-entry + ;; "" #'profiler-report-previous-entry + "RET" #'profiler-report-toggle-entry + "TAB" #'profiler-report-toggle-entry + "i" #'profiler-report-toggle-entry + "f" #'profiler-report-find-entry + "j" #'profiler-report-find-entry + "d" #'profiler-report-describe-entry + "C" #'profiler-report-render-calltree + "B" #'profiler-report-render-reversed-calltree + "A" #'profiler-report-ascending-sort + "D" #'profiler-report-descending-sort + "=" #'profiler-report-compare-profile + "C-x C-w" #'profiler-report-write-profile + "" 'mouse-face + "" #'profiler-report-find-entry + + :menu + '("Profiler" + ["Next Entry" profiler-report-next-entry :active t + :help "Move to next entry"] + ["Previous Entry" profiler-report-previous-entry :active t + :help "Move to previous entry"] + "--" + ["Toggle Entry" profiler-report-toggle-entry + :active (profiler-report-calltree-at-point) + :help "Expand or collapse the current entry"] + ["Find Entry" profiler-report-find-entry + ;; FIXME should deactivate if not on a known function. + :active (profiler-report-calltree-at-point) + :help "Find the definition of the current entry"] + ["Describe Entry" profiler-report-describe-entry + :active (profiler-report-calltree-at-point) + :help "Show the documentation of the current entry"] + "--" + ["Show Calltree" profiler-report-render-calltree + :active profiler-report-reversed + :help "Show calltree view"] + ["Show Reversed Calltree" profiler-report-render-reversed-calltree + :active (not profiler-report-reversed) + :help "Show reversed calltree view"] + ["Sort Ascending" profiler-report-ascending-sort + :active (not (eq profiler-report-order 'ascending)) + :help "Sort calltree view in ascending order"] + ["Sort Descending" profiler-report-descending-sort + :active (not (eq profiler-report-order 'descending)) + :help "Sort calltree view in descending order"] + "--" + ["Compare Profile..." profiler-report-compare-profile :active t + :help "Compare current profile with another"] + ["Write Profile..." profiler-report-write-profile :active t + :help "Write current profile to a file"] + "--" + ["Start Profiler" profiler-start :active (not (profiler-running-p)) + :help "Start profiling"] + ["Stop Profiler" profiler-stop :active (profiler-running-p) + :help "Stop profiling"] + ["New Report" profiler-report :active (profiler-running-p) + :help "Make a new report"])) (defun profiler-report-make-buffer-name (profile) (format "*%s-Profiler-Report %s*" commit 2eb2eb0c9ead205935be58ce9bb54465d48b20c8 Author: Jonas Bernoulli Date: Wed Nov 2 23:33:59 2022 +0100 ; * emoji.el (emoji--define-transient): Adapt to recent changes in transient. diff --git a/lisp/international/emoji.el b/lisp/international/emoji.el index 4f4d4f4832..3d065b778e 100644 --- a/lisp/international/emoji.el +++ b/lisp/international/emoji.el @@ -552,8 +552,7 @@ the name is not known." (apply (or class 'transient-prefix) :command name (cons :variable-pitch (cons t slots)))) (put name 'transient--layout - (cl-mapcan (lambda (s) (transient--parse-child name s)) - suffixes))) + (transient-parse-suffixes name suffixes))) name)) (defun emoji--recent-transient (end-function) commit eb8478c5142c32efacb19e22c5203885393a423c Author: Po Lu Date: Thu Nov 3 19:27:24 2022 +0800 Further simplify valuator reset code * src/xterm.c (xi_reset_scroll_valuators_for_device_id): Minor style adjustments. (handle_one_xevent): Don't check frames; reset on all XI_Enter and XI_Leave events. diff --git a/src/xterm.c b/src/xterm.c index 17ff35a671..1b666fae7e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5610,8 +5610,11 @@ static void xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id) { - struct xi_device_t *device = xi_device_from_id (dpyinfo, id); + struct xi_device_t *device; struct xi_scroll_valuator_t *valuator; + int i; + + device = xi_device_from_id (dpyinfo, id); if (!device) return; @@ -5619,7 +5622,7 @@ xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, if (!device->scroll_valuator_count) return; - for (int i = 0; i < device->scroll_valuator_count; ++i) + for (i = 0; i < device->scroll_valuator_count; ++i) { valuator = &device->valuators[i]; valuator->invalid_p = true; @@ -21399,6 +21402,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, related to those grabs arrive. The only way to remedy this is to never reset scroll valuators on a grab-related crossing event. (bug#57476) */ + if (enter->mode != XINotifyUngrab && enter->mode != XINotifyGrab && enter->mode != XINotifyPassiveGrab @@ -21528,17 +21532,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, was very complicated and kept running into server bugs. */ #ifdef HAVE_XINPUT2_1 - if (any - /* xfwm4 selects for button events on the frame - window, resulting in passive grabs being - generated along with the delivery of emulated - button events; this then interferes with - scrolling, since device valuators will constantly - be reset as the crossing events related to those - grabs arrive. The only way to remedy this is to - never reset scroll valuators on a grab-related - crossing event. (bug#57476) */ - && leave->mode != XINotifyUngrab + /* xfwm4 selects for button events on the frame window, + resulting in passive grabs being generated along with + the delivery of emulated button events; this then + interferes with scrolling, since device valuators + will constantly be reset as the crossing events + related to those grabs arrive. The only way to + remedy this is to never reset scroll valuators on a + grab-related crossing event. (bug#57476) */ + + if (leave->mode != XINotifyUngrab && leave->mode != XINotifyGrab && leave->mode != XINotifyPassiveUngrab && leave->mode != XINotifyPassiveGrab) @@ -21575,19 +21578,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, masks are set on the frame widget's window. */ f = x_window_to_frame (dpyinfo, leave->event); - /* Also do this again here, since the test for `any' - above may not have found a frame, as that usually - just looks up a top window on Xt builds. */ - -#ifdef HAVE_XINPUT2_1 - if (f && leave->mode != XINotifyUngrab - && leave->mode != XINotifyGrab - && leave->mode != XINotifyPassiveUngrab - && leave->mode != XINotifyPassiveGrab) - xi_reset_scroll_valuators_for_device_id (dpyinfo, - leave->deviceid); -#endif - if (!f) f = x_top_window_to_frame (dpyinfo, leave->event); #endif commit e01e8a8f848600532bce76705339c96e19b3ae40 Author: Eli Zaretskii Date: Thu Nov 3 11:59:30 2022 +0200 ; * lisp/dired-aux.el (dired-show-file-type): Doc fix. diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index b62e94fa77..e31951351b 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -3282,9 +3282,9 @@ REGEXP should use constructs supported by your local `grep' command." ;;;###autoload (defun dired-show-file-type (file &optional deref-symlinks) "Print the type of FILE, according to the `file' command. -If you give a prefix to this command, and FILE is a symbolic -link, then the type of the file linked to by FILE is printed -instead." +If you give a prefix argument \\[universal-argument] to this command, and +FILE is a symbolic link, then the command will print the type +of the target of the link instead." (interactive (list (dired-get-filename t) current-prefix-arg)) (let (process-file-side-effects) (with-temp-buffer commit d16494cffbed79a916482558ae5ed1bdcc67c88d Author: Gerd Möllmann Date: Thu Nov 3 10:39:37 2022 +0100 Suppress deprecation warnings on macOS (bug#58966) * configure.ac (CHECK_LISP_OBJECT_TYPE): Add -Wno-deprecated-declarations for darwin. diff --git a/configure.ac b/configure.ac index 63cb9c412e..c9d1eb5709 100644 --- a/configure.ac +++ b/configure.ac @@ -1144,6 +1144,12 @@ AS_IF([test $gl_gcc_warnings = no], gl_WARN_ADD([-Wno-int-in-bool-context]) fi + # Suppress deprecation warnings from using sprintf variants, + # starting with Xcode 14.1 on macOS 13. + if test $opsys = darwin; then + gl_WARN_ADD([-Wno-deprecated-declarations]) + fi + # This causes too much noise in the MinGW build if test $opsys = mingw32; then gl_WARN_ADD([-Wno-pointer-sign]) commit dffc34a2d4a2320acd2ce454115f2c9631eb4ce2 Author: Eli Zaretskii Date: Thu Nov 3 11:25:50 2022 +0200 Fix 'text-property-search-backward' with 1-char long properties * lisp/emacs-lisp/text-property-search.el (text-property--find-end-backward): Don't miss the end of text-property value at point. This fixes searches backward when the property is on a single character position. (Bug#58937) diff --git a/lisp/emacs-lisp/text-property-search.el b/lisp/emacs-lisp/text-property-search.el index d11980f4f4..d41222bdbf 100644 --- a/lisp/emacs-lisp/text-property-search.el +++ b/lisp/emacs-lisp/text-property-search.el @@ -208,8 +208,14 @@ and if a matching region is found, place point at the start of the region." (goto-char end) (setq ended t))))) ;; End this at the first place the property changes value. - (setq end (previous-single-property-change - (point) property nil (point-min))) + (setq end + (if (and (> (point) (point-min)) + (text-property--match-p + value (get-text-property (1- (point)) property) + predicate)) + (previous-single-property-change (point) + property nil (point-min)) + (point))) (goto-char end)) (make-prop-match :beginning end :end (1+ start) commit 1c9d7fba0ae7445f09b5137f077e9d894202be61 Author: dannyfreeman Date: Wed Nov 2 13:24:30 2022 -0400 ; Fix a typo in Eglot manual * doc/mist/eglot.texi (Customizing Eglot): 'flymake-error' face mistakenly appears twice. (Bug#58969) diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi index 5a20028702..30bdaeb780 100644 --- a/doc/misc/eglot.texi +++ b/doc/misc/eglot.texi @@ -872,7 +872,7 @@ Eglot supports and enhances (@pxref{Eglot Features}). For example: @item To configure the face used for server-derived errors and warnings, customize the Flymake faces @code{flymake-error} and -@code{flymake-error}. +@code{flymake-warning}. @item To configure the amount of space taken up by documentation in the