@jrichman/ink 6.5.1-beta.0 → 6.5.1-beta.2
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/build/components/App.js +0 -3
- package/build/components/App.js.map +1 -1
- package/build/components/AppContext.js +0 -1
- package/build/components/AppContext.js.map +1 -1
- package/build/components/FocusContext.js +0 -1
- package/build/components/FocusContext.js.map +1 -1
- package/build/components/Static.js +1 -1
- package/build/components/Static.js.map +1 -1
- package/build/components/StaticRender.js +9 -1
- package/build/components/StaticRender.js.map +1 -1
- package/build/components/StderrContext.js +0 -1
- package/build/components/StderrContext.js.map +1 -1
- package/build/components/StdinContext.js +0 -3
- package/build/components/StdinContext.js.map +1 -1
- package/build/components/StdoutContext.js +0 -1
- package/build/components/StdoutContext.js.map +1 -1
- package/build/data-limited-lru-map.d.ts +1 -0
- package/build/data-limited-lru-map.js +4 -0
- package/build/data-limited-lru-map.js.map +1 -1
- package/build/devtools.js +0 -3
- package/build/devtools.js.map +1 -1
- package/build/dom.d.ts +7 -5
- package/build/dom.js +6 -2
- package/build/dom.js.map +1 -1
- package/build/hooks/use-input.js +0 -1
- package/build/hooks/use-input.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/ink.d.ts +3 -1
- package/build/ink.js +12 -4
- package/build/ink.js.map +1 -1
- package/build/log-update.d.ts +2 -2
- package/build/log-update.js +4 -4
- package/build/log-update.js.map +1 -1
- package/build/measure-element.js +15 -45
- package/build/measure-element.js.map +1 -1
- package/build/measure-text.d.ts +11 -23
- package/build/measure-text.js +112 -136
- package/build/measure-text.js.map +1 -1
- package/build/output.d.ts +15 -14
- package/build/output.js +60 -87
- package/build/output.js.map +1 -1
- package/build/reconciler.js +23 -7
- package/build/reconciler.js.map +1 -1
- package/build/render-cached.d.ts +2 -1
- package/build/render-cached.js +6 -3
- package/build/render-cached.js.map +1 -1
- package/build/render-container.d.ts +2 -1
- package/build/render-container.js +4 -1
- package/build/render-container.js.map +1 -1
- package/build/render-node-to-output.d.ts +3 -1
- package/build/render-node-to-output.js +10 -2
- package/build/render-node-to-output.js.map +1 -1
- package/build/render-scrollbar.d.ts +5 -3
- package/build/render-scrollbar.js +9 -10
- package/build/render-scrollbar.js.map +1 -1
- package/build/render-sticky.d.ts +5 -8
- package/build/render-sticky.js +4 -1
- package/build/render-sticky.js.map +1 -1
- package/build/render-text-node.d.ts +4 -8
- package/build/render-text-node.js +62 -44
- package/build/render-text-node.js.map +1 -1
- package/build/render.d.ts +3 -1
- package/build/render.js.map +1 -1
- package/build/renderer.d.ts +3 -2
- package/build/renderer.js +7 -5
- package/build/renderer.js.map +1 -1
- package/build/replay.d.ts +1 -2
- package/build/replay.js +24 -34
- package/build/replay.js.map +1 -1
- package/build/selection.d.ts +3 -3
- package/build/selection.js +29 -36
- package/build/selection.js.map +1 -1
- package/build/serialization.d.ts +3 -6
- package/build/serialization.js +53 -98
- package/build/serialization.js.map +1 -1
- package/build/styled-line.d.ts +73 -0
- package/build/styled-line.js +412 -0
- package/build/styled-line.js.map +1 -0
- package/build/styled-lines.d.ts +29 -0
- package/build/styled-lines.js +110 -0
- package/build/styled-lines.js.map +1 -0
- package/build/styles.js.map +1 -1
- package/build/terminal-buffer.d.ts +4 -2
- package/build/terminal-buffer.js +33 -7
- package/build/terminal-buffer.js.map +1 -1
- package/build/text-wrap.d.ts +6 -6
- package/build/text-wrap.js +66 -50
- package/build/text-wrap.js.map +1 -1
- package/build/tokenize.d.ts +47 -0
- package/build/tokenize.js +419 -0
- package/build/tokenize.js.map +1 -0
- package/build/worker/canvas.d.ts +6 -16
- package/build/worker/canvas.js +10 -25
- package/build/worker/canvas.js.map +1 -1
- package/build/worker/compositor.js +27 -19
- package/build/worker/compositor.js.map +1 -1
- package/build/worker/render-worker.js +27 -19
- package/build/worker/render-worker.js.map +1 -1
- package/build/worker/scene-manager.js +12 -3
- package/build/worker/scene-manager.js.map +1 -1
- package/build/worker/terminal-writer.d.ts +4 -4
- package/build/worker/terminal-writer.js +36 -52
- package/build/worker/terminal-writer.js.map +1 -1
- package/build/wrap-text.d.ts +6 -0
- package/build/wrap-text.js +120 -0
- package/build/wrap-text.js.map +1 -0
- package/package.json +15 -4
package/build/measure-text.js
CHANGED
|
@@ -1,126 +1,115 @@
|
|
|
1
1
|
import stringWidth from 'string-width';
|
|
2
|
-
import { tokenize,
|
|
2
|
+
import { tokenize, styledLineFromTokens } from './tokenize.js';
|
|
3
|
+
import { StyledLine } from './styled-line.js';
|
|
3
4
|
import { DataLimitedLruMap } from './data-limited-lru-map.js';
|
|
4
5
|
const defaultStringWidth = stringWidth;
|
|
5
6
|
let currentStringWidth = defaultStringWidth;
|
|
6
7
|
// This cache must be cleared each time the string width function is changed.
|
|
7
|
-
// The strings passed as input are single characters so there is no need to
|
|
8
|
-
// limit the size of the cache as there are only a limited number of valid
|
|
9
|
-
// characters.
|
|
10
8
|
const widthCache = new Map();
|
|
11
9
|
// This cache can persist for the lifetime of the application.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const toStyledCharactersCache = new DataLimitedLruMap(2000, 100_000);
|
|
11
|
+
let toStyledCharactersCacheEnabled = true;
|
|
12
|
+
export function setEnableToStyledCharactersCache(enabled) {
|
|
13
|
+
toStyledCharactersCacheEnabled = enabled;
|
|
14
|
+
if (!enabled) {
|
|
15
|
+
toStyledCharactersCache.clear();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
16
18
|
export function setStringWidthFunction(fn) {
|
|
17
19
|
currentStringWidth = fn;
|
|
18
|
-
// Clear the width cache to avoid stale values.
|
|
19
20
|
clearStringWidthCache();
|
|
20
21
|
}
|
|
21
22
|
export function clearStringWidthCache() {
|
|
22
23
|
widthCache.clear();
|
|
23
24
|
}
|
|
25
|
+
export function clearToStyledCharactersCache() {
|
|
26
|
+
toStyledCharactersCache.clear();
|
|
27
|
+
}
|
|
24
28
|
export function toStyledCharacters(text) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
if (toStyledCharactersCacheEnabled) {
|
|
30
|
+
const cached = toStyledCharactersCache.get(text);
|
|
31
|
+
if (cached !== undefined) {
|
|
32
|
+
return cached;
|
|
33
|
+
}
|
|
28
34
|
}
|
|
29
35
|
const tokens = tokenize(text);
|
|
30
|
-
const characters =
|
|
31
|
-
const
|
|
36
|
+
const characters = styledLineFromTokens(tokens);
|
|
37
|
+
const combinedLine = new StyledLine();
|
|
32
38
|
for (let i = 0; i < characters.length; i++) {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
const value = characters.getValue(i);
|
|
40
|
+
const formatFlags = characters.getFormatFlags(i);
|
|
41
|
+
const fgColor = characters.getFgColor(i);
|
|
42
|
+
const bgColor = characters.getBgColor(i);
|
|
43
|
+
const link = characters.getLink(i);
|
|
44
|
+
if (value === '\t') {
|
|
45
|
+
for (let j = 0; j < 4; j++) {
|
|
46
|
+
combinedLine.pushChar(' ', formatFlags, fgColor, bgColor, link);
|
|
47
|
+
}
|
|
40
48
|
continue;
|
|
41
49
|
}
|
|
42
|
-
if (
|
|
50
|
+
if (value === '\b') {
|
|
43
51
|
continue;
|
|
44
52
|
}
|
|
45
|
-
let
|
|
53
|
+
let combinedValue = value;
|
|
46
54
|
let isCombined = false;
|
|
47
|
-
const firstCodePoint =
|
|
55
|
+
const firstCodePoint = combinedValue.codePointAt(0);
|
|
48
56
|
// 1. Regional Indicators (Flags)
|
|
49
|
-
// These combine in pairs.
|
|
50
|
-
// See: https://en.wikipedia.org/wiki/Regional_indicator_symbol
|
|
51
57
|
if (firstCodePoint &&
|
|
52
58
|
firstCodePoint >= 0x1_f1_e6 &&
|
|
53
59
|
firstCodePoint <= 0x1_f1_ff &&
|
|
54
60
|
i + 1 < characters.length) {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
combinedCharacters.push({ ...character, value });
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
61
|
+
const nextValue = characters.getValue(i + 1);
|
|
62
|
+
const nextFirstCodePoint = nextValue.codePointAt(0);
|
|
63
|
+
if (nextFirstCodePoint &&
|
|
64
|
+
nextFirstCodePoint >= 0x1_f1_e6 &&
|
|
65
|
+
nextFirstCodePoint <= 0x1_f1_ff) {
|
|
66
|
+
combinedValue += nextValue;
|
|
67
|
+
i++;
|
|
68
|
+
isCombined = true;
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
// Merge with previous character
|
|
98
|
-
value += nextCharacter.value;
|
|
99
|
-
i++; // Consume next character.
|
|
100
|
-
isCombined = true;
|
|
101
|
-
// If it was a ZWJ, also consume the character after it.
|
|
102
|
-
if (isZeroWidthJoiner && i + 1 < characters.length) {
|
|
103
|
-
const characterAfterZwj = characters[i + 1];
|
|
104
|
-
if (characterAfterZwj) {
|
|
105
|
-
value += characterAfterZwj.value;
|
|
106
|
-
i++; // Consume character after ZWJ.
|
|
71
|
+
if (!isCombined) {
|
|
72
|
+
// 2. Other combining characters
|
|
73
|
+
while (i + 1 < characters.length) {
|
|
74
|
+
const nextValue = characters.getValue(i + 1);
|
|
75
|
+
if (!nextValue)
|
|
76
|
+
break;
|
|
77
|
+
const nextFirstCodePoint = nextValue.codePointAt(0);
|
|
78
|
+
if (!nextFirstCodePoint)
|
|
79
|
+
break;
|
|
80
|
+
const isUnicodeMark = /\p{Mark}/u.test(nextValue);
|
|
81
|
+
const isSkinToneModifier = nextFirstCodePoint >= 0x1_f3_fb && nextFirstCodePoint <= 0x1_f3_ff;
|
|
82
|
+
const isZeroWidthJoiner = nextFirstCodePoint === 0x20_0d;
|
|
83
|
+
const isTagsBlock = nextFirstCodePoint >= 0xe_00_00 && nextFirstCodePoint <= 0xe_00_7f;
|
|
84
|
+
const isCombining = isUnicodeMark ||
|
|
85
|
+
isSkinToneModifier ||
|
|
86
|
+
isZeroWidthJoiner ||
|
|
87
|
+
isTagsBlock;
|
|
88
|
+
if (!isCombining) {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
combinedValue += nextValue;
|
|
92
|
+
i++;
|
|
93
|
+
if (isZeroWidthJoiner && i + 1 < characters.length) {
|
|
94
|
+
const characterAfterZwj = characters.getValue(i + 1);
|
|
95
|
+
if (characterAfterZwj) {
|
|
96
|
+
combinedValue += characterAfterZwj;
|
|
97
|
+
i++;
|
|
98
|
+
}
|
|
107
99
|
}
|
|
108
100
|
}
|
|
109
101
|
}
|
|
110
|
-
|
|
111
|
-
combinedCharacters.push({ ...character, value });
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
combinedCharacters.push(character);
|
|
115
|
-
}
|
|
102
|
+
combinedLine.pushChar(combinedValue, formatFlags, fgColor, bgColor, link);
|
|
116
103
|
}
|
|
117
|
-
|
|
118
|
-
|
|
104
|
+
if (toStyledCharactersCacheEnabled) {
|
|
105
|
+
toStyledCharactersCache.set(text, combinedLine);
|
|
106
|
+
}
|
|
107
|
+
return combinedLine;
|
|
119
108
|
}
|
|
120
|
-
export function styledCharsWidth(
|
|
109
|
+
export function styledCharsWidth(line) {
|
|
121
110
|
let length = 0;
|
|
122
|
-
for (
|
|
123
|
-
length += inkCharacterWidth(
|
|
111
|
+
for (let i = 0; i < line.length; i++) {
|
|
112
|
+
length += inkCharacterWidth(line.getValue(i));
|
|
124
113
|
}
|
|
125
114
|
return length;
|
|
126
115
|
}
|
|
@@ -134,27 +123,32 @@ export function inkCharacterWidth(text) {
|
|
|
134
123
|
calculatedWidth = currentStringWidth(text);
|
|
135
124
|
}
|
|
136
125
|
catch {
|
|
137
|
-
// Ignore errors and use default width of 1.
|
|
138
|
-
// We catch this result to avoid throwing exceptions repeatedly.
|
|
139
126
|
calculatedWidth = 1;
|
|
140
127
|
console.warn(`Failed to calculate string width for ${JSON.stringify(text)}`);
|
|
141
128
|
}
|
|
142
129
|
widthCache.set(text, calculatedWidth);
|
|
143
130
|
return calculatedWidth;
|
|
144
131
|
}
|
|
145
|
-
export function wordBreakStyledChars(
|
|
132
|
+
export function wordBreakStyledChars(line) {
|
|
146
133
|
const words = [];
|
|
147
|
-
let currentWord =
|
|
148
|
-
for (
|
|
149
|
-
|
|
134
|
+
let currentWord = new StyledLine();
|
|
135
|
+
for (let i = 0; i < line.length; i++) {
|
|
136
|
+
const val = line.getValue(i);
|
|
137
|
+
const flags = line.getFormatFlags(i);
|
|
138
|
+
const fg = line.getFgColor(i);
|
|
139
|
+
const bg = line.getBgColor(i);
|
|
140
|
+
const link = line.getLink(i);
|
|
141
|
+
if (val === '\n' || val === ' ') {
|
|
150
142
|
if (currentWord.length > 0) {
|
|
151
143
|
words.push(currentWord);
|
|
152
144
|
}
|
|
153
|
-
currentWord =
|
|
154
|
-
|
|
145
|
+
currentWord = new StyledLine();
|
|
146
|
+
const spaceLine = new StyledLine();
|
|
147
|
+
spaceLine.pushChar(val, flags, fg, bg, link);
|
|
148
|
+
words.push(spaceLine);
|
|
155
149
|
}
|
|
156
150
|
else {
|
|
157
|
-
currentWord.
|
|
151
|
+
currentWord.pushChar(val, flags, fg, bg, link);
|
|
158
152
|
}
|
|
159
153
|
}
|
|
160
154
|
if (currentWord.length > 0) {
|
|
@@ -162,14 +156,17 @@ export function wordBreakStyledChars(styledChars) {
|
|
|
162
156
|
}
|
|
163
157
|
return words;
|
|
164
158
|
}
|
|
165
|
-
export function splitStyledCharsByNewline(
|
|
166
|
-
const lines = [
|
|
167
|
-
for (
|
|
168
|
-
|
|
169
|
-
|
|
159
|
+
export function splitStyledCharsByNewline(line) {
|
|
160
|
+
const lines = [new StyledLine()];
|
|
161
|
+
for (let i = 0; i < line.length; i++) {
|
|
162
|
+
const val = line.getValue(i);
|
|
163
|
+
if (val === '\n') {
|
|
164
|
+
lines.push(new StyledLine());
|
|
170
165
|
}
|
|
171
166
|
else {
|
|
172
|
-
lines
|
|
167
|
+
lines
|
|
168
|
+
.at(-1)
|
|
169
|
+
.pushChar(val, line.getFormatFlags(i), line.getFgColor(i), line.getBgColor(i), line.getLink(i));
|
|
173
170
|
}
|
|
174
171
|
}
|
|
175
172
|
return lines;
|
|
@@ -181,56 +178,35 @@ export function widestLineFromStyledChars(lines) {
|
|
|
181
178
|
}
|
|
182
179
|
return maxWidth;
|
|
183
180
|
}
|
|
184
|
-
export function styledCharsToString(
|
|
185
|
-
|
|
186
|
-
for (const char of styledChars) {
|
|
187
|
-
result += char.value;
|
|
188
|
-
}
|
|
189
|
-
return result;
|
|
181
|
+
export function styledCharsToString(line) {
|
|
182
|
+
return line.getValues().join('');
|
|
190
183
|
}
|
|
191
|
-
export function measureStyledChars(
|
|
192
|
-
if (
|
|
193
|
-
return {
|
|
194
|
-
width: 0,
|
|
195
|
-
height: 0,
|
|
196
|
-
};
|
|
184
|
+
export function measureStyledChars(line) {
|
|
185
|
+
if (line.length === 0) {
|
|
186
|
+
return { width: 0, height: 0 };
|
|
197
187
|
}
|
|
198
|
-
const lines = splitStyledCharsByNewline(
|
|
188
|
+
const lines = splitStyledCharsByNewline(line);
|
|
199
189
|
const width = widestLineFromStyledChars(lines);
|
|
200
190
|
const height = lines.length;
|
|
201
|
-
|
|
202
|
-
return dimensions;
|
|
191
|
+
return { width, height };
|
|
203
192
|
}
|
|
204
|
-
|
|
205
|
-
* Calculate row and column position at a given character offset.
|
|
206
|
-
* This is the unified cursor position calculation logic used by both
|
|
207
|
-
* render-node-to-output.ts and output.ts.
|
|
208
|
-
*
|
|
209
|
-
* The character offset counting method matches CharOffsetMap used in
|
|
210
|
-
* selection.ts and squash-text-nodes.ts, ensuring consistent behavior
|
|
211
|
-
* between cursor positioning and text selection.
|
|
212
|
-
*
|
|
213
|
-
* Character counting rules:
|
|
214
|
-
* - Each StyledChar counts by its value.length (handles combining marks)
|
|
215
|
-
* - Newlines ('\n') advance row and reset column
|
|
216
|
-
* - Other characters add their visual width to column
|
|
217
|
-
*/
|
|
218
|
-
export function getPositionAtOffset(styledChars, targetOffset) {
|
|
193
|
+
export function getPositionAtOffset(line, targetOffset) {
|
|
219
194
|
let row = 0;
|
|
220
195
|
let col = 0;
|
|
221
196
|
let charCount = 0;
|
|
222
|
-
for (
|
|
197
|
+
for (let i = 0; i < line.length; i++) {
|
|
223
198
|
if (charCount >= targetOffset) {
|
|
224
199
|
break;
|
|
225
200
|
}
|
|
226
|
-
|
|
201
|
+
const val = line.getValue(i);
|
|
202
|
+
if (val === '\n') {
|
|
227
203
|
row++;
|
|
228
204
|
col = 0;
|
|
229
205
|
}
|
|
230
206
|
else {
|
|
231
|
-
col += inkCharacterWidth(
|
|
207
|
+
col += inkCharacterWidth(val);
|
|
232
208
|
}
|
|
233
|
-
charCount +=
|
|
209
|
+
charCount += val.length;
|
|
234
210
|
}
|
|
235
211
|
return { row, col };
|
|
236
212
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measure-text.js","sourceRoot":"","sources":["../src/measure-text.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,
|
|
1
|
+
{"version":3,"file":"measure-text.js","sourceRoot":"","sources":["../src/measure-text.ts"],"names":[],"mappings":"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"}
|
package/build/output.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type StyledChar } from '@alcalzone/ansi-tokenize';
|
|
2
1
|
import { type OutputTransformer } from './render-node-to-output.js';
|
|
3
2
|
import { type CursorPosition } from './log-update.js';
|
|
4
3
|
import { type StickyHeader, type DOMElement } from './dom.js';
|
|
@@ -9,12 +8,14 @@ Handles the positioning and saving of the output of each node in the tree. Also
|
|
|
9
8
|
|
|
10
9
|
Used to generate the final output of all nodes before writing it to actual output stream (e.g. stdout)
|
|
11
10
|
*/
|
|
12
|
-
|
|
11
|
+
import { StyledLine } from './styled-line.js';
|
|
12
|
+
export declare function clampCursorColumn(line: StyledLine, col: number): number;
|
|
13
13
|
type Options = {
|
|
14
14
|
width: number;
|
|
15
15
|
height: number;
|
|
16
16
|
node?: DOMElement;
|
|
17
17
|
id?: string | number;
|
|
18
|
+
trackSelection?: boolean;
|
|
18
19
|
};
|
|
19
20
|
type Clip = {
|
|
20
21
|
x1: number | undefined;
|
|
@@ -54,8 +55,8 @@ export type Region = {
|
|
|
54
55
|
y: number;
|
|
55
56
|
width: number;
|
|
56
57
|
height: number;
|
|
57
|
-
readonly lines:
|
|
58
|
-
readonly styledOutput:
|
|
58
|
+
readonly lines: readonly StyledLine[];
|
|
59
|
+
readonly styledOutput: readonly StyledLine[];
|
|
59
60
|
isScrollable: boolean;
|
|
60
61
|
isVerticallyScrollable?: boolean;
|
|
61
62
|
isHorizontallyScrollable?: boolean;
|
|
@@ -91,6 +92,12 @@ export type RegionNode = {
|
|
|
91
92
|
id: string | number;
|
|
92
93
|
children: RegionNode[];
|
|
93
94
|
};
|
|
95
|
+
export declare function treesEqual(a: RegionNode, b: RegionNode): boolean;
|
|
96
|
+
export type SerializedStickyHeader = Omit<StickyHeader, 'lines' | 'stuckLines' | 'styledOutput' | 'node'> & {
|
|
97
|
+
lines: Uint8Array;
|
|
98
|
+
stuckLines?: Uint8Array;
|
|
99
|
+
styledOutput: Uint8Array;
|
|
100
|
+
};
|
|
94
101
|
export type RegionUpdate = {
|
|
95
102
|
id: string | number;
|
|
96
103
|
x?: number;
|
|
@@ -113,7 +120,7 @@ export type RegionUpdate = {
|
|
|
113
120
|
opaque?: boolean;
|
|
114
121
|
borderTop?: number;
|
|
115
122
|
borderBottom?: number;
|
|
116
|
-
stickyHeaders?:
|
|
123
|
+
stickyHeaders?: SerializedStickyHeader[];
|
|
117
124
|
lines?: {
|
|
118
125
|
updates: Array<{
|
|
119
126
|
start: number;
|
|
@@ -151,6 +158,7 @@ export declare function copyRegionProperty<K extends (typeof regionLayoutPropert
|
|
|
151
158
|
export default class Output {
|
|
152
159
|
width: number;
|
|
153
160
|
height: number;
|
|
161
|
+
trackSelection: boolean;
|
|
154
162
|
root: Region;
|
|
155
163
|
private readonly activeRegionStack;
|
|
156
164
|
private readonly clips;
|
|
@@ -190,7 +198,7 @@ export default class Output {
|
|
|
190
198
|
}): void;
|
|
191
199
|
endChildRegion(): void;
|
|
192
200
|
addStickyHeader(header: StickyHeader): void;
|
|
193
|
-
write(x: number, y: number, items: string |
|
|
201
|
+
write(x: number, y: number, items: string | StyledLine, options: {
|
|
194
202
|
transformers: OutputTransformer[];
|
|
195
203
|
lineIndex?: number;
|
|
196
204
|
preserveBackgroundColor?: boolean;
|
|
@@ -202,7 +210,6 @@ export default class Output {
|
|
|
202
210
|
unclip(): void;
|
|
203
211
|
get(): Region;
|
|
204
212
|
addRegionTree(region: Region, x: number, y: number): void;
|
|
205
|
-
private cloneRegion;
|
|
206
213
|
private trimRegionLines;
|
|
207
214
|
private clampCursorPosition;
|
|
208
215
|
private initLines;
|
|
@@ -210,12 +217,6 @@ export default class Output {
|
|
|
210
217
|
private clearRange;
|
|
211
218
|
private clipChars;
|
|
212
219
|
}
|
|
213
|
-
/**
|
|
214
|
-
* Flattens a hierarchy of nested regions into a single 2D array of styled characters
|
|
215
|
-
* that represents the final visual output to be written to the terminal.
|
|
216
|
-
* This effectively renders the nested region tree (much like compositing layers
|
|
217
|
-
* in a web browser) into a single screen buffer.
|
|
218
|
-
*/
|
|
219
220
|
export declare function flattenRegion(root: Region, options?: {
|
|
220
221
|
context?: {
|
|
221
222
|
cursorPosition?: {
|
|
@@ -225,7 +226,7 @@ export declare function flattenRegion(root: Region, options?: {
|
|
|
225
226
|
};
|
|
226
227
|
skipScrollbars?: boolean;
|
|
227
228
|
skipStickyHeaders?: boolean;
|
|
228
|
-
}):
|
|
229
|
+
}): StyledLine[];
|
|
229
230
|
export declare const extractSelectableText: (spans: Array<{
|
|
230
231
|
y: number;
|
|
231
232
|
startX: number;
|