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#47712: 27.1; Provide `string-display-width` function, which takes properties into account, `substring-width` Date: Mon, 12 Apr 2021 15:21:38 +0300 Message-ID: <83lf9n3d7x.fsf@gnu.org> References: <642c8a37-31c7-2723-12af-06cd7f120c2f@daniel-mendler.de> <83r1jg2q72.fsf@gnu.org> Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="13206"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 47712@debbugs.gnu.org To: Daniel Mendler Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Apr 12 14:23:14 2021 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 1lVvaz-0003DT-Ri for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 12 Apr 2021 14:23:13 +0200 Original-Received: from localhost ([::1]:48736 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lVvay-0005aO-PW for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 12 Apr 2021 08:23:12 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:35596) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lVvao-0005ZL-D6 for bug-gnu-emacs@gnu.org; Mon, 12 Apr 2021 08:23:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:45180) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lVvao-0006K7-4e for bug-gnu-emacs@gnu.org; Mon, 12 Apr 2021 08:23:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lVvao-0005VD-0o for bug-gnu-emacs@gnu.org; Mon, 12 Apr 2021 08:23: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: Mon, 12 Apr 2021 12:23:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47712 X-GNU-PR-Package: emacs Original-Received: via spool by 47712-submit@debbugs.gnu.org id=B47712.161823012421079 (code B ref 47712); Mon, 12 Apr 2021 12:23:01 +0000 Original-Received: (at 47712) by debbugs.gnu.org; 12 Apr 2021 12:22:04 +0000 Original-Received: from localhost ([127.0.0.1]:56726 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lVvZs-0005Tu-CC for submit@debbugs.gnu.org; Mon, 12 Apr 2021 08:22:04 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:50884) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lVvZq-0005TQ-Gm for 47712@debbugs.gnu.org; Mon, 12 Apr 2021 08:22:02 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]:53262) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lVvZk-0005bq-FJ; Mon, 12 Apr 2021 08:21:56 -0400 Original-Received: from 84.94.185.95.cable.012.net.il ([84.94.185.95]:3089 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1lVvZj-0001u5-Q6; Mon, 12 Apr 2021 08:21:56 -0400 In-Reply-To: (message from Daniel Mendler on Mon, 12 Apr 2021 10:45:45 +0200) 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" Xref: news.gmane.io gmane.emacs.bugs:203894 Archived-At: > Cc: 47712@debbugs.gnu.org > From: Daniel Mendler > Date: Mon, 12 Apr 2021 10:45:45 +0200 > > On 4/12/21 4:26 AM, Eli Zaretskii wrote: > > We already have window-text-pixel-size; doesn't it fit the bill? If > > not, why not? > > `window-text-pixel-size` computes the size of a portion of the window, > it does not take a string argument. That is easy to work around, right? Just insert the string into a temporary buffer and say with-current-buffer (and/or with-selected-window, if needed). > The function `string-width` instead takes a string argument > returning the number of columns needed to display this string. This > function is needed to compute widths of strings which are not yet > displayed. But you compute the width because you are going to display that string soon enough, right? Or did I misunderstand the purpose? In general, calculating a string's width out of display context is meaningless in Emacs. More about that below. > `string-display-width` is a proposed function which takes properties > into account as `window-text-pixel-size` does, but without going through > the display system first. That's exactly my point: by not using the display code, you allow up front inaccurate results. There's no practical way to implement this in Lisp without yielding inaccurate and even grossly incorrect results in some cases (see below), so any such implementation will be limited from the get-go, in ways that are hard to even document precisely, let alone use reliably. Thus, users of such an implementation are bound to be unpleasantly surprised if they try using it in a situation different from yours. > Instead it computes the `string-width` of a flattened string, where > the invisible parts have been removed and the displayed parts have > been replaced. Yes, I understood what the code does. But it only handles some of the possible use cases, and will fail in others. For example, it ignores faces (which could change the metrics of characters); it assumes that all the characters of the string can be displayed by the buffer's fonts (because "tofu" has very different dimensions); it uses char-width to measure a character's width (which is only accurate for text-mode frames); it doesn't handle display properties that aren't strings, such as (space :align-to N); etc. > Orgmode uses its incarnation of `string-display-width`, > `org-string-width`, for formatting its tables (see org-table.el). The > width computation is performed before displaying the strings in the window. What you propose might be good enough for org-table, but it falls short of what is required from a general-purpose core feature: such a feature needs to support, or at least be able to support, all the possible display-related features that could affect the string's width. Your proposed implementation cannot support all of those features even in principle, because some of the display features mentioned above aren't accessible directly from Lisp. And if we try implementing this in C, we will end up with window-text-pixel-size, because that's why it was written in the first place. It was written to use the display code and requires a context of a window, because otherwise the problem you are trying to solve cannot be solved: features like fonts, faces, invisibility specs, etc. -- all of those depend on windows or buffers or frames, so trying to estimate a string's width without that context will produce incorrect results. So I urge you to try to use window-text-pixel-size for org-table and elsewhere, because that's what that function is for. If it lacks some feature or has bugs, we will improve it. Thanks.