[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 08/38] org-string-width: Reimplement to work with new folding
From: |
Ihor Radchenko |
Subject: |
[PATCH v2 08/38] org-string-width: Reimplement to work with new folding |
Date: |
Wed, 20 Apr 2022 21:25:02 +0800 |
* 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
- [PATCH v2 00/38] Final call for comments: Merge org-fold feature branch, Ihor Radchenko, 2022/04/20
- [PATCH v2 01/38] Add org-fold-core: new folding engine---, Ihor Radchenko, 2022/04/20
- [PATCH v2 02/38] Separate folding functions from org.el into new library: org-fold, Ihor Radchenko, 2022/04/20
- [PATCH v2 03/38] Separate cycling functions from org.el into new library: org-cycle, Ihor Radchenko, 2022/04/20
- [PATCH v2 04/38] Remove functions from org.el that are now moved elsewhere, Ihor Radchenko, 2022/04/20
- [PATCH v2 05/38] Disable native-comp in agendaIt caused cryptic bugs in the past., Ihor Radchenko, 2022/04/20
- [PATCH v2 06/38] org-macs: New function org-find-text-property-region---, Ihor Radchenko, 2022/04/20
- [PATCH v2 07/38] org-at-heading-p: Accept optional argument* lisp/org.el (org-at-heading-p): Use second argument to allow, Ihor Radchenko, 2022/04/20
- [PATCH v2 08/38] org-string-width: Reimplement to work with new folding,
Ihor Radchenko <=
- [PATCH v2 09/38] Rename old function call to use org-fold---, Ihor Radchenko, 2022/04/20
- [PATCH v2 10/38] Implement link folding* lisp/ol.el (org-link--link-folding-spec):, Ihor Radchenko, 2022/04/20
- [PATCH v2 12/38] org-fold: Handle indirect buffer visibility---, Ihor Radchenko, 2022/04/20
- [PATCH v2 11/38] Implement overlay- and text-property-based versions of some functions, Ihor Radchenko, 2022/04/20
- [PATCH v2 13/38] Fix subtle differences between overlays and invisible text properties, Ihor Radchenko, 2022/04/20
- [PATCH v2 14/38] Support extra org-fold optimisations for huge buffers, Ihor Radchenko, 2022/04/20
- [PATCH v2 15/38] Alias new org-fold functions to their old shorter names, Ihor Radchenko, 2022/04/20
- [PATCH v2 16/38] Obsolete old function names that are now in org-fold---, Ihor Radchenko, 2022/04/20
- [PATCH v2 18/38] Move `org-buffer-list' to org-macs.el---, Ihor Radchenko, 2022/04/20
- [PATCH v2 19/38] Restore old visibility behaviour of org-refile---, Ihor Radchenko, 2022/04/20