github.com/andrewhsu/cli/v2@v2.0.1-0.20210910131313-d4b4061f5b89/pkg/text/truncate.go (about) 1 package text 2 3 import ( 4 "strings" 5 6 "github.com/muesli/reflow/ansi" 7 "github.com/muesli/reflow/truncate" 8 ) 9 10 const ( 11 ellipsis = "..." 12 minWidthForEllipsis = len(ellipsis) + 2 13 ) 14 15 // DisplayWidth calculates what the rendered width of a string may be 16 func DisplayWidth(s string) int { 17 return ansi.PrintableRuneWidth(s) 18 } 19 20 // Truncate shortens a string to fit the maximum display width 21 func Truncate(maxWidth int, s string) string { 22 w := DisplayWidth(s) 23 if w <= maxWidth { 24 return s 25 } 26 27 tail := "" 28 if maxWidth >= minWidthForEllipsis { 29 tail = ellipsis 30 } 31 32 r := truncate.StringWithTail(s, uint(maxWidth), tail) 33 if DisplayWidth(r) < maxWidth { 34 r += " " 35 } 36 37 return r 38 } 39 40 // TruncateColumn replaces the first new line character with an ellipsis 41 // and shortens a string to fit the maximum display width 42 func TruncateColumn(maxWidth int, s string) string { 43 if i := strings.IndexAny(s, "\r\n"); i >= 0 { 44 s = s[:i] + ellipsis 45 } 46 return Truncate(maxWidth, s) 47 }