diff --git a/src/tableFormatter.ts b/src/tableFormatter.ts index 64a400aa..da01f6a9 100644 --- a/src/tableFormatter.ts +++ b/src/tableFormatter.ts @@ -138,9 +138,10 @@ class MarkdownDocumentFormatter implements vscode.DocumentFormattingEditProvider const fieldRegExp = new RegExp(/((\\\||[^\|])*)\|/gu); // Emoji and CJK characters with double visual width (width 2) // https://www.ling.upenn.edu/courses/Spring_2003/ling538/UnicodeRanges.html - // Extended_Pictographic includes all graphical emoji chars + // Extended_Pictographic includes all graphical emoji chars (e.g. ✅ ⬜ ❌) // CJK ranges: U+3000-U+9FFF, U+AC00-U+D7AF, U+FF01-U+FF60 - const doubleWidthRegex = /\p{Extended_Pictographic}|[\u3000-\u9fff\uac00-\ud7af\uff01-\uff60]/gu; + // Arrows (U+2190-U+21FF, e.g. ↑ ↓ ← →) are rendered double-width in CJK contexts + const doubleWidthRegex = /\p{Extended_Pictographic}|[\u1100-\u115F\u2190-\u21FF\u2329\u232A\u2E80-\u2FFF\u3000-\u9FFF\uA000-\uA4CF\uA960-\uA97F\uAC00-\uD7FF\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6\u{16FE0}-\u{16FF6}\u{17000}-\u{18D1E}\u{1AFF0}-\u{1AFFE}\u{1B000}-\u{1B2FB}\u{1D300}-\u{1D376}\u{1F200}-\u{1F265}\u{20000}-\u{3FFFD}]/gu; const lines = rows.map((row, iRow) => { // Normalize @@ -223,7 +224,7 @@ class MarkdownDocumentFormatter implements vscode.DocumentFormattingEditProvider const visualWidth = colWidth[iCol]; let jsLength = splitter.splitGraphemes(cell + ' '.repeat(visualWidth)).slice(0, visualWidth).join('').length; - // Subtract double-width characters (emoji and CJK) + // Subtract double-width characters (emoji, CJK, and wide symbols) jsLength -= cell.match(doubleWidthRegex)?.length ?? 0; return this.alignText(cell, colAlign[iCol], jsLength); diff --git a/src/test/suite/integration/tableFormatter.test.ts b/src/test/suite/integration/tableFormatter.test.ts index 12debb20..0b4cd3c5 100644 --- a/src/test/suite/integration/tableFormatter.test.ts +++ b/src/test/suite/integration/tableFormatter.test.ts @@ -471,4 +471,24 @@ suite("Table formatter.", () => { ], new Selection(0, 0, 0, 0)); }); + + test("Wide symbols in table cells", () => { + return testCommand('editor.action.formatDocument', + [ + '| 阶段 | 状态 |', + '| --- | --- |', + '| 需求定义 | ✅ 完成 |', + '| 测试 | ⬜ 待开始 |', + '| 方向 | ↑↓←→ |' + ], + new Selection(0, 0, 0, 0), + [ + '| 阶段 | 状态 |', + '| -------- | --------- |', + '| 需求定义 | ✅ 完成 |', + '| 测试 | ⬜ 待开始 |', + '| 方向 | ↑↓←→ |' + ], + new Selection(0, 0, 0, 0)); + }); });