From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id EOUtD1cLYGI2ZwAAbAwnHQ (envelope-from ) for ; Wed, 20 Apr 2022 15:32:07 +0200 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id QH8TD1cLYGKDVgAAauVa8A (envelope-from ) for ; Wed, 20 Apr 2022 15:32:07 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id CDC612A6FB for ; Wed, 20 Apr 2022 15:32:06 +0200 (CEST) Received: from localhost ([::1]:54548 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nhARB-0003CT-V0 for larch@yhetil.org; Wed, 20 Apr 2022 09:32:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36844) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nhAJY-0002lu-Sg for emacs-orgmode@gnu.org; Wed, 20 Apr 2022 09:24:12 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]:56249) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nhAJX-0003L4-4i for emacs-orgmode@gnu.org; Wed, 20 Apr 2022 09:24:12 -0400 Received: by mail-pj1-x102e.google.com with SMTP id ll10so1906129pjb.5 for ; Wed, 20 Apr 2022 06:24:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:in-reply-to:references:message-id:date:mime-version; bh=77irkAvxlEW6iEgYNvD5ZNCH6myjtCQV9N09BhRZciw=; b=af7Yds/Lt+jpfen38DeLjmjDblRyL3OGSgowzRofjGULAJuUTnQ85rIwUWhy/O/amC ZYTcJZisprZuMssQQF9nuiKiwacuo7BIrChSOYuTlJs66FtPfdynmmUJllkLhuSs0e2A 0kwXXp50+t3cco74jrz7kPBqWqd/fTMLmjmebYeq3GECZPLpUYn8Cy1kMvr/zAUPapAv Mntk4ua+JahyB6/zB1xZjnICt/DVfQ7RcRIoQQkVBC2oZuJB7ZhR40CnhtzOg0wowB0w mDMeLBLCBAxvOQJWnOhaXjO42f7Em9IPkzVP92t11rKht8K8w2Sfrmd+HmABX9Y+XwL0 IeWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:in-reply-to:references :message-id:date:mime-version; bh=77irkAvxlEW6iEgYNvD5ZNCH6myjtCQV9N09BhRZciw=; b=zK7o+K2o1X50gDszkpqETL90SRVwR9soOz8Qj+dx6c1yi1M2ga9HKLwjO4AEYTfWXj fkklcPVVNiSXrW9EDysHwj0VmC/0h14f1LD+2agNua3WgAhpa27iWY/79USYRrSOZYe7 vcCR8ZGFTKTAnhtp+8t2SIAOlp7dbI1fwmUcBzJ64r6uxGpuy0MKkGhSk95NWhX2pEGh JSoiNX+nR25FhZvPWtgLxQKYCmC0gzMUESUpddFfqeZoIEfbdOdOj0mxY7+QK5TU/sHY Ij49/TUU8f4k7oUgvNk9jW4JIjL0a9SbFMEZQlWZffvAIWmZ/YwhlQpH4JsYk8wbNNPj R9vg== X-Gm-Message-State: AOAM5302/KGHdoUSYlpowiYH21RGS92VjUpgJBMIWIC06R1nVOSXNAQW z1TW33sc7GTYB3uqcoOkUpQ/d0X+ic+78A== X-Google-Smtp-Source: ABdhPJx6k5H0/aDqsfXQF1OIUXTgn5+SVVCvk6V4pddfk3XmSLB/tKL5b8HZpPHTntvWOo1y/W8wSA== X-Received: by 2002:a17:90b:4b10:b0:1d2:c235:6c8e with SMTP id lx16-20020a17090b4b1000b001d2c2356c8emr4395060pjb.21.1650461049515; Wed, 20 Apr 2022 06:24:09 -0700 (PDT) Received: from localhost ([64.32.23.62]) by smtp.gmail.com with ESMTPSA id l15-20020a62be0f000000b005059cc9cc34sm20403963pff.92.2022.04.20.06.24.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Apr 2022 06:24:09 -0700 (PDT) From: Ihor Radchenko To: emacs-orgmode@gnu.org Subject: [PATCH v2 08/38] org-string-width: Reimplement to work with new folding In-Reply-To: References: Message-Id: <86903765767be808feecbf69be34d79de1d96404.1650460489.git.yantar92@gmail.com> Date: Wed, 20 Apr 2022 21:25:02 +0800 MIME-Version: 1.0 Content-Type: text/plain Received-SPF: pass client-ip=2607:f8b0:4864:20::102e; envelope-from=yantar92@gmail.com; helo=mail-pj1-x102e.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1650461526; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=77irkAvxlEW6iEgYNvD5ZNCH6myjtCQV9N09BhRZciw=; b=WBwZfXVL6uvAIVubahuwCOo7GDCilD6WK+z7omNdyCbHA8YEA79BZDA7BUk1DRJoAQLhQU dWl3+hcr/lOyf+nG/orZ5w6UjDNvHP4dpGuWSLkmdt968tLskTS2HcGoAIHjV7+Pv3In4E +eulRCykK4GALX2oF22VUBZu78EwsDeRKpZ7aJ+oWhnPjg8sE70u8phWhU73BoHSeaBge7 7katkPIaI73HqL/0iIdreoRBfCgqcLsukGiwYEP+LxGvgI4IQF18voia9Nu4QRQCvS3ARD OMo9cinJ3XKzkgy+B9d0huiCuZXB7KsfvA0MVbUBR2eWDYcytKwcT7vC8YpsJw== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1650461526; a=rsa-sha256; cv=none; b=P7MtYiOIiAMZxdyyqJoeMy3CVC9CmDmYnjbjQ284VFLlfdV9TS0AWAdSBgBxIOATk7pD10 guEi1xajMQj9SOpKC3gvMSQluyAzvxOK6sKSOQXGTk36aFXy4oj7yKkGmtFxdo859q19pI ScuKhSvjU+q/CsWiZYIkNZ192lyDo9mrXajrp0yvY/f+XgL6OeNRt7fcPJRWedHTg5M9Ox 9d0axT15mnqcLIqDmZswcU1lVwJ/Gn+8fgl8nRPKFPJG9o/KjyV14Q9NHFLc7vT/kpDegj sNNoX5KxhGbwevuaU2oJJ7DzTaNFN59e09EUtgjCfeSAmNPn2WxaC+nbAQm08A== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b="af7Yds/L"; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -3.04 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b="af7Yds/L"; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: CDC612A6FB X-Spam-Score: -3.04 X-Migadu-Scanner: scn1.migadu.com X-TUID: xQUqAh32DoQs * lisp/org-macs.el (org--string-from-props): Removed since it is no longer needed. (org-string-width): Updated to use `window-text-pixel-size'. --- lisp/org-macs.el | 121 ++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 64 deletions(-) diff --git a/lisp/org-macs.el b/lisp/org-macs.el index 6161a7bfc..f63458f70 100644 --- a/lisp/org-macs.el +++ b/lisp/org-macs.el @@ -889,71 +889,64 @@ (defun org-split-string (string &optional separators) results ;skip trailing separator (cons (substring string i) results))))))) -(defun org--string-from-props (s property beg end) - "Return the visible part of string S. -Visible part is determined according to text PROPERTY, which is -either `invisible' or `display'. BEG and END are 0-indices -delimiting S." - (let ((width 0) - (cursor beg)) - (while (setq beg (text-property-not-all beg end property nil s)) - (let* ((next (next-single-property-change beg property s end)) - (props (text-properties-at beg s)) - (spec (plist-get props property)) - (value - (pcase property - (`invisible - ;; If `invisible' property in PROPS means text is to - ;; be invisible, return 0. Otherwise return nil so - ;; as to resume search. - (and (or (eq t buffer-invisibility-spec) - (assoc-string spec buffer-invisibility-spec)) - 0)) - (`display - (pcase spec - (`nil nil) - (`(space . ,props) - (let ((width (plist-get props :width))) - (and (wholenump width) width))) - (`(image . ,_) - (and (fboundp 'image-size) - (ceiling (car (image-size spec))))) - ((pred stringp) - ;; Displayed string could contain invisible parts, - ;; but no nested display. - (org--string-from-props spec 'invisible 0 (length spec))) - (_ - ;; Un-handled `display' value. Ignore it. - ;; Consider the original string instead. - nil))) - (_ (error "Unknown property: %S" property))))) - (when value - (cl-incf width - ;; When looking for `display' parts, we still need - ;; to look for `invisible' property elsewhere. - (+ (cond ((eq property 'display) - (org--string-from-props s 'invisible cursor beg)) - ((= cursor beg) 0) - (t (string-width (substring s cursor beg)))) - value)) - (setq cursor next)) - (setq beg next))) - (+ width - ;; Look for `invisible' property in the last part of the - ;; string. See above. - (cond ((eq property 'display) - (org--string-from-props s 'invisible cursor end)) - ((= cursor end) 0) - (t (string-width (substring s cursor end))))))) - -(defun org-string-width (string) +(defun org-string-width (string &optional pixels) "Return width of STRING when displayed in the current buffer. -Unlike `string-width', this function takes into consideration -`invisible' and `display' text properties. It supports the -latter in a limited way, mostly for combinations used in Org. -Results may be off sometimes if it cannot handle a given -`display' value." - (org--string-from-props string 'display 0 (length string))) +Return width in pixels when PIXELS is non-nil." + ;; Wrap/line prefix will make `window-text-pizel-size' return too + ;; large value including the prefix. + ;; Face should be removed to make sure that all the string symbols + ;; are using default face with constant width. Constant char width + ;; is critical to get right string width from pixel width. + (remove-text-properties 0 (length string) + '(wrap-prefix t line-prefix t face t) + string) + (let (;; We need to remove the folds to make sure that folded table + ;; alignment is not messed up. + (current-invisibility-spec + (or (and (not (listp buffer-invisibility-spec)) + buffer-invisibility-spec) + (let (result) + (dolist (el buffer-invisibility-spec) + (unless (or (memq el + '(org-fold-drawer + org-fold-block + org-fold-outline)) + (and (listp el) + (memq (car el) + '(org-fold-drawer + org-fold-block + org-fold-outline)))) + (push el result))) + result))) + (current-char-property-alias-alist char-property-alias-alist)) + (with-temp-buffer + (setq-local display-line-numbers nil) + (setq-local buffer-invisibility-spec + current-invisibility-spec) + (setq-local char-property-alias-alist + current-char-property-alias-alist) + (let (pixel-width symbol-width) + (with-silent-modifications + (setf (buffer-string) string) + (setq pixel-width + (if (get-buffer-window (current-buffer)) + (car (window-text-pixel-size + nil (line-beginning-position) (point-max))) + (set-window-buffer nil (current-buffer)) + (car (window-text-pixel-size + nil (line-beginning-position) (point-max))))) + (unless pixels + (setf (buffer-string) "a") + (setq symbol-width + (if (get-buffer-window (current-buffer)) + (car (window-text-pixel-size + nil (line-beginning-position) (point-max))) + (set-window-buffer nil (current-buffer)) + (car (window-text-pixel-size + nil (line-beginning-position) (point-max))))))) + (if pixels + pixel-width + (/ pixel-width symbol-width)))))) (defun org-not-nil (v) "If V not nil, and also not the string \"nil\", then return V. -- 2.35.1 -- Ihor Radchenko, PhD, Center for Advancing Materials Performance from the Nanoscale (CAMP-nano) State Key Laboratory for Mechanical Behavior of Materials, Xi'an Jiaotong University, Xi'an, China Email: yantar92@gmail.com, ihor_radchenko@alumni.sutd.edu.sg