Handle zero-width marks in string width (#19538)
Co-authored-by: fisker Cheung <lionkay@gmail.com>
This commit is contained in:
1 parent
e46109d602
commit
fdd6965b2e
6 files changed
+64
-10
No files matched your search
@@ -0,0 +1,20 @@
|
||||
#### Handle Unicode zero-width marks in string width (#19538 by @TheAlexLichter)
|
||||
|
||||
Prettier now treats Unicode nonspacing and enclosing marks as zero-width when measuring lines.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```js
|
||||
// Input
|
||||
moment.updateLocale("bo", { monthsShort: "ཟླ་༡_ཟླ་༢_ཟླ་༣_ཟླ་༤_ཟླ་༥_ཟླ་༦_ཟླ་༧_ཟླ་༨_ཟླ་༩_ཟླ་༡༠_ཟླ་༡༡_ཟླ་༡༢".split("_") });
|
||||
|
||||
// Prettier stable
|
||||
moment.updateLocale("bo", {
|
||||
monthsShort:
|
||||
"ཟླ་༡_ཟླ་༢_ཟླ་༣_ཟླ་༤_ཟླ་༥_ཟླ་༦_ཟླ་༧_ཟླ་༨_ཟླ་༩_ཟླ་༡༠_ཟླ་༡༡_ཟླ་༡༢".split("_"),
|
||||
});
|
||||
|
||||
// Prettier main
|
||||
moment.updateLocale("bo", {
|
||||
monthsShort: "ཟླ་༡_ཟླ་༢_ཟླ་༣_ཟླ་༤_ཟླ་༥_ཟླ་༦_ཟླ་༧_ཟླ་༨_ཟླ་༩_ཟླ་༡༠_ཟླ་༡༡_ཟླ་༡༢".split("_"),
|
||||
});
|
||||
```
|
||||
@@ -8,6 +8,8 @@ import {
|
||||
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.
|
||||
@@ -42,13 +44,8 @@ function getStringWidth(text) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore combining characters
|
||||
if (codePoint >= 0x300 && codePoint <= 0x36f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore Variation Selectors
|
||||
if (codePoint >= 0xfe00 && codePoint <= 0xfe0f) {
|
||||
// Ignore zero-width marks, including combining marks and variation selectors
|
||||
if (zeroWidthMarkRegex.test(character)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`string-width.js format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80 (default) |
|
||||
=====================================input======================================
|
||||
should___fit_____________("ཟླ་༡_ཟླ་༢_ཟླ་༣_ཟླ་༤_ཟླ་༥_ཟླ་༦_ཟླ་༧_ཟླ་༨_ཟླ་༩_ཟླ་༡༠_ཟླ་༡༡_ཟླ་༡༢");
|
||||
should_break_____________("ཟླ་༡_ཟླ་༢_ཟླ་༣_ཟླ་༤_ཟླ་༥_ཟླ་༦_ཟླ་༧_ཟླ་༨_ཟླ་༩_ཟླ་༡༠_ཟླ་༡༡_ཟླ་༡༢ ");
|
||||
|
||||
// https://github.com/react/react/blob/06b2a50f321502514443f675eaa44be8ae826218/fixtures/fizz/src/BigComponent.js#L154
|
||||
should___fit_____("यह Google अनुवाद में अंग्रेज़ी से दूसरी भाषा में अनुवादित टेक्स्ट ब्लॉक है।");
|
||||
should_break_____("यह Google अनुवाद में अंग्रेज़ी से दूसरी भाषा में अनुवादित टेक्स्ट ब्लॉक है। ");
|
||||
|
||||
=====================================output=====================================
|
||||
should___fit_____________("ཟླ་༡_ཟླ་༢_ཟླ་༣_ཟླ་༤_ཟླ་༥_ཟླ་༦_ཟླ་༧_ཟླ་༨_ཟླ་༩_ཟླ་༡༠_ཟླ་༡༡_ཟླ་༡༢");
|
||||
should_break_____________(
|
||||
"ཟླ་༡_ཟླ་༢_ཟླ་༣_ཟླ་༤_ཟླ་༥_ཟླ་༦_ཟླ་༧_ཟླ་༨_ཟླ་༩_ཟླ་༡༠_ཟླ་༡༡_ཟླ་༡༢ ",
|
||||
);
|
||||
|
||||
// https://github.com/react/react/blob/06b2a50f321502514443f675eaa44be8ae826218/fixtures/fizz/src/BigComponent.js#L154
|
||||
should___fit_____("यह Google अनुवाद में अंग्रेज़ी से दूसरी भाषा में अनुवादित टेक्स्ट ब्लॉक है।");
|
||||
should_break_____(
|
||||
"यह Google अनुवाद में अंग्रेज़ी से दूसरी भाषा में अनुवादित टेक्स्ट ब्लॉक है। ",
|
||||
);
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -0,0 +1 @@
|
||||
runFormatTest(import.meta, ["babel", "flow", "typescript"]);
|
||||
@@ -0,0 +1,6 @@
|
||||
should___fit_____________("ཟླ་༡_ཟླ་༢_ཟླ་༣_ཟླ་༤_ཟླ་༥_ཟླ་༦_ཟླ་༧_ཟླ་༨_ཟླ་༩_ཟླ་༡༠_ཟླ་༡༡_ཟླ་༡༢");
|
||||
should_break_____________("ཟླ་༡_ཟླ་༢_ཟླ་༣_ཟླ་༤_ཟླ་༥_ཟླ་༦_ཟླ་༧_ཟླ་༨_ཟླ་༩_ཟླ་༡༠_ཟླ་༡༡_ཟླ་༡༢ ");
|
||||
|
||||
// https://github.com/react/react/blob/06b2a50f321502514443f675eaa44be8ae826218/fixtures/fizz/src/BigComponent.js#L154
|
||||
should___fit_____("यह Google अनुवाद में अंग्रेज़ी से दूसरी भाषा में अनुवादित टेक्स्ट ब्लॉक है।");
|
||||
should_break_____("यह Google अनुवाद में अंग्रेज़ी से दूसरी भाषा में अनुवादित टेक्स्ट ब्लॉक है। ");
|
||||
@@ -71,9 +71,7 @@ test("sharedUtil.getStringWidth", () => {
|
||||
expect(getStringWidth("\u{2194}\u{FE0F}")).toBe(2);
|
||||
expect(getStringWidth("\u{1F469}")).toBe(2);
|
||||
expect(getStringWidth("\u{1F469}\u{1F3FF}")).toBe(2);
|
||||
// Ideally this should be `2`, switch to use `Intl.Segmenter` will fix it
|
||||
// https://github.com/prettier/prettier/pull/14793#discussion_r1185840038
|
||||
expect(getStringWidth("\u{845B}\u{E0100}")).toBe(3);
|
||||
expect(getStringWidth("\u{845B}\u{E0100}")).toBe(2);
|
||||
|
||||
expect(getStringWidth(String.fromCharCode(0))).toBe(0);
|
||||
expect(getStringWidth(String.fromCharCode(31))).toBe(0);
|
||||
@@ -82,6 +80,10 @@ test("sharedUtil.getStringWidth", () => {
|
||||
expect(getStringWidth(String.fromCharCode(159))).toBe(0);
|
||||
expect(getStringWidth("\u001B")).toBe(0);
|
||||
expect(getStringWidth("x\u0300")).toBe(1);
|
||||
expect(getStringWidth("ཟླ")).toBe(1);
|
||||
expect(getStringWidth("a\u20DD")).toBe(1);
|
||||
expect(getStringWidth("\u093E")).toBe(1);
|
||||
expect(getStringWidth("\u0915\u093E")).toBe(2);
|
||||
|
||||
expect(getStringWidth("👶")).toBe(2);
|
||||
expect(getStringWidth("👶🏽")).toBe(2);
|
||||
|
||||
Reference in new issue
Block a user