emacs-diffs
[Top][All Lists]
Advanced

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

master 6e5ec08551 2/2: buffer.c: evaporate overlays in all indirect buff


From: Stefan Monnier
Subject: master 6e5ec08551 2/2: buffer.c: evaporate overlays in all indirect buffers
Date: Sat, 5 Nov 2022 17:22:46 -0400 (EDT)

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

    buffer.c: evaporate overlays in all indirect buffers
    
    This fixes bug#58928.  The patch works by moving the
    `evaporate_overlays` check closer to `itree_delete_gap`.
    
    * src/buffer.c (adjust_overlays_for_delete_in_buffer): New function,
    integrating the functionality of `evaporate_overlays`.
    (adjust_overlays_for_delete): Use it.
    (evaporate_overlays): Delete function.
    
    * src/buffer.h (evaporate_overlays): Delete declaration.
    
    * src/insdel.c (adjust_markers_for_replace): Minor optimization.
    (adjust_after_replace, replace_range, replace_range_2, del_range_2):
    Don't call `evaporate_overlays`.
    
    * test/src/buffer-tests.el (buffer-tests--overlays-indirect-evaporate):
    Remove the `:expected-result :failed` attribute.
---
 src/buffer.c             | 51 +++++++++++++++++++++++++++---------------------
 src/buffer.h             |  1 -
 src/insdel.c             | 18 +++++++----------
 test/src/buffer-tests.el |  1 -
 4 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/src/buffer.c b/src/buffer.c
index 390ccff5c8..ec2d34daf8 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3472,21 +3472,47 @@ adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t 
length, bool before_markers
     }
 }
 
+static void
+adjust_overlays_for_delete_in_buffer (struct buffer * buf,
+                                      ptrdiff_t pos, ptrdiff_t length)
+{
+  Lisp_Object hit_list = Qnil;
+  struct itree_node *node;
+
+  /* Ideally, the evaporate check would be done directly within
+     `itree_delete_gap`, but that code isn't supposed to know about overlays,
+     only about `itree_node`s, so it would break an abstraction boundary.  */
+  itree_delete_gap (buf->overlays, pos, length);
+
+  /* Delete any zero-sized overlays at position POS, if the `evaporate'
+     property is set.  */
+
+  ITREE_FOREACH (node, buf->overlays, pos, pos, ASCENDING)
+    {
+      if (node->end == pos && node->begin == pos
+          && ! NILP (Foverlay_get (node->data, Qevaporate)))
+        hit_list = Fcons (node->data, hit_list);
+    }
+
+  for (; CONSP (hit_list); hit_list = XCDR (hit_list))
+    Fdelete_overlay (XCAR (hit_list));
+}
+
 void
 adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
 {
   if (!current_buffer->indirections)
-    itree_delete_gap (current_buffer->overlays, pos, length);
+    adjust_overlays_for_delete_in_buffer (current_buffer, 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);
+      adjust_overlays_for_delete_in_buffer (base, pos, length);
       FOR_EACH_LIVE_BUFFER (tail, other)
         if (XBUFFER (other)->base_buffer == base)
-          itree_delete_gap (XBUFFER (other)->overlays, pos, length);
+          adjust_overlays_for_delete_in_buffer (XBUFFER (other), pos, length);
     }
 }
 
@@ -4099,25 +4125,6 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object 
overlay, bool after,
     }
 }
 
-/* Delete any zero-sized overlays at position POS, if the `evaporate'
-   property is set.  */
-void
-evaporate_overlays (ptrdiff_t pos)
-{
-  Lisp_Object hit_list = Qnil;
-  struct itree_node *node;
-
-  ITREE_FOREACH (node, current_buffer->overlays, pos, pos, ASCENDING)
-    {
-      if (node->end == pos
-          && ! NILP (Foverlay_get (node->data, Qevaporate)))
-        hit_list = Fcons (node->data, hit_list);
-    }
-
-  for (; CONSP (hit_list); hit_list = XCDR (hit_list))
-    Fdelete_overlay (XCAR (hit_list));
-}
-
 /***********************************************************************
                         Allocation with mmap
  ***********************************************************************/
diff --git a/src/buffer.h b/src/buffer.h
index 3ea4125645..2e80c8a7b0 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1170,7 +1170,6 @@ extern EMACS_INT fix_position (Lisp_Object);
 extern void delete_all_overlays (struct buffer *);
 extern void reset_buffer (struct buffer *);
 extern void compact_buffer (struct buffer *);
-extern void evaporate_overlays (ptrdiff_t);
 extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, 
ptrdiff_t *);
 extern ptrdiff_t overlays_in (ptrdiff_t, ptrdiff_t, bool, Lisp_Object **,
                               ptrdiff_t *,  bool, bool, ptrdiff_t *);
diff --git a/src/insdel.c b/src/insdel.c
index ef17f99d21..03ce59b340 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -345,6 +345,11 @@ adjust_markers_for_replace (ptrdiff_t from, ptrdiff_t 
from_byte,
   ptrdiff_t diff_bytes = new_bytes - old_bytes;
 
   adjust_suspend_auto_hscroll (from, from + old_chars);
+
+  /* FIXME: When OLD_CHARS is 0, this "replacement" is really just an
+     insertion, but the behavior we provide here in that case is that of
+     `insert-before-markers` rather than that of `insert`.
+     Maybe not a bug, but not a feature either.  */
   for (m = BUF_MARKERS (current_buffer); m; m = m->next)
     {
       if (m->bytepos >= prev_to_byte)
@@ -362,7 +367,8 @@ 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);
+  if (old_chars)
+    adjust_overlays_for_delete (from, old_chars);
 }
 
 /* Starting at POS (BYTEPOS), find the byte position corresponding to
@@ -1334,8 +1340,6 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte,
 
   check_markers ();
 
-  if (len == 0)
-    evaporate_overlays (from);
   modiff_incr (&MODIFF, nchars_del + len);
   CHARS_MODIFF = MODIFF;
 }
@@ -1521,9 +1525,6 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object 
new,
                  (from_byte + outgoing_insbytes
                   - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
 
-  if (outgoing_insbytes == 0)
-    evaporate_overlays (from);
-
   check_markers ();
 
   modiff_incr (&MODIFF, nchars_del + inschars);
@@ -1647,9 +1648,6 @@ replace_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
        adjust_point (inschars - nchars_del, insbytes - nbytes_del);
     }
 
-  if (insbytes == 0)
-    evaporate_overlays (from);
-
   check_markers ();
 
   modiff_incr (&MODIFF, nchars_del + inschars);
@@ -1858,8 +1856,6 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
 
   check_markers ();
 
-  evaporate_overlays (from);
-
   return deletion;
 }
 
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el
index 3c37176095..b11243e021 100644
--- a/test/src/buffer-tests.el
+++ b/test/src/buffer-tests.el
@@ -301,7 +301,6 @@ with parameters from the *Messages* buffer modification."
 
 Deleting characters from either a base or an indirect buffer
 should evaporate overlays in both."
-  :expected-result :failed
   ;; Loop twice, erasing from the base buffer the first time and the
   ;; indirect buffer the second.
   (dolist (erase-where '(base indirect))



reply via email to

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