vterm.js 0.7.0 → 0.8.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 +5 -1
- package/dist/index.d.mts +18 -1
- package/dist/index.mjs +281 -243
- package/package.json +4 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/screen.ts
|
|
2
2
|
/** Default retained payload bound for one APC/DCS sequence (16 MiB of ASCII/base64). */
|
|
3
|
-
const DEFAULT_MAX_STRING_SEQUENCE_LENGTH =
|
|
3
|
+
const DEFAULT_MAX_STRING_SEQUENCE_LENGTH = 16777216;
|
|
4
4
|
/** Frozen sentinel for unwritten cells — never mutate, copy-on-write in writeChar(). */
|
|
5
5
|
const EMPTY_CELL = Object.freeze({
|
|
6
6
|
char: "",
|
|
@@ -58,7 +58,7 @@ const F_HIDDEN$1 = 64;
|
|
|
58
58
|
const F_BLINK$1 = 128;
|
|
59
59
|
const F_WIDE$1 = 256;
|
|
60
60
|
const UL_SHIFT$1 = 9;
|
|
61
|
-
const UL_MASK$1 =
|
|
61
|
+
const UL_MASK$1 = 3584;
|
|
62
62
|
const F_HAS_FG = 4096;
|
|
63
63
|
const F_HAS_BG = 8192;
|
|
64
64
|
const F_HAS_UL = 16384;
|
|
@@ -79,6 +79,17 @@ function underlineToBits(u) {
|
|
|
79
79
|
function bitsToUnderline(meta) {
|
|
80
80
|
return UL_STYLES[(meta & UL_MASK$1) >> UL_SHIFT$1] ?? "none";
|
|
81
81
|
}
|
|
82
|
+
/** Require an invariant-owned value and fail where the impossible state is first observed. */
|
|
83
|
+
function required(value, subject) {
|
|
84
|
+
if (value === null || value === void 0) throw new Error(`Missing ${subject}`);
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
/** Read a dense indexed value and fail at the violated invariant instead of propagating `undefined`. */
|
|
88
|
+
function itemAt(items, index, subject) {
|
|
89
|
+
const value = items[index];
|
|
90
|
+
if (value === void 0) throw new RangeError(`${subject}[${index}] is outside its ${items.length}-item range`);
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
82
93
|
/** Pack a color's 8-bit channels into a 24-bit `0xRRGGBB` word. */
|
|
83
94
|
function packRgb(c) {
|
|
84
95
|
return ((c.r & 255) << 16 | (c.g & 255) << 8 | c.b & 255) >>> 0;
|
|
@@ -110,7 +121,7 @@ function makePackedRow(width) {
|
|
|
110
121
|
let ulIdx = null;
|
|
111
122
|
let urlMap = null;
|
|
112
123
|
function setFg(col, c) {
|
|
113
|
-
if (fgRgb === null) {
|
|
124
|
+
if (fgRgb === null || fgIdx === null) {
|
|
114
125
|
fgRgb = new Uint32Array(width);
|
|
115
126
|
fgIdx = new Int16Array(width);
|
|
116
127
|
}
|
|
@@ -118,7 +129,7 @@ function makePackedRow(width) {
|
|
|
118
129
|
fgIdx[col] = c.index ?? -1;
|
|
119
130
|
}
|
|
120
131
|
function setBg(col, c) {
|
|
121
|
-
if (bgRgb === null) {
|
|
132
|
+
if (bgRgb === null || bgIdx === null) {
|
|
122
133
|
bgRgb = new Uint32Array(width);
|
|
123
134
|
bgIdx = new Int16Array(width);
|
|
124
135
|
}
|
|
@@ -126,7 +137,7 @@ function makePackedRow(width) {
|
|
|
126
137
|
bgIdx[col] = c.index ?? -1;
|
|
127
138
|
}
|
|
128
139
|
function setUl(col, c) {
|
|
129
|
-
if (ulRgb === null) {
|
|
140
|
+
if (ulRgb === null || ulIdx === null) {
|
|
130
141
|
ulRgb = new Uint32Array(width);
|
|
131
142
|
ulIdx = new Int16Array(width);
|
|
132
143
|
}
|
|
@@ -211,27 +222,27 @@ function makePackedRow(width) {
|
|
|
211
222
|
} else meta[col] = 0;
|
|
212
223
|
},
|
|
213
224
|
widen(col) {
|
|
214
|
-
meta[col] = (meta
|
|
225
|
+
meta[col] = (itemAt(meta, col, "packed row metadata") | F_WIDE$1) >>> 0;
|
|
215
226
|
if (col + 1 < width) row.setEmpty(col + 1);
|
|
216
227
|
},
|
|
217
228
|
appendChar(col, ch) {
|
|
218
|
-
chars[col] = chars
|
|
229
|
+
chars[col] = itemAt(chars, col, "packed row characters") + ch;
|
|
219
230
|
},
|
|
220
231
|
copyCellFrom(col, src, srcCol) {
|
|
221
232
|
row.setCellRaw(col, src.getCellRaw(srcCol));
|
|
222
233
|
},
|
|
223
234
|
getCellRaw(col) {
|
|
224
|
-
const m = meta
|
|
235
|
+
const m = itemAt(meta, col, "packed row metadata");
|
|
225
236
|
if (m === 0 && chars[col] === "") return emptyCell();
|
|
226
237
|
return {
|
|
227
|
-
char: chars
|
|
228
|
-
fg: m & F_HAS_FG ? unpackColor(fgRgb
|
|
229
|
-
bg: m & F_HAS_BG ? unpackColor(bgRgb
|
|
238
|
+
char: itemAt(chars, col, "packed row characters"),
|
|
239
|
+
fg: m & F_HAS_FG ? unpackColor(itemAt(required(fgRgb, "foreground color plane"), col, "foreground color plane"), itemAt(required(fgIdx, "foreground color index plane"), col, "foreground color index plane")) : null,
|
|
240
|
+
bg: m & F_HAS_BG ? unpackColor(itemAt(required(bgRgb, "background color plane"), col, "background color plane"), itemAt(required(bgIdx, "background color index plane"), col, "background color index plane")) : null,
|
|
230
241
|
bold: (m & F_BOLD$1) !== 0,
|
|
231
242
|
faint: (m & F_FAINT$1) !== 0,
|
|
232
243
|
italic: (m & F_ITALIC$1) !== 0,
|
|
233
244
|
underline: bitsToUnderline(m),
|
|
234
|
-
underlineColor: m & F_HAS_UL ? unpackColor(ulRgb
|
|
245
|
+
underlineColor: m & F_HAS_UL ? unpackColor(itemAt(required(ulRgb, "underline color plane"), col, "underline color plane"), itemAt(required(ulIdx, "underline color index plane"), col, "underline color index plane")) : null,
|
|
235
246
|
overline: (m & F_OVERLINE$1) !== 0,
|
|
236
247
|
strikethrough: (m & F_STRIKE$1) !== 0,
|
|
237
248
|
inverse: (m & F_INVERSE$1) !== 0,
|
|
@@ -239,7 +250,7 @@ function makePackedRow(width) {
|
|
|
239
250
|
blink: (m & F_BLINK$1) !== 0,
|
|
240
251
|
protected: (m & F_PROTECTED$1) !== 0,
|
|
241
252
|
wide: (m & F_WIDE$1) !== 0,
|
|
242
|
-
url: m & F_HAS_URL ? urlMap.get(col) ?? null : null
|
|
253
|
+
url: m & F_HAS_URL ? required(urlMap, "packed row URL map").get(col) ?? null : null
|
|
243
254
|
};
|
|
244
255
|
},
|
|
245
256
|
toCells() {
|
|
@@ -254,10 +265,10 @@ function makePackedRow(width) {
|
|
|
254
265
|
return meta[col] === 0 && chars[col] === "";
|
|
255
266
|
},
|
|
256
267
|
getChar(col) {
|
|
257
|
-
return chars
|
|
268
|
+
return itemAt(chars, col, "packed row characters");
|
|
258
269
|
},
|
|
259
270
|
isWide(col) {
|
|
260
|
-
return (meta
|
|
271
|
+
return (itemAt(meta, col, "packed row metadata") & F_WIDE$1) !== 0;
|
|
261
272
|
}
|
|
262
273
|
};
|
|
263
274
|
return row;
|
|
@@ -361,9 +372,9 @@ function buildPalette256() {
|
|
|
361
372
|
255
|
|
362
373
|
];
|
|
363
374
|
for (let r = 0; r < 6; r++) for (let g = 0; g < 6; g++) for (let b = 0; b < 6; b++) palette.push({
|
|
364
|
-
r: levels
|
|
365
|
-
g: levels
|
|
366
|
-
b: levels
|
|
375
|
+
r: itemAt(levels, r, "ANSI cube red levels"),
|
|
376
|
+
g: itemAt(levels, g, "ANSI cube green levels"),
|
|
377
|
+
b: itemAt(levels, b, "ANSI cube blue levels")
|
|
367
378
|
});
|
|
368
379
|
for (let i = 0; i < 24; i++) {
|
|
369
380
|
const v = 8 + i * 10;
|
|
@@ -389,14 +400,14 @@ function parseColorSpec(spec) {
|
|
|
389
400
|
return Math.round(v * 255 / max);
|
|
390
401
|
};
|
|
391
402
|
return {
|
|
392
|
-
r: scale(rgbMatch
|
|
393
|
-
g: scale(rgbMatch
|
|
394
|
-
b: scale(rgbMatch
|
|
403
|
+
r: scale(itemAt(rgbMatch, 1, "X11 red capture")),
|
|
404
|
+
g: scale(itemAt(rgbMatch, 2, "X11 green capture")),
|
|
405
|
+
b: scale(itemAt(rgbMatch, 3, "X11 blue capture"))
|
|
395
406
|
};
|
|
396
407
|
}
|
|
397
408
|
const hex6 = /^#([0-9a-fA-F]{6})$/.exec(s);
|
|
398
409
|
if (hex6) {
|
|
399
|
-
const v = hex6
|
|
410
|
+
const v = itemAt(hex6, 1, "six-digit hex capture");
|
|
400
411
|
return {
|
|
401
412
|
r: parseInt(v.substring(0, 2), 16),
|
|
402
413
|
g: parseInt(v.substring(2, 4), 16),
|
|
@@ -405,12 +416,12 @@ function parseColorSpec(spec) {
|
|
|
405
416
|
}
|
|
406
417
|
const hex3 = /^#([0-9a-fA-F]{3})$/.exec(s);
|
|
407
418
|
if (hex3) {
|
|
408
|
-
const v = hex3
|
|
419
|
+
const v = itemAt(hex3, 1, "three-digit hex capture");
|
|
409
420
|
const expand = (ch) => parseInt(ch + ch, 16);
|
|
410
421
|
return {
|
|
411
|
-
r: expand(v
|
|
412
|
-
g: expand(v
|
|
413
|
-
b: expand(v
|
|
422
|
+
r: expand(itemAt(v, 0, "short hex red channel")),
|
|
423
|
+
g: expand(itemAt(v, 1, "short hex green channel")),
|
|
424
|
+
b: expand(itemAt(v, 2, "short hex blue channel"))
|
|
414
425
|
};
|
|
415
426
|
}
|
|
416
427
|
return null;
|
|
@@ -467,6 +478,7 @@ function createScreen(options = {}) {
|
|
|
467
478
|
let rows = options.rows ?? 24;
|
|
468
479
|
let scrollbackLimit = options.scrollbackLimit ?? 1e3;
|
|
469
480
|
const onResponse = options.onResponse;
|
|
481
|
+
const kittyGraphicsImages = options.kittyGraphicsImages ?? false;
|
|
470
482
|
const maxStringSequenceLength = options.maxStringSequenceLength ?? 16777216;
|
|
471
483
|
if (!Number.isSafeInteger(maxStringSequenceLength) || maxStringSequenceLength < 0) throw new RangeError("maxStringSequenceLength must be a non-negative safe integer");
|
|
472
484
|
let mainGrid = makeGrid(cols, rows);
|
|
@@ -484,12 +496,15 @@ function createScreen(options = {}) {
|
|
|
484
496
|
attrs: resetAttrs(),
|
|
485
497
|
originMode: false,
|
|
486
498
|
autoWrap: true,
|
|
487
|
-
charsetG0: false
|
|
499
|
+
charsetG0: false,
|
|
500
|
+
charsetG1: false,
|
|
501
|
+
activeG1: false
|
|
488
502
|
};
|
|
489
503
|
let savedCurX = 0;
|
|
490
504
|
let savedCurY = 0;
|
|
491
505
|
let attrs = resetAttrs();
|
|
492
506
|
let title = "";
|
|
507
|
+
let iconLabel = "";
|
|
493
508
|
let useAltScreen = false;
|
|
494
509
|
let bracketedPaste = false;
|
|
495
510
|
let applicationCursor = false;
|
|
@@ -506,7 +521,6 @@ function createScreen(options = {}) {
|
|
|
506
521
|
let syncOutput = false;
|
|
507
522
|
let kittyKeyboardFlags = 0;
|
|
508
523
|
let kittyKeyboardStack = [];
|
|
509
|
-
let hasKittyGraphics = false;
|
|
510
524
|
let scrollTop = 0;
|
|
511
525
|
let scrollBottom = rows - 1;
|
|
512
526
|
let leftRightMarginMode = false;
|
|
@@ -663,6 +677,8 @@ function createScreen(options = {}) {
|
|
|
663
677
|
assertBoolean("savedState.originMode", saved.originMode);
|
|
664
678
|
assertBoolean("savedState.autoWrap", saved.autoWrap);
|
|
665
679
|
assertBoolean("savedState.charsetG0", saved.charsetG0);
|
|
680
|
+
if (Object.hasOwn(saved, "charsetG1")) assertBoolean("savedState.charsetG1", saved.charsetG1);
|
|
681
|
+
if (Object.hasOwn(saved, "activeG1")) assertBoolean("savedState.activeG1", saved.activeG1);
|
|
666
682
|
assertRecord("attrs", value.attrs);
|
|
667
683
|
const modes = value.modes;
|
|
668
684
|
assertRecord("modes", modes);
|
|
@@ -701,6 +717,7 @@ function createScreen(options = {}) {
|
|
|
701
717
|
if (!Array.isArray(value.tabStops)) throw new TypeError("Invalid vterm snapshot tabStops");
|
|
702
718
|
for (const stop of value.tabStops) assertInteger("tabStops", stop);
|
|
703
719
|
assertString("title", value.title);
|
|
720
|
+
if (Object.hasOwn(value, "iconLabel")) assertString("iconLabel", value.iconLabel);
|
|
704
721
|
assertString("clipboard", value.clipboard);
|
|
705
722
|
assertString("cwd", value.cwd);
|
|
706
723
|
if (!Array.isArray(value.notifications) || value.notifications.some((entry) => typeof entry !== "string")) throw new TypeError("Invalid vterm snapshot notifications");
|
|
@@ -745,6 +762,8 @@ function createScreen(options = {}) {
|
|
|
745
762
|
const unicode = value.unicode;
|
|
746
763
|
assertRecord("unicode", unicode);
|
|
747
764
|
assertBoolean("unicode.charsetG0", unicode.charsetG0);
|
|
765
|
+
if (Object.hasOwn(unicode, "charsetG1")) assertBoolean("unicode.charsetG1", unicode.charsetG1);
|
|
766
|
+
if (Object.hasOwn(unicode, "activeG1")) assertBoolean("unicode.activeG1", unicode.activeG1);
|
|
748
767
|
assertString("unicode.lastChar", unicode.lastChar);
|
|
749
768
|
if (unicode.pendingRegionalIndicator !== null) assertString("unicode.pendingRegionalIndicator", unicode.pendingRegionalIndicator);
|
|
750
769
|
assertBoolean("unicode.afterZWJ", unicode.afterZWJ);
|
|
@@ -765,15 +784,14 @@ function createScreen(options = {}) {
|
|
|
765
784
|
return 0;
|
|
766
785
|
}
|
|
767
786
|
let textScale = 1;
|
|
768
|
-
const CELL_W_PX = 8;
|
|
769
|
-
const CELL_H_PX = 17;
|
|
770
|
-
const FONT_ASCENT_PX = 14;
|
|
771
787
|
let fontSize = 12;
|
|
772
788
|
let fontWindowSize = 12;
|
|
773
789
|
let locale = "en_US.UTF-8";
|
|
774
790
|
let advancedClipboard = "";
|
|
775
791
|
let viewportOffset = 0;
|
|
776
792
|
let charsetG0 = false;
|
|
793
|
+
let charsetG1 = false;
|
|
794
|
+
let activeG1 = false;
|
|
777
795
|
let clipboard = "";
|
|
778
796
|
let cwd = "";
|
|
779
797
|
let notifications = [];
|
|
@@ -939,13 +957,12 @@ function createScreen(options = {}) {
|
|
|
939
957
|
if (bytes.length === 0) return 0;
|
|
940
958
|
let continuationCount = 0;
|
|
941
959
|
let leadIndex = bytes.length - 1;
|
|
942
|
-
while (leadIndex >= 0 && (bytes
|
|
960
|
+
while (leadIndex >= 0 && (itemAt(bytes, leadIndex, "UTF-8 pending bytes") & 192) === 128 && continuationCount < 3) {
|
|
943
961
|
continuationCount++;
|
|
944
962
|
leadIndex--;
|
|
945
963
|
}
|
|
946
964
|
if (leadIndex < 0) return bytes.length;
|
|
947
|
-
const
|
|
948
|
-
const expectedLength = utf8SequenceLength(lead);
|
|
965
|
+
const expectedLength = utf8SequenceLength(itemAt(bytes, leadIndex, "UTF-8 lead byte"));
|
|
949
966
|
if (expectedLength === 0) return bytes.length;
|
|
950
967
|
return expectedLength > bytes.length - leadIndex ? leadIndex : bytes.length;
|
|
951
968
|
}
|
|
@@ -1051,11 +1068,11 @@ function createScreen(options = {}) {
|
|
|
1051
1068
|
const lm = leftMargin;
|
|
1052
1069
|
const rm = rightMargin;
|
|
1053
1070
|
for (let r = top; r < bottom; r++) {
|
|
1054
|
-
const srcRow = grid
|
|
1055
|
-
const dstRow = grid
|
|
1071
|
+
const srcRow = itemAt(grid, r + 1, "scroll source rows");
|
|
1072
|
+
const dstRow = itemAt(grid, r, "scroll destination rows");
|
|
1056
1073
|
for (let c = lm; c <= rm && c < cols; c++) dstRow.copyCellFrom(c, srcRow, c);
|
|
1057
1074
|
}
|
|
1058
|
-
const bottomRow = grid
|
|
1075
|
+
const bottomRow = itemAt(grid, bottom, "scroll bottom row");
|
|
1059
1076
|
for (let c = lm; c <= rm && c < cols; c++) bottomRow.setEmpty(c);
|
|
1060
1077
|
markScreenRowsDirty(top, bottom);
|
|
1061
1078
|
} else {
|
|
@@ -1098,16 +1115,16 @@ function createScreen(options = {}) {
|
|
|
1098
1115
|
const lm = leftMargin;
|
|
1099
1116
|
const rm = rightMargin;
|
|
1100
1117
|
for (let r = bottom; r > top; r--) {
|
|
1101
|
-
const srcRow = grid
|
|
1102
|
-
const dstRow = grid
|
|
1118
|
+
const srcRow = itemAt(grid, r - 1, "reverse-scroll source rows");
|
|
1119
|
+
const dstRow = itemAt(grid, r, "reverse-scroll destination rows");
|
|
1103
1120
|
for (let c = lm; c <= rm && c < cols; c++) dstRow.copyCellFrom(c, srcRow, c);
|
|
1104
1121
|
}
|
|
1105
|
-
const topRow = grid
|
|
1122
|
+
const topRow = itemAt(grid, top, "reverse-scroll top row");
|
|
1106
1123
|
for (let c = lm; c <= rm && c < cols; c++) topRow.setEmpty(c);
|
|
1107
1124
|
} else {
|
|
1108
1125
|
for (let i = bottom; i > top; i--) {
|
|
1109
|
-
grid[i] = grid
|
|
1110
|
-
softWrapped[i] = softWrapped
|
|
1126
|
+
grid[i] = itemAt(grid, i - 1, "reverse-scroll source rows");
|
|
1127
|
+
softWrapped[i] = itemAt(softWrapped, i - 1, "reverse-scroll source wrap flags");
|
|
1111
1128
|
}
|
|
1112
1129
|
grid[top] = makeRow(cols);
|
|
1113
1130
|
softWrapped[top] = false;
|
|
@@ -1132,7 +1149,7 @@ function createScreen(options = {}) {
|
|
|
1132
1149
|
if (prevRow < 0) return null;
|
|
1133
1150
|
prevCol = cols - 1;
|
|
1134
1151
|
}
|
|
1135
|
-
const row = grid
|
|
1152
|
+
const row = itemAt(grid, prevRow, "previous-cell rows");
|
|
1136
1153
|
if (prevCol > 0 && row.getChar(prevCol) === "" && row.isWide(prevCol - 1)) prevCol--;
|
|
1137
1154
|
if (row.isEmpty(prevCol)) return null;
|
|
1138
1155
|
return {
|
|
@@ -1146,7 +1163,7 @@ function createScreen(options = {}) {
|
|
|
1146
1163
|
row.widen(col);
|
|
1147
1164
|
}
|
|
1148
1165
|
function writeChar(ch) {
|
|
1149
|
-
if (charsetG0 && ch.length === 1) {
|
|
1166
|
+
if ((activeG1 ? charsetG1 : charsetG0) && ch.length === 1) {
|
|
1150
1167
|
const mapped = DEC_SPECIAL_GRAPHICS[ch];
|
|
1151
1168
|
if (mapped) ch = mapped;
|
|
1152
1169
|
}
|
|
@@ -1196,14 +1213,16 @@ function createScreen(options = {}) {
|
|
|
1196
1213
|
return;
|
|
1197
1214
|
}
|
|
1198
1215
|
}
|
|
1199
|
-
if (isRegionalIndicator(codePoint))
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1216
|
+
if (isRegionalIndicator(codePoint)) {
|
|
1217
|
+
if (pendingRegionalIndicator !== null) {
|
|
1218
|
+
const flag = pendingRegionalIndicator + ch;
|
|
1219
|
+
pendingRegionalIndicator = null;
|
|
1220
|
+
writeCharCore(flag, true);
|
|
1221
|
+
return;
|
|
1222
|
+
} else {
|
|
1223
|
+
pendingRegionalIndicator = ch;
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1207
1226
|
}
|
|
1208
1227
|
if (pendingRegionalIndicator !== null) {
|
|
1209
1228
|
const ri = pendingRegionalIndicator;
|
|
@@ -1218,18 +1237,20 @@ function createScreen(options = {}) {
|
|
|
1218
1237
|
const charWidth = wide ? 2 : 1;
|
|
1219
1238
|
const wrapBoundary = leftRightMarginMode ? rightMargin + 1 : rowCols(curY);
|
|
1220
1239
|
const wrapReturn = leftRightMarginMode ? leftMargin : 0;
|
|
1221
|
-
if (curX + charWidth > wrapBoundary)
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
curY
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1240
|
+
if (curX + charWidth > wrapBoundary) {
|
|
1241
|
+
if (autoWrap) {
|
|
1242
|
+
softWrapped[curY] = true;
|
|
1243
|
+
curX = wrapReturn;
|
|
1244
|
+
curY++;
|
|
1245
|
+
if (curY > scrollBottom) {
|
|
1246
|
+
curY = scrollBottom;
|
|
1247
|
+
scrollUp(scrollTop, scrollBottom);
|
|
1248
|
+
}
|
|
1249
|
+
} else curX = wrapBoundary - charWidth;
|
|
1250
|
+
}
|
|
1230
1251
|
if (insertMode) {
|
|
1231
1252
|
const insertEnd = leftRightMarginMode ? rightMargin + 1 : cols;
|
|
1232
|
-
mutateRowAsCells(grid
|
|
1253
|
+
mutateRowAsCells(itemAt(grid, curY, "cursor row"), (cells) => {
|
|
1233
1254
|
for (let i = 0; i < charWidth; i++) {
|
|
1234
1255
|
cells.splice(insertEnd - 1, 1);
|
|
1235
1256
|
cells.splice(curX, 0, emptyCell());
|
|
@@ -1272,7 +1293,6 @@ function createScreen(options = {}) {
|
|
|
1272
1293
|
case 6:
|
|
1273
1294
|
cursorShape = "bar";
|
|
1274
1295
|
cursorBlinking = false;
|
|
1275
|
-
break;
|
|
1276
1296
|
}
|
|
1277
1297
|
else if (finalByte === "@") handleShiftLeft(Math.max(parts[0] ?? 1, 1));
|
|
1278
1298
|
else if (finalByte === "A") handleShiftRight(Math.max(parts[0] ?? 1, 1));
|
|
@@ -1301,7 +1321,7 @@ function createScreen(options = {}) {
|
|
|
1301
1321
|
const { t, l, b, r } = normalizeRect(parts[1] ?? 1, parts[2] ?? 1, parts[3] ?? rows, parts[4] ?? cols);
|
|
1302
1322
|
const fillChar = String.fromCharCode(charCode);
|
|
1303
1323
|
for (let row = t; row <= b && row < rows; row++) {
|
|
1304
|
-
const gr = grid
|
|
1324
|
+
const gr = itemAt(grid, row, "rectangular erase rows");
|
|
1305
1325
|
for (let col = l; col <= r && col < cols; col++) {
|
|
1306
1326
|
const cell = emptyCell();
|
|
1307
1327
|
cell.char = fillChar;
|
|
@@ -1312,7 +1332,7 @@ function createScreen(options = {}) {
|
|
|
1312
1332
|
} else if (finalByte === "z" || finalByte === "{") {
|
|
1313
1333
|
const { t, l, b, r } = normalizeRect(parts[0] ?? 1, parts[1] ?? 1, parts[2] ?? rows, parts[3] ?? cols);
|
|
1314
1334
|
for (let row = t; row <= b && row < rows; row++) {
|
|
1315
|
-
const gr = grid
|
|
1335
|
+
const gr = itemAt(grid, row, "rectangular fill rows");
|
|
1316
1336
|
for (let col = l; col <= r && col < cols; col++) gr.setEmpty(col);
|
|
1317
1337
|
}
|
|
1318
1338
|
markScreenRowsDirty(t, Math.min(b, rows - 1));
|
|
@@ -1332,11 +1352,11 @@ function createScreen(options = {}) {
|
|
|
1332
1352
|
for (let row = 0; row < h; row++) {
|
|
1333
1353
|
const dr = dstTop + row;
|
|
1334
1354
|
if (dr < 0 || dr >= rows) continue;
|
|
1335
|
-
const dstRow = grid
|
|
1355
|
+
const dstRow = itemAt(grid, dr, "rectangular copy destination rows");
|
|
1336
1356
|
for (let col = 0; col < w; col++) {
|
|
1337
1357
|
const dc = dstLeft + col;
|
|
1338
1358
|
if (dc < 0 || dc >= cols) continue;
|
|
1339
|
-
dstRow.setCellRaw(dc, snapshot
|
|
1359
|
+
dstRow.setCellRaw(dc, itemAt(itemAt(snapshot, row, "rectangular copy rows"), col, "rectangular copy cells"));
|
|
1340
1360
|
}
|
|
1341
1361
|
}
|
|
1342
1362
|
markScreenRowsDirty(Math.max(0, dstTop), Math.min(dstTop + h - 1, rows - 1));
|
|
@@ -1345,7 +1365,7 @@ function createScreen(options = {}) {
|
|
|
1345
1365
|
const sgrParts = parts.slice(4);
|
|
1346
1366
|
const reverse = finalByte === "t";
|
|
1347
1367
|
for (let row = t; row <= b && row < rows; row++) {
|
|
1348
|
-
const gr = grid
|
|
1368
|
+
const gr = itemAt(grid, row, "rectangular attribute rows");
|
|
1349
1369
|
for (let col = l; col <= r && col < cols; col++) {
|
|
1350
1370
|
const cell = gr.getCellRaw(col);
|
|
1351
1371
|
applyRectAttrs(cell, sgrParts, reverse);
|
|
@@ -1444,24 +1464,20 @@ function createScreen(options = {}) {
|
|
|
1444
1464
|
case "t": {
|
|
1445
1465
|
const op = parts[0] ?? 0;
|
|
1446
1466
|
if (!onResponse) break;
|
|
1447
|
-
const CELL_H = 16;
|
|
1448
|
-
const CELL_W = 8;
|
|
1449
1467
|
switch (op) {
|
|
1450
1468
|
case 14:
|
|
1451
|
-
onResponse(
|
|
1469
|
+
onResponse("\x1B[4;0;0t");
|
|
1452
1470
|
break;
|
|
1453
1471
|
case 16:
|
|
1454
|
-
onResponse(
|
|
1472
|
+
onResponse("\x1B[6;0;0t");
|
|
1455
1473
|
break;
|
|
1456
1474
|
case 18:
|
|
1457
1475
|
onResponse(`\x1b[8;${rows};${cols}t`);
|
|
1458
1476
|
break;
|
|
1459
1477
|
case 20:
|
|
1460
|
-
onResponse(`\x1b]L${
|
|
1461
|
-
break;
|
|
1462
|
-
case 21:
|
|
1463
|
-
onResponse(`\x1b]l${title}\x1b\\`);
|
|
1478
|
+
onResponse(`\x1b]L${iconLabel}\x1b\\`);
|
|
1464
1479
|
break;
|
|
1480
|
+
case 21: onResponse(`\x1b]l${title}\x1b\\`);
|
|
1465
1481
|
}
|
|
1466
1482
|
break;
|
|
1467
1483
|
}
|
|
@@ -1580,8 +1596,6 @@ function createScreen(options = {}) {
|
|
|
1580
1596
|
curX = savedCurX;
|
|
1581
1597
|
curY = savedCurY;
|
|
1582
1598
|
clampCursor();
|
|
1583
|
-
break;
|
|
1584
|
-
default: break;
|
|
1585
1599
|
}
|
|
1586
1600
|
}
|
|
1587
1601
|
function handleCSIGt(params, _intermediates, finalByte) {
|
|
@@ -1688,9 +1702,7 @@ function createScreen(options = {}) {
|
|
|
1688
1702
|
case 1007:
|
|
1689
1703
|
value = altScrollMode ? 1 : 2;
|
|
1690
1704
|
break;
|
|
1691
|
-
case 1048:
|
|
1692
|
-
value = 2;
|
|
1693
|
-
break;
|
|
1705
|
+
case 1048: value = 2;
|
|
1694
1706
|
}
|
|
1695
1707
|
onResponse(`\x1b[?${mode};${value}$y`);
|
|
1696
1708
|
}
|
|
@@ -1819,16 +1831,14 @@ function createScreen(options = {}) {
|
|
|
1819
1831
|
case 1007:
|
|
1820
1832
|
altScrollMode = set;
|
|
1821
1833
|
break;
|
|
1822
|
-
case 1048:
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
}
|
|
1831
|
-
break;
|
|
1834
|
+
case 1048: if (set) {
|
|
1835
|
+
savedCurX = curX;
|
|
1836
|
+
savedCurY = curY;
|
|
1837
|
+
} else {
|
|
1838
|
+
curX = savedCurX;
|
|
1839
|
+
curY = savedCurY;
|
|
1840
|
+
clampCursor();
|
|
1841
|
+
}
|
|
1832
1842
|
}
|
|
1833
1843
|
}
|
|
1834
1844
|
function handleEraseDisplay(mode, selective = false) {
|
|
@@ -1846,7 +1856,6 @@ function createScreen(options = {}) {
|
|
|
1846
1856
|
for (let row = 0; row < rows; row++) eraseCells(row, 0, row, cols - 1, selective);
|
|
1847
1857
|
if (mode === 3) clearScrollback();
|
|
1848
1858
|
markAllDirty();
|
|
1849
|
-
break;
|
|
1850
1859
|
}
|
|
1851
1860
|
}
|
|
1852
1861
|
function handleEraseLine(mode, selective = false) {
|
|
@@ -1859,9 +1868,7 @@ function createScreen(options = {}) {
|
|
|
1859
1868
|
case 1:
|
|
1860
1869
|
eraseCells(curY, eraseLeft, curY, curX, selective);
|
|
1861
1870
|
break;
|
|
1862
|
-
case 2:
|
|
1863
|
-
eraseCells(curY, eraseLeft, curY, eraseRight, selective);
|
|
1864
|
-
break;
|
|
1871
|
+
case 2: eraseCells(curY, eraseLeft, curY, eraseRight, selective);
|
|
1865
1872
|
}
|
|
1866
1873
|
}
|
|
1867
1874
|
function eraseCells(row, startCol, _endRow, endCol, selective = false) {
|
|
@@ -2014,9 +2021,7 @@ function createScreen(options = {}) {
|
|
|
2014
2021
|
case 25:
|
|
2015
2022
|
cell.blink = false;
|
|
2016
2023
|
break;
|
|
2017
|
-
case 27:
|
|
2018
|
-
cell.inverse = false;
|
|
2019
|
-
break;
|
|
2024
|
+
case 27: cell.inverse = false;
|
|
2020
2025
|
}
|
|
2021
2026
|
}
|
|
2022
2027
|
function handleSGR(rawParams) {
|
|
@@ -2026,7 +2031,7 @@ function createScreen(options = {}) {
|
|
|
2026
2031
|
for (const seg of segments) if (seg.includes(":")) {
|
|
2027
2032
|
const subs = seg.split(":").map((s) => s === "" ? 0 : parseInt(s, 10));
|
|
2028
2033
|
subParams.set(params.length, subs);
|
|
2029
|
-
params.push(subs
|
|
2034
|
+
params.push(itemAt(subs, 0, "SGR sub-parameters"));
|
|
2030
2035
|
} else params.push(seg === "" ? 0 : parseInt(seg, 10));
|
|
2031
2036
|
if (params.length === 0 || params.length === 1 && params[0] === 0) {
|
|
2032
2037
|
attrs = resetSgrAttrs();
|
|
@@ -2034,7 +2039,7 @@ function createScreen(options = {}) {
|
|
|
2034
2039
|
}
|
|
2035
2040
|
let i = 0;
|
|
2036
2041
|
while (i < params.length) {
|
|
2037
|
-
const code = params
|
|
2042
|
+
const code = itemAt(params, i, "SGR parameters");
|
|
2038
2043
|
switch (code) {
|
|
2039
2044
|
case 0:
|
|
2040
2045
|
attrs = resetSgrAttrs();
|
|
@@ -2050,7 +2055,7 @@ function createScreen(options = {}) {
|
|
|
2050
2055
|
break;
|
|
2051
2056
|
case 4: {
|
|
2052
2057
|
const subs = subParams.get(i);
|
|
2053
|
-
if (subs && subs.length > 1) switch (subs
|
|
2058
|
+
if (subs && subs.length > 1) switch (itemAt(subs, 1, "underline style sub-parameters")) {
|
|
2054
2059
|
case 0:
|
|
2055
2060
|
attrs.underline = "none";
|
|
2056
2061
|
break;
|
|
@@ -2069,9 +2074,7 @@ function createScreen(options = {}) {
|
|
|
2069
2074
|
case 5:
|
|
2070
2075
|
attrs.underline = "dashed";
|
|
2071
2076
|
break;
|
|
2072
|
-
default:
|
|
2073
|
-
attrs.underline = "single";
|
|
2074
|
-
break;
|
|
2077
|
+
default: attrs.underline = "single";
|
|
2075
2078
|
}
|
|
2076
2079
|
else attrs.underline = "single";
|
|
2077
2080
|
break;
|
|
@@ -2125,7 +2128,7 @@ function createScreen(options = {}) {
|
|
|
2125
2128
|
case 36:
|
|
2126
2129
|
case 37:
|
|
2127
2130
|
attrs.fg = {
|
|
2128
|
-
...palette256
|
|
2131
|
+
...itemAt(palette256, code - 30, "basic foreground palette"),
|
|
2129
2132
|
index: code - 30
|
|
2130
2133
|
};
|
|
2131
2134
|
break;
|
|
@@ -2155,7 +2158,7 @@ function createScreen(options = {}) {
|
|
|
2155
2158
|
case 46:
|
|
2156
2159
|
case 47:
|
|
2157
2160
|
attrs.bg = {
|
|
2158
|
-
...palette256
|
|
2161
|
+
...itemAt(palette256, code - 40, "basic background palette"),
|
|
2159
2162
|
index: code - 40
|
|
2160
2163
|
};
|
|
2161
2164
|
break;
|
|
@@ -2208,7 +2211,7 @@ function createScreen(options = {}) {
|
|
|
2208
2211
|
case 96:
|
|
2209
2212
|
case 97:
|
|
2210
2213
|
attrs.fg = {
|
|
2211
|
-
...palette256
|
|
2214
|
+
...itemAt(palette256, code - 90 + 8, "bright foreground palette"),
|
|
2212
2215
|
index: code - 90 + 8
|
|
2213
2216
|
};
|
|
2214
2217
|
break;
|
|
@@ -2219,12 +2222,10 @@ function createScreen(options = {}) {
|
|
|
2219
2222
|
case 104:
|
|
2220
2223
|
case 105:
|
|
2221
2224
|
case 106:
|
|
2222
|
-
case 107:
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
};
|
|
2227
|
-
break;
|
|
2225
|
+
case 107: attrs.bg = {
|
|
2226
|
+
...itemAt(palette256, code - 100 + 8, "bright background palette"),
|
|
2227
|
+
index: code - 100 + 8
|
|
2228
|
+
};
|
|
2228
2229
|
}
|
|
2229
2230
|
i++;
|
|
2230
2231
|
}
|
|
@@ -2233,7 +2234,7 @@ function createScreen(options = {}) {
|
|
|
2233
2234
|
if (startIndex + 1 >= params.length) return null;
|
|
2234
2235
|
const type = params[startIndex + 1];
|
|
2235
2236
|
if (type === 5 && startIndex + 2 < params.length) {
|
|
2236
|
-
const idx = params
|
|
2237
|
+
const idx = itemAt(params, startIndex + 2, "indexed color parameters");
|
|
2237
2238
|
const entry = palette256[idx];
|
|
2238
2239
|
return {
|
|
2239
2240
|
color: entry ? {
|
|
@@ -2248,9 +2249,9 @@ function createScreen(options = {}) {
|
|
|
2248
2249
|
};
|
|
2249
2250
|
} else if (type === 2 && startIndex + 4 < params.length) return {
|
|
2250
2251
|
color: {
|
|
2251
|
-
r: params
|
|
2252
|
-
g: params
|
|
2253
|
-
b: params
|
|
2252
|
+
r: itemAt(params, startIndex + 2, "truecolor red parameter"),
|
|
2253
|
+
g: itemAt(params, startIndex + 3, "truecolor green parameter"),
|
|
2254
|
+
b: itemAt(params, startIndex + 4, "truecolor blue parameter")
|
|
2254
2255
|
},
|
|
2255
2256
|
nextIndex: startIndex + 5
|
|
2256
2257
|
};
|
|
@@ -2261,7 +2262,7 @@ function createScreen(options = {}) {
|
|
|
2261
2262
|
if (subs.length < 3) return null;
|
|
2262
2263
|
const type = subs[1];
|
|
2263
2264
|
if (type === 5 && subs.length >= 3) {
|
|
2264
|
-
const idx = subs
|
|
2265
|
+
const idx = itemAt(subs, 2, "indexed color sub-parameters");
|
|
2265
2266
|
const entry = palette256[idx];
|
|
2266
2267
|
return entry ? {
|
|
2267
2268
|
...entry,
|
|
@@ -2274,18 +2275,18 @@ function createScreen(options = {}) {
|
|
|
2274
2275
|
} else if (type === 2) {
|
|
2275
2276
|
if (subs.length >= 5) {
|
|
2276
2277
|
if (subs.length >= 6) return {
|
|
2277
|
-
r: subs
|
|
2278
|
-
g: subs
|
|
2279
|
-
b: subs
|
|
2278
|
+
r: itemAt(subs, 3, "colorspace red sub-parameter"),
|
|
2279
|
+
g: itemAt(subs, 4, "colorspace green sub-parameter"),
|
|
2280
|
+
b: itemAt(subs, 5, "colorspace blue sub-parameter")
|
|
2280
2281
|
};
|
|
2281
2282
|
return {
|
|
2282
|
-
r: subs
|
|
2283
|
-
g: subs
|
|
2284
|
-
b: subs
|
|
2283
|
+
r: itemAt(subs, 2, "truecolor red sub-parameter"),
|
|
2284
|
+
g: itemAt(subs, 3, "truecolor green sub-parameter"),
|
|
2285
|
+
b: itemAt(subs, 4, "truecolor blue sub-parameter")
|
|
2285
2286
|
};
|
|
2286
2287
|
} else if (subs.length >= 4) return {
|
|
2287
|
-
r: subs
|
|
2288
|
-
g: subs
|
|
2288
|
+
r: itemAt(subs, 2, "partial truecolor red sub-parameter"),
|
|
2289
|
+
g: itemAt(subs, 3, "partial truecolor green sub-parameter"),
|
|
2289
2290
|
b: 0
|
|
2290
2291
|
};
|
|
2291
2292
|
}
|
|
@@ -2298,6 +2299,9 @@ function createScreen(options = {}) {
|
|
|
2298
2299
|
const value = semicolonIdx === -1 ? "" : oscString.substring(semicolonIdx + 1);
|
|
2299
2300
|
switch (code) {
|
|
2300
2301
|
case 0:
|
|
2302
|
+
iconLabel = value;
|
|
2303
|
+
title = value;
|
|
2304
|
+
break;
|
|
2301
2305
|
case 2:
|
|
2302
2306
|
title = value;
|
|
2303
2307
|
break;
|
|
@@ -2317,17 +2321,16 @@ function createScreen(options = {}) {
|
|
|
2317
2321
|
startCol: curX
|
|
2318
2322
|
});
|
|
2319
2323
|
break;
|
|
2320
|
-
case "C":
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
});
|
|
2326
|
-
break;
|
|
2327
|
-
case "D": break;
|
|
2324
|
+
case "C": semanticZones.push({
|
|
2325
|
+
type: "output",
|
|
2326
|
+
startRow: curY,
|
|
2327
|
+
startCol: curX
|
|
2328
|
+
});
|
|
2328
2329
|
}
|
|
2329
2330
|
break;
|
|
2330
|
-
case 1:
|
|
2331
|
+
case 1:
|
|
2332
|
+
iconLabel = value;
|
|
2333
|
+
break;
|
|
2331
2334
|
case 7:
|
|
2332
2335
|
cwd = value;
|
|
2333
2336
|
break;
|
|
@@ -2342,8 +2345,8 @@ function createScreen(options = {}) {
|
|
|
2342
2345
|
case 4: {
|
|
2343
2346
|
const fields = value.split(";");
|
|
2344
2347
|
for (let fi = 0; fi + 1 < fields.length; fi += 2) {
|
|
2345
|
-
const idx = parseInt(fields
|
|
2346
|
-
const spec = fields
|
|
2348
|
+
const idx = parseInt(itemAt(fields, fi, "OSC 4 palette fields"), 10);
|
|
2349
|
+
const spec = itemAt(fields, fi + 1, "OSC 4 palette fields");
|
|
2347
2350
|
if (isNaN(idx) || idx < 0 || idx > 255) continue;
|
|
2348
2351
|
if (spec === "?") {
|
|
2349
2352
|
const c = palette256[idx];
|
|
@@ -2358,8 +2361,8 @@ function createScreen(options = {}) {
|
|
|
2358
2361
|
case 5: {
|
|
2359
2362
|
const fields = value.split(";");
|
|
2360
2363
|
for (let fi = 0; fi + 1 < fields.length; fi += 2) {
|
|
2361
|
-
const idx = parseInt(fields
|
|
2362
|
-
const spec = fields
|
|
2364
|
+
const idx = parseInt(itemAt(fields, fi, "OSC 5 special-color fields"), 10);
|
|
2365
|
+
const spec = itemAt(fields, fi + 1, "OSC 5 special-color fields");
|
|
2363
2366
|
if (isNaN(idx) || idx < 0 || idx > 4) continue;
|
|
2364
2367
|
if (spec === "?") {
|
|
2365
2368
|
const c = specialColors.get(idx);
|
|
@@ -2469,70 +2472,76 @@ function createScreen(options = {}) {
|
|
|
2469
2472
|
const isQuery = val === "?";
|
|
2470
2473
|
const paletteMatch = /^color(\d+)$/.exec(key);
|
|
2471
2474
|
if (paletteMatch) {
|
|
2472
|
-
const idx = parseInt(paletteMatch
|
|
2475
|
+
const idx = parseInt(itemAt(paletteMatch, 1, "OSC 104 palette capture"), 10);
|
|
2473
2476
|
if (idx < 0 || idx > 255) continue;
|
|
2474
2477
|
if (isQuery) {
|
|
2475
2478
|
const c = palette256[idx];
|
|
2476
2479
|
if (c) response.push(`${key}=${formatColorResponse(c)}`);
|
|
2477
2480
|
} else if (val === "") {
|
|
2478
2481
|
const fresh = buildPalette256();
|
|
2479
|
-
palette256[idx] = fresh
|
|
2482
|
+
palette256[idx] = itemAt(fresh, idx, "fresh ANSI palette");
|
|
2480
2483
|
} else {
|
|
2481
2484
|
const c = parseColorSpec(val);
|
|
2482
2485
|
if (c) palette256[idx] = c;
|
|
2483
2486
|
}
|
|
2484
|
-
} else if (key === "foreground")
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
if (
|
|
2487
|
+
} else if (key === "foreground") {
|
|
2488
|
+
if (isQuery) {
|
|
2489
|
+
const c = defaultFgColor ?? {
|
|
2490
|
+
r: 255,
|
|
2491
|
+
g: 255,
|
|
2492
|
+
b: 255
|
|
2493
|
+
};
|
|
2494
|
+
response.push(`${key}=${formatColorResponse(c)}`);
|
|
2495
|
+
} else if (val === "") defaultFgColor = null;
|
|
2496
|
+
else {
|
|
2497
|
+
const c = parseColorSpec(val);
|
|
2498
|
+
if (c) defaultFgColor = c;
|
|
2499
|
+
}
|
|
2500
|
+
} else if (key === "background") {
|
|
2501
|
+
if (isQuery) {
|
|
2502
|
+
const c = defaultBgColor ?? {
|
|
2503
|
+
r: 0,
|
|
2504
|
+
g: 0,
|
|
2505
|
+
b: 0
|
|
2506
|
+
};
|
|
2507
|
+
response.push(`${key}=${formatColorResponse(c)}`);
|
|
2508
|
+
} else if (val === "") defaultBgColor = null;
|
|
2509
|
+
else {
|
|
2510
|
+
const c = parseColorSpec(val);
|
|
2511
|
+
if (c) defaultBgColor = c;
|
|
2512
|
+
}
|
|
2513
|
+
} else if (key === "cursor") {
|
|
2514
|
+
if (isQuery) {
|
|
2515
|
+
const c = cursorColor ?? defaultFgColor ?? {
|
|
2516
|
+
r: 255,
|
|
2517
|
+
g: 255,
|
|
2518
|
+
b: 255
|
|
2519
|
+
};
|
|
2520
|
+
response.push(`${key}=${formatColorResponse(c)}`);
|
|
2521
|
+
} else if (val === "") cursorColor = null;
|
|
2522
|
+
else {
|
|
2523
|
+
const c = parseColorSpec(val);
|
|
2524
|
+
if (c) cursorColor = c;
|
|
2525
|
+
}
|
|
2526
|
+
} else if (key === "selection_background") {
|
|
2527
|
+
if (isQuery) {
|
|
2528
|
+
const c = highlightBgColor ?? defaultFgColor ?? {
|
|
2529
|
+
r: 255,
|
|
2530
|
+
g: 255,
|
|
2531
|
+
b: 255
|
|
2532
|
+
};
|
|
2533
|
+
response.push(`${key}=${formatColorResponse(c)}`);
|
|
2534
|
+
} else highlightBgColor = val === "" ? null : parseColorSpec(val);
|
|
2535
|
+
} else if (key === "selection_foreground") {
|
|
2536
|
+
if (isQuery) {
|
|
2537
|
+
const c = highlightFgColor ?? defaultBgColor ?? {
|
|
2538
|
+
r: 0,
|
|
2539
|
+
g: 0,
|
|
2540
|
+
b: 0
|
|
2541
|
+
};
|
|
2542
|
+
response.push(`${key}=${formatColorResponse(c)}`);
|
|
2543
|
+
} else highlightFgColor = val === "" ? null : parseColorSpec(val);
|
|
2519
2544
|
}
|
|
2520
|
-
else if (key === "selection_background") if (isQuery) {
|
|
2521
|
-
const c = highlightBgColor ?? defaultFgColor ?? {
|
|
2522
|
-
r: 255,
|
|
2523
|
-
g: 255,
|
|
2524
|
-
b: 255
|
|
2525
|
-
};
|
|
2526
|
-
response.push(`${key}=${formatColorResponse(c)}`);
|
|
2527
|
-
} else highlightBgColor = val === "" ? null : parseColorSpec(val);
|
|
2528
|
-
else if (key === "selection_foreground") if (isQuery) {
|
|
2529
|
-
const c = highlightFgColor ?? defaultBgColor ?? {
|
|
2530
|
-
r: 0,
|
|
2531
|
-
g: 0,
|
|
2532
|
-
b: 0
|
|
2533
|
-
};
|
|
2534
|
-
response.push(`${key}=${formatColorResponse(c)}`);
|
|
2535
|
-
} else highlightFgColor = val === "" ? null : parseColorSpec(val);
|
|
2536
2545
|
}
|
|
2537
2546
|
if (response.length > 0 && onResponse) onResponse(`\x1b]21;${response.join(";")}\x1b\\`);
|
|
2538
2547
|
break;
|
|
@@ -2543,7 +2552,7 @@ function createScreen(options = {}) {
|
|
|
2543
2552
|
const fresh = buildPalette256();
|
|
2544
2553
|
for (const tok of value.split(";")) {
|
|
2545
2554
|
const idx = parseInt(tok, 10);
|
|
2546
|
-
if (!isNaN(idx) && idx >= 0 && idx < 256) palette256[idx] = fresh
|
|
2555
|
+
if (!isNaN(idx) && idx >= 0 && idx < 256) palette256[idx] = itemAt(fresh, idx, "fresh ANSI palette");
|
|
2547
2556
|
}
|
|
2548
2557
|
}
|
|
2549
2558
|
break;
|
|
@@ -2614,14 +2623,11 @@ function createScreen(options = {}) {
|
|
|
2614
2623
|
startCol: curX
|
|
2615
2624
|
});
|
|
2616
2625
|
break;
|
|
2617
|
-
case "C":
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
});
|
|
2623
|
-
break;
|
|
2624
|
-
case "D": break;
|
|
2626
|
+
case "C": semanticZones.push({
|
|
2627
|
+
type: "output",
|
|
2628
|
+
startRow: curY,
|
|
2629
|
+
startCol: curX
|
|
2630
|
+
});
|
|
2625
2631
|
}
|
|
2626
2632
|
break;
|
|
2627
2633
|
case 66:
|
|
@@ -2656,7 +2662,7 @@ function createScreen(options = {}) {
|
|
|
2656
2662
|
break;
|
|
2657
2663
|
}
|
|
2658
2664
|
case 776:
|
|
2659
|
-
if (onResponse) onResponse(
|
|
2665
|
+
if (onResponse) onResponse("\x1B]776;0;0;0\x1B\\");
|
|
2660
2666
|
break;
|
|
2661
2667
|
case 7770:
|
|
2662
2668
|
if (value === "?") {
|
|
@@ -2694,10 +2700,8 @@ function createScreen(options = {}) {
|
|
|
2694
2700
|
advancedClipboard = "";
|
|
2695
2701
|
}
|
|
2696
2702
|
break;
|
|
2697
|
-
case 1337:
|
|
2698
|
-
|
|
2699
|
-
else if (value === "RequestCapabilities" && onResponse) onResponse("\x1B]1337;Capabilities=\x1B\\");
|
|
2700
|
-
break;
|
|
2703
|
+
case 1337: if (value === "ReportCellSize" && onResponse) onResponse("\x1B]1337;ReportCellSize=0;0\x1B\\");
|
|
2704
|
+
else if (value === "RequestCapabilities" && onResponse) onResponse("\x1B]1337;Capabilities=\x1B\\");
|
|
2701
2705
|
}
|
|
2702
2706
|
}
|
|
2703
2707
|
function handleDCS(data) {
|
|
@@ -2705,7 +2709,7 @@ function createScreen(options = {}) {
|
|
|
2705
2709
|
if (match) {
|
|
2706
2710
|
hasSixel = true;
|
|
2707
2711
|
sixelImages.push({
|
|
2708
|
-
data: match
|
|
2712
|
+
data: itemAt(match, 2, "sixel payload capture"),
|
|
2709
2713
|
row: dcsStartRow,
|
|
2710
2714
|
col: dcsStartCol
|
|
2711
2715
|
});
|
|
@@ -2726,7 +2730,6 @@ function createScreen(options = {}) {
|
|
|
2726
2730
|
}
|
|
2727
2731
|
function handleAPC(data) {
|
|
2728
2732
|
if (!data.startsWith("G")) return;
|
|
2729
|
-
hasKittyGraphics = true;
|
|
2730
2733
|
const semicolonIdx = data.indexOf(";");
|
|
2731
2734
|
const kvPart = semicolonIdx >= 0 ? data.substring(1, semicolonIdx) : data.substring(1);
|
|
2732
2735
|
const params = {};
|
|
@@ -2734,7 +2737,11 @@ function createScreen(options = {}) {
|
|
|
2734
2737
|
const eqIdx = pair.indexOf("=");
|
|
2735
2738
|
if (eqIdx >= 0) params[pair.substring(0, eqIdx)] = pair.substring(eqIdx + 1);
|
|
2736
2739
|
}
|
|
2737
|
-
if (params.a === "q" && onResponse)
|
|
2740
|
+
if (params.a === "q" && onResponse) {
|
|
2741
|
+
if (kittyGraphicsImages) {
|
|
2742
|
+
if (params.q !== "1" && params.q !== "2") onResponse(`\x1b_Gi=${params.i ?? "0"};OK\x1b\\`);
|
|
2743
|
+
} else if (params.q !== "2") onResponse(`\x1b_Gi=${params.i ?? "0"};ENOTSUP\x1b\\`);
|
|
2744
|
+
}
|
|
2738
2745
|
}
|
|
2739
2746
|
function softReset() {
|
|
2740
2747
|
insertMode = false;
|
|
@@ -2759,6 +2766,8 @@ function createScreen(options = {}) {
|
|
|
2759
2766
|
rightMargin = cols - 1;
|
|
2760
2767
|
attrs = resetAttrs();
|
|
2761
2768
|
charsetG0 = false;
|
|
2769
|
+
charsetG1 = false;
|
|
2770
|
+
activeG1 = false;
|
|
2762
2771
|
curX = 0;
|
|
2763
2772
|
curY = 0;
|
|
2764
2773
|
}
|
|
@@ -2781,10 +2790,13 @@ function createScreen(options = {}) {
|
|
|
2781
2790
|
attrs: resetAttrs(),
|
|
2782
2791
|
originMode: false,
|
|
2783
2792
|
autoWrap: true,
|
|
2784
|
-
charsetG0: false
|
|
2793
|
+
charsetG0: false,
|
|
2794
|
+
charsetG1: false,
|
|
2795
|
+
activeG1: false
|
|
2785
2796
|
};
|
|
2786
2797
|
attrs = resetAttrs();
|
|
2787
2798
|
title = "";
|
|
2799
|
+
iconLabel = "";
|
|
2788
2800
|
useAltScreen = false;
|
|
2789
2801
|
bracketedPaste = false;
|
|
2790
2802
|
applicationCursor = false;
|
|
@@ -2801,7 +2813,6 @@ function createScreen(options = {}) {
|
|
|
2801
2813
|
syncOutput = false;
|
|
2802
2814
|
kittyKeyboardFlags = 0;
|
|
2803
2815
|
kittyKeyboardStack = [];
|
|
2804
|
-
hasKittyGraphics = false;
|
|
2805
2816
|
hasSixel = false;
|
|
2806
2817
|
sixelImages = [];
|
|
2807
2818
|
scrollTop = 0;
|
|
@@ -2820,6 +2831,8 @@ function createScreen(options = {}) {
|
|
|
2820
2831
|
advancedClipboard = "";
|
|
2821
2832
|
viewportOffset = 0;
|
|
2822
2833
|
charsetG0 = false;
|
|
2834
|
+
charsetG1 = false;
|
|
2835
|
+
activeG1 = false;
|
|
2823
2836
|
clipboard = "";
|
|
2824
2837
|
cwd = "";
|
|
2825
2838
|
notifications = [];
|
|
@@ -3015,6 +3028,12 @@ function createScreen(options = {}) {
|
|
|
3015
3028
|
} else if (code === 13) {
|
|
3016
3029
|
curX = 0;
|
|
3017
3030
|
emitExecute(13);
|
|
3031
|
+
} else if (code === 14) {
|
|
3032
|
+
activeG1 = true;
|
|
3033
|
+
emitExecute(14);
|
|
3034
|
+
} else if (code === 15) {
|
|
3035
|
+
activeG1 = false;
|
|
3036
|
+
emitExecute(15);
|
|
3018
3037
|
} else if (code >= 32) {
|
|
3019
3038
|
let char = ch;
|
|
3020
3039
|
if (code >= 55296 && code <= 56319 && i + 1 < text.length) {
|
|
@@ -3067,7 +3086,9 @@ function createScreen(options = {}) {
|
|
|
3067
3086
|
},
|
|
3068
3087
|
originMode,
|
|
3069
3088
|
autoWrap,
|
|
3070
|
-
charsetG0
|
|
3089
|
+
charsetG0,
|
|
3090
|
+
charsetG1,
|
|
3091
|
+
activeG1
|
|
3071
3092
|
};
|
|
3072
3093
|
parserState = "ground";
|
|
3073
3094
|
emitEsc("7", "");
|
|
@@ -3083,6 +3104,8 @@ function createScreen(options = {}) {
|
|
|
3083
3104
|
originMode = savedState.originMode;
|
|
3084
3105
|
autoWrap = savedState.autoWrap;
|
|
3085
3106
|
charsetG0 = savedState.charsetG0;
|
|
3107
|
+
charsetG1 = savedState.charsetG1;
|
|
3108
|
+
activeG1 = savedState.activeG1;
|
|
3086
3109
|
clampCursor();
|
|
3087
3110
|
parserState = "ground";
|
|
3088
3111
|
emitEsc("8", "");
|
|
@@ -3104,9 +3127,11 @@ function createScreen(options = {}) {
|
|
|
3104
3127
|
parserState = "escape_hash";
|
|
3105
3128
|
} else if (ch === "(") {
|
|
3106
3129
|
escIntermediate = "(";
|
|
3130
|
+
escBuf = "(";
|
|
3107
3131
|
parserState = "escape_charset";
|
|
3108
3132
|
} else if (ch === ")") {
|
|
3109
3133
|
escIntermediate = ")";
|
|
3134
|
+
escBuf = ")";
|
|
3110
3135
|
parserState = "escape_charset";
|
|
3111
3136
|
} else if (ch === "=") {
|
|
3112
3137
|
applicationKeypad = true;
|
|
@@ -3126,17 +3151,19 @@ function createScreen(options = {}) {
|
|
|
3126
3151
|
} else parserState = "ground";
|
|
3127
3152
|
break;
|
|
3128
3153
|
case "escape_charset":
|
|
3129
|
-
|
|
3130
|
-
|
|
3154
|
+
const designator = escBuf === ")" ? ")" : "(";
|
|
3155
|
+
if (designator === ")") charsetG1 = ch === "0";
|
|
3156
|
+
else charsetG0 = ch === "0";
|
|
3157
|
+
escBuf = "";
|
|
3131
3158
|
parserState = "ground";
|
|
3132
|
-
emitEsc(ch,
|
|
3159
|
+
emitEsc(ch, designator);
|
|
3133
3160
|
break;
|
|
3134
3161
|
case "escape_hash":
|
|
3135
3162
|
if (ch === "8") {
|
|
3136
3163
|
const alignCell = emptyCell();
|
|
3137
3164
|
alignCell.char = "E";
|
|
3138
3165
|
for (let r = 0; r < rows; r++) {
|
|
3139
|
-
const row = grid
|
|
3166
|
+
const row = itemAt(grid, r, "selective erase rows");
|
|
3140
3167
|
for (let c = 0; c < cols; c++) row.setCellRaw(c, alignCell);
|
|
3141
3168
|
softWrapped[r] = false;
|
|
3142
3169
|
}
|
|
@@ -3223,7 +3250,6 @@ function createScreen(options = {}) {
|
|
|
3223
3250
|
apcOverflow = false;
|
|
3224
3251
|
}
|
|
3225
3252
|
parserState = "ground";
|
|
3226
|
-
break;
|
|
3227
3253
|
}
|
|
3228
3254
|
}
|
|
3229
3255
|
flushPrintRun();
|
|
@@ -3283,10 +3309,10 @@ function createScreen(options = {}) {
|
|
|
3283
3309
|
const outLine = [];
|
|
3284
3310
|
let tracked = null;
|
|
3285
3311
|
for (let li = 0; li < logicalLines.length; li++) {
|
|
3286
|
-
const line = logicalLines
|
|
3312
|
+
const line = itemAt(logicalLines, li, "reflow logical lines");
|
|
3287
3313
|
let lineLen = line.length;
|
|
3288
3314
|
while (lineLen > 0) {
|
|
3289
|
-
const cell = line
|
|
3315
|
+
const cell = itemAt(line, lineLen - 1, "reflow logical-line cells");
|
|
3290
3316
|
if (cell.char === "" && !cell.wide) lineLen--;
|
|
3291
3317
|
else break;
|
|
3292
3318
|
}
|
|
@@ -3305,7 +3331,7 @@ function createScreen(options = {}) {
|
|
|
3305
3331
|
const row = makeRow(newCols);
|
|
3306
3332
|
let col = 0;
|
|
3307
3333
|
while (col < newCols && pos < lineLen) {
|
|
3308
|
-
const cell = line
|
|
3334
|
+
const cell = itemAt(line, pos, "reflow logical-line cells");
|
|
3309
3335
|
if (cell.wide && col + 2 > newCols) break;
|
|
3310
3336
|
if (track?.line === li && pos === track.offset) tracked = {
|
|
3311
3337
|
row: outRows.length,
|
|
@@ -3351,14 +3377,11 @@ function createScreen(options = {}) {
|
|
|
3351
3377
|
*/
|
|
3352
3378
|
function trimTrailingEmptyRows(result) {
|
|
3353
3379
|
const floor = result.tracked == null ? 1 : Math.max(1, result.tracked.row + 1);
|
|
3354
|
-
while (result.rows.length > floor) {
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
result.lineIndex?.pop();
|
|
3360
|
-
} else break;
|
|
3361
|
-
}
|
|
3380
|
+
while (result.rows.length > floor) if (packedRowIsBlank(itemAt(result.rows, result.rows.length - 1, "reflow result rows")) && !result.wrapped[result.rows.length - 2]) {
|
|
3381
|
+
result.rows.pop();
|
|
3382
|
+
result.wrapped.pop();
|
|
3383
|
+
result.lineIndex?.pop();
|
|
3384
|
+
} else break;
|
|
3362
3385
|
}
|
|
3363
3386
|
function resize(newCols, newRows) {
|
|
3364
3387
|
if (newCols === cols && newRows === rows) return;
|
|
@@ -3388,7 +3411,7 @@ function createScreen(options = {}) {
|
|
|
3388
3411
|
if (restoredRows.length > 0) {
|
|
3389
3412
|
let completed = 0;
|
|
3390
3413
|
for (const wrapped of restoredWrapped) if (!wrapped) completed++;
|
|
3391
|
-
if (cursorTrack.line === 0 && restoredWrapped[restoredWrapped.length - 1] === true) for (let i = restoredWrapped.length - 1; i >= 0 && restoredWrapped[i]; i--) cursorTrack.offset += restoredRows
|
|
3414
|
+
if (cursorTrack.line === 0 && restoredWrapped[restoredWrapped.length - 1] === true) for (let i = restoredWrapped.length - 1; i >= 0 && restoredWrapped[i]; i--) cursorTrack.offset += itemAt(restoredRows, i, "restored rows").length;
|
|
3392
3415
|
cursorTrack.line += completed;
|
|
3393
3416
|
}
|
|
3394
3417
|
const mainSrc = restoredRows.length > 0 ? [...restoredRows, ...mainGrid] : mainGrid;
|
|
@@ -3410,8 +3433,8 @@ function createScreen(options = {}) {
|
|
|
3410
3433
|
if (overflow !== void 0) bankScrollbackRow(overflow, mainResult.wrapped[r] ?? false, mainLogicalAttrs[mainResult.lineIndex[r] ?? 0] ?? 0);
|
|
3411
3434
|
}
|
|
3412
3435
|
for (let r = 0; r < newRows && mainStartRow + r < mainResult.rows.length; r++) {
|
|
3413
|
-
newMain[r] = mainResult.rows
|
|
3414
|
-
newMainWrapped[r] = mainResult.wrapped
|
|
3436
|
+
newMain[r] = itemAt(mainResult.rows, mainStartRow + r, "resized main rows");
|
|
3437
|
+
newMainWrapped[r] = itemAt(mainResult.wrapped, mainStartRow + r, "resized main wrap flags");
|
|
3415
3438
|
newMainAttrs[r] = mainLogicalAttrs[mainResult.lineIndex[mainStartRow + r] ?? 0] ?? 0;
|
|
3416
3439
|
}
|
|
3417
3440
|
const newAlt = makeGrid(newCols, newRows);
|
|
@@ -3419,8 +3442,8 @@ function createScreen(options = {}) {
|
|
|
3419
3442
|
const newAltAttrs = new Array(newRows).fill(0);
|
|
3420
3443
|
const altStartRow = Math.max(0, altResult.rows.length - newRows);
|
|
3421
3444
|
for (let r = 0; r < newRows && altStartRow + r < altResult.rows.length; r++) {
|
|
3422
|
-
newAlt[r] = altResult.rows
|
|
3423
|
-
newAltWrapped[r] = altResult.wrapped
|
|
3445
|
+
newAlt[r] = itemAt(altResult.rows, altStartRow + r, "resized alternate rows");
|
|
3446
|
+
newAltWrapped[r] = itemAt(altResult.wrapped, altStartRow + r, "resized alternate wrap flags");
|
|
3424
3447
|
newAltAttrs[r] = altLogicalAttrs[altResult.lineIndex[altStartRow + r] ?? 0] ?? 0;
|
|
3425
3448
|
}
|
|
3426
3449
|
const activeResult = useAltScreen ? altResult : mainResult;
|
|
@@ -3492,7 +3515,9 @@ function createScreen(options = {}) {
|
|
|
3492
3515
|
attrs: cloneAttrsSnapshot(savedState.attrs),
|
|
3493
3516
|
originMode: savedState.originMode,
|
|
3494
3517
|
autoWrap: savedState.autoWrap,
|
|
3495
|
-
charsetG0: savedState.charsetG0
|
|
3518
|
+
charsetG0: savedState.charsetG0,
|
|
3519
|
+
charsetG1: savedState.charsetG1,
|
|
3520
|
+
activeG1: savedState.activeG1
|
|
3496
3521
|
},
|
|
3497
3522
|
attrs: cloneAttrsSnapshot(attrs),
|
|
3498
3523
|
modes: {
|
|
@@ -3511,7 +3536,7 @@ function createScreen(options = {}) {
|
|
|
3511
3536
|
syncOutput,
|
|
3512
3537
|
kittyKeyboardFlags,
|
|
3513
3538
|
kittyKeyboardStack: [...kittyKeyboardStack],
|
|
3514
|
-
kittyGraphics:
|
|
3539
|
+
kittyGraphics: kittyGraphicsImages,
|
|
3515
3540
|
colorSchemeReporting,
|
|
3516
3541
|
decColumn: decColumnMode,
|
|
3517
3542
|
altScroll: altScrollMode,
|
|
@@ -3530,6 +3555,7 @@ function createScreen(options = {}) {
|
|
|
3530
3555
|
},
|
|
3531
3556
|
tabStops: [...tabStops].sort((a, b) => a - b),
|
|
3532
3557
|
title,
|
|
3558
|
+
iconLabel,
|
|
3533
3559
|
clipboard,
|
|
3534
3560
|
cwd,
|
|
3535
3561
|
notifications: [...notifications],
|
|
@@ -3556,6 +3582,8 @@ function createScreen(options = {}) {
|
|
|
3556
3582
|
},
|
|
3557
3583
|
unicode: {
|
|
3558
3584
|
charsetG0,
|
|
3585
|
+
charsetG1,
|
|
3586
|
+
activeG1,
|
|
3559
3587
|
lastChar,
|
|
3560
3588
|
pendingRegionalIndicator,
|
|
3561
3589
|
afterZWJ
|
|
@@ -3593,7 +3621,9 @@ function createScreen(options = {}) {
|
|
|
3593
3621
|
attrs: cloneAttrsSnapshot(snapshotValue.savedState.attrs),
|
|
3594
3622
|
originMode: snapshotValue.savedState.originMode,
|
|
3595
3623
|
autoWrap: snapshotValue.savedState.autoWrap,
|
|
3596
|
-
charsetG0: snapshotValue.savedState.charsetG0
|
|
3624
|
+
charsetG0: snapshotValue.savedState.charsetG0,
|
|
3625
|
+
charsetG1: snapshotValue.savedState.charsetG1 ?? false,
|
|
3626
|
+
activeG1: snapshotValue.savedState.activeG1 ?? false
|
|
3597
3627
|
};
|
|
3598
3628
|
attrs = cloneAttrsSnapshot(snapshotValue.attrs);
|
|
3599
3629
|
bracketedPaste = snapshotValue.modes.bracketedPaste;
|
|
@@ -3611,7 +3641,6 @@ function createScreen(options = {}) {
|
|
|
3611
3641
|
syncOutput = snapshotValue.modes.syncOutput;
|
|
3612
3642
|
kittyKeyboardFlags = snapshotValue.modes.kittyKeyboardFlags;
|
|
3613
3643
|
kittyKeyboardStack = [...snapshotValue.modes.kittyKeyboardStack];
|
|
3614
|
-
hasKittyGraphics = snapshotValue.modes.kittyGraphics;
|
|
3615
3644
|
colorSchemeReporting = snapshotValue.modes.colorSchemeReporting;
|
|
3616
3645
|
decColumnMode = snapshotValue.modes.decColumn;
|
|
3617
3646
|
altScrollMode = snapshotValue.modes.altScroll;
|
|
@@ -3626,6 +3655,7 @@ function createScreen(options = {}) {
|
|
|
3626
3655
|
colorStack.push(...snapshotValue.colors.stack.map(cloneColorStateSnapshot));
|
|
3627
3656
|
tabStops = new Set(snapshotValue.tabStops);
|
|
3628
3657
|
title = snapshotValue.title;
|
|
3658
|
+
iconLabel = Object.hasOwn(snapshotValue, "iconLabel") ? snapshotValue.iconLabel : snapshotValue.title;
|
|
3629
3659
|
clipboard = snapshotValue.clipboard;
|
|
3630
3660
|
cwd = snapshotValue.cwd;
|
|
3631
3661
|
notifications = [...snapshotValue.notifications];
|
|
@@ -3645,6 +3675,8 @@ function createScreen(options = {}) {
|
|
|
3645
3675
|
apcOverflow = snapshotValue.parser.apcOverflow ?? false;
|
|
3646
3676
|
utf8PendingBytes = [...snapshotValue.parser.utf8PendingBytes];
|
|
3647
3677
|
charsetG0 = snapshotValue.unicode.charsetG0;
|
|
3678
|
+
charsetG1 = snapshotValue.unicode.charsetG1 ?? false;
|
|
3679
|
+
activeG1 = snapshotValue.unicode.activeG1 ?? false;
|
|
3648
3680
|
lastChar = snapshotValue.unicode.lastChar;
|
|
3649
3681
|
pendingRegionalIndicator = snapshotValue.unicode.pendingRegionalIndicator;
|
|
3650
3682
|
afterZWJ = snapshotValue.unicode.afterZWJ;
|
|
@@ -3678,7 +3710,7 @@ function createScreen(options = {}) {
|
|
|
3678
3710
|
}
|
|
3679
3711
|
function getText() {
|
|
3680
3712
|
const lines = [];
|
|
3681
|
-
for (let r = 0; r < rows; r++) lines.push(rowToString(grid
|
|
3713
|
+
for (let r = 0; r < rows; r++) lines.push(rowToString(itemAt(grid, r, "screen text rows")));
|
|
3682
3714
|
return lines.join("\n");
|
|
3683
3715
|
}
|
|
3684
3716
|
function getScrollbackText() {
|
|
@@ -3697,7 +3729,7 @@ function createScreen(options = {}) {
|
|
|
3697
3729
|
}
|
|
3698
3730
|
function getRowAbsolute(row) {
|
|
3699
3731
|
if (row < 0 || row >= scrollback.length + rows) return makeRow(cols).toCells();
|
|
3700
|
-
return (row < scrollback.length ? scrollback
|
|
3732
|
+
return (row < scrollback.length ? itemAt(scrollback, row, "scrollback rows") : itemAt(grid, row - scrollback.length, "screen rows")).toCells().map(stripCellColorIndex);
|
|
3701
3733
|
}
|
|
3702
3734
|
function firstRetainedRow() {
|
|
3703
3735
|
return trimmedRowCount;
|
|
@@ -3772,7 +3804,7 @@ function createScreen(options = {}) {
|
|
|
3772
3804
|
case "leftRightMargin": return leftRightMarginMode;
|
|
3773
3805
|
case "colorSchemeReporting": return colorSchemeReporting;
|
|
3774
3806
|
case "kittyKeyboard": return kittyKeyboardFlags > 0;
|
|
3775
|
-
case "kittyGraphics": return
|
|
3807
|
+
case "kittyGraphics": return kittyGraphicsImages;
|
|
3776
3808
|
case "sixel": return hasSixel;
|
|
3777
3809
|
default: return false;
|
|
3778
3810
|
}
|
|
@@ -3850,7 +3882,7 @@ function createScreen(options = {}) {
|
|
|
3850
3882
|
leftRightMargin: leftRightMarginMode,
|
|
3851
3883
|
colorSchemeReporting,
|
|
3852
3884
|
kittyKeyboard: kittyKeyboardFlags > 0,
|
|
3853
|
-
kittyGraphics:
|
|
3885
|
+
kittyGraphics: kittyGraphicsImages,
|
|
3854
3886
|
sixel: hasSixel
|
|
3855
3887
|
};
|
|
3856
3888
|
}
|
|
@@ -4267,7 +4299,7 @@ function serializeSnapshot(snapshot, options = {}) {
|
|
|
4267
4299
|
const wraps = snapshot.scrollbackSoftWrapped;
|
|
4268
4300
|
const last = snapshot.scrollback.length - 1;
|
|
4269
4301
|
for (let i = 0; i < snapshot.scrollback.length; i++) {
|
|
4270
|
-
const row = snapshot.scrollback
|
|
4302
|
+
const row = itemAt(snapshot.scrollback, i, "snapshot scrollback rows");
|
|
4271
4303
|
if (wraps?.[i] === true && i < last) out.push(serializeEncodeRow(row, hyperlinks, snapshot.cols), "\x1B[0m");
|
|
4272
4304
|
else out.push(serializeEncodeRow(row, hyperlinks), "\x1B[0m\r\n");
|
|
4273
4305
|
}
|
|
@@ -4295,7 +4327,7 @@ function serializeSnapshot(snapshot, options = {}) {
|
|
|
4295
4327
|
const def = SERIALIZE_DEFAULT_PALETTE[i];
|
|
4296
4328
|
if (cur !== void 0 && def !== void 0 && !serializeColorEq(cur, def)) out.push(`\x1b]4;${String(i)};${serializeColorSpec(cur)}\x1b\\`);
|
|
4297
4329
|
}
|
|
4298
|
-
if (options.includeTitle === true && snapshot.title.length > 0) out.push(`\x1b]
|
|
4330
|
+
if (options.includeTitle === true && snapshot.title.length > 0) out.push(`\x1b]2;${snapshot.title}\x1b\\`);
|
|
4299
4331
|
out.push("\x1B[?7l", "\x1B[H\x1B[2J");
|
|
4300
4332
|
const grid = snapshot.activeBuffer === "alt" ? snapshot.alt.grid : snapshot.main.grid;
|
|
4301
4333
|
for (let r = 0; r < rows; r++) {
|
|
@@ -4306,6 +4338,8 @@ function serializeSnapshot(snapshot, options = {}) {
|
|
|
4306
4338
|
out.push(m.autoWrap ? "\x1B[?7h" : "\x1B[?7l");
|
|
4307
4339
|
if (snapshot.cursor.shape !== "block" || !snapshot.cursor.blinking) out.push(`\x1b[${String(serializeCursorStyleCode(snapshot.cursor.shape, snapshot.cursor.blinking))} q`);
|
|
4308
4340
|
if (snapshot.unicode.charsetG0) out.push("\x1B(0");
|
|
4341
|
+
if (snapshot.unicode.charsetG1) out.push("\x1B)0");
|
|
4342
|
+
if (snapshot.unicode.activeG1) out.push("");
|
|
4309
4343
|
if (m.insert && !excluded.has("insert")) out.push("\x1B[4h");
|
|
4310
4344
|
if (!serializeTabStopsAreDefault(snapshot.tabStops, snapshot.cols)) {
|
|
4311
4345
|
out.push("\x1B[3g");
|
|
@@ -4791,6 +4825,7 @@ function readGridSection(r, softWrapNullable, expected, strings, colors, styles)
|
|
|
4791
4825
|
* deterministic for identical input and decodes back to a deep-equal snapshot.
|
|
4792
4826
|
*/
|
|
4793
4827
|
function encodeScreenSnapshotBinary(snapshot) {
|
|
4828
|
+
if (Object.hasOwn(snapshot, "iconLabel") && typeof snapshot.iconLabel !== "string") throw new TypeError("vterm snapshot codec: invalid iconLabel");
|
|
4794
4829
|
const w = createWriter();
|
|
4795
4830
|
w.u8(VERSION);
|
|
4796
4831
|
const header = {
|
|
@@ -4807,6 +4842,7 @@ function encodeScreenSnapshotBinary(snapshot) {
|
|
|
4807
4842
|
colors: snapshot.colors,
|
|
4808
4843
|
tabStops: snapshot.tabStops,
|
|
4809
4844
|
title: snapshot.title,
|
|
4845
|
+
...Object.hasOwn(snapshot, "iconLabel") ? { iconLabel: snapshot.iconLabel } : {},
|
|
4810
4846
|
clipboard: snapshot.clipboard,
|
|
4811
4847
|
cwd: snapshot.cwd,
|
|
4812
4848
|
notifications: snapshot.notifications,
|
|
@@ -4840,6 +4876,7 @@ function decodeScreenSnapshotBinary(bytes) {
|
|
|
4840
4876
|
if (version !== VERSION) throw new Error(`vterm snapshot codec: unsupported version byte ${version} (expected ${VERSION})`);
|
|
4841
4877
|
const headerLen = r.varint();
|
|
4842
4878
|
const header = JSON.parse(decoder.decode(r.take(headerLen)));
|
|
4879
|
+
if (Object.hasOwn(header, "iconLabel") && typeof header.iconLabel !== "string") throw new TypeError("vterm snapshot codec: invalid iconLabel");
|
|
4843
4880
|
const strings = readStringTable(r);
|
|
4844
4881
|
const colors = readColorTable(r);
|
|
4845
4882
|
const styles = readStyleTable(r);
|
|
@@ -4875,6 +4912,7 @@ function decodeScreenSnapshotBinary(bytes) {
|
|
|
4875
4912
|
colors: header.colors,
|
|
4876
4913
|
tabStops: header.tabStops,
|
|
4877
4914
|
title: header.title,
|
|
4915
|
+
...Object.hasOwn(header, "iconLabel") ? { iconLabel: header.iconLabel } : {},
|
|
4878
4916
|
clipboard: header.clipboard,
|
|
4879
4917
|
cwd: header.cwd,
|
|
4880
4918
|
notifications: header.notifications,
|