From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#72721: 31.0.50; Visual-wrap-prefix-mode breaks Magit log buffers Date: Thu, 22 Aug 2024 12:53:23 +0300 Message-ID: <86h6bcubn0.fsf@gnu.org> References: <87cym4ry3e.fsf@gautierponsinet.xyz> <49828281-6a20-3791-91bd-9708ec51eb57@gmail.com> <86jzgbwgud.fsf@gnu.org> <36584786-6af4-c59f-bb3e-f3459b2904be@gmail.com> <86r0ajuigi.fsf@gnu.org> Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="35494"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 72721@debbugs.gnu.org, gautier@gautierponsinet.xyz To: Jim Porter Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Aug 22 11:54:32 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sh4WV-000933-JK for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 22 Aug 2024 11:54:32 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sh4WJ-0003k9-0y; Thu, 22 Aug 2024 05:54:19 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sh4WH-0003gB-Pb for bug-gnu-emacs@gnu.org; Thu, 22 Aug 2024 05:54:17 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sh4WH-0002I2-G4 for bug-gnu-emacs@gnu.org; Thu, 22 Aug 2024 05:54:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=References:In-Reply-To:From:Date:To:Subject; bh=/Mf68nd6gkDdVL6+d9VRj6NusIDaRRODAvmCu+M51tA=; b=qwIKPZnqDcodkvOyWaKIZbz5gcZ4WsKWsKEqOvLHq8vaKq9uO2wmBVXkIxhmI8qP530w7mOsDHeQ3lGbgVNqZ0xQ057Ss4y3z3BjA4u0pGrB4t77Quz8ROnyCmlTxtDJVi4aaPaDaZhMKV6lNnQhxEloI5QM80wnj8hwoZo3M7fN+wlxNuRr4ZakmtQ/0rAbOBgdSaKGpOKHD3jztkvVam/mHOC18BZwR803aFB0H4j6nbGiuXh06i/XHsOceOIC80+EqJ5g9afZMw0l7w6VfuYFmV0sTege6hACZE41sGgtkrkmGGRTlYyoCrSx61g5x0zFKKAp/Xejd1luBaKKfg==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1sh4X0-0004Oz-3D for bug-gnu-emacs@gnu.org; Thu, 22 Aug 2024 05:55:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 22 Aug 2024 09:55:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 72721 X-GNU-PR-Package: emacs Original-Received: via spool by 72721-submit@debbugs.gnu.org id=B72721.172432046116854 (code B ref 72721); Thu, 22 Aug 2024 09:55:02 +0000 Original-Received: (at 72721) by debbugs.gnu.org; 22 Aug 2024 09:54:21 +0000 Original-Received: from localhost ([127.0.0.1]:36753 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sh4WL-0004Nl-8k for submit@debbugs.gnu.org; Thu, 22 Aug 2024 05:54:21 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:53862) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sh4WJ-0004NZ-SF for 72721@debbugs.gnu.org; Thu, 22 Aug 2024 05:54:20 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sh4VT-0002Cg-5p; Thu, 22 Aug 2024 05:53:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=/Mf68nd6gkDdVL6+d9VRj6NusIDaRRODAvmCu+M51tA=; b=Fcr9y3I7EAIG M7/S36aiW7PiJmLUtEce/7Id54IfO0UNDUbz19vpITqilg+jDsPc04oHtN+LPp7ZjShY60q0cbpz/ PAEHCX2VNdA4o6i5aDtWVzSdqcefV13ZEdHkjutW8aB/caprxae5jnhfNdQOCxoDIzX4klQ0vDpo6 q5DzC3k3wQZvp8OmCKSPuR+8gXlQDIBX/b3WTams9PZYaEzoVaWNCf67Z8BJ63PO7vRc+paqJTKuj wuzjl8fsyEPQuGZ0UkWhxWszMEhXZkEVsUowuOBxNGxTavfhUTdePiUbI/Bj6Jxl58tntAG0c6aSt EWLs7hjmdFcuMYoz04tJiQ==; In-Reply-To: (message from Jim Porter on Tue, 20 Aug 2024 20:15:48 -0700) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:290519 Archived-At: > Date: Tue, 20 Aug 2024 20:15:48 -0700 > Cc: 72721@debbugs.gnu.org, gautier@gautierponsinet.xyz > From: Jim Porter > > > M-x describe-text-properties will show you the properties and overlays > > at point, and it should be possible to concoct some Lisp which just > > reproduces those properties. > > I'd tried that but just wasn't looking at the right point. I've now > figured it out and provided a few reduced test cases. (The "simple" and > "consecutive" cases should already work.) > > While making these test cases, I noticed a similar issue with a nested > 'display' property (see the "nested" case), and fixed that too (I hope!). Thanks for the test cases, they helped a lot. Can you please try the patch below, including in the original use case with Magit? I hope I've figured out all of the quirks of min-width and its possible uses, and the few extensions you demonstrated. It should be possible now to have min-width on overlay strings as well, I think (but I didn't test that). If the patch below gives good results, I will install it. diff --git a/src/xdisp.c b/src/xdisp.c index 30771a1..1e92ed4 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -5632,16 +5632,24 @@ find_display_property (Lisp_Object disp, Lisp_Object prop) return XCDR (elem); } +/* Return the value of 'display' property PROP of character at CHARPOS + in OBJECT. Return nil if character at CHARPOS has no 'display' + property or if the 'display' property of that character does not + include PROP. OBJECT can be a buffer or a string. */ static Lisp_Object -get_display_property (ptrdiff_t bufpos, Lisp_Object prop, Lisp_Object object) +get_display_property (ptrdiff_t charpos, Lisp_Object prop, Lisp_Object object) { - return find_display_property (Fget_text_property (make_fixnum (bufpos), + return find_display_property (Fget_text_property (make_fixnum (charpos), Qdisplay, object), prop); } +/* Handle 'display' property '(min-width (WIDTH))' at CHARPOS in OBJECT. + OBJECT can be a buffer (or nil, which means the current buffer) or a + string. MIN_WIDTH is the value of min-width spec that we expect to + process. */ static void -display_min_width (struct it *it, ptrdiff_t bufpos, +display_min_width (struct it *it, ptrdiff_t charpos, Lisp_Object object, Lisp_Object width_spec) { /* We're being called at the end of the `min-width' sequence, @@ -5652,15 +5660,21 @@ display_min_width (struct it *it, ptrdiff_t bufpos, /* When called from display_string (i.e., the mode line), we're being called with a string as the object, and we may be called with many sub-strings belonging to the same - :propertize run. */ - if ((bufpos == 0 - && !EQ (it->min_width_property, - get_display_property (0, Qmin_width, object))) + :propertize run. */ + if ((STRINGP (object) + && ((charpos == 0 + && !EQ (it->min_width_property, + get_display_property (0, Qmin_width, object))) + || (charpos > 0 + && EQ (it->min_width_property, + get_display_property (charpos - 1, Qmin_width, + object))))) /* In a buffer -- check that we're really right after the sequence of characters covered by this `min-width'. */ - || (bufpos > BEGV + || (!STRINGP (object) + && charpos > BEGV && EQ (it->min_width_property, - get_display_property (bufpos - 1, Qmin_width, object)))) + get_display_property (charpos - 1, Qmin_width, object)))) { Lisp_Object w = Qnil; double width; @@ -5707,15 +5721,18 @@ display_min_width (struct it *it, ptrdiff_t bufpos, the end. */ if (CONSP (width_spec)) { - if (bufpos == BEGV + if ((!STRINGP (object) + && charpos == BEGV) /* Mode line (see above). */ - || (bufpos == 0 + || (STRINGP (object) + && charpos == 0 && !EQ (it->min_width_property, get_display_property (0, Qmin_width, object))) /* Buffer. */ - || (bufpos > BEGV + || (!STRINGP (object) + && charpos > BEGV && !EQ (width_spec, - get_display_property (bufpos - 1, Qmin_width, object)))) + get_display_property (charpos - 1, Qmin_width, object)))) { it->min_width_property = width_spec; it->min_width_start = it->current_x; @@ -5798,7 +5815,17 @@ handle_display_prop (struct it *it) /* Handle min-width ends. */ if (!NILP (it->min_width_property) && NILP (find_display_property (propval, Qmin_width))) - display_min_width (it, bufpos, object, Qnil); + { + ptrdiff_t pos = bufpos, start = BEGV; + + if (STRINGP (object)) + { + pos = IT_STRING_CHARPOS (*it); + start = 0; + } + if (pos > start) + display_min_width (it, pos, object, Qnil); + } if (NILP (propval)) return HANDLED_NORMALLY; @@ -6099,7 +6126,13 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, && CONSP (XCAR (XCDR (spec)))) { if (it) - display_min_width (it, bufpos, object, XCAR (XCDR (spec))); + { + ptrdiff_t pos = bufpos; + + if (STRINGP (object)) + pos = IT_STRING_CHARPOS (*it); + display_min_width (it, pos, object, XCAR (XCDR (spec))); + } return 0; } @@ -9004,6 +9037,10 @@ set_iterator_to_next (struct it *it, bool reseat_p) next, if there is one. */ if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)) { + /* Maybe add a stretch glyph if the string had 'min-width' + display spec. */ + display_min_width (it, IT_STRING_CHARPOS (*it), it->string, + Qnil); it->ellipsis_p = false; next_overlay_string (it); if (it->ellipsis_p) @@ -9019,6 +9056,12 @@ set_iterator_to_next (struct it *it, bool reseat_p) if (IT_STRING_CHARPOS (*it) == SCHARS (it->string) && it->sp > 0) { + /* Maybe add a stretch glyph if the string had 'min-width' + display spec. We only do this if it->sp > 0 because + mode-line strings are handled differently, see + display_min_width. */ + display_min_width (it, IT_STRING_CHARPOS (*it), it->string, + Qnil); pop_it (it); if (it->method == GET_FROM_STRING) goto consider_string_end;