diff --git a/lisp/org-colview.el b/lisp/org-colview.el index 92a3b473d..e8106f9cd 100644 --- a/lisp/org-colview.el +++ b/lisp/org-colview.el @@ -452,14 +452,30 @@ DATELINE is non-nil when the face used should be "Type \\`\\[org-columns-edit-value]' \ to edit property"))))))) +(defun org-columns--substring-below-width (string start width) + "Similar to `substring', but use `string-width' to check width. +The returned value is a substring of STRING, starting at START, +and is the largest possible substring whose width does not exceed +WIDTH." + (let ((end (min (+ start width) (length string))) res) + (while (and end (>= end start)) + (let* ((curr (string-width string start end)) + (excess (- curr width))) + (if (cl-plusp excess) + (cl-decf end (max 1 (/ excess 2))) + (setq res (substring string start end) end nil)))) + res)) + (defun org-columns-add-ellipses (string width) "Truncate STRING with WIDTH characters, with ellipses." (cond - ((<= (length string) width) string) - ((<= width (length org-columns-ellipses)) - (substring org-columns-ellipses 0 width)) - (t (concat (substring string 0 (- width (length org-columns-ellipses))) - org-columns-ellipses)))) + ((<= (string-width string) width) string) + ((<= width (string-width org-columns-ellipses)) + (org-columns--substring-below-width org-columns-ellipses 0 width)) + (t (concat + (org-columns--substring-below-width + string 0 (- width (length org-columns-ellipses))) + org-columns-ellipses)))) (defvar org-columns-full-header-line-format nil "The full header line format, will be shifted by horizontal scrolling." )