Files
test-repo/src/utilities/get-string-width.js
T
787b716266 Update dependency get-east-asian-width to v1.7.0 (#20094)
Co-authored-by: fisker <lionkay@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-17 16:14:14 +08:00

59 lines
1.7 KiB
JavaScript

import emojiRegex from "emoji-regex";
import {
// @ts-expect-error -- Private
_isFullwidth as isFullwidth,
// @ts-expect-error -- Private
_isWide as isWide,
} from "get-east-asian-width";
import { isNarrowEmojiCharacter } from "narrow-emojis";
const notAsciiRegex = /[^\x20-\x7F]/;
// Exclude [`Spacing Mark`](https://www.compart.com/en/unicode/category/Mc) because spacing marks contribute horizontal width.
const zeroWidthMarkRegex = /[\p{Nonspacing_Mark}\p{Enclosing_Mark}]/u;
// Similar to https://github.com/sindresorhus/string-width
// We don't strip ansi, always treat ambiguous width characters as having narrow width.
/**
* @param {string} text
* @returns {number}
*/
function getStringWidth(text) {
if (!text) {
return 0;
}
// shortcut to avoid needless string `RegExp`s, replacements, and allocations
if (!notAsciiRegex.test(text)) {
return text.length;
}
let width = 0;
text = text.replace(emojiRegex(), (character) => {
width += isNarrowEmojiCharacter(character) ? 1 : 2;
return "";
});
// Use `Intl.Segmenter` when we drop support for Node.js v14
// https://github.com/prettier/prettier/pull/14793#discussion_r1185840038
// https://github.com/sindresorhus/string-width/pull/47
for (const character of text) {
const codePoint = character.codePointAt(0);
// Ignore control characters
if (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f)) {
continue;
}
// Ignore zero-width marks, including combining marks and variation selectors
if (zeroWidthMarkRegex.test(character)) {
continue;
}
width += isFullwidth(codePoint) || isWide(codePoint) ? 2 : 1;
}
return width;
}
export default getStringWidth;