@tuidom/core 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,5 +17,13 @@
17
17
  * constructor: tab expands to the next tab stop, `\r` is zero-width, single
18
18
  * code units go through {@link getCharDisplayWidth}, multi-code-unit clusters
19
19
  * through {@link getGraphemeDisplayWidth}.
20
+ *
21
+ * A prefix of printable ASCII and tabs is counted without segmentation: each
22
+ * such code unit is a grapheme of its own (see `isStandalone` in
23
+ * `segmentGraphemes`) one column wide, or a tab stop. Program text is mostly
24
+ * that, and the per-grapheme generator was the whole cost of measuring a
25
+ * 200k-line file. The last code unit of the prefix is handed back to the
26
+ * generic path, since what follows may join it into one cluster (a combining
27
+ * mark, a ZWJ, a variation selector).
20
28
  */
21
29
  export declare function measureTextWidth(raw: string, tabSize?: number, stopAfter?: number): number;
@@ -20,11 +20,44 @@ const DEFAULT_TAB_SIZE = 4;
20
20
  * constructor: tab expands to the next tab stop, `\r` is zero-width, single
21
21
  * code units go through {@link getCharDisplayWidth}, multi-code-unit clusters
22
22
  * through {@link getGraphemeDisplayWidth}.
23
+ *
24
+ * A prefix of printable ASCII and tabs is counted without segmentation: each
25
+ * such code unit is a grapheme of its own (see `isStandalone` in
26
+ * `segmentGraphemes`) one column wide, or a tab stop. Program text is mostly
27
+ * that, and the per-grapheme generator was the whole cost of measuring a
28
+ * 200k-line file. The last code unit of the prefix is handed back to the
29
+ * generic path, since what follows may join it into one cluster (a combining
30
+ * mark, a ZWJ, a variation selector).
23
31
  */
24
32
  export function measureTextWidth(raw, tabSize = DEFAULT_TAB_SIZE, stopAfter = Infinity) {
33
+ const end = Math.min(raw.length, stopAfter);
25
34
  let column = 0;
26
- for (const { segment, index } of segmentGraphemes(raw)) {
27
- if (index >= stopAfter)
35
+ let columnBefore = 0;
36
+ let i = 0;
37
+ for (; i < end; i++) {
38
+ const c = raw.charCodeAt(i);
39
+ if (c === 0x09) {
40
+ columnBefore = column;
41
+ column += tabSize - (column % tabSize);
42
+ }
43
+ else if (c >= 0x20 && c <= 0x7e) {
44
+ columnBefore = column;
45
+ column++;
46
+ }
47
+ else {
48
+ break;
49
+ }
50
+ }
51
+ // The whole string is such a prefix: nothing after it can join its last code unit.
52
+ if (i >= raw.length)
53
+ return column;
54
+ // Resume one code unit back, where the break is certain, from the column before it.
55
+ const start = Math.max(0, i - 1);
56
+ if (start < i)
57
+ column = columnBefore;
58
+ const tail = start === 0 ? raw : raw.slice(start);
59
+ for (const { segment, index } of segmentGraphemes(tail)) {
60
+ if (start + index >= stopAfter)
28
61
  break;
29
62
  if (segment === "\t") {
30
63
  column += tabSize - (column % tabSize);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuidom/core",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "description": "Experimental terminal UI DOM — core: element tree, flex layout, grid rendering, input parsing. API is unstable.",
6
6
  "license": "MIT",