github.com/xeptore/docker-cli@v20.10.14+incompatible/cli/command/formatter/displayutils.go (about)

     1  package formatter
     2  
     3  import (
     4  	"unicode/utf8"
     5  
     6  	"golang.org/x/text/width"
     7  )
     8  
     9  // charWidth returns the number of horizontal positions a character occupies,
    10  // and is used to account for wide characters when displaying strings.
    11  //
    12  // In a broad sense, wide characters include East Asian Wide, East Asian Full-width,
    13  // (when not in East Asian context) see http://unicode.org/reports/tr11/.
    14  func charWidth(r rune) int {
    15  	switch width.LookupRune(r).Kind() {
    16  	case width.EastAsianWide, width.EastAsianFullwidth:
    17  		return 2
    18  	default:
    19  		return 1
    20  	}
    21  }
    22  
    23  // Ellipsis truncates a string to fit within maxDisplayWidth, and appends ellipsis (…).
    24  // For maxDisplayWidth of 1 and lower, no ellipsis is appended.
    25  // For maxDisplayWidth of 1, first char of string will return even if its width > 1.
    26  func Ellipsis(s string, maxDisplayWidth int) string {
    27  	if maxDisplayWidth <= 0 {
    28  		return ""
    29  	}
    30  	rs := []rune(s)
    31  	if maxDisplayWidth == 1 {
    32  		return string(rs[0])
    33  	}
    34  
    35  	byteLen := len(s)
    36  	if byteLen == utf8.RuneCountInString(s) {
    37  		if byteLen <= maxDisplayWidth {
    38  			return s
    39  		}
    40  		return string(rs[:maxDisplayWidth-1]) + "…"
    41  	}
    42  
    43  	var (
    44  		display      []int
    45  		displayWidth int
    46  	)
    47  	for _, r := range rs {
    48  		cw := charWidth(r)
    49  		displayWidth += cw
    50  		display = append(display, displayWidth)
    51  	}
    52  	if displayWidth <= maxDisplayWidth {
    53  		return s
    54  	}
    55  	for i := range display {
    56  		if display[i] <= maxDisplayWidth-1 && display[i+1] > maxDisplayWidth-1 {
    57  			return string(rs[:i+1]) + "…"
    58  		}
    59  	}
    60  	return s
    61  }