aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2024-08-25 10:24:35 +0300
committerEli Zaretskii2024-08-25 10:24:35 +0300
commit71505b723c9fb9de20f6d38be7c73d595e9be3ce (patch)
tree020a27270c21cedae068b09d9d0adb5a914785bb /src
parent8a94cee3b58a59eac6ca24c001769f0fe12bf020 (diff)
downloademacs-71505b723c9fb9de20f6d38be7c73d595e9be3ce.tar.gz
emacs-71505b723c9fb9de20f6d38be7c73d595e9be3ce.zip
Fix handling of 'min-width' display property
* src/xdisp.c (get_display_property, display_min_width): Rename BUFPOS to CHARPOS, to avoid confusion (it is not necessarily a buffer position). Suggested by Jim Porter <jporterbugs@gmail.com>. (get_display_property): Call 'Fget_char_property' to support 'min-width' properties of overlays as well. (display_min_width): Handle the buffer and string cases more accurately, without relying only on the values of positions. (handle_display_prop, handle_single_display_spec): Pass correct position to 'display_min_width', when iterating over a string. (handle_display_prop): When OBJECT is a window, pass it to display_min_width. (set_iterator_to_next): Call 'display_min_width' when at end of a display or overlay string. (Bug#72721) * etc/NEWS: Announce the support for overlays.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c75
1 files changed, 60 insertions, 15 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 30771a1c83d..f9a10267bad 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -5632,16 +5632,25 @@ find_display_property (Lisp_Object disp, Lisp_Object prop)
5632 return XCDR (elem); 5632 return XCDR (elem);
5633} 5633}
5634 5634
5635/* Return the value of 'display' text or overlay property PROP of
5636 character at CHARPOS in OBJECT. Return nil if character at CHARPOS
5637 has no 'display' property or if the 'display' property of that
5638 character does not include PROP. OBJECT can be a buffer or a window
5639 or a string. */
5635static Lisp_Object 5640static Lisp_Object
5636get_display_property (ptrdiff_t bufpos, Lisp_Object prop, Lisp_Object object) 5641get_display_property (ptrdiff_t charpos, Lisp_Object prop, Lisp_Object object)
5637{ 5642{
5638 return find_display_property (Fget_text_property (make_fixnum (bufpos), 5643 return find_display_property (Fget_char_property (make_fixnum (charpos),
5639 Qdisplay, object), 5644 Qdisplay, object),
5640 prop); 5645 prop);
5641} 5646}
5642 5647
5648/* Handle 'display' property '(min-width (WIDTH))' at CHARPOS in OBJECT.
5649 OBJECT can be a buffer (or nil, which means the current buffer) or a
5650 string. MIN_WIDTH is the value of min-width spec that we expect to
5651 process. */
5643static void 5652static void
5644display_min_width (struct it *it, ptrdiff_t bufpos, 5653display_min_width (struct it *it, ptrdiff_t charpos,
5645 Lisp_Object object, Lisp_Object width_spec) 5654 Lisp_Object object, Lisp_Object width_spec)
5646{ 5655{
5647 /* We're being called at the end of the `min-width' sequence, 5656 /* We're being called at the end of the `min-width' sequence,
@@ -5652,15 +5661,21 @@ display_min_width (struct it *it, ptrdiff_t bufpos,
5652 /* When called from display_string (i.e., the mode line), 5661 /* When called from display_string (i.e., the mode line),
5653 we're being called with a string as the object, and we 5662 we're being called with a string as the object, and we
5654 may be called with many sub-strings belonging to the same 5663 may be called with many sub-strings belonging to the same
5655 :propertize run. */ 5664 :propertize run. */
5656 if ((bufpos == 0 5665 if ((STRINGP (object)
5657 && !EQ (it->min_width_property, 5666 && ((charpos == 0
5658 get_display_property (0, Qmin_width, object))) 5667 && !EQ (it->min_width_property,
5668 get_display_property (0, Qmin_width, object)))
5669 || (charpos > 0
5670 && EQ (it->min_width_property,
5671 get_display_property (charpos - 1, Qmin_width,
5672 object)))))
5659 /* In a buffer -- check that we're really right after the 5673 /* In a buffer -- check that we're really right after the
5660 sequence of characters covered by this `min-width'. */ 5674 sequence of characters covered by this `min-width'. */
5661 || (bufpos > BEGV 5675 || (!STRINGP (object)
5676 && charpos > BEGV
5662 && EQ (it->min_width_property, 5677 && EQ (it->min_width_property,
5663 get_display_property (bufpos - 1, Qmin_width, object)))) 5678 get_display_property (charpos - 1, Qmin_width, object))))
5664 { 5679 {
5665 Lisp_Object w = Qnil; 5680 Lisp_Object w = Qnil;
5666 double width; 5681 double width;
@@ -5707,15 +5722,18 @@ display_min_width (struct it *it, ptrdiff_t bufpos,
5707 the end. */ 5722 the end. */
5708 if (CONSP (width_spec)) 5723 if (CONSP (width_spec))
5709 { 5724 {
5710 if (bufpos == BEGV 5725 if ((!STRINGP (object)
5726 && charpos == BEGV)
5711 /* Mode line (see above). */ 5727 /* Mode line (see above). */
5712 || (bufpos == 0 5728 || (STRINGP (object)
5729 && charpos == 0
5713 && !EQ (it->min_width_property, 5730 && !EQ (it->min_width_property,
5714 get_display_property (0, Qmin_width, object))) 5731 get_display_property (0, Qmin_width, object)))
5715 /* Buffer. */ 5732 /* Buffer. */
5716 || (bufpos > BEGV 5733 || (!STRINGP (object)
5734 && charpos > BEGV
5717 && !EQ (width_spec, 5735 && !EQ (width_spec,
5718 get_display_property (bufpos - 1, Qmin_width, object)))) 5736 get_display_property (charpos - 1, Qmin_width, object))))
5719 { 5737 {
5720 it->min_width_property = width_spec; 5738 it->min_width_property = width_spec;
5721 it->min_width_start = it->current_x; 5739 it->min_width_start = it->current_x;
@@ -5792,13 +5810,24 @@ handle_display_prop (struct it *it)
5792 Qdisplay, object, &overlay); 5810 Qdisplay, object, &overlay);
5793 5811
5794 /* Rest of the code must have OBJECT be either a string or a buffer. */ 5812 /* Rest of the code must have OBJECT be either a string or a buffer. */
5813 Lisp_Object objwin = object;
5795 if (!STRINGP (it->string)) 5814 if (!STRINGP (it->string))
5796 object = it->w->contents; 5815 object = it->w->contents;
5797 5816
5798 /* Handle min-width ends. */ 5817 /* Handle min-width ends. */
5799 if (!NILP (it->min_width_property) 5818 if (!NILP (it->min_width_property)
5800 && NILP (find_display_property (propval, Qmin_width))) 5819 && NILP (find_display_property (propval, Qmin_width)))
5801 display_min_width (it, bufpos, object, Qnil); 5820 {
5821 ptrdiff_t pos = bufpos, start = BEGV;
5822
5823 if (STRINGP (object))
5824 {
5825 pos = IT_STRING_CHARPOS (*it);
5826 start = 0;
5827 }
5828 if (pos > start)
5829 display_min_width (it, pos, objwin, Qnil);
5830 }
5802 5831
5803 if (NILP (propval)) 5832 if (NILP (propval))
5804 return HANDLED_NORMALLY; 5833 return HANDLED_NORMALLY;
@@ -6099,7 +6128,13 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
6099 && CONSP (XCAR (XCDR (spec)))) 6128 && CONSP (XCAR (XCDR (spec))))
6100 { 6129 {
6101 if (it) 6130 if (it)
6102 display_min_width (it, bufpos, object, XCAR (XCDR (spec))); 6131 {
6132 ptrdiff_t pos = bufpos;
6133
6134 if (STRINGP (object))
6135 pos = IT_STRING_CHARPOS (*it);
6136 display_min_width (it, pos, object, XCAR (XCDR (spec)));
6137 }
6103 return 0; 6138 return 0;
6104 } 6139 }
6105 6140
@@ -9004,6 +9039,10 @@ set_iterator_to_next (struct it *it, bool reseat_p)
9004 next, if there is one. */ 9039 next, if there is one. */
9005 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)) 9040 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
9006 { 9041 {
9042 /* Maybe add a stretch glyph if the string had 'min-width'
9043 display spec. */
9044 display_min_width (it, IT_STRING_CHARPOS (*it), it->string,
9045 Qnil);
9007 it->ellipsis_p = false; 9046 it->ellipsis_p = false;
9008 next_overlay_string (it); 9047 next_overlay_string (it);
9009 if (it->ellipsis_p) 9048 if (it->ellipsis_p)
@@ -9019,6 +9058,12 @@ set_iterator_to_next (struct it *it, bool reseat_p)
9019 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string) 9058 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
9020 && it->sp > 0) 9059 && it->sp > 0)
9021 { 9060 {
9061 /* Maybe add a stretch glyph if the string had 'min-width'
9062 display spec. We only do this if it->sp > 0 because
9063 mode-line strings are handled differently, see
9064 display_min_width. */
9065 display_min_width (it, IT_STRING_CHARPOS (*it), it->string,
9066 Qnil);
9022 pop_it (it); 9067 pop_it (it);
9023 if (it->method == GET_FROM_STRING) 9068 if (it->method == GET_FROM_STRING)
9024 goto consider_string_end; 9069 goto consider_string_end;