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 }