visibleSize returns the number of columns the string will cover when displayed in the terminal. This is the number of runes, i.e. characters, not the number of bytes it consists of.
(s string)
| 342 | // when displayed in the terminal. This is the number of runes, |
| 343 | // i.e. characters, not the number of bytes it consists of. |
| 344 | func visibleSize(s string) (int, error) { |
| 345 | // This code re-implements the basic functionality of |
| 346 | // RuneCountInString to account for special cases. Namely |
| 347 | // UTF-8 characters taking up 3 bytes (**) appear as double-width. |
| 348 | // |
| 349 | // (**) I wonder if that is the set of characters outside of |
| 350 | // the BMP <=> the set of characters requiring surrogates (2 |
| 351 | // slots) when encoded in UCS-2. |
| 352 | |
| 353 | r := strings.NewReader(s) |
| 354 | |
| 355 | var size int |
| 356 | for range s { |
| 357 | _, runeSize, err := r.ReadRune() |
| 358 | if err != nil { |
| 359 | return -1, fmt.Errorf("error when calculating visible size of: %s", s) |
| 360 | } |
| 361 | |
| 362 | if runeSize == 3 { |
| 363 | size += 2 // Kanji and Katakana characters appear as double-width |
| 364 | } else { |
| 365 | size++ |
| 366 | } |
| 367 | } |
| 368 | |
| 369 | return size, nil |
| 370 | } |
no outgoing calls
no test coverage detected