Function: truncate-string-to-width

truncate-string-to-width is an autoloaded and byte-compiled function defined in mule-util.el.gz.

Signature

(truncate-string-to-width STR END-COLUMN &optional START-COLUMN PADDING ELLIPSIS ELLIPSIS-TEXT-PROPERTY)

Documentation

Truncate string STR to end at column END-COLUMN.

The optional 3rd arg START-COLUMN, if non-nil, specifies the starting column (default: zero); that means to return the characters occupying columns START-COLUMN ... END-COLUMN of STR. Both END-COLUMN and START-COLUMN are specified in terms of character display width in the current buffer; see char-width.

Since character composition on display can produce glyphs whose width is smaller than the sum of char-width values of the composed characters, this function can produce inaccurate results when used in such cases.

The optional 4th arg PADDING, if non-nil, specifies a padding character (which should have a display width of 1) to add at the end of the result if STR doesn't reach column END-COLUMN, or if END-COLUMN comes in the middle of a character in STR. PADDING is also added at the beginning of the result if column START-COLUMN appears in the middle of a character in STR.

If PADDING is nil, no padding is added in these cases, so the resulting string may be narrower than END-COLUMN.

If ELLIPSIS is non-nil, it should be a string which will replace the end of STR (including any padding) if it extends beyond END-COLUMN, unless the display width of STR is equal to or less than the display 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-TEXT-PROPERTY is non-nil, a too-long string will not be truncated, but instead the elided parts will be covered by a display text property showing the ellipsis.

Other relevant functions are documented in the string group.

View in manual

Probably introduced at or before Emacs version 20.1.

Shortdoc

;; string
(truncate-string-to-width "foobar" 3)
    => "foo"
  (truncate-string-to-width "你好bar" 5)
    => "你好b"

Source Code

;; Defined in /usr/src/emacs/lisp/international/mule-util.el.gz
;;;###autoload
(defun truncate-string-to-width (str end-column
				     &optional start-column padding ellipsis
                                     ellipsis-text-property)
  "Truncate string STR to end at column END-COLUMN.
The optional 3rd arg START-COLUMN, if non-nil, specifies the starting
column (default: zero); that means to return the characters occupying
columns START-COLUMN ... END-COLUMN of STR.  Both END-COLUMN and
START-COLUMN are specified in terms of character display width in the
current buffer; see `char-width'.

Since character composition on display can produce glyphs whose
width is smaller than the sum of `char-width' values of the
composed characters, this function can produce inaccurate results
when used in such cases.

The optional 4th arg PADDING, if non-nil, specifies a padding
character (which should have a display width of 1) to add at the end
of the result if STR doesn't reach column END-COLUMN, or if END-COLUMN
comes in the middle of a character in STR.  PADDING is also added at
the beginning of the result if column START-COLUMN appears in the
middle of a character in STR.

If PADDING is nil, no padding is added in these cases, so
the resulting string may be narrower than END-COLUMN.

If ELLIPSIS is non-nil, it should be a string which will replace the
end of STR (including any padding) if it extends beyond END-COLUMN,
unless the display width of STR is equal to or less than the display
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-TEXT-PROPERTY is non-nil, a too-long string will not
be truncated, but instead the elided parts will be covered by a
`display' text property showing the ellipsis."
  (or start-column
      (setq start-column 0))
  (when (and ellipsis (not (stringp ellipsis)))
    (setq ellipsis (truncate-string-ellipsis)))
  (let ((str-len (length str))
	(str-width (string-width str))
	(ellipsis-width (if ellipsis (string-width ellipsis) 0))
	(idx 0)
	(column 0)
	(head-padding "") (tail-padding "")
	ch last-column last-idx from-idx)
    (condition-case nil
	(while (< column start-column)
	  (setq ch (aref str idx)
		column (+ column (char-width ch))
		idx (1+ idx)))
      (args-out-of-range (setq idx str-len)))
    (if (< column start-column)
	(if padding (make-string end-column padding) "")
      (when (and padding (> column start-column))
	(setq head-padding (make-string (- column start-column) padding)))
      (setq from-idx idx)
      (when (>= end-column column)
	(if (and (< end-column str-width)
		 (> str-width ellipsis-width))
	    (setq end-column (- end-column ellipsis-width))
	  (setq ellipsis ""))
	(condition-case nil
	    (while (< column end-column)
	      (setq last-column column
		    last-idx idx
		    ch (aref str idx)
		    column (+ column (char-width ch))
		    idx (1+ idx)))
	  (args-out-of-range (setq idx str-len)))
	(when (> column end-column)
	  (setq column last-column
		idx last-idx))
	(when (and padding (< column end-column))
	  (setq tail-padding (make-string (- end-column column) padding))))
      (if (and ellipsis-text-property
               (not (equal ellipsis ""))
               idx)
          ;; Use text properties for the ellipsis.
          (concat head-padding
                  (substring str from-idx idx)
                  (propertize (substring str idx) 'display (or ellipsis "")))
        ;; (Possibly) chop off bits of the string.
        (concat head-padding (substring str from-idx idx)
                tail-padding ellipsis)))))