@promptctl/rich-js 0.28.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 -7
- package/dist/core/animation.d.ts +37 -37
- package/dist/core/animation.js +61 -61
- package/dist/core/ansi.d.ts +4 -4
- package/dist/core/ansi.js +9 -9
- package/dist/core/bidi.js +6 -6
- package/dist/core/cells.d.ts +1 -1
- package/dist/core/cells.js +5 -5
- package/dist/core/clock.d.ts +1 -1
- package/dist/core/color.d.ts +50 -50
- package/dist/core/color.js +69 -69
- package/dist/core/console.d.ts +8 -8
- package/dist/core/console.js +5 -5
- package/dist/core/control-codes.d.ts +3 -3
- package/dist/core/control-codes.js +7 -7
- package/dist/core/easing.d.ts +40 -40
- package/dist/core/easing.js +40 -40
- package/dist/core/env.d.ts +1 -1
- package/dist/core/env.js +1 -1
- package/dist/core/export-html.js +1 -1
- package/dist/core/export-lines.d.ts +11 -11
- package/dist/core/export-lines.js +12 -12
- package/dist/core/export-svg.d.ts +3 -3
- package/dist/core/export-svg.js +4 -4
- package/dist/core/markup.js +1 -1
- 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 +3 -3
- package/dist/core/orient.js +3 -3
- 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 +3 -3
- package/dist/core/protocol.d.ts +26 -26
- package/dist/core/protocol.js +22 -22
- package/dist/core/render.d.ts +11 -11
- package/dist/core/render.js +12 -12
- package/dist/core/segment.d.ts +3 -3
- package/dist/core/segment.js +5 -5
- package/dist/core/strip.d.ts +83 -83
- package/dist/core/strip.js +70 -70
- package/dist/core/style.d.ts +20 -20
- package/dist/core/style.js +55 -55
- package/dist/core/text.d.ts +2 -2
- package/dist/core/text.js +5 -5
- package/dist/core/timeline.d.ts +5 -5
- package/dist/core/timeline.js +9 -9
- package/dist/core/tween.d.ts +6 -6
- package/dist/core/tween.js +10 -10
- package/dist/core/view.d.ts +4 -4
- package/dist/core/view.js +12 -12
- package/dist/host/app.d.ts +9 -9
- package/dist/host/app.js +12 -12
- package/dist/host/host-environment.d.ts +2 -2
- package/dist/host/host-environment.js +2 -2
- package/dist/host/index.d.ts +2 -2
- package/dist/host/input.d.ts +7 -7
- package/dist/host/input.js +4 -4
- package/dist/host/terminal-colors.d.ts +2 -2
- package/dist/host/terminal-colors.js +4 -4
- package/dist/host/terminal-host.d.ts +2 -2
- package/dist/host/terminal-host.js +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.js +10 -10
- 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.js +2 -2
- package/dist/renderables/effect.d.ts +39 -39
- package/dist/renderables/effect.js +45 -45
- package/dist/renderables/effects.d.ts +81 -81
- package/dist/renderables/effects.js +157 -157
- 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 +6 -6
- package/dist/renderables/frames.js +11 -11
- package/dist/renderables/glyph-effect.d.ts +15 -15
- package/dist/renderables/glyph-effect.js +17 -17
- package/dist/renderables/glyph-effects.d.ts +7 -7
- package/dist/renderables/glyph-effects.js +16 -16
- package/dist/renderables/html-entities.d.ts +1 -1
- package/dist/renderables/html-entities.js +1 -1
- package/dist/renderables/lifecycle.d.ts +4 -4
- package/dist/renderables/lifecycle.js +12 -12
- 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/panel.js +3 -3
- package/dist/renderables/progress.d.ts +1 -1
- package/dist/renderables/progress.js +1 -1
- package/dist/renderables/progressBar.d.ts +1 -1
- package/dist/renderables/progressBar.js +6 -6
- 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 +2 -2
- package/dist/renderables/table.js +3 -3
- 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 +14 -14
- package/dist/template-bindings/animation-funcs.js +27 -27
- 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 +9 -9
- package/dist/template-bindings/index.js +9 -9
- package/dist/template-bindings/palette-funcs.d.ts +1 -1
- package/dist/template-bindings/palette-funcs.js +3 -3
- 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 +3 -3
- package/dist/themes/buildPalette.js +20 -20
- 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/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.js +4 -4
- package/dist/themes/terminalThemes.d.ts +1 -1
- package/dist/themes/terminalThemes.js +1 -1
- package/dist/widgets/button.d.ts +2 -2
- package/dist/widgets/button.js +4 -4
- package/dist/widgets/checkbox.d.ts +2 -2
- package/dist/widgets/checkbox.js +2 -2
- package/dist/widgets/dropdown.d.ts +2 -2
- package/dist/widgets/dropdown.js +3 -3
- 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 +1 -1
- package/dist/widgets/toggle.d.ts +3 -3
- package/dist/widgets/toggle.js +3 -3
- 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 +1 -1
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
* them with its hold at the frame's time (`placedRender`). The exit is
|
|
24
24
|
* drawn over whatever the arrival draws, so an element told to leave while
|
|
25
25
|
* it is still arriving leaves from where it is, never shown whole first —
|
|
26
|
-
* though a
|
|
26
|
+
* though a color exit is spread over the cells each frame shows, so a cell
|
|
27
27
|
* the arrival adds can move one already leaving back toward whole
|
|
28
28
|
* (`ownChange`, `./effects.ts`). [LAW:dataflow-not-control-flow]
|
|
29
29
|
*
|
|
30
|
-
* A half draws the element through a
|
|
30
|
+
* A half draws the element through a color transition (`throughColors`, a
|
|
31
31
|
* `fadeIn`) or a glyph one (`throughGlyphs`, a `typewriter`): each binds its
|
|
32
32
|
* transition to the one wrapper that draws it, so nothing here asks which kind
|
|
33
33
|
* a half is, and a line can type itself in and dissolve out. A half
|
|
@@ -46,11 +46,11 @@ import { firstReaching } from "../core/easing.js";
|
|
|
46
46
|
import { Timeline } from "../core/timeline.js";
|
|
47
47
|
import { Effected } from "./effect.js";
|
|
48
48
|
import { GlyphEffected } from "./glyph-effect.js";
|
|
49
|
-
/** `transition`'s
|
|
49
|
+
/** `transition`'s colors drawn over an element, arriving from and leaving to the ground of the terminal the frame is drawn on. */
|
|
50
50
|
export function throughColors(transition) {
|
|
51
51
|
return (element, key) => scheduled(new Effected(element, transition.effect, { key }), transition.schedule);
|
|
52
52
|
}
|
|
53
|
-
/** `transition`'s glyphs drawn over an element, at every depth, with no
|
|
53
|
+
/** `transition`'s glyphs drawn over an element, at every depth, with no color too. */
|
|
54
54
|
export function throughGlyphs(transition) {
|
|
55
55
|
return (element, key) => scheduled(new GlyphEffected(element, transition.effect, { key }), transition.schedule);
|
|
56
56
|
}
|
|
@@ -59,14 +59,14 @@ export function throughGlyphs(transition) {
|
|
|
59
59
|
* `schedule`, the transition's own, says: its frames with the one word on
|
|
60
60
|
* when they change that the transition has and the wrapper lacks, whose own
|
|
61
61
|
* answer is "now" until it is drawn. [LAW:one-source-of-truth] Reduced,
|
|
62
|
-
* both are reduced together, as `
|
|
62
|
+
* both are reduced together, as `sampleAndHold` steps both: a one-shot's effect
|
|
63
63
|
* and its schedule each reduce to a cut at 0 (`transition`, `./effects.ts`).
|
|
64
64
|
*/
|
|
65
65
|
function scheduled(placed, schedule) {
|
|
66
66
|
return Animation.of({
|
|
67
67
|
at: (t) => placed.at(t),
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
validUntil: (t) => schedule.validUntil(t),
|
|
69
|
+
validFrom: (t) => schedule.validFrom(t),
|
|
70
70
|
reduced: () => scheduled(placed.reduced(), schedule.reduced()),
|
|
71
71
|
});
|
|
72
72
|
}
|
|
@@ -120,7 +120,7 @@ function life(element, options, halves, entered, left) {
|
|
|
120
120
|
const arriving = Timeline.run(Timeline.play(entered), arrival);
|
|
121
121
|
// What the element draws by `t` if it is not leaving: arriving through `enter`, then itself.
|
|
122
122
|
const shown = (t) => (t < arrived ? arrival.at(t - entered) : element);
|
|
123
|
-
const held = (schedule, t) => ({ last: schedule.
|
|
123
|
+
const held = (schedule, t) => ({ last: schedule.validFrom(t), next: schedule.validUntil(t) });
|
|
124
124
|
// [LAW:one-source-of-truth] Each phase's frame and its hold, side by side, so the two cannot disagree.
|
|
125
125
|
// The frames say nothing of when they change — the hold does, stamped where the lifecycle is placed.
|
|
126
126
|
const phase = (t) => {
|
|
@@ -146,16 +146,16 @@ function life(element, options, halves, entered, left) {
|
|
|
146
146
|
: { frame: NOTHING, last: left, next: t < goneAt ? goneAt : Number.POSITIVE_INFINITY };
|
|
147
147
|
const present = Animation.of({
|
|
148
148
|
at: (t) => there(t).frame,
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
validUntil: (t) => there(t).next,
|
|
150
|
+
validFrom: (t) => there(t).last,
|
|
151
151
|
reduced: () => present,
|
|
152
152
|
});
|
|
153
153
|
return Animation.of({
|
|
154
154
|
entered,
|
|
155
155
|
left,
|
|
156
156
|
at: (t) => phase(t).frame,
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
validUntil: (t) => phase(t).next,
|
|
158
|
+
validFrom: (t) => phase(t).last,
|
|
159
159
|
// Reduced, the element is there from when it entered until it is told to leave: no arrival or exit to show, and the times kept.
|
|
160
160
|
reduced: () => present,
|
|
161
161
|
// [LAW:one-source-of-truth] The moment `phase` draws nothing from, so an element not yet told to leave is never asked its exit at -Infinity.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* when the display stops, as Rich's `Live` does.
|
|
15
15
|
*
|
|
16
16
|
* Live is not built on `App`, though both take a terminal, paint a frame over
|
|
17
|
-
* the last and hand the terminal back. That much is the `
|
|
17
|
+
* the last and hand the terminal back. That much is the `Renderer`'s, and both
|
|
18
18
|
* hold one. The rest differs in who owns what. An `App` owns its terminal: it
|
|
19
19
|
* starts and stops a `TerminalHost`, sets raw mode, reads keys and pointers,
|
|
20
20
|
* suspends, and builds its own `Console` from the host. A `Live` owns none of
|
|
@@ -35,7 +35,7 @@ export interface LiveOptions {
|
|
|
35
35
|
* positive and finite, fractional included. The next frame comes a frame
|
|
36
36
|
* interval after the last one drawn, a `refresh()` of your own included,
|
|
37
37
|
* or sooner when that frame's content says it changes sooner
|
|
38
|
-
* (`Segment.
|
|
38
|
+
* (`Segment.validUntil`).
|
|
39
39
|
*/
|
|
40
40
|
refreshPerSecond?: number;
|
|
41
41
|
/** What the auto-refresh waits on. The platform's, unless given. */
|
package/dist/renderables/live.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* when the display stops, as Rich's `Live` does.
|
|
15
15
|
*
|
|
16
16
|
* Live is not built on `App`, though both take a terminal, paint a frame over
|
|
17
|
-
* the last and hand the terminal back. That much is the `
|
|
17
|
+
* the last and hand the terminal back. That much is the `Renderer`'s, and both
|
|
18
18
|
* hold one. The rest differs in who owns what. An `App` owns its terminal: it
|
|
19
19
|
* starts and stops a `TerminalHost`, sets raw mode, reads keys and pointers,
|
|
20
20
|
* suspends, and builds its own `Console` from the host. A `Live` owns none of
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
import { frameRate, systemClock } from "../core/clock.js";
|
|
28
28
|
import { Console } from "../core/console.js";
|
|
29
29
|
import { Segment } from "../core/segment.js";
|
|
30
|
-
import {
|
|
30
|
+
import { FinalFrameRenderer, SurfaceRenderer } from "../core/paint.js";
|
|
31
31
|
import { fitHeight, render } from "../core/protocol.js";
|
|
32
32
|
import { Timeline } from "../core/timeline.js";
|
|
33
33
|
import { drawView, frameNow, hostView, undrawn } from "../core/view.js";
|
|
@@ -71,8 +71,8 @@ export class Live {
|
|
|
71
71
|
// The final frame is a print, as in Rich, so a recording or a capture
|
|
72
72
|
// holds it with everything else the console wrote.
|
|
73
73
|
this._painter = this._console.isInteractive
|
|
74
|
-
? new
|
|
75
|
-
: new
|
|
74
|
+
? new SurfaceRenderer(options?.altScreen ? "alternate" : "inline", (bytes) => void this._console.file.write(bytes))
|
|
75
|
+
: new FinalFrameRenderer((frame) => this._console.print(linesOf(frame)));
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
78
|
* The console to print through while this Live runs: what it prints lands
|
|
@@ -177,7 +177,7 @@ export class Live {
|
|
|
177
177
|
this._wake(held, said ?? undrawn(this._clock.now()));
|
|
178
178
|
}
|
|
179
179
|
// Arm the one wait for the next auto-refresh frame while `held`, from what
|
|
180
|
-
// the frame says: at its `
|
|
180
|
+
// the frame says: at its `validUntil` when it holds until a moment sooner
|
|
181
181
|
// than the rate, and at the rate otherwise — every view is drawn from state
|
|
182
182
|
// that may change without saying so, which the auto-refresh polls, as
|
|
183
183
|
// Rich's does, a paused timeline's included. Every moment is measured from the
|
|
@@ -185,11 +185,11 @@ export class Live {
|
|
|
185
185
|
// does not stretch by what a frame cost to draw, and a change that fell
|
|
186
186
|
// due while it was drawn is drawn at once (`Clock.at` fires now for a time
|
|
187
187
|
// already past).
|
|
188
|
-
_wake(held, { t,
|
|
188
|
+
_wake(held, { t, validUntil }) {
|
|
189
189
|
this._waking.get()?.stop();
|
|
190
190
|
this._waking.set(undefined);
|
|
191
191
|
const rate = t + this._rate.interval;
|
|
192
|
-
const at =
|
|
192
|
+
const at = validUntil <= t ? rate : Math.min(validUntil, rate);
|
|
193
193
|
if (!this._autoRefresh)
|
|
194
194
|
return;
|
|
195
195
|
// No caller is on the stack to run `stop()` for a frame that throws
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { linkHref, normalizeLinkText } from "./markdown-url.js";
|
|
15
15
|
import { PY_WHITESPACE, pyStrip } from "./python-space.js";
|
|
16
|
-
import {
|
|
16
|
+
import { namedCharacterReference } from "./html-entities.js";
|
|
17
17
|
import { pattern } from "../core/pattern.js";
|
|
18
18
|
/** A line of the source as the top level holds it. */
|
|
19
19
|
function sourceLine(text) {
|
|
@@ -807,7 +807,7 @@ function referenceAt(text, i) {
|
|
|
807
807
|
const named = matchAt(NAMED_REFERENCE, text, i);
|
|
808
808
|
if (!named)
|
|
809
809
|
return undefined;
|
|
810
|
-
const chars =
|
|
810
|
+
const chars = namedCharacterReference(named[1]);
|
|
811
811
|
return chars === undefined ? undefined : { kind: "text", text: chars, end: i + named[0].length };
|
|
812
812
|
}
|
|
813
813
|
/**
|
|
@@ -821,7 +821,7 @@ function unescapeAll(text) {
|
|
|
821
821
|
if (escaped !== undefined)
|
|
822
822
|
return escaped;
|
|
823
823
|
const numeric = DESTINATION_NUMERIC.exec(whole);
|
|
824
|
-
const chars = numeric ? referencedCharacter(referencedCode(numeric[1])) :
|
|
824
|
+
const chars = numeric ? referencedCharacter(referencedCode(numeric[1])) : namedCharacterReference(whole.slice(1, -1));
|
|
825
825
|
return chars ?? whole;
|
|
826
826
|
});
|
|
827
827
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Panel — a bordered box that wraps content, with optional title and subtitle.
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { labeled } from "../core/orient.js";
|
|
5
5
|
import { cellLen, setCellSize, asCellCol, cellCount } from "../core/cells.js";
|
|
6
6
|
import { Segment } from "../core/segment.js";
|
|
7
7
|
import { NULL_STYLE } from "../core/style.js";
|
|
@@ -40,7 +40,7 @@ function borderTitle(label, options) {
|
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* The style of text set into a border — title, subtitle and accessory alike:
|
|
43
|
-
* its own laid over the border's, the one rule for "what
|
|
43
|
+
* its own laid over the border's, the one rule for "what color is the title
|
|
44
44
|
* text in". Laid over rather than in place of it, as Rich's `stylize_before`
|
|
45
45
|
* does, because the border's style carries the panel's own: a title that
|
|
46
46
|
* replaced it cut a hole in the panel's background on the top row. The text
|
|
@@ -243,7 +243,7 @@ export class Panel {
|
|
|
243
243
|
const corner = box.bottom.right.repeat(geometry.right);
|
|
244
244
|
const [close, afterAccessory] = accessoryText === "" ? [corner, ""] : ["", corner];
|
|
245
245
|
yield* borderRow(options, box.bottom, geometry, geometry.spanWidth - cellLen(accessoryText), this._subtitleLabel, subtitleStyle, border, close);
|
|
246
|
-
yield*
|
|
246
|
+
yield* labeled("", accessoryText, "", borderTextStyle(border, accessoryOwn), options.textOrder);
|
|
247
247
|
yield new Segment(afterAccessory, border);
|
|
248
248
|
yield Segment.line();
|
|
249
249
|
}
|
|
@@ -89,7 +89,7 @@ export declare class BarColumn implements ProgressColumn {
|
|
|
89
89
|
* toward, pulses, and a pulse draws no fill. Otherwise the bar is the
|
|
90
90
|
* task's `fill` drawn at the frame's time, every cell stamped with when the
|
|
91
91
|
* fill next moves, so a host draws while it eases and the bar asks for
|
|
92
|
-
* nothing once it lands. Its
|
|
92
|
+
* nothing once it lands. Its color is the task's: an ease that overshoots
|
|
93
93
|
* the total does not finish the bar, and one that dips back does not
|
|
94
94
|
* unfinish it.
|
|
95
95
|
*/
|
|
@@ -113,7 +113,7 @@ export class BarColumn {
|
|
|
113
113
|
* toward, pulses, and a pulse draws no fill. Otherwise the bar is the
|
|
114
114
|
* task's `fill` drawn at the frame's time, every cell stamped with when the
|
|
115
115
|
* fill next moves, so a host draws while it eases and the bar asks for
|
|
116
|
-
* nothing once it lands. Its
|
|
116
|
+
* nothing once it lands. Its color is the task's: an ease that overshoots
|
|
117
117
|
* the total does not finish the bar, and one that dips back does not
|
|
118
118
|
* unfinish it.
|
|
119
119
|
*/
|
|
@@ -44,7 +44,7 @@ export declare class ProgressBar implements Renderable, Measurable {
|
|
|
44
44
|
set finished(value: boolean | undefined);
|
|
45
45
|
render(options: RenderOptions): Iterable<Segment>;
|
|
46
46
|
/**
|
|
47
|
-
* The shimmer over this bar's back
|
|
47
|
+
* The shimmer over this bar's back color as `Effected` sees it drawn,
|
|
48
48
|
* toward `bar.pulse`. A bar has no words to keep legible, so its back takes
|
|
49
49
|
* the whole of the light.
|
|
50
50
|
*/
|
|
@@ -20,7 +20,7 @@ const HALF_BAR_LEFT = "╺";
|
|
|
20
20
|
*/
|
|
21
21
|
const PULSE_CURVE = { ...EFFECT_CURVES.shimmer, seconds: 5 };
|
|
22
22
|
const PULSE_REACH = 10;
|
|
23
|
-
/** Rich's pulse back where the back style names no
|
|
23
|
+
/** Rich's pulse back where the back style names no color. */
|
|
24
24
|
const PULSE_BACK = ColorSpec.fromRgba(new ColorRgba(0, 0, 0));
|
|
25
25
|
export class ProgressBar {
|
|
26
26
|
// Rich's ProgressBar is updated after it is built: `bar.completed = n`.
|
|
@@ -70,11 +70,11 @@ export class ProgressBar {
|
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
const depth = options.colorSystem ?? ColorDepth.TRUECOLOR;
|
|
73
|
-
// Rich's pulse resolves its
|
|
73
|
+
// Rich's pulse resolves its colors on the terminal a depth assumes, as
|
|
74
74
|
// `get_truecolor` does with no theme; so does this with none named.
|
|
75
75
|
const terminal = resolveTerminal(options.terminal, depth);
|
|
76
|
-
// Rich writes the pulse's back as a
|
|
77
|
-
// back style names none, so the light always has the bar's
|
|
76
|
+
// Rich writes the pulse's back as a color of its own, black where the
|
|
77
|
+
// back style names none, so the light always has the bar's color to fall
|
|
78
78
|
// on: one the terminal supplies takes no light.
|
|
79
79
|
const style = getStyle(options, this.style);
|
|
80
80
|
const ink = style.color?.isDefault === false ? style.color : ColorSpec.fromRgba((style.color ?? PULSE_BACK).getTruecolor(terminal, true));
|
|
@@ -85,7 +85,7 @@ export class ProgressBar {
|
|
|
85
85
|
yield* render(new Effected(track, this.pulseEffect(options, back), { key: "progress-bar" }), options);
|
|
86
86
|
}
|
|
87
87
|
/**
|
|
88
|
-
* The shimmer over this bar's back
|
|
88
|
+
* The shimmer over this bar's back color as `Effected` sees it drawn,
|
|
89
89
|
* toward `bar.pulse`. A bar has no words to keep legible, so its back takes
|
|
90
90
|
* the whole of the light.
|
|
91
91
|
*/
|
|
@@ -117,7 +117,7 @@ export class ProgressBar {
|
|
|
117
117
|
yield new Segment(bar.repeat(barCount), fillStyle);
|
|
118
118
|
if (halfBarCount)
|
|
119
119
|
yield new Segment(drawable(options, HALF_BAR_RIGHT, " "), fillStyle);
|
|
120
|
-
// The back is drawn in
|
|
120
|
+
// The back is drawn in color alone, so an output with none leaves it blank.
|
|
121
121
|
if (options.colorSystem === null)
|
|
122
122
|
return;
|
|
123
123
|
let remaining = width - barCount - halfBarCount;
|
|
@@ -29,7 +29,7 @@ import { RichText } from "../core/text.js";
|
|
|
29
29
|
* on, and resolves with the raw user response. Implementations decide where
|
|
30
30
|
* the input comes from (stdin readline, network, in-memory queue, etc.); the
|
|
31
31
|
* console is what the prompt is drawn with, as Rich's `Console.input` draws
|
|
32
|
-
* it — its theme, its
|
|
32
|
+
* it — its theme, its colors, the target it writes to.
|
|
33
33
|
*
|
|
34
34
|
* [LAW:effects-at-boundaries] The prompt arrives as a `RichText`, not bytes:
|
|
35
35
|
* encoding it is the console's job, and the console arrives with it.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* [LAW:one-type-per-behavior] A marquee, a scroll and a slide are one window
|
|
7
7
|
* and differ only in the motion handed in: the offset along each axis is an
|
|
8
|
-
* `Animation<number>`, so a marquee is a looping `
|
|
8
|
+
* `Animation<number>`, so a marquee is a looping `WrapMode` scaled to the span
|
|
9
9
|
* it crosses and a slide-in is a `tween` to 0, and when the window next
|
|
10
10
|
* changes is `Animation.all`'s answer over the two. Nothing here knows which
|
|
11
11
|
* one it is drawing.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* [LAW:one-type-per-behavior] A marquee, a scroll and a slide are one window
|
|
7
7
|
* and differ only in the motion handed in: the offset along each axis is an
|
|
8
|
-
* `Animation<number>`, so a marquee is a looping `
|
|
8
|
+
* `Animation<number>`, so a marquee is a looping `WrapMode` scaled to the span
|
|
9
9
|
* it crosses and a slide-in is a `tween` to 0, and when the window next
|
|
10
10
|
* changes is `Animation.all`'s answer over the two. Nothing here knows which
|
|
11
11
|
* one it is drawing.
|
|
@@ -91,8 +91,8 @@ class ScrollFrame {
|
|
|
91
91
|
// [LAW:one-source-of-truth] What the window shows is cut from the whole content, so it may change
|
|
92
92
|
// when anything in the content does — a row above the slot entering pushes every row down, and run
|
|
93
93
|
// backwards, leaving it pulls them up. The cut throws away the cells that hold rode on, so it is
|
|
94
|
-
// told to the frame (`RenderOptions.
|
|
95
|
-
options.
|
|
94
|
+
// told to the frame (`RenderOptions.onValidity`).
|
|
95
|
+
options.onValidity?.({ validFrom: Segment.validFrom(drawn), validUntil: Segment.validUntil(drawn) });
|
|
96
96
|
for (let r = 0; r < this.height; r++) {
|
|
97
97
|
const line = lines[this.row + r] ?? [];
|
|
98
98
|
const shown = Segment.divide(line, [start, start + width - blank])[1] ?? [];
|
|
@@ -75,8 +75,8 @@ export declare class Spinner implements Animation<Renderable & Measurable> {
|
|
|
75
75
|
private readonly _ascii;
|
|
76
76
|
/**
|
|
77
77
|
* The spinner drawn at the frame's time, its cells saying the hold it is in
|
|
78
|
-
* on the host's clock (`
|
|
79
|
-
* draws, where `
|
|
78
|
+
* on the host's clock (`stampValidityFrame`) — exactly, for the frames the output
|
|
79
|
+
* draws, where `validUntil` must answer for both. Under reduced motion it
|
|
80
80
|
* is the spinner reduced, which never turns (`shownAt`).
|
|
81
81
|
*/
|
|
82
82
|
private readonly _placed;
|
|
@@ -109,9 +109,9 @@ export declare class Spinner implements Animation<Renderable & Measurable> {
|
|
|
109
109
|
* output keeps its own interval. An early answer, on the output that draws
|
|
110
110
|
* the other one, which the contract allows; the drawn cells carry the exact one.
|
|
111
111
|
*/
|
|
112
|
-
|
|
112
|
+
validUntil(t: number): number;
|
|
113
113
|
/** When the spinner drawn at `t` began to be drawn: the later of its two sequences' answers, by the same argument. */
|
|
114
|
-
|
|
114
|
+
validFrom(t: number): number;
|
|
115
115
|
private _render;
|
|
116
116
|
/**
|
|
117
117
|
* The frame in progress and the label as one text, as Rich's
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
* frame forever, which a paused timeline is and a rate is not, and the
|
|
47
47
|
* timeline refuses it.
|
|
48
48
|
*/
|
|
49
|
-
import { Animation, frameTimeOf,
|
|
49
|
+
import { Animation, frameTimeOf, validityOf, shownAt, stampValidityFrame } from "../core/animation.js";
|
|
50
50
|
import { Segment } from "../core/segment.js";
|
|
51
51
|
import { NULL_STYLE } from "../core/style.js";
|
|
52
52
|
import { RichText } from "../core/text.js";
|
|
@@ -88,8 +88,8 @@ export class Spinner {
|
|
|
88
88
|
_ascii;
|
|
89
89
|
/**
|
|
90
90
|
* The spinner drawn at the frame's time, its cells saying the hold it is in
|
|
91
|
-
* on the host's clock (`
|
|
92
|
-
* draws, where `
|
|
91
|
+
* on the host's clock (`stampValidityFrame`) — exactly, for the frames the output
|
|
92
|
+
* draws, where `validUntil` must answer for both. Under reduced motion it
|
|
93
93
|
* is the spinner reduced, which never turns (`shownAt`).
|
|
94
94
|
*/
|
|
95
95
|
_placed;
|
|
@@ -113,7 +113,7 @@ export class Spinner {
|
|
|
113
113
|
this._placed = this._frame((played, options) => {
|
|
114
114
|
const t = frameTimeOf(options);
|
|
115
115
|
const shown = shownAt(played, t, options);
|
|
116
|
-
return { value: shown.value,
|
|
116
|
+
return { value: shown.value, validity: validityOf(shown, t) };
|
|
117
117
|
});
|
|
118
118
|
}
|
|
119
119
|
get frames() {
|
|
@@ -150,9 +150,9 @@ export class Spinner {
|
|
|
150
150
|
const drawn = (options) => drawable(options, this._named, this._ascii, sequenceGlyphs);
|
|
151
151
|
return {
|
|
152
152
|
render: (options) => {
|
|
153
|
-
const { value,
|
|
153
|
+
const { value, validity } = choose(drawn(options).played, options);
|
|
154
154
|
const segments = this._render(value, options);
|
|
155
|
-
return
|
|
155
|
+
return validity === undefined ? segments : stampValidityFrame(segments, validity);
|
|
156
156
|
},
|
|
157
157
|
// Measured at the frames' one width, the widest frame's, so a column
|
|
158
158
|
// holding it never narrows as it turns, and never offered less than
|
|
@@ -172,12 +172,12 @@ export class Spinner {
|
|
|
172
172
|
* output keeps its own interval. An early answer, on the output that draws
|
|
173
173
|
* the other one, which the contract allows; the drawn cells carry the exact one.
|
|
174
174
|
*/
|
|
175
|
-
|
|
176
|
-
return Math.min(this._named.played.
|
|
175
|
+
validUntil(t) {
|
|
176
|
+
return Math.min(this._named.played.validUntil(t), this._ascii.played.validUntil(t));
|
|
177
177
|
}
|
|
178
178
|
/** When the spinner drawn at `t` began to be drawn: the later of its two sequences' answers, by the same argument. */
|
|
179
|
-
|
|
180
|
-
return Math.max(this._named.played.
|
|
179
|
+
validFrom(t) {
|
|
180
|
+
return Math.max(this._named.played.validFrom(t), this._ascii.played.validFrom(t));
|
|
181
181
|
}
|
|
182
182
|
*_render(frame, options) {
|
|
183
183
|
yield* render(this._line(frame, options), options);
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Syntax — renders source code with basic syntax highlighting.
|
|
3
3
|
* Uses built-in tokenization (no external dependency).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Colors are names in the console's theme (`syntax.keyword`,
|
|
6
6
|
* `syntax.line_number`, …), not a per-instance palette: a theme is how every
|
|
7
7
|
* other renderable here is restyled, and a second styling vocabulary on this
|
|
8
|
-
* one class would be a second answer to "what
|
|
8
|
+
* one class would be a second answer to "what color is a keyword".
|
|
9
9
|
*/
|
|
10
10
|
import { Segment } from "../core/segment.js";
|
|
11
11
|
import { type Measurable, type Renderable, type RenderOptions } from "../core/protocol.js";
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Syntax — renders source code with basic syntax highlighting.
|
|
3
3
|
* Uses built-in tokenization (no external dependency).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Colors are names in the console's theme (`syntax.keyword`,
|
|
6
6
|
* `syntax.line_number`, …), not a per-instance palette: a theme is how every
|
|
7
7
|
* other renderable here is restyled, and a second styling vocabulary on this
|
|
8
|
-
* one class would be a second answer to "what
|
|
8
|
+
* one class would be a second answer to "what color is a keyword".
|
|
9
9
|
*/
|
|
10
10
|
import { escaped } from "../core/bidi.js";
|
|
11
11
|
import { cellLen, expandTabs, parseTabSize, unicodeEscape } from "../core/cells.js";
|
|
@@ -6,7 +6,7 @@ import { Segment } from "../core/segment.js";
|
|
|
6
6
|
import { NULL_STYLE } from "../core/style.js";
|
|
7
7
|
import { HEAVY_HEAD } from "../core/box.js";
|
|
8
8
|
import { RichText } from "../core/text.js";
|
|
9
|
-
import { EmbeddedText, embed,
|
|
9
|
+
import { EmbeddedText, embed, mounted } from "./embed.js";
|
|
10
10
|
import { Padding, normalizePadding } from "./padding.js";
|
|
11
11
|
import { exactWeights, ratioDistribute, ratioReduce } from "./ratio.js";
|
|
12
12
|
import { getStyle, render, stackedHeight, withBoundedWidth, withCellWidth } from "../core/protocol.js";
|
|
@@ -367,9 +367,9 @@ export class Table {
|
|
|
367
367
|
// An empty title draws no row, as the reference's `if self.title` draws
|
|
368
368
|
// none; markup that styles nothing is a title, and draws a blank one.
|
|
369
369
|
const titleVal = options?.title;
|
|
370
|
-
this._title =
|
|
370
|
+
this._title = mounted(titleVal) ? new EmbeddedText(titleVal) : undefined;
|
|
371
371
|
const captionVal = options?.caption;
|
|
372
|
-
this._caption =
|
|
372
|
+
this._caption = mounted(captionVal) ? new EmbeddedText(captionVal) : undefined;
|
|
373
373
|
// A declared width is the table's size, not a ceiling on it: the
|
|
374
374
|
// reference's `expand` is `self._expand or self.width is not None`, and a
|
|
375
375
|
// port that sized to content inside it drew Rich code narrower than Rich.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* an inspector session pausing on exceptions — would have to pause on every
|
|
14
14
|
* throw, caught ones included, to serve `new Traceback(caughtError)`, and it
|
|
15
15
|
* cannot exist in a browser at all. Nor is there a `width` or `theme`: those
|
|
16
|
-
* sized and
|
|
16
|
+
* sized and colored a source-code excerpt this renderer does not produce.
|
|
17
17
|
*/
|
|
18
18
|
import { Segment } from "../core/segment.js";
|
|
19
19
|
import { type Renderable, type RenderOptions } from "../core/protocol.js";
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* an inspector session pausing on exceptions — would have to pause on every
|
|
14
14
|
* throw, caught ones included, to serve `new Traceback(caughtError)`, and it
|
|
15
15
|
* cannot exist in a browser at all. Nor is there a `width` or `theme`: those
|
|
16
|
-
* sized and
|
|
16
|
+
* sized and colored a source-code excerpt this renderer does not produce.
|
|
17
17
|
*/
|
|
18
18
|
import { Segment } from "../core/segment.js";
|
|
19
19
|
import { RichText } from "../core/text.js";
|
package/dist/renderables/tree.js
CHANGED
|
@@ -18,15 +18,15 @@ const ASCII_GUIDES = { fork: "+-- ", end: "`-- ", continue: "| ", space: "
|
|
|
18
18
|
* The guide attributes a glyph set stands for, switched off on the guide itself
|
|
19
19
|
* as Rich's `remove_guide_styles` does: a bold guide is drawn heavy, not bold.
|
|
20
20
|
*/
|
|
21
|
-
const REMOVE_GUIDE_STYLES = new Style({ bold: false,
|
|
21
|
+
const REMOVE_GUIDE_STYLES = new Style({ bold: false, doubleUnderline: false });
|
|
22
22
|
const guideGlyphs = (glyphs) => Object.values(glyphs).join("");
|
|
23
23
|
/**
|
|
24
24
|
* The glyphs a column of guide is drawn with, read off its resolved guide style
|
|
25
|
-
* as Rich does: heavy when bold, double when
|
|
25
|
+
* as Rich does: heavy when bold, double when doubleUnderline, light otherwise — and
|
|
26
26
|
* ASCII whenever the terminal cannot draw the chosen set.
|
|
27
27
|
*/
|
|
28
28
|
function glyphsFor(options, style) {
|
|
29
|
-
const weight = style.bold === true ? HEAVY_GUIDES : style.
|
|
29
|
+
const weight = style.bold === true ? HEAVY_GUIDES : style.doubleUnderline === true ? DOUBLE_GUIDES : LIGHT_GUIDES;
|
|
30
30
|
return drawable(options, weight, ASCII_GUIDES, guideGlyphs);
|
|
31
31
|
}
|
|
32
32
|
/** A row a label is known to draw, unread. */
|
|
@@ -29,36 +29,36 @@
|
|
|
29
29
|
* arguments on every evaluation, so the sequence is prepared on every one:
|
|
30
30
|
* a template has nowhere to keep it, and keeping it here would be the memo
|
|
31
31
|
* keyed on the arguments that `FrameSequence` is instead of. `stepped <seconds>
|
|
32
|
-
* <color> <seconds> <color> …` is the
|
|
33
|
-
*
|
|
34
|
-
* nests where a
|
|
32
|
+
* <color> <seconds> <color> …` is the color in progress at the moment, a
|
|
33
|
+
* color value like every color function's (`./color-funcs.ts`), so it
|
|
34
|
+
* nests where a color goes — `fg (stepped …)`, `ensureContrast (stepped …) $bg
|
|
35
35
|
* 4.5` — and the ground it must read on is the template's to name, as it
|
|
36
|
-
* is for any
|
|
36
|
+
* is for any color. Either argument list is one float/value cycle end to
|
|
37
37
|
* end, so the engine's `alternating` gate types every slot and lifts each
|
|
38
38
|
* string frame to a fragment; the pairing — a trailing hold with no frame or
|
|
39
|
-
*
|
|
39
|
+
* color — is parsed in `pairs`, once. [LAW:types-are-the-program]
|
|
40
40
|
*
|
|
41
41
|
* The rest start at a moment the template names, on the timeline's clock —
|
|
42
42
|
* a field of the host's state, the moment a value changed — and each is the
|
|
43
43
|
* animation `Timeline.play(start)` runs, so a start is a timeline like any
|
|
44
44
|
* other and nothing here offsets a time by hand. `tween <seconds> <ease>
|
|
45
45
|
* <start> <from> <to>` is a number eased from one value to another and held
|
|
46
|
-
* (`core/tween.ts`), its ease spelled by name (`
|
|
46
|
+
* (`core/tween.ts`), its ease spelled by name (`parseEasing`); `loop <seconds>
|
|
47
47
|
* <start>` is the way through a period, 0 to 1 and round again — two
|
|
48
48
|
* cells started a step apart are a stagger. Each is a number, so it goes
|
|
49
|
-
* wherever a number goes: a
|
|
49
|
+
* wherever a number goes: a color tween is `ramp (tween …) "linear" 0 $from
|
|
50
50
|
* 1 $to` and a ramp scrolling is `ramp (loop …) …`, because `ColorRamp` is
|
|
51
|
-
* the one place two
|
|
51
|
+
* the one place two colors are blended and a color tween is a two-stop
|
|
52
52
|
* ramp read over time (`ColorRamp.over`). [LAW:one-source-of-truth] A
|
|
53
53
|
* second blender here would be a second answer to what lies between two
|
|
54
|
-
*
|
|
54
|
+
* colors. `glyphs <name> <start> <fragment>` is the fragment through a
|
|
55
55
|
* glyph effect from the catalogue (`GLYPH_EFFECT_CATALOGUE`), at its
|
|
56
56
|
* defaults, before any render (`reglyphText`). Every argument list is an
|
|
57
57
|
* exact arity of typed slots, so a slot of the wrong kind fails at the gate.
|
|
58
58
|
*
|
|
59
59
|
* Every function says when what it drew changes, so a host paints a
|
|
60
60
|
* template while it moves and not after — and says it only for what the
|
|
61
|
-
* output depends on. A number or a
|
|
61
|
+
* output depends on. A number or a color has no cells to carry a hold, and
|
|
62
62
|
* a fragment's cells lose theirs the moment it is flattened (`printf "%s"`),
|
|
63
63
|
* so no function stamps cells or tells the frame itself. Each marks its
|
|
64
64
|
* return with the hold its value is in (`marked`, the engine's evaluation
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
* the output depends on it. `emitted` is where a template's cells take a
|
|
68
68
|
* hold: every fragment the template emits, stamped with the holds of the
|
|
69
69
|
* marked values its action read. `decided` is the route for a hold no cell
|
|
70
|
-
* can carry, told to the frame (`TemplateFrame.
|
|
70
|
+
* can carry, told to the frame (`TemplateFrame.onValidity`): a mark an
|
|
71
71
|
* `if`/`with`/`range` consumed, whichever arm it took, because the frame may
|
|
72
72
|
* show cells for it later and must say when without a cell to say it on, as
|
|
73
73
|
* a placed animation of no cells does (`placed`) — and, by the same rule, a
|
|
@@ -93,7 +93,7 @@ export interface AnimationOptions {
|
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
95
|
* The frame a template is evaluated for, in the fields a render's options
|
|
96
|
-
* carry under the same names: `time` in seconds, `
|
|
96
|
+
* carry under the same names: `time` in seconds, `onValidity`, told the hold of
|
|
97
97
|
* an animated value the output may depend on with no cell to carry it — one
|
|
98
98
|
* a decision read, whichever arm it took, a writing function's input, a
|
|
99
99
|
* throwing action's (the engine's `decided`) — and the reader's preferences,
|
|
@@ -103,12 +103,12 @@ export interface AnimationOptions {
|
|
|
103
103
|
* [LAW:one-source-of-truth]
|
|
104
104
|
*
|
|
105
105
|
* `time` is on the clock `AnimationOptions.timeline` maps from, and
|
|
106
|
-
* `
|
|
106
|
+
* `onValidity` hears on that clock. A host outside rich-js hands its own clock's
|
|
107
107
|
* time. Inside a rich-js frame the time is the frame's, which its host's
|
|
108
108
|
* timeline has already mapped, so a template drawn there registers no
|
|
109
109
|
* `timeline` and is handed `templateFrame(options)`.
|
|
110
110
|
*/
|
|
111
|
-
export interface TemplateFrame extends Pick<RenderOptions, "
|
|
111
|
+
export interface TemplateFrame extends Pick<RenderOptions, "onValidity" | "reducedMotion" | "asciiOnly"> {
|
|
112
112
|
readonly time: number;
|
|
113
113
|
}
|
|
114
114
|
/** The frame a renderable is drawn in, as the frame a template it evaluates there is drawn for. */
|