emacs-diffs
[Top][All Lists]
Advanced

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

feature/noverlay f2a51774a9 1/4: Fix a narrow-to-region vs. overlays-at


From: Stefan Monnier
Subject: feature/noverlay f2a51774a9 1/4: Fix a narrow-to-region vs. overlays-at bug
Date: Mon, 24 Oct 2022 12:59:49 -0400 (EDT)

branch: feature/noverlay
commit f2a51774a934f29848c5796b46faa5e3b022c401
Author: Matt Armstrong <matt@rfc20.org>
Commit: Matt Armstrong <matt@rfc20.org>

    Fix a narrow-to-region vs. overlays-at bug
    
    See bug#58703.
    
    * src/buffer.c (overlays_in): Add a new TRAILING arg expressing the
    behavior wanted by `overlays-at', namely to include all overlays
    beginning at the POS passed to `overlays-at', even if POS is the end
    of the narrowed region.  Pass true and the search range is extended to
    ZV+1 if END is greater than ZV, just as is done for EMPTY.
    (overlays_at): Pass 'true' for the new trailing arg.  At present this
    is the only caller passing 'true'.
    (mouse_face_overlay_overlaps): Pass 'false' for the new trailing arg.
    (disable_line_numbers_overlay_at_eob): ditto.
    (Foverlays_in): ditto.
    * src/editfns.c (overlays_around): ditto.
    * test/src/buffer-tests.el (sorted-overlays): Add a spot test for
    this.
---
 src/buffer.c             | 31 +++++++++++++++++++++----------
 src/buffer.h             |  2 +-
 src/editfns.c            |  2 +-
 test/src/buffer-tests.el | 39 +++++++++++++++++++++++++++------------
 4 files changed, 50 insertions(+), 24 deletions(-)

diff --git a/src/buffer.c b/src/buffer.c
index fe6b515493..dcb3c3944b 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2943,6 +2943,10 @@ the normal hook `change-major-mode-hook'.  */)
    END, provided END denotes the position at the end of the accessible
    part of the buffer.
 
+   If TRAILING is true, include overlays that begin at END, provided
+   END denotes the position at the end of the accessible part of the
+   buffer.
+
    Return the number found, and store them in a vector in *VEC_PTR.
    Store in *LEN_PTR the size allocated for the vector.
    Store in *NEXT_PTR the next position after POS where an overlay starts,
@@ -2959,7 +2963,8 @@ the normal hook `change-major-mode-hook'.  */)
 
 ptrdiff_t
 overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
-            Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,  bool empty,
+            Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
+            bool empty, bool trailing,
              ptrdiff_t *next_ptr)
 {
   ptrdiff_t idx = 0;
@@ -2968,9 +2973,14 @@ overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
   Lisp_Object *vec = *vec_ptr;
   struct itree_node *node;
 
-  ITREE_FOREACH (node, current_buffer->overlays, beg,
-                 /* Find empty OV at ZV ? */
-                 (end >= ZV && empty) ? ZV + 1 : ZV, ASCENDING)
+  /* Extend the search range if overlays beginning at ZV are
+     wanted.  */
+  ptrdiff_t search_end = ZV;
+  if (end >= ZV && (empty || trailing))
+    ++search_end;
+
+  ITREE_FOREACH (node, current_buffer->overlays, beg, search_end,
+                 ASCENDING)
     {
       if (node->begin > end)
         {
@@ -3022,7 +3032,8 @@ overlays_at (ptrdiff_t pos, bool extend,
              Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
              ptrdiff_t *next_ptr)
 {
-  return overlays_in (pos, pos + 1, extend, vec_ptr, len_ptr, false, next_ptr);
+  return overlays_in (pos, pos + 1, extend, vec_ptr, len_ptr,
+                     false, true, next_ptr);
 }
 
 ptrdiff_t
@@ -3085,11 +3096,11 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
 
   size = ARRAYELTS (vbuf);
   v = vbuf;
-  n = overlays_in (start, end, 0, &v, &size, true, NULL);
+  n = overlays_in (start, end, 0, &v, &size, true, false, NULL);
   if (n > size)
     {
       SAFE_NALLOCA (v, 1, n);
-      overlays_in (start, end, 0, &v, &n, true, NULL);
+      overlays_in (start, end, 0, &v, &n, true, false, NULL);
     }
 
   for (i = 0; i < n; ++i)
@@ -3114,11 +3125,11 @@ disable_line_numbers_overlay_at_eob (void)
 
   size = ARRAYELTS (vbuf);
   v = vbuf;
-  n = overlays_in (ZV, ZV, 0, &v, &size, false, NULL);
+  n = overlays_in (ZV, ZV, 0, &v, &size, false, false, NULL);
   if (n > size)
     {
       SAFE_NALLOCA (v, 1, n);
-      overlays_in (ZV, ZV, 0, &v, &n, false, NULL);
+      overlays_in (ZV, ZV, 0, &v, &n, false, false, NULL);
     }
 
   for (i = 0; i < n; ++i)
@@ -3798,7 +3809,7 @@ end of the accessible part of the buffer.  */)
   /* Put all the overlays we want in a vector in overlay_vec.
      Store the length in len.  */
   noverlays = overlays_in (XFIXNUM (beg), XFIXNUM (end), 1, &overlay_vec, &len,
-                           true, NULL);
+                           true, false, NULL);
 
   /* Make a list of them all.  */
   result = Flist (noverlays, overlay_vec);
diff --git a/src/buffer.h b/src/buffer.h
index ce1b7b27b0..3ea4125645 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1173,7 +1173,7 @@ 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, ptrdiff_t *);
+                              ptrdiff_t *,  bool, bool, ptrdiff_t *);
 extern ptrdiff_t previous_overlay_change (ptrdiff_t);
 extern ptrdiff_t next_overlay_change (ptrdiff_t);
 extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *);
diff --git a/src/editfns.c b/src/editfns.c
index 1af6ea1b11..0038017585 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -270,7 +270,7 @@ If you set the marker not to point anywhere, the buffer 
will have no mark.  */)
 static ptrdiff_t
 overlays_around (ptrdiff_t pos, Lisp_Object *vec, ptrdiff_t len)
 {
-  return overlays_in (pos - 1, pos, false, &vec, &len, false, NULL);
+  return overlays_in (pos - 1, pos, false, &vec, &len, false, false, NULL);
 }
 
 DEFUN ("get-pos-property", Fget_pos_property, Sget_pos_property, 2, 3, 0,
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el
index 6d5d9913a0..c6d176cc17 100644
--- a/test/src/buffer-tests.el
+++ b/test/src/buffer-tests.el
@@ -860,6 +860,33 @@ with parameters from the *Messages* buffer modification."
       (should-length 1 (overlays-at 15))
       (should-length 1 (overlays-at (point-max))))))
 
+(defun sorted-overlays (overlays)
+  (sort
+   (mapcar (lambda (overlay)
+             (list (overlay-start overlay)
+                   (overlay-end overlay)))
+           overlays)
+   (lambda (first second)
+     (cl-loop for a in first
+              for b in second
+              thereis (< a b)
+              until (> a b)))))
+
+(defun sorted-overlays-at (pos)
+  (sorted-overlays (overlays-at pos)))
+
+(defun sorted-overlays-in (beg end)
+  (sorted-overlays (overlays-in beg end)))
+
+(ert-deftest test-overlays-at-narrow-to-region-end ()
+  ;; See bug#58703.
+  (with-temp-buffer
+   (insert (make-string 30 ?x))
+   (make-overlay 10 11)
+   (narrow-to-region 10 10)
+   (should (equal
+            '((10 11))
+            (sorted-overlays-at 10)))))
 
 ;; +==========================================================================+
 ;; | overlay-in
@@ -937,18 +964,6 @@ with parameters from the *Messages* buffer modification."
 (deftest-overlays-in-1 ae 9 11 (a) (a 10 10))
 (deftest-overlays-in-1 af 10 11 (a) (a 10 10))
 
-(defun sorted-overlays-in (beg end)
-  (sort
-   (mapcar (lambda (overlay)
-             (list (overlay-start overlay)
-                   (overlay-end overlay)))
-           (overlays-in beg end))
-   (lambda (first second)
-     (cl-loop for a in first
-              for b in second
-              thereis (< a b)
-              until (> a b)))))
-
 ;; behavior for empty range
 (ert-deftest test-overlays-in-empty-range ()
     (with-temp-buffer



reply via email to

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