github.com/axw/llgo@v0.0.0-20160805011314-95b5fe4dca20/third_party/liner/width.go (about)

     1  package liner
     2  
     3  import "unicode"
     4  
     5  // These character classes are mostly zero width (when combined).
     6  // A few might not be, depending on the user's font. Fixing this
     7  // is non-trivial, given that some terminals don't support
     8  // ANSI DSR/CPR
     9  var zeroWidth = []*unicode.RangeTable{
    10  	unicode.Mn,
    11  	unicode.Me,
    12  	unicode.Cc,
    13  	unicode.Cf,
    14  }
    15  
    16  var doubleWidth = []*unicode.RangeTable{
    17  	unicode.Han,
    18  	unicode.Hangul,
    19  	unicode.Hiragana,
    20  	unicode.Katakana,
    21  }
    22  
    23  // countGlyphs considers zero-width characters to be zero glyphs wide,
    24  // and members of Chinese, Japanese, and Korean scripts to be 2 glyphs wide.
    25  func countGlyphs(s []rune) int {
    26  	n := 0
    27  	for _, r := range s {
    28  		switch {
    29  		case unicode.IsOneOf(zeroWidth, r):
    30  		case unicode.IsOneOf(doubleWidth, r):
    31  			n += 2
    32  		default:
    33  			n++
    34  		}
    35  	}
    36  	return n
    37  }
    38  
    39  func countMultiLineGlyphs(s []rune, columns int, start int) int {
    40  	n := start
    41  	for _, r := range s {
    42  		switch {
    43  		case unicode.IsOneOf(zeroWidth, r):
    44  		case unicode.IsOneOf(doubleWidth, r):
    45  			n += 2
    46  			// no room for a 2-glyphs-wide char in the ending
    47  			// so skip a column and display it at the beginning
    48  			if n%columns == 1 {
    49  				n++
    50  			}
    51  		default:
    52  			n++
    53  		}
    54  	}
    55  	return n
    56  }
    57  
    58  func getPrefixGlyphs(s []rune, num int) []rune {
    59  	p := 0
    60  	for n := 0; n < num && p < len(s); p++ {
    61  		if !unicode.IsOneOf(zeroWidth, s[p]) {
    62  			n++
    63  		}
    64  	}
    65  	for p < len(s) && unicode.IsOneOf(zeroWidth, s[p]) {
    66  		p++
    67  	}
    68  	return s[:p]
    69  }
    70  
    71  func getSuffixGlyphs(s []rune, num int) []rune {
    72  	p := len(s)
    73  	for n := 0; n < num && p > 0; p-- {
    74  		if !unicode.IsOneOf(zeroWidth, s[p-1]) {
    75  			n++
    76  		}
    77  	}
    78  	return s[p:]
    79  }