From: Stefan Monnier Date: Wed, 2 Nov 2022 01:38:55 +0000 (-0400) Subject: src/buffer.c: Fix interaction between overlays & indirect buffers (bug#58928) X-Git-Tag: emacs-29.0.90~1616^2~351 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=8a5678906fa1b899c4d111e5ee4334b278f50d48;p=emacs.git src/buffer.c: Fix interaction between overlays & indirect buffers (bug#58928) * src/buffer.c (adjust_overlays_for_insert) (adjust_overlays_for_delete): Repeat for all buffers sharing the same text. * src/itree.c (itree_insert_gap, itree_delete_gap): Allow an empty tree. * test/src/buffer-tests.el (buffer-tests--overlays-indirect-bug58928): New test. --- diff --git a/src/buffer.c b/src/buffer.c index b67b989326e..3129aa2890e 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -3456,19 +3456,37 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) void adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length) { - /* After an insertion, the lists are still sorted properly, - but we may need to update the value of the overlay center. */ - if (! current_buffer->overlays) - return; - itree_insert_gap (current_buffer->overlays, pos, length); + if (!current_buffer->indirections) + itree_insert_gap (current_buffer->overlays, pos, length); + 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); + FOR_EACH_LIVE_BUFFER (tail, other) + if (XBUFFER (other)->base_buffer == base) + itree_insert_gap (XBUFFER (other)->overlays, pos, length); + } } void adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length) { - if (! current_buffer->overlays) - return; - itree_delete_gap (current_buffer->overlays, pos, length); + if (!current_buffer->indirections) + itree_delete_gap (current_buffer->overlays, pos, length); + else + { + struct buffer *base = current_buffer->base_buffer + ? current_buffer->base_buffer + : current_buffer; + Lisp_Object tail, other; + itree_delete_gap (base->overlays, pos, length); + FOR_EACH_LIVE_BUFFER (tail, other) + if (XBUFFER (other)->base_buffer == base) + itree_delete_gap (XBUFFER (other)->overlays, pos, length); + } } diff --git a/src/itree.c b/src/itree.c index 3b10802ff09..bd4e8cc5740 100644 --- a/src/itree.c +++ b/src/itree.c @@ -1196,7 +1196,7 @@ void itree_insert_gap (struct itree_tree *tree, ptrdiff_t pos, ptrdiff_t length) { - if (length <= 0 || tree->root == NULL) + if (!tree || length <= 0 || tree->root == NULL) return; uintmax_t ootick = tree->otick; @@ -1280,7 +1280,7 @@ void itree_delete_gap (struct itree_tree *tree, ptrdiff_t pos, ptrdiff_t length) { - if (length <= 0 || tree->root == NULL) + if (!tree || length <= 0 || tree->root == NULL) return; /* FIXME: Don't allocate stack anew every time. */ diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el index e0207325241..b96a8dcacd2 100644 --- a/test/src/buffer-tests.el +++ b/test/src/buffer-tests.el @@ -275,6 +275,27 @@ with parameters from the *Messages* buffer modification." (with-temp-buffer (should (eq (buffer-base-buffer (current-buffer)) nil)))) +(ert-deftest buffer-tests--overlays-indirect-bug58928 () + (with-temp-buffer + (insert "hello world") + (let* ((base (current-buffer)) + (ol1 (make-overlay (+ 2 (point-min)) (+ 8 (point-min)))) + (ib (make-indirect-buffer + base (generate-new-buffer-name "bug58928"))) + (ol2 (with-current-buffer ib + (make-overlay (+ 2 (point-min)) (+ 8 (point-min)))))) + (should (equal (overlay-start ol1) (overlay-start ol2))) + (should (equal (overlay-end ol1) (overlay-end ol2))) + (goto-char (+ 3 (point-min))) + (insert "a") (delete-char 2) + (should (equal (overlay-start ol1) (overlay-start ol2))) + (should (equal (overlay-end ol1) (overlay-end ol2))) + (with-current-buffer ib + (goto-char (+ 4 (point-min))) + (insert "a") (delete-char 2)) + (should (equal (overlay-start ol1) (overlay-start ol2))) + (should (equal (overlay-end ol1) (overlay-end ol2)))))) + (ert-deftest overlay-evaporation-after-killed-buffer () (let* ((ols (with-temp-buffer (insert "toto")