File size: 964 Bytes
c9c900b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
}