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  }