aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2024-02-05 17:58:47 -0500
committerStefan Monnier2024-02-05 17:58:47 -0500
commit10faaa3c91045390755791c21349cd562546fdea (patch)
tree8f813e8bbc6497ff788ccf8d07addb5b4f31a736 /src
parentaedfb4f04837ef7b6f50d6a9d833a3ec0f33b11d (diff)
downloademacs-10faaa3c91045390755791c21349cd562546fdea.tar.gz
emacs-10faaa3c91045390755791c21349cd562546fdea.zip
Prefer `ITREE_FOREACH` over `overlays_in`
Use `ITREE_FOREACH` instead of `overlays_in` if that can save us from allocating an array. * src/buffer.c (overlays_in): Mark as static. (mouse_face_overlay_overlaps): Use `ITREE_FOREACH` instead of `overlays_in`. (disable_line_numbers_overlay_at_eob): Same, and also change return value to a boolean. * src/buffer.h (overlays_in): Don't declare. * src/editfns.c (overlays_around): Delete function. (Fget_pos_property): Use `ITREE_FOREACH` and keep the "best so far" instead of using `overlays_in` and sorting the elements. * src/lisp.h (disable_line_numbers_overlay_at_eob): Change return type to a boolean. * src/xdisp.c (should_produce_line_number): Adjust accordingly.
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c60
-rw-r--r--src/buffer.h2
-rw-r--r--src/editfns.c82
-rw-r--r--src/lisp.h2
-rw-r--r--src/xdisp.c2
5 files changed, 49 insertions, 99 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 352aca8ddfd..d67e1d67cd6 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3002,7 +3002,7 @@ the normal hook `change-major-mode-hook'. */)
3002 But still return the total number of overlays. 3002 But still return the total number of overlays.
3003*/ 3003*/
3004 3004
3005ptrdiff_t 3005static ptrdiff_t
3006overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend, 3006overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
3007 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr, 3007 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
3008 bool empty, bool trailing, 3008 bool empty, bool trailing,
@@ -3125,56 +3125,38 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
3125{ 3125{
3126 ptrdiff_t start = OVERLAY_START (overlay); 3126 ptrdiff_t start = OVERLAY_START (overlay);
3127 ptrdiff_t end = OVERLAY_END (overlay); 3127 ptrdiff_t end = OVERLAY_END (overlay);
3128 ptrdiff_t n, i, size; 3128 Lisp_Object tem;
3129 Lisp_Object *v, tem; 3129 struct itree_node *node;
3130 Lisp_Object vbuf[10];
3131 USE_SAFE_ALLOCA;
3132 3130
3133 size = ARRAYELTS (vbuf); 3131 ITREE_FOREACH (node, current_buffer->overlays,
3134 v = vbuf; 3132 start, min (end, ZV) + 1,
3135 n = overlays_in (start, end, 0, &v, &size, true, false, NULL); 3133 ASCENDING)
3136 if (n > size)
3137 { 3134 {
3138 SAFE_NALLOCA (v, 1, n); 3135 if (node->begin < end && node->end > start
3139 overlays_in (start, end, 0, &v, &n, true, false, NULL); 3136 && node->begin < node->end
3137 && !EQ (node->data, overlay)
3138 && (tem = Foverlay_get (overlay, Qmouse_face),
3139 !NILP (tem)))
3140 return true;
3140 } 3141 }
3141 3142 return false;
3142 for (i = 0; i < n; ++i)
3143 if (!EQ (v[i], overlay)
3144 && (tem = Foverlay_get (overlay, Qmouse_face),
3145 !NILP (tem)))
3146 break;
3147
3148 SAFE_FREE ();
3149 return i < n;
3150} 3143}
3151 3144
3152/* Return the value of the 'display-line-numbers-disable' property at 3145/* Return the value of the 'display-line-numbers-disable' property at
3153 EOB, if there's an overlay at ZV with a non-nil value of that property. */ 3146 EOB, if there's an overlay at ZV with a non-nil value of that property. */
3154Lisp_Object 3147bool
3155disable_line_numbers_overlay_at_eob (void) 3148disable_line_numbers_overlay_at_eob (void)
3156{ 3149{
3157 ptrdiff_t n, i, size; 3150 Lisp_Object tem = Qnil;
3158 Lisp_Object *v, tem = Qnil; 3151 struct itree_node *node;
3159 Lisp_Object vbuf[10];
3160 USE_SAFE_ALLOCA;
3161 3152
3162 size = ARRAYELTS (vbuf); 3153 ITREE_FOREACH (node, current_buffer->overlays, ZV, ZV, ASCENDING)
3163 v = vbuf;
3164 n = overlays_in (ZV, ZV, 0, &v, &size, false, false, NULL);
3165 if (n > size)
3166 { 3154 {
3167 SAFE_NALLOCA (v, 1, n); 3155 if ((tem = Foverlay_get (node->data, Qdisplay_line_numbers_disable),
3168 overlays_in (ZV, ZV, 0, &v, &n, false, false, NULL); 3156 !NILP (tem)))
3157 return true;
3169 } 3158 }
3170 3159 return false;
3171 for (i = 0; i < n; ++i)
3172 if ((tem = Foverlay_get (v[i], Qdisplay_line_numbers_disable),
3173 !NILP (tem)))
3174 break;
3175
3176 SAFE_FREE ();
3177 return tem;
3178} 3160}
3179 3161
3180 3162
diff --git a/src/buffer.h b/src/buffer.h
index 9e0982f5da7..87ba2802b39 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1174,8 +1174,6 @@ extern void delete_all_overlays (struct buffer *);
1174extern void reset_buffer (struct buffer *); 1174extern void reset_buffer (struct buffer *);
1175extern void compact_buffer (struct buffer *); 1175extern void compact_buffer (struct buffer *);
1176extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, ptrdiff_t *); 1176extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, ptrdiff_t *);
1177extern ptrdiff_t overlays_in (ptrdiff_t, ptrdiff_t, bool, Lisp_Object **,
1178 ptrdiff_t *, bool, bool, ptrdiff_t *);
1179extern ptrdiff_t previous_overlay_change (ptrdiff_t); 1177extern ptrdiff_t previous_overlay_change (ptrdiff_t);
1180extern ptrdiff_t next_overlay_change (ptrdiff_t); 1178extern ptrdiff_t next_overlay_change (ptrdiff_t);
1181extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *); 1179extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *);
diff --git a/src/editfns.c b/src/editfns.c
index 0cecd81c07f..cce52cddbf8 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -272,24 +272,6 @@ If you set the marker not to point anywhere, the buffer will have no mark. */)
272} 272}
273 273
274 274
275/* Find all the overlays in the current buffer that touch position POS.
276 Return the number found, and store them in a vector in VEC
277 of length LEN.
278
279 Note: this can return overlays that do not touch POS. The caller
280 should filter these out. */
281
282static ptrdiff_t
283overlays_around (ptrdiff_t pos, Lisp_Object *vec, ptrdiff_t len)
284{
285 /* Find all potentially rear-advance overlays at (POS - 1). Find
286 all overlays at POS, so end at (POS + 1). Find even empty
287 overlays, which due to the way 'overlays-in' works implies that
288 we might also fetch empty overlays starting at (POS + 1). */
289 return overlays_in (pos - 1, pos + 1, false, &vec, &len,
290 true, false, NULL);
291}
292
293DEFUN ("get-pos-property", Fget_pos_property, Sget_pos_property, 2, 3, 0, 275DEFUN ("get-pos-property", Fget_pos_property, Sget_pos_property, 2, 3, 0,
294 doc: /* Return the value of POSITION's property PROP, in OBJECT. 276 doc: /* Return the value of POSITION's property PROP, in OBJECT.
295Almost identical to `get-char-property' except for the following difference: 277Almost identical to `get-char-property' except for the following difference:
@@ -315,53 +297,41 @@ at POSITION. */)
315 else 297 else
316 { 298 {
317 EMACS_INT posn = XFIXNUM (position); 299 EMACS_INT posn = XFIXNUM (position);
318 ptrdiff_t noverlays; 300 Lisp_Object tem;
319 Lisp_Object *overlay_vec, tem;
320 struct buffer *obuf = current_buffer; 301 struct buffer *obuf = current_buffer;
321 USE_SAFE_ALLOCA; 302 struct itree_node *node;
322 303 struct sortvec items[2];
323 set_buffer_temp (XBUFFER (object)); 304 struct sortvec *result = NULL;
305 struct buffer *b = XBUFFER (object);
306 Lisp_Object res = Qnil;
324 307
325 /* First try with room for 40 overlays. */ 308 set_buffer_temp (b);
326 Lisp_Object overlay_vecbuf[40];
327 noverlays = ARRAYELTS (overlay_vecbuf);
328 overlay_vec = overlay_vecbuf;
329 noverlays = overlays_around (posn, overlay_vec, noverlays);
330 309
331 /* If there are more than 40, 310 ITREE_FOREACH (node, b->overlays, posn - 1, posn + 1, ASCENDING)
332 make enough space for all, and try again. */
333 if (ARRAYELTS (overlay_vecbuf) < noverlays)
334 { 311 {
335 SAFE_ALLOCA_LISP (overlay_vec, noverlays); 312 Lisp_Object ol = node->data;
336 noverlays = overlays_around (posn, overlay_vec, noverlays);
337 }
338 noverlays = sort_overlays (overlay_vec, noverlays, NULL);
339
340 set_buffer_temp (obuf);
341
342 /* Now check the overlays in order of decreasing priority. */
343 while (--noverlays >= 0)
344 {
345 Lisp_Object ol = overlay_vec[noverlays];
346 tem = Foverlay_get (ol, prop); 313 tem = Foverlay_get (ol, prop);
347 if (!NILP (tem)) 314 if (NILP (tem)
348 {
349 /* Check the overlay is indeed active at point. */ 315 /* Check the overlay is indeed active at point. */
350 if ((OVERLAY_START (ol) == posn 316 || ((node->begin == posn
351 && OVERLAY_FRONT_ADVANCE_P (ol)) 317 && OVERLAY_FRONT_ADVANCE_P (ol))
352 || (OVERLAY_END (ol) == posn 318 || (node->end == posn
353 && ! OVERLAY_REAR_ADVANCE_P (ol)) 319 && ! OVERLAY_REAR_ADVANCE_P (ol))
354 || OVERLAY_START (ol) > posn 320 || node->begin > posn
355 || OVERLAY_END (ol) < posn) 321 || node->end < posn))
356 ; /* The overlay will not cover a char inserted at point. */ 322 /* The overlay will not cover a char inserted at point. */
357 else 323 continue;
358 { 324
359 SAFE_FREE (); 325 struct sortvec *this = (result == items ? items + 1 : items);
360 return tem; 326 if (NILP (res)
361 } 327 || (make_sortvec_item (this, node->data),
362 } 328 compare_overlays (result, this) < 0))
329 res = tem;
363 } 330 }
364 SAFE_FREE (); 331 set_buffer_temp (obuf);
332
333 if (!NILP (res))
334 return res;
365 335
366 { /* Now check the text properties. */ 336 { /* Now check the text properties. */
367 int stickiness = text_property_stickiness (prop, position, object); 337 int stickiness = text_property_stickiness (prop, position, object);
diff --git a/src/lisp.h b/src/lisp.h
index 75134425a07..e6fd8cacb1b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4802,7 +4802,7 @@ extern void syms_of_editfns (void);
4802 4802
4803/* Defined in buffer.c. */ 4803/* Defined in buffer.c. */
4804extern bool mouse_face_overlay_overlaps (Lisp_Object); 4804extern bool mouse_face_overlay_overlaps (Lisp_Object);
4805extern Lisp_Object disable_line_numbers_overlay_at_eob (void); 4805extern bool disable_line_numbers_overlay_at_eob (void);
4806extern AVOID nsberror (Lisp_Object); 4806extern AVOID nsberror (Lisp_Object);
4807extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t, bool); 4807extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t, bool);
4808extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t); 4808extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t);
diff --git a/src/xdisp.c b/src/xdisp.c
index 750ebb703a6..2dcf0d58a14 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -25060,7 +25060,7 @@ should_produce_line_number (struct it *it)
25060 because get-char-property always returns nil for ZV, except if 25060 because get-char-property always returns nil for ZV, except if
25061 the property is in 'default-text-properties'. */ 25061 the property is in 'default-text-properties'. */
25062 if (NILP (val) && IT_CHARPOS (*it) >= ZV) 25062 if (NILP (val) && IT_CHARPOS (*it) >= ZV)
25063 val = disable_line_numbers_overlay_at_eob (); 25063 return !disable_line_numbers_overlay_at_eob ();
25064 return NILP (val) ? true : false; 25064 return NILP (val) ? true : false;
25065} 25065}
25066 25066