]> git.eshelyaron.com Git - emacs.git/commitdiff
src/buffer.c: Fix interaction between overlays & indirect buffers (bug#58928)
authorStefan Monnier <monnier@iro.umontreal.ca>
Wed, 2 Nov 2022 01:38:55 +0000 (21:38 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Wed, 2 Nov 2022 01:39:12 +0000 (21:39 -0400)
* 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.

src/buffer.c
src/itree.c
test/src/buffer-tests.el

index b67b989326eb69b01d84872756468809c8af1578..3129aa2890e62003ef076e5ade80cac936d94e45 100644 (file)
@@ -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);
+    }
 }
 
 \f
index 3b10802ff095eb934113d88c072e32403afb519c..bd4e8cc57405fc646fecfe5684585db56d990b9b 100644 (file)
@@ -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. */
index e0207325241b6dfa3450c7d025f67182905c4a98..b96a8dcacd219b62792dc0887c75c7df8bb05502 100644 (file)
@@ -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")