diff options
Diffstat (limited to 'src/textprop.c')
-rw-r--r-- | src/textprop.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/src/textprop.c b/src/textprop.c index c91a2b729c6..c2c3622d05f 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -1,6 +1,5 @@ /* Interface code for dealing with text properties. - Copyright (C) 1993-1995, 1997, 1999-2022 Free Software Foundation, - Inc. + Copyright (C) 1993-2022 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -634,36 +633,42 @@ get_char_property_and_overlay (Lisp_Object position, register Lisp_Object prop, } if (BUFFERP (object)) { - ptrdiff_t noverlays; - Lisp_Object *overlay_vec; - struct buffer *obuf = current_buffer; - - if (! (BUF_BEGV (XBUFFER (object)) <= pos - && pos <= BUF_ZV (XBUFFER (object)))) + struct buffer *b = XBUFFER (object); + struct interval_node *node; + struct sortvec items[2]; + struct sortvec *result = NULL; + Lisp_Object result_tem = Qnil; + + if (! (BUF_BEGV (b) <= pos + && pos <= BUF_ZV (b))) xsignal1 (Qargs_out_of_range, position); - set_buffer_temp (XBUFFER (object)); - - USE_SAFE_ALLOCA; - GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false); - noverlays = sort_overlays (overlay_vec, noverlays, w); - - set_buffer_temp (obuf); + buffer_overlay_iter_start (b, pos, pos + 1, ITREE_ASCENDING); /* Now check the overlays in order of decreasing priority. */ - while (--noverlays >= 0) + while ((node = buffer_overlay_iter_next (b))) { - Lisp_Object tem = Foverlay_get (overlay_vec[noverlays], prop); - if (!NILP (tem)) - { - if (overlay) - /* Return the overlay we got the property from. */ - *overlay = overlay_vec[noverlays]; - SAFE_FREE (); - return tem; - } + Lisp_Object tem = Foverlay_get (node->data, prop); + struct sortvec *this; + + if (NILP (tem) || (w && ! overlay_matches_window (w, node->data))) + continue; + + this = (result == items ? items + 1 : items); + make_sortvec_item (this, node->data); + if (! result || (compare_overlays (result, this) < 0)) + { + result = this; + result_tem = tem; + } } - SAFE_FREE (); + buffer_overlay_iter_finish (b); + if (result) + { + if (overlay) + *overlay = result->overlay; + return result_tem; + } } if (overlay) |