| import { FIRST_WIDE_POINT } from './first-wide-point' | |
| import { WIDE_RANGES } from './wide-ranges' | |
| import { ZERO_WIDTH_RANGES } from './zero-width-ranges' | |
| /** | |
| * How many terminal cells a sanitized line takes: one per code point, two | |
| * for a wide one, none for a combining or zero-width one. | |
| * | |
| * Everything below FIRST_WIDE_POINT, the common case in a diff, never | |
| * reaches the tables. | |
| * | |
| * @param text a line with no tabs or control characters | |
| * @returns its width in cells | |
| */ | |
| export function cellWidth(text: string) { | |
| let width = 0 | |
| for (const character of text) { | |
| const point = character.codePointAt(0) ?? 0 | |
| const holds = ([low, high]: readonly [number, number]) => | |
| point >= low && point <= high | |
| const isNarrow = point < FIRST_WIDE_POINT | |
| const isZero = !isNarrow && ZERO_WIDTH_RANGES.some(holds) | |
| const isWide = !isNarrow && !isZero && WIDE_RANGES.some(holds) | |
| width += isZero ? 0 : isWide ? 2 : 1 | |
| } | |
| return width | |
| } | |