(grapheme: string)
| 104 | } |
| 105 | |
| 106 | function getEmojiWidth(grapheme: string): number { |
| 107 | // Regional indicators: single = 1, pair = 2 |
| 108 | const first = grapheme.codePointAt(0)! |
| 109 | if (first >= 0x1f1e6 && first <= 0x1f1ff) { |
| 110 | let count = 0 |
| 111 | for (const _ of grapheme) count++ |
| 112 | return count === 1 ? 1 : 2 |
| 113 | } |
| 114 | |
| 115 | // Incomplete keycap: digit/symbol + VS16 without U+20E3 |
| 116 | if (grapheme.length === 2) { |
| 117 | const second = grapheme.codePointAt(1) |
| 118 | if ( |
| 119 | second === 0xfe0f && |
| 120 | ((first >= 0x30 && first <= 0x39) || first === 0x23 || first === 0x2a) |
| 121 | ) { |
| 122 | return 1 |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | return 2 |
| 127 | } |
| 128 | |
| 129 | function isZeroWidth(codePoint: number): boolean { |
| 130 | // Fast path for common printable range |
no outgoing calls
no test coverage detected