emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 8a5678906f: src/buffer.c: Fix interaction between overlays & indi


From: Stefan Monnier
Subject: master 8a5678906f: src/buffer.c: Fix interaction between overlays & indirect buffers (bug#58928)
Date: Tue, 1 Nov 2022 21:39:17 -0400 (EDT)

branch: master
commit 8a5678906fa1b899c4d111e5ee4334b278f50d48
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    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.
---
 src/buffer.c             | 34 ++++++++++++++++++++++++++--------
 src/itree.c              |  4 ++--
 test/src/buffer-tests.el | 21 +++++++++++++++++++++
 3 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/src/buffer.c b/src/buffer.c
index b67b989326..3129aa2890 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 3b10802ff0..bd4e8cc574 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 e020732524..b96a8dcacd 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")



reply via email to

[Prev in Thread] Current Thread [Next in Thread]