diff options
| author | Stefan Monnier | 2024-02-05 17:58:47 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2024-02-05 17:58:47 -0500 |
| commit | 10faaa3c91045390755791c21349cd562546fdea (patch) | |
| tree | 8f813e8bbc6497ff788ccf8d07addb5b4f31a736 /src | |
| parent | aedfb4f04837ef7b6f50d6a9d833a3ec0f33b11d (diff) | |
| download | emacs-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.c | 60 | ||||
| -rw-r--r-- | src/buffer.h | 2 | ||||
| -rw-r--r-- | src/editfns.c | 82 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/xdisp.c | 2 |
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 | ||
| 3005 | ptrdiff_t | 3005 | static ptrdiff_t |
| 3006 | overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend, | 3006 | overlays_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. */ |
| 3154 | Lisp_Object | 3147 | bool |
| 3155 | disable_line_numbers_overlay_at_eob (void) | 3148 | disable_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 *); | |||
| 1174 | extern void reset_buffer (struct buffer *); | 1174 | extern void reset_buffer (struct buffer *); |
| 1175 | extern void compact_buffer (struct buffer *); | 1175 | extern void compact_buffer (struct buffer *); |
| 1176 | extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, ptrdiff_t *); | 1176 | extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, ptrdiff_t *); |
| 1177 | extern ptrdiff_t overlays_in (ptrdiff_t, ptrdiff_t, bool, Lisp_Object **, | ||
| 1178 | ptrdiff_t *, bool, bool, ptrdiff_t *); | ||
| 1179 | extern ptrdiff_t previous_overlay_change (ptrdiff_t); | 1177 | extern ptrdiff_t previous_overlay_change (ptrdiff_t); |
| 1180 | extern ptrdiff_t next_overlay_change (ptrdiff_t); | 1178 | extern ptrdiff_t next_overlay_change (ptrdiff_t); |
| 1181 | extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *); | 1179 | extern 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 | |||
| 282 | static ptrdiff_t | ||
| 283 | overlays_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 | |||
| 293 | DEFUN ("get-pos-property", Fget_pos_property, Sget_pos_property, 2, 3, 0, | 275 | DEFUN ("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. |
| 295 | Almost identical to `get-char-property' except for the following difference: | 277 | Almost 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. */ |
| 4804 | extern bool mouse_face_overlay_overlaps (Lisp_Object); | 4804 | extern bool mouse_face_overlay_overlaps (Lisp_Object); |
| 4805 | extern Lisp_Object disable_line_numbers_overlay_at_eob (void); | 4805 | extern bool disable_line_numbers_overlay_at_eob (void); |
| 4806 | extern AVOID nsberror (Lisp_Object); | 4806 | extern AVOID nsberror (Lisp_Object); |
| 4807 | extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t, bool); | 4807 | extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t, bool); |
| 4808 | extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t); | 4808 | extern 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 | ||