branch: externals/org
commit d5dbe92e7f227c3af2f00443f69186100ebcd941
Author: Kenny Chen <[email protected]>
Commit: Ihor Radchenko <[email protected]>
org-table.el: Cache cell width when aligning tables
* lisp/org-table.el (org-table-align): Cache `org-string-width' results
and reuse when possible instead of calling it for every cell, twice.
(org-table--align-field): Accept a new optional argument for the field
width.
---
lisp/org-table.el | 33 ++++++++++++++++++++++++---------
1 file changed, 24 insertions(+), 9 deletions(-)
diff --git a/lisp/org-table.el b/lisp/org-table.el
index 4a84ab147e..8fcd3693ea 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -4376,11 +4376,12 @@ extension of the given file name, and finally on the
variable
(user-error "TABLE_EXPORT_FORMAT invalid")))))
;;;###autoload
-(defun org-table--align-field (field width align)
+(defun org-table--align-field (field width align &optional field-width)
"Format FIELD according to column WIDTH and alignment ALIGN.
FIELD is a string. WIDTH is a number. ALIGN is either \"c\",
-\"l\" or\"r\"."
- (let* ((spaces (- width (org-string-width field nil 'org-table)))
+\"l\" or\"r\". If FIELD-WIDTH is non-nil, then it's used as
+FIELD's width. Otherwise, it's calculated."
+ (let* ((spaces (- width (or field-width (org-string-width field nil
'org-table))))
(prefix (pcase align
("l" "")
("r" (make-string spaces ?\s))
@@ -4409,7 +4410,15 @@ FIELD is a string. WIDTH is a number. ALIGN is either
\"c\",
(rows (remq 'hline table))
(widths nil)
(alignments nil)
- (columns-number 1))
+ (columns-number 1)
+ (cell-width-cache (make-hash-table :test 'equal))
+ (get-or-compute-cell-width
+ (lambda (cell)
+ (or (gethash cell cell-width-cache)
+ (puthash
+ cell
+ (org-string-width cell nil 'org-table)
+ cell-width-cache)))))
(if (null rows)
;; Table contains only horizontal rules. Compute the
;; number of columns anyway, and choose an arbitrary width
@@ -4429,7 +4438,7 @@ FIELD is a string. WIDTH is a number. ALIGN is either
\"c\",
(non-empty 0))
(dolist (row rows)
(let ((cell (or (nth i row) "")))
- (setq max-width (max max-width (org-string-width cell nil
'org-table)))
+ (setq max-width (max max-width (funcall
get-or-compute-cell-width cell)))
(cond (fixed-align? nil)
((equal cell "") nil)
((string-match "\\`<\\([lrc]\\)[0-9]*>\\'" cell)
@@ -4470,10 +4479,16 @@ FIELD is a string. WIDTH is a number. ALIGN is either
\"c\",
(append row
(make-list offset
"")))))
(mapconcat #'identity
- (cl-mapcar
#'org-table--align-field
- fields
- widths
- alignments)
+ (cl-mapcar
+ (lambda (field width alignment)
+ (org-table--align-field
+ field
+ width
+ alignment
+ (funcall
get-or-compute-cell-width field)))
+ fields
+ widths
+ alignments)
"|")))
"|")))
(if (equal new previous)