package util import ( "unicode" ) func isWide(r rune) bool { return r >= 0x1100 && (r <= 0x115f || // Hangul Jamo r == 0x2329 || r == 0x232a || (r >= 0x2e80 && r <= 0xa4cf) || (r >= 0xac00 && r <= 0xd7a3) || (r >= 0xf900 && r <= 0xfaff) || (r >= 0xfe10 && r <= 0xfe19) || (r >= 0xfe30 && r <= 0xfe6f) || (r >= 0xff00 && r <= 0xff60) || (r >= 0xffe0 && r <= 0xffe6)) } func isEmoji(r rune) bool { return r >= 0x1f300 && r <= 0x1faff } func RuneWidth(r rune) int { // control code if r == 0 { return 0 } if r < 32 || (r >= 0x7f && r < 0xa0) { return 0 } // combining mark if unicode.Is(unicode.Mn, r) { return 0 } // wide (loose CJK) if isWide(r) { return 2 } // emoji if isEmoji(r) { return 2 } return 1 } func StringWidth(s string, col int) int { sum := 0 i := 0 for _, r := range s { if i >= col { break } sum += RuneWidth(r) i++ } return sum }