Function: truncate-string-pixelwise

truncate-string-pixelwise is an autoloaded and byte-compiled function defined in subr-x.el.gz.

Signature

(truncate-string-pixelwise STRING MAX-PIXELS &optional BUFFER ELLIPSIS ELLIPSIS-PIXELS)

Documentation

Return STRING truncated to fit within MAX-PIXELS.

If BUFFER is non-nil, use the face remappings, alternative and default properties from that buffer when determining the width. If you call this function to measure pixel width of a string with embedded newlines, it returns the width of the widest substring that does not include newlines.

If ELLIPSIS is non-nil, it should be a string which will replace the end of STRING if it extends beyond MAX-PIXELS, unless the pixel width of STRING is equal to or less than the pixel width of ELLIPSIS. If it is non-nil and not a string, then ELLIPSIS defaults to truncate-string-ellipsis(var)/truncate-string-ellipsis(fun), or to three dots when it's nil.

If ELLIPSIS-PIXELS is non-nil, it is the pixel width of ELLIPSIS, and can be used to avoid the cost of recomputing this for multiple calls to this function using the same ELLIPSIS.

View in manual

Probably introduced at or before Emacs version 31.1.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/subr-x.el.gz
;;;###autoload
(defun truncate-string-pixelwise (string max-pixels &optional buffer
                                  ellipsis ellipsis-pixels)
  "Return STRING truncated to fit within MAX-PIXELS.
If BUFFER is non-nil, use the face remappings, alternative and default
properties from that buffer when determining the width.
If you call this function to measure pixel width of a string
with embedded newlines, it returns the width of the widest
substring that does not include newlines.

If ELLIPSIS is non-nil, it should be a string which will replace the end
of STRING if it extends beyond MAX-PIXELS, unless the pixel width of
STRING is equal to or less than the pixel width of ELLIPSIS.  If it is
non-nil and not a string, then ELLIPSIS defaults to
`truncate-string-ellipsis', or to three dots when it's nil.

If ELLIPSIS-PIXELS is non-nil, it is the pixel width of ELLIPSIS, and
can be used to avoid the cost of recomputing this for multiple calls to
this function using the same ELLIPSIS."
  (declare (important-return-value t))
  (if (zerop (length string))
      string
    ;; Keeping a work buffer around is more efficient than creating a
    ;; new temporary buffer.
    (let* ((window (selected-window))
           (original-buffer (window-buffer window))
           (window-dedication (window-dedicated-p window))
           (buffer-list-update-hook)
           (window-scroll-functions)
           (window-configuration-change-hook))
      (with-work-buffer
        ;; Use a binary search to prune the number of calls to
        ;; `window-text-pixel-size'.
        ;; These are 1-based buffer indexes.
        (unwind-protect
            (let* ((low 1)
                   (high (1+ (length string)))
                   mid)
              (work-buffer--prepare-pixelwise string buffer)
              (set-window-dedicated-p window nil)
              (set-window-buffer window (current-buffer) 'keep-margins)
              (when (> (car (window-text-pixel-size nil 1 high)) max-pixels)
                (when (and ellipsis (not (stringp ellipsis)))
                  (setq ellipsis (truncate-string-ellipsis)))
                (setq ellipsis-pixels (if ellipsis
                                          (if ellipsis-pixels
                                              ellipsis-pixels
                                            (string-pixel-width ellipsis buffer))
                                        0))
                (let ((adjusted-pixels
                       (if (> max-pixels ellipsis-pixels)
                           (- max-pixels ellipsis-pixels)
                         max-pixels)))
                  (while (<= low high)
                    (setq mid (floor (+ low high) 2))
                    (if (<= (car (window-text-pixel-size nil 1 mid))
                            adjusted-pixels)
                        (setq low (1+ mid))
                      (setq high (1- mid))))))
              (if mid
                  ;; Binary search ran.
                  (if (and ellipsis (> max-pixels ellipsis-pixels))
                      (concat (substring string 0 (1- high)) ellipsis)
                    (substring string 0 (1- high)))
                ;; Fast path.
                string))
          (set-window-buffer window original-buffer 'keep-margins)
          (set-window-dedicated-p window window-dedication)
          (unrecord-window-buffer window (current-buffer) t))))))