@promptctl/rich-js 0.27.0 → 0.29.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.
- package/README.md +7 -6
- package/THIRD-PARTY-NOTICES +42 -0
- package/dist/core/animation.d.ts +65 -46
- package/dist/core/animation.js +91 -67
- package/dist/core/ansi.d.ts +19 -12
- package/dist/core/ansi.js +114 -36
- package/dist/core/bidi-data.d.ts +14 -0
- package/dist/core/bidi-data.js +385 -0
- package/dist/core/bidi.d.ts +89 -0
- package/dist/core/bidi.js +615 -0
- package/dist/core/box.d.ts +9 -1
- package/dist/core/box.js +11 -0
- package/dist/core/cell-widths.d.ts +3 -2
- package/dist/core/cell-widths.js +93 -93
- package/dist/core/cells.d.ts +20 -0
- package/dist/core/cells.js +94 -6
- package/dist/core/clock.d.ts +1 -1
- package/dist/core/color.d.ts +56 -57
- package/dist/core/color.js +79 -81
- package/dist/core/console.d.ts +24 -7
- package/dist/core/console.js +27 -8
- package/dist/core/control-codes.d.ts +61 -0
- package/dist/core/control-codes.js +157 -0
- package/dist/core/easing.d.ts +40 -40
- package/dist/core/easing.js +40 -40
- package/dist/core/env.d.ts +6 -0
- package/dist/core/env.js +9 -1
- package/dist/core/export-html.js +5 -4
- package/dist/core/export-lines.d.ts +13 -11
- package/dist/core/export-lines.js +19 -15
- package/dist/core/export-svg.d.ts +3 -3
- package/dist/core/export-svg.js +10 -9
- package/dist/core/json.js +9 -2
- package/dist/core/markup.js +5 -4
- package/dist/core/memo.d.ts +1 -1
- package/dist/core/memo.js +1 -1
- package/dist/core/oklch.d.ts +14 -14
- package/dist/core/oklch.js +10 -10
- package/dist/core/orient.d.ts +68 -0
- package/dist/core/orient.js +224 -0
- package/dist/core/osc8.d.ts +12 -5
- package/dist/core/osc8.js +14 -7
- package/dist/core/paint.d.ts +9 -9
- package/dist/core/paint.js +3 -3
- package/dist/core/pretty.d.ts +1 -1
- package/dist/core/pretty.js +23 -19
- package/dist/core/protocol.d.ts +47 -26
- package/dist/core/protocol.js +31 -23
- package/dist/core/render.d.ts +19 -14
- package/dist/core/render.js +30 -17
- package/dist/core/seal.d.ts +26 -0
- package/dist/core/seal.js +75 -0
- package/dist/core/segment.d.ts +12 -4
- package/dist/core/segment.js +16 -6
- package/dist/core/strip.d.ts +83 -83
- package/dist/core/strip.js +70 -70
- package/dist/core/style.d.ts +46 -18
- package/dist/core/style.js +92 -56
- package/dist/core/text-order.d.ts +51 -0
- package/dist/core/text-order.js +50 -0
- package/dist/core/text.d.ts +12 -2
- package/dist/core/text.js +136 -90
- package/dist/core/timeline.d.ts +5 -5
- package/dist/core/timeline.js +11 -11
- package/dist/core/tween.d.ts +6 -6
- package/dist/core/tween.js +10 -10
- package/dist/core/view.d.ts +5 -5
- package/dist/core/view.js +15 -14
- package/dist/core/wrap.d.ts +24 -6
- package/dist/core/wrap.js +82 -16
- package/dist/host/app.d.ts +50 -9
- package/dist/host/app.js +120 -15
- package/dist/host/host-environment.d.ts +2 -2
- package/dist/host/host-environment.js +2 -2
- package/dist/host/index.d.ts +3 -2
- package/dist/host/index.js +1 -0
- package/dist/host/input.d.ts +42 -9
- package/dist/host/input.js +91 -7
- package/dist/host/terminal-colors.d.ts +18 -0
- package/dist/host/terminal-colors.js +46 -0
- package/dist/host/terminal-host.d.ts +4 -3
- package/dist/host/terminal-host.js +1 -1
- package/dist/index.d.ts +17 -16
- package/dist/index.js +11 -11
- package/dist/node/prompt.d.ts +1 -1
- package/dist/node/prompt.js +1 -1
- package/dist/node/terminal-host.d.ts +1 -1
- package/dist/node/traceback.js +2 -2
- package/dist/renderables/change.d.ts +1 -3
- package/dist/renderables/change.js +6 -8
- package/dist/renderables/effect.d.ts +88 -87
- package/dist/renderables/effect.js +124 -114
- package/dist/renderables/effects.d.ts +105 -76
- package/dist/renderables/effects.js +309 -176
- package/dist/renderables/embed.d.ts +1 -1
- package/dist/renderables/embed.js +2 -2
- package/dist/renderables/flexStrip.d.ts +7 -7
- package/dist/renderables/flexStrip.js +15 -15
- package/dist/renderables/frames.d.ts +7 -16
- package/dist/renderables/frames.js +12 -27
- package/dist/renderables/glyph-effect.d.ts +22 -23
- package/dist/renderables/glyph-effect.js +43 -41
- package/dist/renderables/glyph-effects.d.ts +33 -14
- package/dist/renderables/glyph-effects.js +90 -22
- package/dist/renderables/html-entities.d.ts +1 -1
- package/dist/renderables/html-entities.js +1 -1
- package/dist/renderables/lifecycle.d.ts +8 -10
- package/dist/renderables/lifecycle.js +17 -18
- package/dist/renderables/live.d.ts +2 -2
- package/dist/renderables/live.js +7 -7
- package/dist/renderables/markdown-parse.js +3 -3
- package/dist/renderables/markdown.js +4 -2
- package/dist/renderables/panel.js +7 -5
- package/dist/renderables/progress.d.ts +1 -1
- package/dist/renderables/progress.js +1 -1
- package/dist/renderables/progressBar.d.ts +3 -3
- package/dist/renderables/progressBar.js +21 -18
- package/dist/renderables/prompt.d.ts +1 -1
- package/dist/renderables/scroll.d.ts +1 -1
- package/dist/renderables/scroll.js +3 -3
- package/dist/renderables/spinner.d.ts +4 -4
- package/dist/renderables/spinner.js +10 -10
- package/dist/renderables/syntax.d.ts +2 -2
- package/dist/renderables/syntax.js +9 -4
- package/dist/renderables/table.js +5 -4
- package/dist/renderables/traceback.d.ts +1 -1
- package/dist/renderables/traceback.js +1 -1
- package/dist/renderables/tree.js +3 -3
- package/dist/template-bindings/animation-funcs.d.ts +60 -29
- package/dist/template-bindings/animation-funcs.js +126 -43
- package/dist/template-bindings/color-funcs.d.ts +14 -14
- package/dist/template-bindings/color-funcs.js +25 -25
- package/dist/template-bindings/index.d.ts +16 -14
- package/dist/template-bindings/index.js +17 -14
- package/dist/template-bindings/palette-funcs.d.ts +2 -2
- package/dist/template-bindings/palette-funcs.js +4 -4
- package/dist/template-bindings/style-funcs.d.ts +5 -5
- package/dist/template-bindings/style-funcs.js +16 -16
- package/dist/themes/{transpose.d.ts → adjust.d.ts} +23 -23
- package/dist/themes/{transpose.js → adjust.js} +28 -28
- package/dist/themes/buildPalette.d.ts +6 -5
- package/dist/themes/buildPalette.js +22 -22
- package/dist/themes/colorMath.d.ts +16 -16
- package/dist/themes/colorMath.js +32 -32
- package/dist/themes/data/ansi-tables.d.ts +2 -2
- package/dist/themes/data/ansi-tables.js +2 -2
- package/dist/themes/data/index.js +1 -4
- package/dist/themes/data/textual-ansi.js +0 -143
- package/dist/themes/data/types.d.ts +4 -4
- package/dist/themes/data/types.js +2 -2
- package/dist/themes/palette.d.ts +12 -12
- package/dist/themes/palette.js +16 -16
- package/dist/themes/ramp.d.ts +17 -17
- package/dist/themes/ramp.js +12 -12
- package/dist/themes/registry.d.ts +6 -8
- package/dist/themes/registry.js +6 -8
- package/dist/themes/terminalThemes.d.ts +4 -11
- package/dist/themes/terminalThemes.js +31 -47
- package/dist/widgets/button.d.ts +3 -3
- package/dist/widgets/button.js +8 -8
- package/dist/widgets/checkbox.d.ts +2 -2
- package/dist/widgets/checkbox.js +4 -4
- package/dist/widgets/dropdown.d.ts +3 -3
- package/dist/widgets/dropdown.js +7 -5
- package/dist/widgets/event-router.d.ts +6 -6
- package/dist/widgets/event-router.js +2 -2
- package/dist/widgets/focus-manager.d.ts +3 -3
- package/dist/widgets/focus-manager.js +3 -3
- package/dist/widgets/index.d.ts +2 -2
- package/dist/widgets/index.js +1 -1
- package/dist/widgets/ink.d.ts +3 -3
- package/dist/widgets/ink.js +4 -4
- package/dist/widgets/slider.d.ts +2 -2
- package/dist/widgets/static-item.d.ts +2 -2
- package/dist/widgets/text-input.d.ts +2 -2
- package/dist/widgets/text-input.js +5 -5
- package/dist/widgets/themed-widget.js +4 -4
- package/dist/widgets/toggle.d.ts +4 -4
- package/dist/widgets/toggle.js +6 -6
- package/dist/widgets/types.d.ts +6 -6
- package/dist/widgets/types.js +2 -2
- package/dist/widgets/widget-app.d.ts +10 -10
- package/dist/widgets/widget-app.js +8 -8
- package/dist/widgets/widget-base.d.ts +2 -2
- package/package.json +5 -4
package/dist/core/style.js
CHANGED
|
@@ -6,7 +6,7 @@ import { shiftAnchor } from "./anchor.js";
|
|
|
6
6
|
import { Memo } from "./memo.js";
|
|
7
7
|
import { pattern } from "./pattern.js";
|
|
8
8
|
// [LAW:one-way-deps] `core/style` depends only on `core/color`. The substrate
|
|
9
|
-
// a translucent
|
|
9
|
+
// a translucent color is flattened over is `SURFACE_BLACK`, defined beside
|
|
10
10
|
// `compositeOver`.
|
|
11
11
|
// --- Attribute definitions ---
|
|
12
12
|
/**
|
|
@@ -21,11 +21,11 @@ export const ATTRIBUTE_NAMES = [
|
|
|
21
21
|
"italic",
|
|
22
22
|
"underline",
|
|
23
23
|
"blink",
|
|
24
|
-
"
|
|
24
|
+
"rapidBlink",
|
|
25
25
|
"reverse",
|
|
26
26
|
"conceal",
|
|
27
27
|
"strike",
|
|
28
|
-
"
|
|
28
|
+
"doubleUnderline",
|
|
29
29
|
"frame",
|
|
30
30
|
"encircle",
|
|
31
31
|
"overline",
|
|
@@ -37,11 +37,11 @@ export const ATTRIBUTE_SGR = {
|
|
|
37
37
|
italic: 3,
|
|
38
38
|
underline: 4,
|
|
39
39
|
blink: 5,
|
|
40
|
-
|
|
40
|
+
rapidBlink: 6,
|
|
41
41
|
reverse: 7,
|
|
42
42
|
conceal: 8,
|
|
43
43
|
strike: 9,
|
|
44
|
-
|
|
44
|
+
doubleUnderline: 21,
|
|
45
45
|
frame: 51,
|
|
46
46
|
encircle: 52,
|
|
47
47
|
overline: 53,
|
|
@@ -60,10 +60,14 @@ export const ATTRIBUTE_SHORT_ALIASES = {
|
|
|
60
60
|
s: "strike",
|
|
61
61
|
r: "reverse",
|
|
62
62
|
o: "overline",
|
|
63
|
-
uu: "
|
|
63
|
+
uu: "doubleUnderline",
|
|
64
64
|
};
|
|
65
65
|
/** The hold of a cell that never changes: always was, and always will be. */
|
|
66
|
-
const NEVER_CHANGES = {
|
|
66
|
+
export const NEVER_CHANGES = { validFrom: Number.NEGATIVE_INFINITY, validUntil: Number.POSITIVE_INFINITY };
|
|
67
|
+
/** The moments both `a` and `b` hold through: the later `validFrom` and the sooner `validUntil`. */
|
|
68
|
+
export function intersection(a, b) {
|
|
69
|
+
return { validFrom: Math.max(a.validFrom, b.validFrom), validUntil: Math.min(a.validUntil, b.validUntil) };
|
|
70
|
+
}
|
|
67
71
|
export class StyleSyntaxError extends Error {
|
|
68
72
|
constructor(message, options) {
|
|
69
73
|
super(message, options);
|
|
@@ -81,11 +85,11 @@ export class Style {
|
|
|
81
85
|
italic;
|
|
82
86
|
underline;
|
|
83
87
|
blink;
|
|
84
|
-
|
|
88
|
+
rapidBlink;
|
|
85
89
|
reverse;
|
|
86
90
|
conceal;
|
|
87
91
|
strike;
|
|
88
|
-
|
|
92
|
+
doubleUnderline;
|
|
89
93
|
frame;
|
|
90
94
|
encircle;
|
|
91
95
|
overline;
|
|
@@ -97,32 +101,49 @@ export class Style {
|
|
|
97
101
|
* unequal, because they came from different places.
|
|
98
102
|
*/
|
|
99
103
|
anchor;
|
|
104
|
+
/**
|
|
105
|
+
* The drawing of a box these cells are the frame of (`Box.frame`), compared
|
|
106
|
+
* by identity. A frame is told by what drew it, never by its glyphs, as a
|
|
107
|
+
* strip's seam is (`JOIN`, `./strip.ts`): a box may draw its frame in blanks,
|
|
108
|
+
* and what it draws in ink an element's own content may draw too. It is a
|
|
109
|
+
* drawing and not a box, so two panels of one `ROUNDED` are two frames, and
|
|
110
|
+
* it is no `Anchor`: a frame's cells say whose they are and not where, since
|
|
111
|
+
* a table draws its top rule before it knows its height. It draws nothing.
|
|
112
|
+
*/
|
|
113
|
+
boxFrame;
|
|
114
|
+
/**
|
|
115
|
+
* What drawing said of these cells' direction, compared by identity, as a
|
|
116
|
+
* link is a fact the encoder turns into bytes: `Segment` never holds a control
|
|
117
|
+
* the library wrote, so no cut of a row can unbalance one, and what survives a
|
|
118
|
+
* cut still names its stamp (`./seal.ts`). It draws nothing.
|
|
119
|
+
*/
|
|
120
|
+
bidi;
|
|
100
121
|
/**
|
|
101
122
|
* The hold this style's cells are in, on the timeline of whoever drew the
|
|
102
|
-
* frame: since when what they show has been what it is (`
|
|
103
|
-
* when it next changes (`
|
|
123
|
+
* frame: since when what they show has been what it is (`validFrom`), and
|
|
124
|
+
* when it next changes (`validUntil`) — both `t` for a cell drawn by
|
|
104
125
|
* something that moves every frame, and `-Infinity`/`Infinity` for one
|
|
105
126
|
* that never changes. It draws nothing. Whatever draws for a handed time
|
|
106
127
|
* stamps its cells with it (`placedRender`, `Effected`), the stamp rides up
|
|
107
128
|
* through every container as the anchor does (`./anchor.ts`), and whoever
|
|
108
|
-
* holds the composed frame reads it off (`Segment.
|
|
109
|
-
* `Segment.
|
|
129
|
+
* holds the composed frame reads it off (`Segment.validUntil`, and
|
|
130
|
+
* `Segment.validFrom` for a host running its timeline backwards), so a
|
|
110
131
|
* host knows when to draw again without asking each container. Two styles
|
|
111
132
|
* laid together are in the intersection of their holds.
|
|
112
133
|
*/
|
|
113
|
-
|
|
134
|
+
validity;
|
|
114
135
|
constructor(options = {}) {
|
|
115
|
-
const
|
|
116
|
-
const {
|
|
136
|
+
const validity = options.validity ?? NEVER_CHANGES;
|
|
137
|
+
const { validFrom, validUntil } = validity;
|
|
117
138
|
// [LAW:parse-dont-validate] A time or never, settled where the style is
|
|
118
139
|
// made: NaN and the far infinity fail here, so no reader of a frame meets one.
|
|
119
|
-
if (!(
|
|
120
|
-
throw new RangeError(`Style
|
|
140
|
+
if (!(validUntil > Number.NEGATIVE_INFINITY)) {
|
|
141
|
+
throw new RangeError(`Style validUntil must be a time in seconds or Infinity, got ${validUntil}`);
|
|
121
142
|
}
|
|
122
|
-
if (!(
|
|
123
|
-
throw new RangeError(`Style
|
|
143
|
+
if (!(validFrom < Number.POSITIVE_INFINITY)) {
|
|
144
|
+
throw new RangeError(`Style validFrom must be a time in seconds or -Infinity, got ${validFrom}`);
|
|
124
145
|
}
|
|
125
|
-
this.
|
|
146
|
+
this.validity = validity;
|
|
126
147
|
this.color = resolveColor(options.color);
|
|
127
148
|
this.bgcolor = resolveBackground(options.bgcolor);
|
|
128
149
|
this.bold = options.bold;
|
|
@@ -130,11 +151,11 @@ export class Style {
|
|
|
130
151
|
this.italic = options.italic;
|
|
131
152
|
this.underline = options.underline;
|
|
132
153
|
this.blink = options.blink;
|
|
133
|
-
this.
|
|
154
|
+
this.rapidBlink = options.rapidBlink;
|
|
134
155
|
this.reverse = options.reverse;
|
|
135
156
|
this.conceal = options.conceal;
|
|
136
157
|
this.strike = options.strike;
|
|
137
|
-
this.
|
|
158
|
+
this.doubleUnderline = options.doubleUnderline;
|
|
138
159
|
this.frame = options.frame;
|
|
139
160
|
this.encircle = options.encircle;
|
|
140
161
|
this.overline = options.overline;
|
|
@@ -142,6 +163,8 @@ export class Style {
|
|
|
142
163
|
this.link = options.link || undefined;
|
|
143
164
|
this.meta = options.meta;
|
|
144
165
|
this.anchor = options.anchor;
|
|
166
|
+
this.boxFrame = options.boxFrame;
|
|
167
|
+
this.bidi = options.bidi;
|
|
145
168
|
}
|
|
146
169
|
get isNull() {
|
|
147
170
|
return (this.color === undefined &&
|
|
@@ -151,19 +174,21 @@ export class Style {
|
|
|
151
174
|
this.italic === undefined &&
|
|
152
175
|
this.underline === undefined &&
|
|
153
176
|
this.blink === undefined &&
|
|
154
|
-
this.
|
|
177
|
+
this.rapidBlink === undefined &&
|
|
155
178
|
this.reverse === undefined &&
|
|
156
179
|
this.conceal === undefined &&
|
|
157
180
|
this.strike === undefined &&
|
|
158
|
-
this.
|
|
181
|
+
this.doubleUnderline === undefined &&
|
|
159
182
|
this.frame === undefined &&
|
|
160
183
|
this.encircle === undefined &&
|
|
161
184
|
this.overline === undefined &&
|
|
162
185
|
this.link === undefined &&
|
|
163
186
|
this.meta === undefined &&
|
|
164
187
|
this.anchor === undefined &&
|
|
165
|
-
this.
|
|
166
|
-
this.
|
|
188
|
+
this.boxFrame === undefined &&
|
|
189
|
+
this.bidi === undefined &&
|
|
190
|
+
this.validity.validUntil === Number.POSITIVE_INFINITY &&
|
|
191
|
+
this.validity.validFrom === Number.NEGATIVE_INFINITY);
|
|
167
192
|
}
|
|
168
193
|
get transparentBackground() {
|
|
169
194
|
return this.bgcolor === undefined || this.bgcolor.isDefault;
|
|
@@ -199,6 +224,14 @@ export class Style {
|
|
|
199
224
|
withAnchor(anchor) {
|
|
200
225
|
return this.with({ anchor });
|
|
201
226
|
}
|
|
227
|
+
/** The same look, as the frame of the drawing `boxFrame` names, or of none. */
|
|
228
|
+
withBoxFrame(boxFrame) {
|
|
229
|
+
return this.with({ boxFrame });
|
|
230
|
+
}
|
|
231
|
+
/** The same look, its cells' direction as `bidi` says. */
|
|
232
|
+
withBidi(bidi) {
|
|
233
|
+
return this.with({ bidi });
|
|
234
|
+
}
|
|
202
235
|
/** The style's text attributes, each as it sets it. */
|
|
203
236
|
get attributes() {
|
|
204
237
|
// [LAW:one-source-of-truth] Keyed by `ATTRIBUTE_NAMES`, whose every name is a key here: the cast is that list's own claim.
|
|
@@ -210,16 +243,16 @@ export class Style {
|
|
|
210
243
|
*/
|
|
211
244
|
withAttributes(attributes) {
|
|
212
245
|
// Only the attribute names are read: a wider object — a `Style`, say —
|
|
213
|
-
// satisfies the type and must not carry its
|
|
246
|
+
// satisfies the type and must not carry its colors or anchor in with it.
|
|
214
247
|
return this.with(Object.fromEntries(ATTRIBUTE_NAMES.filter((name) => name in attributes).map((name) => [name, attributes[name]])));
|
|
215
248
|
}
|
|
216
249
|
/**
|
|
217
250
|
* This style with its motion taken out, what reduced motion draws: `blink`
|
|
218
|
-
* and `
|
|
251
|
+
* and `rapidBlink`, the motion a terminal makes on its own, unset, and every
|
|
219
252
|
* other field as it was. A style that does not blink is its own.
|
|
220
253
|
*/
|
|
221
254
|
reduced() {
|
|
222
|
-
return this.blink || this.
|
|
255
|
+
return this.blink || this.rapidBlink ? this.withAttributes({ blink: undefined, rapidBlink: undefined }) : this;
|
|
223
256
|
}
|
|
224
257
|
/**
|
|
225
258
|
* This style on the cell `cells` to the right: its anchor shifted along its
|
|
@@ -244,11 +277,11 @@ export class Style {
|
|
|
244
277
|
italic: other.italic ?? this.italic,
|
|
245
278
|
underline: other.underline ?? this.underline,
|
|
246
279
|
blink: other.blink ?? this.blink,
|
|
247
|
-
|
|
280
|
+
rapidBlink: other.rapidBlink ?? this.rapidBlink,
|
|
248
281
|
reverse: other.reverse ?? this.reverse,
|
|
249
282
|
conceal: other.conceal ?? this.conceal,
|
|
250
283
|
strike: other.strike ?? this.strike,
|
|
251
|
-
|
|
284
|
+
doubleUnderline: other.doubleUnderline ?? this.doubleUnderline,
|
|
252
285
|
frame: other.frame ?? this.frame,
|
|
253
286
|
encircle: other.encircle ?? this.encircle,
|
|
254
287
|
overline: other.overline ?? this.overline,
|
|
@@ -257,9 +290,10 @@ export class Style {
|
|
|
257
290
|
? { ...this.meta, ...other.meta }
|
|
258
291
|
: other.meta ?? this.meta,
|
|
259
292
|
anchor: other.anchor ?? this.anchor,
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
293
|
+
boxFrame: other.boxFrame ?? this.boxFrame,
|
|
294
|
+
bidi: other.bidi ?? this.bidi,
|
|
295
|
+
// Cells under both change when either does.
|
|
296
|
+
validity: intersection(this.validity, other.validity),
|
|
263
297
|
});
|
|
264
298
|
}
|
|
265
299
|
equals(other) {
|
|
@@ -272,21 +306,23 @@ export class Style {
|
|
|
272
306
|
this.italic === other.italic &&
|
|
273
307
|
this.underline === other.underline &&
|
|
274
308
|
this.blink === other.blink &&
|
|
275
|
-
this.
|
|
309
|
+
this.rapidBlink === other.rapidBlink &&
|
|
276
310
|
this.reverse === other.reverse &&
|
|
277
311
|
this.conceal === other.conceal &&
|
|
278
312
|
this.strike === other.strike &&
|
|
279
|
-
this.
|
|
313
|
+
this.doubleUnderline === other.doubleUnderline &&
|
|
280
314
|
this.frame === other.frame &&
|
|
281
315
|
this.encircle === other.encircle &&
|
|
282
316
|
this.overline === other.overline &&
|
|
283
317
|
this.link === other.link &&
|
|
284
318
|
anchorsEqual(this.anchor, other.anchor) &&
|
|
285
|
-
this.
|
|
286
|
-
this.
|
|
319
|
+
this.boxFrame === other.boxFrame &&
|
|
320
|
+
this.bidi === other.bidi &&
|
|
321
|
+
this.validity.validUntil === other.validity.validUntil &&
|
|
322
|
+
this.validity.validFrom === other.validity.validFrom);
|
|
287
323
|
}
|
|
288
324
|
/**
|
|
289
|
-
* The
|
|
325
|
+
* The colors this style puts on screen at `colorSystem`: each flattened
|
|
290
326
|
* onto what lies beneath it — the background onto the terminal's black, the
|
|
291
327
|
* foreground onto that background — then downgraded to the depth. The one
|
|
292
328
|
* account of what a style draws: `toSgrCodes` encodes exactly these, and a
|
|
@@ -332,8 +368,8 @@ export class Style {
|
|
|
332
368
|
}
|
|
333
369
|
/**
|
|
334
370
|
* The look as a canonical string that round-trips through `Style.parse()`:
|
|
335
|
-
*
|
|
336
|
-
* What a style carries beyond its look — `meta`, `anchor`, `hold` —
|
|
371
|
+
* colors, attributes and the link, which is all a style string can spell.
|
|
372
|
+
* What a style carries beyond its look — `meta`, `anchor`, `boxFrame`, `bidi`, `hold` —
|
|
337
373
|
* has no spelling and is not here, so two styles that differ only there
|
|
338
374
|
* read alike; `equals` tells them apart.
|
|
339
375
|
*/
|
|
@@ -480,7 +516,7 @@ export class Theme {
|
|
|
480
516
|
// --- Parse helpers ---
|
|
481
517
|
const ATTRIBUTE_SET = new Set(ATTRIBUTE_NAMES);
|
|
482
518
|
// The words each position of a definition can hold: a bare token is a keyword,
|
|
483
|
-
// an attribute or a
|
|
519
|
+
// an attribute or a color name; `on` takes a color name; `not` an attribute.
|
|
484
520
|
// The short aliases are left out, since `b` is no help to someone who typed
|
|
485
521
|
// `bolt` and a one-letter name sits one edit from every other short word.
|
|
486
522
|
// [LAW:one-source-of-truth] Derived from the lists the parser accepts from; the
|
|
@@ -512,8 +548,8 @@ function editDistance(a, b) {
|
|
|
512
548
|
* Plausible means within one edit per three letters, at least one, which lets
|
|
513
549
|
* `rd` reach `red` and keeps `hello` from reaching `yellow`. Every name tied
|
|
514
550
|
* for nearest is offered: `gold` is one edit from `bold` and from three
|
|
515
|
-
* `goldN`
|
|
516
|
-
* tell from a finding. Case is not an edit, because the
|
|
551
|
+
* `goldN` colors, and choosing among them would be a guess the reader cannot
|
|
552
|
+
* tell from a finding. Case is not an edit, because the color parser ignores
|
|
517
553
|
* it: `Cyna` is as near `cyan` as `cyna` is.
|
|
518
554
|
*
|
|
519
555
|
* This runs on every render that meets the bad style, since only successful
|
|
@@ -535,12 +571,12 @@ function nearMiss(word, words) {
|
|
|
535
571
|
return names.length === 0 ? "" : ` (did you mean ${names.join(" or ")}?)`;
|
|
536
572
|
}
|
|
537
573
|
/**
|
|
538
|
-
* A style token read as a
|
|
574
|
+
* A style token read as a color. The color parser's own error is the reason
|
|
539
575
|
* the token failed, so it rides along twice: in the message, for a reader with
|
|
540
576
|
* only the text, and as `cause`, for code that wants the original error.
|
|
541
577
|
*
|
|
542
|
-
* [LAW:single-enforcer] Both
|
|
543
|
-
* the near miss is named here rather than by the
|
|
578
|
+
* [LAW:single-enforcer] Both color positions in a definition rewrap here, and
|
|
579
|
+
* the near miss is named here rather than by the color parser: only a
|
|
544
580
|
* definition knows whether the token could also have been an attribute.
|
|
545
581
|
*/
|
|
546
582
|
function parseStyleColor(token, failure, words) {
|
|
@@ -619,7 +655,7 @@ function resolveColor(c) {
|
|
|
619
655
|
// so it is no background: a style added on top of another keeps that one's,
|
|
620
656
|
// which is what Textual's `#00000000` means. A transparent foreground is not
|
|
621
657
|
// the same, it draws its glyph in whatever lies beneath it — the background,
|
|
622
|
-
// or `SURFACE_BLACK` when there is none — so it stays a
|
|
658
|
+
// or `SURFACE_BLACK` when there is none — so it stays a color.
|
|
623
659
|
function resolveBackground(c) {
|
|
624
660
|
const spec = resolveColor(c);
|
|
625
661
|
return spec?.value?.alpha === 0 ? undefined : spec;
|
|
@@ -636,11 +672,11 @@ export const DEFAULT_STYLES = {
|
|
|
636
672
|
italic: false,
|
|
637
673
|
underline: false,
|
|
638
674
|
blink: false,
|
|
639
|
-
|
|
675
|
+
rapidBlink: false,
|
|
640
676
|
reverse: false,
|
|
641
677
|
conceal: false,
|
|
642
678
|
strike: false,
|
|
643
|
-
|
|
679
|
+
doubleUnderline: false,
|
|
644
680
|
frame: false,
|
|
645
681
|
encircle: false,
|
|
646
682
|
overline: false,
|
|
@@ -650,11 +686,11 @@ export const DEFAULT_STYLES = {
|
|
|
650
686
|
italic: new Style({ italic: true }),
|
|
651
687
|
underline: new Style({ underline: true }),
|
|
652
688
|
blink: new Style({ blink: true }),
|
|
653
|
-
|
|
689
|
+
rapidBlink: new Style({ rapidBlink: true }),
|
|
654
690
|
reverse: new Style({ reverse: true }),
|
|
655
691
|
conceal: new Style({ conceal: true }),
|
|
656
692
|
strike: new Style({ strike: true }),
|
|
657
|
-
|
|
693
|
+
doubleUnderline: new Style({ doubleUnderline: true }),
|
|
658
694
|
frame: new Style({ frame: true }),
|
|
659
695
|
encircle: new Style({ encircle: true }),
|
|
660
696
|
overline: new Style({ overline: true }),
|
|
@@ -719,9 +755,9 @@ export const DEFAULT_STYLES = {
|
|
|
719
755
|
"syntax.number": Style.parse("cyan"),
|
|
720
756
|
"syntax.comment": Style.parse("dim italic"),
|
|
721
757
|
"syntax.line_number": Style.parse("dim"),
|
|
722
|
-
// Ink and ground both from the fixed 256-
|
|
758
|
+
// Ink and ground both from the fixed 256-color greys: the terminal theme's
|
|
723
759
|
// own foreground is dark on a light theme and would vanish on grey27. At 16
|
|
724
|
-
//
|
|
760
|
+
// colors `Syntax` draws it without the pair (`groundedStyle`).
|
|
725
761
|
"syntax.line_number.highlight": Style.parse("bold grey93 on grey27"),
|
|
726
762
|
// Markdown
|
|
727
763
|
"markdown.h1": Style.parse("bold underline"),
|
|
@@ -731,7 +767,7 @@ export const DEFAULT_STYLES = {
|
|
|
731
767
|
"markdown.h5": Style.parse("italic"),
|
|
732
768
|
"markdown.h6": Style.parse("dim"),
|
|
733
769
|
// A fixed cyan, not the theme's: `cyan` is dark enough on some themes to
|
|
734
|
-
// sink into grey11. Bold, as Rich's is: at 16
|
|
770
|
+
// sink into grey11. Bold, as Rich's is: at 16 colors a renderable draws it
|
|
735
771
|
// without its pair (`groundedStyle`), and bold is what still marks code.
|
|
736
772
|
"markdown.code": Style.parse("bold dark_turquoise on grey11"),
|
|
737
773
|
"markdown.em": Style.parse("italic"),
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a destination does with text direction.
|
|
3
|
+
*
|
|
4
|
+
* Every order above `plain` is a claim about the terminal, and a wrong claim
|
|
5
|
+
* costs more than none. Visual order on a terminal that also reorders reverses
|
|
6
|
+
* the text twice, and no query answers for every such terminal. An isolate on a
|
|
7
|
+
* terminal whose width table predates it advances the cursor (xterm.js 6 does),
|
|
8
|
+
* which moves a table's border and the rows a painter goes back over. So what
|
|
9
|
+
* nothing is known about gets bare text, and `detectTextOrder` grants more only
|
|
10
|
+
* on evidence.
|
|
11
|
+
*/
|
|
12
|
+
import { type Env } from "./env.js";
|
|
13
|
+
/**
|
|
14
|
+
* - `plain`: nothing is known of the destination, or it is not a display: a
|
|
15
|
+
* pipe, a file, an unknown terminal. Characters only, in logical order, with
|
|
16
|
+
* no explicit bidi control.
|
|
17
|
+
* - `logical`: a display known to reorder and to hold the controls at zero
|
|
18
|
+
* width. Rows are sealed in isolates.
|
|
19
|
+
* - `visual`: a display known not to reorder. Rows are written reordered and
|
|
20
|
+
* shaped, with no controls.
|
|
21
|
+
*/
|
|
22
|
+
export type TextOrder = "plain" | "logical" | "visual";
|
|
23
|
+
/** A row's paragraph direction: 0 left to right, 1 right to left. */
|
|
24
|
+
export type ParagraphLevel = 0 | 1;
|
|
25
|
+
/** Cells written for a terminal that reorders them: their row's direction, and what is still open where they begin. */
|
|
26
|
+
export interface LogicalStamp {
|
|
27
|
+
readonly order: "logical";
|
|
28
|
+
readonly level: ParagraphLevel;
|
|
29
|
+
readonly opens: string;
|
|
30
|
+
}
|
|
31
|
+
/** Cells already in visual order, for an export not to reverse again. */
|
|
32
|
+
export interface VisualStamp {
|
|
33
|
+
readonly order: "visual";
|
|
34
|
+
}
|
|
35
|
+
export type BidiStamp = LogicalStamp | VisualStamp;
|
|
36
|
+
/**
|
|
37
|
+
* The order `env` gives evidence for.
|
|
38
|
+
*
|
|
39
|
+
* An environment is inherited: `code .` from Windows Terminal carries
|
|
40
|
+
* `WT_SESSION` into VS Code's xterm.js terminal, and Alacritty clears nothing
|
|
41
|
+
* from GNOME Terminal. `TERM` is the one variable every terminal writes for its
|
|
42
|
+
* own child, so it is read first, and a variable a parent could have left counts
|
|
43
|
+
* only beside the `TERM` its own terminal sets. The rows are in the order that
|
|
44
|
+
* makes that true; a terminal naming itself off this list is `plain`.
|
|
45
|
+
*
|
|
46
|
+
* Not listed, each for a reason: xterm.js lays a row out through the browser and
|
|
47
|
+
* advances for an isolate, and VS Code is xterm.js. WezTerm's bidi is a setting
|
|
48
|
+
* the environment cannot show. iTerm2, Konsole, Terminal.app, mintty and mlterm
|
|
49
|
+
* are unmeasured. Any program may state its order.
|
|
50
|
+
*/
|
|
51
|
+
export declare function detectTextOrder(env: Env, isTTY: boolean): TextOrder;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a destination does with text direction.
|
|
3
|
+
*
|
|
4
|
+
* Every order above `plain` is a claim about the terminal, and a wrong claim
|
|
5
|
+
* costs more than none. Visual order on a terminal that also reorders reverses
|
|
6
|
+
* the text twice, and no query answers for every such terminal. An isolate on a
|
|
7
|
+
* terminal whose width table predates it advances the cursor (xterm.js 6 does),
|
|
8
|
+
* which moves a table's border and the rows a painter goes back over. So what
|
|
9
|
+
* nothing is known about gets bare text, and `detectTextOrder` grants more only
|
|
10
|
+
* on evidence.
|
|
11
|
+
*/
|
|
12
|
+
import { isDumbTerminal } from "./env.js";
|
|
13
|
+
import { pattern } from "./pattern.js";
|
|
14
|
+
// Terminals that paint their own cells and do not reorder, by the `TERM` each
|
|
15
|
+
// writes for its child. Ghostty forces the embedding level to 0
|
|
16
|
+
// (font/shaper/coretext.zig); Alacritty (#663) and foot (#756) run no bidi.
|
|
17
|
+
const VISUAL_TERM = pattern(/^(alacritty|foot|xterm-ghostty)/);
|
|
18
|
+
/**
|
|
19
|
+
* The order `env` gives evidence for.
|
|
20
|
+
*
|
|
21
|
+
* An environment is inherited: `code .` from Windows Terminal carries
|
|
22
|
+
* `WT_SESSION` into VS Code's xterm.js terminal, and Alacritty clears nothing
|
|
23
|
+
* from GNOME Terminal. `TERM` is the one variable every terminal writes for its
|
|
24
|
+
* own child, so it is read first, and a variable a parent could have left counts
|
|
25
|
+
* only beside the `TERM` its own terminal sets. The rows are in the order that
|
|
26
|
+
* makes that true; a terminal naming itself off this list is `plain`.
|
|
27
|
+
*
|
|
28
|
+
* Not listed, each for a reason: xterm.js lays a row out through the browser and
|
|
29
|
+
* advances for an isolate, and VS Code is xterm.js. WezTerm's bidi is a setting
|
|
30
|
+
* the environment cannot show. iTerm2, Konsole, Terminal.app, mintty and mlterm
|
|
31
|
+
* are unmeasured. Any program may state its order.
|
|
32
|
+
*/
|
|
33
|
+
export function detectTextOrder(env, isTTY) {
|
|
34
|
+
if (!isTTY || isDumbTerminal(env))
|
|
35
|
+
return "plain";
|
|
36
|
+
if (env["TMUX"] || env["STY"] || env["ZELLIJ"] || env["INSIDE_EMACS"] || env["NVIM"] || env["VIM_TERMINAL"])
|
|
37
|
+
return "plain";
|
|
38
|
+
if ((env["TERM"] ?? "").match(VISUAL_TERM) !== null)
|
|
39
|
+
return "visual";
|
|
40
|
+
if (env["TERM_PROGRAM"] || env["TERMINAL_EMULATOR"] || env["KONSOLE_VERSION"])
|
|
41
|
+
return "plain";
|
|
42
|
+
// VTE reorders, and takes the controls at zero width past column 0
|
|
43
|
+
// (`src/unicode-width.hh`, `Terminal::insert_char`).
|
|
44
|
+
if (env["VTE_VERSION"] && env["TERM"] === "xterm-256color")
|
|
45
|
+
return "logical";
|
|
46
|
+
// Windows Terminal (microsoft/terminal#538): a console there has no `TERM`, WSL has this one.
|
|
47
|
+
if (env["WT_SESSION"] && (env["TERM"] === undefined || env["TERM"] === "xterm-256color"))
|
|
48
|
+
return "visual";
|
|
49
|
+
return "plain";
|
|
50
|
+
}
|
package/dist/core/text.d.ts
CHANGED
|
@@ -5,6 +5,13 @@ import { Segment } from "./segment.js";
|
|
|
5
5
|
import { Style, type TextStyle } from "./style.js";
|
|
6
6
|
import type { Renderable, Measurable, OverflowMethod, RenderOptions } from "./protocol.js";
|
|
7
7
|
export declare function stripControlChars(text: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* `text` as a Text's characters hold it: stripped, every line ending an LF, and
|
|
10
|
+
* every control its picture. One code unit for one, so an offset into stripped
|
|
11
|
+
* text holds, and every reader of a Text finds one line break without having to
|
|
12
|
+
* know the others.
|
|
13
|
+
*/
|
|
14
|
+
export declare function sanitized(text: string): string;
|
|
8
15
|
/**
|
|
9
16
|
* The style a stored `TextStyle` stands for in this render.
|
|
10
17
|
*
|
|
@@ -35,9 +42,12 @@ export interface RichTextOptions {
|
|
|
35
42
|
export declare class RichText implements Renderable, Measurable {
|
|
36
43
|
private readonly _text;
|
|
37
44
|
private readonly _spans;
|
|
45
|
+
private readonly _closure;
|
|
38
46
|
private readonly _format;
|
|
39
47
|
private readonly _tabSize;
|
|
40
48
|
constructor(text?: string, options?: RichTextOptions);
|
|
49
|
+
/** The part of the text whose direction state nothing has closed. */
|
|
50
|
+
private _unclosed;
|
|
41
51
|
private _reformat;
|
|
42
52
|
get plain(): string;
|
|
43
53
|
set plain(value: string);
|
|
@@ -75,8 +85,8 @@ export declare class RichText implements Renderable, Measurable {
|
|
|
75
85
|
* any spans covering the leftmost (side="left") or rightmost (side="right")
|
|
76
86
|
* character.
|
|
77
87
|
*
|
|
78
|
-
* [LAW:locality-or-seam] Used by `
|
|
79
|
-
* adjacent `Strip` items.
|
|
88
|
+
* [LAW:locality-or-seam] Used by `Separator`s to paint the transition between
|
|
89
|
+
* adjacent `Strip` items. Separators only ever need the column adjacent to
|
|
80
90
|
* them, so the cell type exposes that column rather than constraining its
|
|
81
91
|
* interior to be uniform. For RichText with uniform styling, both edges
|
|
82
92
|
* return the same style; for RichText with edge variation, each edge
|