From: Eli Zaretskii Date: Sat, 5 Feb 2022 11:01:24 +0000 (+0200) Subject: Fix 'current-column' in the presence of display strings X-Git-Tag: emacs-29.0.90~2508 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=4243747b1b8c3b7e3463822804b32e83febe2878;p=emacs.git Fix 'current-column' in the presence of display strings * src/indent.c (check_display_width): Support calculation of width of 'display' properties whose values are strings. This fixes the value returned by 'current-column' when display strings are present between BOL and point. (Bug#53795) --- diff --git a/src/indent.c b/src/indent.c index 5c21cd8f99d..efeb9e74f43 100644 --- a/src/indent.c +++ b/src/indent.c @@ -468,31 +468,40 @@ check_display_width (ptrdiff_t pos, ptrdiff_t col, ptrdiff_t *endpos) { Lisp_Object val, overlay; - if (CONSP (val = get_char_property_and_overlay - (make_fixnum (pos), Qdisplay, Qnil, &overlay)) - && EQ (Qspace, XCAR (val))) - { /* FIXME: Use calc_pixel_width_or_height. */ - Lisp_Object plist = XCDR (val), prop; + if (!NILP (val = get_char_property_and_overlay (make_fixnum (pos), Qdisplay, + Qnil, &overlay))) + { int width = -1; - EMACS_INT align_to_max = - (col < MOST_POSITIVE_FIXNUM - INT_MAX - ? (EMACS_INT) INT_MAX + col - : MOST_POSITIVE_FIXNUM); - - if ((prop = Fplist_get (plist, QCwidth), - RANGED_FIXNUMP (0, prop, INT_MAX)) - || (prop = Fplist_get (plist, QCrelative_width), - RANGED_FIXNUMP (0, prop, INT_MAX))) - width = XFIXNUM (prop); - else if (FLOATP (prop) && 0 <= XFLOAT_DATA (prop) - && XFLOAT_DATA (prop) <= INT_MAX) - width = (int)(XFLOAT_DATA (prop) + 0.5); - else if ((prop = Fplist_get (plist, QCalign_to), - RANGED_FIXNUMP (col, prop, align_to_max))) - width = XFIXNUM (prop) - col; - else if (FLOATP (prop) && col <= XFLOAT_DATA (prop) - && (XFLOAT_DATA (prop) <= align_to_max)) - width = (int)(XFLOAT_DATA (prop) + 0.5) - col; + Lisp_Object plist = Qnil; + + /* Handle '(space ...)' display specs. */ + if (CONSP (val) && EQ (Qspace, XCAR (val))) + { /* FIXME: Use calc_pixel_width_or_height. */ + Lisp_Object prop; + EMACS_INT align_to_max = + (col < MOST_POSITIVE_FIXNUM - INT_MAX + ? (EMACS_INT) INT_MAX + col + : MOST_POSITIVE_FIXNUM); + + plist = XCDR (val); + if ((prop = Fplist_get (plist, QCwidth), + RANGED_FIXNUMP (0, prop, INT_MAX)) + || (prop = Fplist_get (plist, QCrelative_width), + RANGED_FIXNUMP (0, prop, INT_MAX))) + width = XFIXNUM (prop); + else if (FLOATP (prop) && 0 <= XFLOAT_DATA (prop) + && XFLOAT_DATA (prop) <= INT_MAX) + width = (int)(XFLOAT_DATA (prop) + 0.5); + else if ((prop = Fplist_get (plist, QCalign_to), + RANGED_FIXNUMP (col, prop, align_to_max))) + width = XFIXNUM (prop) - col; + else if (FLOATP (prop) && col <= XFLOAT_DATA (prop) + && (XFLOAT_DATA (prop) <= align_to_max)) + width = (int)(XFLOAT_DATA (prop) + 0.5) - col; + } + /* Handle 'display' strings. */ + else if (STRINGP (val)) + width = XFIXNUM (Fstring_width (val, Qnil, Qnil)); if (width >= 0) { @@ -504,7 +513,8 @@ check_display_width (ptrdiff_t pos, ptrdiff_t col, ptrdiff_t *endpos) /* For :relative-width, we need to multiply by the column width of the character at POS, if it is greater than 1. */ - if (!NILP (Fplist_get (plist, QCrelative_width)) + if (!NILP (plist) + && !NILP (Fplist_get (plist, QCrelative_width)) && !NILP (BVAR (current_buffer, enable_multibyte_characters))) { int b, wd; @@ -516,6 +526,7 @@ check_display_width (ptrdiff_t pos, ptrdiff_t col, ptrdiff_t *endpos) return width; } } + return -1; }