]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix a narrow-to-region vs. overlays-at bug
authorMatt Armstrong <matt@rfc20.org>
Sat, 22 Oct 2022 02:45:13 +0000 (19:45 -0700)
committerMatt Armstrong <matt@rfc20.org>
Sat, 22 Oct 2022 02:58:34 +0000 (19:58 -0700)
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
src/buffer.h
src/editfns.c
test/src/buffer-tests.el

index fe6b515493ef71ed5881254b8b183aff07fe0541..dcb3c3944b7b635c46de49fa1908fe678ccbe852 100644 (file)
@@ -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);
index ce1b7b27b0fcfaef79833d9fa53d3a6583f1f78c..3ea4125645d1dcff69b3eda5b689ed51de600daf 100644 (file)
@@ -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 *);
index 1af6ea1b11dabf960aff87c930a896d9044fccd4..0038017585998775782de0a21355bc6baf74d675 100644 (file)
@@ -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,
index 6d5d9913a014af4a2d66840e97dc6eabb2021e91..c6d176cc171e6a60974cc7641a988544b2596b8a 100644 (file)
@@ -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