@simon_he/vue-tui 0.0.5 → 0.0.6
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/dist/index.cjs +1478 -125
- package/dist/index.d.ts +119 -102
- package/dist/index.js +1295 -112
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isAbsolutePath, normalizePath, parsePathQuery, resolvePath, resolveUserPath as resolveUserPath$1, resolveUserPath$1 as resolveUserPath, stripTrailingSlash, suggestPaths, suggestPaths$1 } from "./path-suggest-CZQYJIIg.js";
|
|
2
|
-
import process from "node:process";
|
|
2
|
+
import process$1 from "node:process";
|
|
3
3
|
import { appendFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { Buffer } from "node:buffer";
|
|
5
5
|
import { EventEmitter } from "node:events";
|
|
6
|
-
import { computed, createRenderer, defineComponent, effectScope, h, inject, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, provide, reactive, ref, shallowReactive, shallowRef, toRef, vShow, watch, watchEffect } from "vue";
|
|
6
|
+
import { computed, createRenderer, defineComponent, effectScope, h, inject, nextTick, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, provide, reactive, ref, shallowReactive, shallowRef, toRef, vShow, watch, watchEffect } from "vue";
|
|
7
7
|
|
|
8
8
|
//#region src/core/ansi-palette.ts
|
|
9
9
|
const ANSI_PALETTE_HEX = Object.freeze({
|
|
@@ -1286,7 +1286,7 @@ function parseMouseSgr(sequence) {
|
|
|
1286
1286
|
handled: false,
|
|
1287
1287
|
event: null
|
|
1288
1288
|
};
|
|
1289
|
-
const env = (process === null || process === void 0 ? void 0 : process.env) ?? {};
|
|
1289
|
+
const env = (process$1 === null || process$1 === void 0 ? void 0 : process$1.env) ?? {};
|
|
1290
1290
|
const invertWheel = String(env.DIMCODE_WHEEL_INVERT ?? env.VUE_TUI_WHEEL_INVERT ?? "") === "1";
|
|
1291
1291
|
const mouseDebugEnabled = String(env.DIMCODE_MOUSE_DEBUG ?? env.VUE_TUI_MOUSE_DEBUG ?? "") === "1";
|
|
1292
1292
|
const mouseDebugPath = String(env.DIMCODE_MOUSE_DEBUG_PATH ?? env.VUE_TUI_MOUSE_DEBUG_PATH ?? "/tmp/goatchain-mouse-debug.log");
|
|
@@ -1654,8 +1654,8 @@ function ctrlKeyFromChar(ch) {
|
|
|
1654
1654
|
return null;
|
|
1655
1655
|
}
|
|
1656
1656
|
function createStdinDriver(options) {
|
|
1657
|
-
const stdin = options.stdin ?? process.stdin;
|
|
1658
|
-
const stdout = options.stdout ?? process.stdout;
|
|
1657
|
+
const stdin = options.stdin ?? process$1.stdin;
|
|
1658
|
+
const stdout = options.stdout ?? process$1.stdout;
|
|
1659
1659
|
if (!stdin || !stdout) throw new Error("createStdinDriver requires Node process.stdin/stdout");
|
|
1660
1660
|
const enableMouse = options.enableMouse ?? true;
|
|
1661
1661
|
const enableMouseMotion = options.enableMouseMotion ?? false;
|
|
@@ -2511,12 +2511,59 @@ function createGridBuffer(cols, rows) {
|
|
|
2511
2511
|
cursorStyle: DEFAULT_STYLE,
|
|
2512
2512
|
scrollback: [],
|
|
2513
2513
|
scrollbackLimit: 1e3,
|
|
2514
|
-
rowPool: []
|
|
2514
|
+
rowPool: [],
|
|
2515
|
+
soaFingerprints: null,
|
|
2516
|
+
fingerprintFn: null
|
|
2515
2517
|
};
|
|
2516
2518
|
}
|
|
2517
2519
|
function clamp$7(n, min, max) {
|
|
2518
2520
|
return Math.max(min, Math.min(max, n));
|
|
2519
2521
|
}
|
|
2522
|
+
/**
|
|
2523
|
+
* Register a fingerprint function on the buffer. This enables SoA fingerprint
|
|
2524
|
+
* pre-computation: cell writes will update fingerprints inline, and the renderer
|
|
2525
|
+
* can read them via getRowFingerprints() instead of per-cell hash computation.
|
|
2526
|
+
*/
|
|
2527
|
+
function setFingerprintFn(buffer, fn) {
|
|
2528
|
+
buffer.fingerprintFn = fn;
|
|
2529
|
+
const len = buffer.rows * buffer.cols;
|
|
2530
|
+
if (!len) {
|
|
2531
|
+
buffer.soaFingerprints = null;
|
|
2532
|
+
return;
|
|
2533
|
+
}
|
|
2534
|
+
buffer.soaFingerprints = new Uint32Array(len);
|
|
2535
|
+
for (let y = 0; y < buffer.rows; y++) {
|
|
2536
|
+
const row = getBufferRow(buffer, y);
|
|
2537
|
+
const physY = physicalRowIndex(buffer, y);
|
|
2538
|
+
const base = physY * buffer.cols;
|
|
2539
|
+
for (let x = 0; x < buffer.cols; x++) {
|
|
2540
|
+
const cell = row[x];
|
|
2541
|
+
buffer.soaFingerprints[base + x] = fn(cell.ch, cell.style);
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
/**
|
|
2546
|
+
* Get pre-computed fingerprints for a logical row as a TypedArray slice.
|
|
2547
|
+
* Returns null if fingerprinting is not enabled on this buffer.
|
|
2548
|
+
*/
|
|
2549
|
+
function getRowFingerprints(buffer, y) {
|
|
2550
|
+
if (!buffer.soaFingerprints) return null;
|
|
2551
|
+
const physY = physicalRowIndex(buffer, y);
|
|
2552
|
+
const base = physY * buffer.cols;
|
|
2553
|
+
return buffer.soaFingerprints.subarray(base, base + buffer.cols);
|
|
2554
|
+
}
|
|
2555
|
+
/** Update the SoA fingerprint for a single cell (called inline from putCell/fillRect). */
|
|
2556
|
+
function updateCellFingerprint(buffer, physY, x, ch, style) {
|
|
2557
|
+
if (!buffer.soaFingerprints || !buffer.fingerprintFn) return;
|
|
2558
|
+
buffer.soaFingerprints[physY * buffer.cols + x] = buffer.fingerprintFn(ch, style);
|
|
2559
|
+
}
|
|
2560
|
+
/** Update SoA fingerprints for a range of cells in a physical row. */
|
|
2561
|
+
function updateRangeFingerprint(buffer, physY, x0, x1, ch, style) {
|
|
2562
|
+
if (!buffer.soaFingerprints || !buffer.fingerprintFn) return;
|
|
2563
|
+
const fp = buffer.fingerprintFn(ch, style);
|
|
2564
|
+
const base = physY * buffer.cols;
|
|
2565
|
+
for (let x = x0; x < x1; x++) buffer.soaFingerprints[base + x] = fp;
|
|
2566
|
+
}
|
|
2520
2567
|
function physicalRowIndex(buffer, y) {
|
|
2521
2568
|
return (buffer.gridStart + y) % buffer.rows;
|
|
2522
2569
|
}
|
|
@@ -2575,8 +2622,14 @@ function putCell(buffer, x, y, ch, style) {
|
|
|
2575
2622
|
markDirty(buffer, y);
|
|
2576
2623
|
return;
|
|
2577
2624
|
}
|
|
2578
|
-
|
|
2625
|
+
const cell = createCell(ch, style);
|
|
2626
|
+
row[x] = cell;
|
|
2579
2627
|
if (width === 2 && x + 1 < buffer.cols) row[x + 1] = createContinuationCell(style);
|
|
2628
|
+
if (buffer.soaFingerprints) {
|
|
2629
|
+
const physY = physicalRowIndex(buffer, y);
|
|
2630
|
+
updateCellFingerprint(buffer, physY, x, cell.ch, cell.style);
|
|
2631
|
+
if (width === 2 && x + 1 < buffer.cols) updateCellFingerprint(buffer, physY, x + 1, "", cell.style);
|
|
2632
|
+
}
|
|
2580
2633
|
markDirty(buffer, y);
|
|
2581
2634
|
}
|
|
2582
2635
|
function fillRect(buffer, x, y, w, h$1, ch = " ", style) {
|
|
@@ -2596,6 +2649,10 @@ function fillRect(buffer, x, y, w, h$1, ch = " ", style) {
|
|
|
2596
2649
|
if ((_row$x = row[x0]) === null || _row$x === void 0 ? void 0 : _row$x.continuation) clearWideIfOverwriting(row, x0);
|
|
2597
2650
|
row.fill(fillCell, x0, x1);
|
|
2598
2651
|
if (x1 < buffer.cols && ((_row$x2 = row[x1]) === null || _row$x2 === void 0 ? void 0 : _row$x2.continuation)) row[x1] = blank;
|
|
2652
|
+
if (buffer.soaFingerprints) {
|
|
2653
|
+
const physY = physicalRowIndex(buffer, yy);
|
|
2654
|
+
updateRangeFingerprint(buffer, physY, x0, x1, fillCell.ch, fillCell.style);
|
|
2655
|
+
}
|
|
2599
2656
|
markDirty(buffer, yy);
|
|
2600
2657
|
}
|
|
2601
2658
|
return;
|
|
@@ -2654,6 +2711,18 @@ function blankRow(buffer) {
|
|
|
2654
2711
|
for (let x = 0; x < buffer.cols; x++) pooled[x] = blank;
|
|
2655
2712
|
return pooled;
|
|
2656
2713
|
}
|
|
2714
|
+
function recomputeFingerprintsForRows(buffer, startY, endY) {
|
|
2715
|
+
if (!buffer.soaFingerprints || !buffer.fingerprintFn) return;
|
|
2716
|
+
for (let y = startY; y < endY; y++) {
|
|
2717
|
+
const row = getBufferRow(buffer, y);
|
|
2718
|
+
const physY = physicalRowIndex(buffer, y);
|
|
2719
|
+
const base = physY * buffer.cols;
|
|
2720
|
+
for (let x = 0; x < buffer.cols; x++) {
|
|
2721
|
+
const cell = row[x];
|
|
2722
|
+
buffer.soaFingerprints[base + x] = buffer.fingerprintFn(cell.ch, cell.style);
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2657
2726
|
function scrollBuffer(buffer, lines) {
|
|
2658
2727
|
const n = Math.trunc(lines);
|
|
2659
2728
|
if (n === 0 || buffer.rows === 0) return;
|
|
@@ -2682,6 +2751,63 @@ function scrollBuffer(buffer, lines) {
|
|
|
2682
2751
|
markAllDirty(buffer);
|
|
2683
2752
|
buffer.cursorY = clamp$7(buffer.cursorY - n, 0, Math.max(0, buffer.rows - 1));
|
|
2684
2753
|
}
|
|
2754
|
+
function scrollBufferRegion(buffer, startY, endY, lines) {
|
|
2755
|
+
const n = Math.trunc(lines);
|
|
2756
|
+
if (n === 0 || buffer.rows === 0) return [];
|
|
2757
|
+
const start = clamp$7(Math.floor(startY), 0, buffer.rows);
|
|
2758
|
+
const end = clamp$7(Math.floor(endY), 0, buffer.rows);
|
|
2759
|
+
const height = end - start;
|
|
2760
|
+
if (height <= 0) return [];
|
|
2761
|
+
const absDelta = Math.abs(n);
|
|
2762
|
+
const insertedRows = [];
|
|
2763
|
+
const replaceRegionWithBlankRows = () => {
|
|
2764
|
+
for (let y = start; y < end; y++) {
|
|
2765
|
+
const physY = physicalRowIndex(buffer, y);
|
|
2766
|
+
buffer.rowPool.push(buffer.grid[physY]);
|
|
2767
|
+
buffer.grid[physY] = blankRow(buffer);
|
|
2768
|
+
markDirty(buffer, y);
|
|
2769
|
+
insertedRows.push(y);
|
|
2770
|
+
}
|
|
2771
|
+
};
|
|
2772
|
+
if (absDelta >= height) {
|
|
2773
|
+
replaceRegionWithBlankRows();
|
|
2774
|
+
recomputeFingerprintsForRows(buffer, start, end);
|
|
2775
|
+
if (buffer.cursorY >= start && buffer.cursorY < end) buffer.cursorY = clamp$7(buffer.cursorY - n, start, Math.max(start, end - 1));
|
|
2776
|
+
return insertedRows;
|
|
2777
|
+
}
|
|
2778
|
+
const regionRows = [];
|
|
2779
|
+
for (let y = start; y < end; y++) regionRows.push(getBufferRow(buffer, y));
|
|
2780
|
+
const nextRows = Array.from({ length: height }, () => []);
|
|
2781
|
+
if (n > 0) {
|
|
2782
|
+
const movedCount = height - n;
|
|
2783
|
+
for (let i = 0; i < movedCount; i++) nextRows[i] = regionRows[i + n];
|
|
2784
|
+
for (let i = 0; i < n; i++) {
|
|
2785
|
+
buffer.rowPool.push(regionRows[i]);
|
|
2786
|
+
const y = end - n + i;
|
|
2787
|
+
nextRows[movedCount + i] = blankRow(buffer);
|
|
2788
|
+
markDirty(buffer, y);
|
|
2789
|
+
insertedRows.push(y);
|
|
2790
|
+
}
|
|
2791
|
+
} else {
|
|
2792
|
+
const insertedCount = -n;
|
|
2793
|
+
const movedCount = height - insertedCount;
|
|
2794
|
+
for (let i = 0; i < insertedCount; i++) {
|
|
2795
|
+
buffer.rowPool.push(regionRows[height - insertedCount + i]);
|
|
2796
|
+
const y = start + i;
|
|
2797
|
+
nextRows[i] = blankRow(buffer);
|
|
2798
|
+
markDirty(buffer, y);
|
|
2799
|
+
insertedRows.push(y);
|
|
2800
|
+
}
|
|
2801
|
+
for (let i = 0; i < movedCount; i++) nextRows[insertedCount + i] = regionRows[i];
|
|
2802
|
+
}
|
|
2803
|
+
for (let i = 0; i < height; i++) {
|
|
2804
|
+
const physY = physicalRowIndex(buffer, start + i);
|
|
2805
|
+
buffer.grid[physY] = nextRows[i];
|
|
2806
|
+
}
|
|
2807
|
+
recomputeFingerprintsForRows(buffer, start, end);
|
|
2808
|
+
if (buffer.cursorY >= start && buffer.cursorY < end) buffer.cursorY = clamp$7(buffer.cursorY - n, start, Math.max(start, end - 1));
|
|
2809
|
+
return insertedRows;
|
|
2810
|
+
}
|
|
2685
2811
|
function resizeBuffer(buffer, cols, rows) {
|
|
2686
2812
|
const nextCols = Math.max(0, Math.floor(cols));
|
|
2687
2813
|
const nextRows = Math.max(0, Math.floor(rows));
|
|
@@ -2712,6 +2838,20 @@ function resizeBuffer(buffer, cols, rows) {
|
|
|
2712
2838
|
buffer.dirtyAll = nextRows > 0;
|
|
2713
2839
|
buffer.cursorX = clamp$7(buffer.cursorX, 0, Math.max(0, nextCols));
|
|
2714
2840
|
buffer.cursorY = clamp$7(buffer.cursorY, 0, Math.max(0, nextRows - 1));
|
|
2841
|
+
if (buffer.fingerprintFn) {
|
|
2842
|
+
const len = nextRows * nextCols;
|
|
2843
|
+
if (len > 0) {
|
|
2844
|
+
buffer.soaFingerprints = new Uint32Array(len);
|
|
2845
|
+
for (let y = 0; y < nextRows; y++) {
|
|
2846
|
+
const row = nextGrid[y];
|
|
2847
|
+
const base = y * nextCols;
|
|
2848
|
+
for (let x = 0; x < nextCols; x++) {
|
|
2849
|
+
const cell = row[x];
|
|
2850
|
+
buffer.soaFingerprints[base + x] = buffer.fingerprintFn(cell.ch, cell.style);
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
} else buffer.soaFingerprints = null;
|
|
2854
|
+
}
|
|
2715
2855
|
}
|
|
2716
2856
|
function snapshotText(buffer) {
|
|
2717
2857
|
const out = [];
|
|
@@ -2874,6 +3014,32 @@ function scrollPlaneCoverage(state, lines) {
|
|
|
2874
3014
|
state.coverage.splice(rows + n, -n);
|
|
2875
3015
|
for (let i = 0; i < -n; i++) state.coverage.unshift(new Uint8Array(cols));
|
|
2876
3016
|
}
|
|
3017
|
+
function scrollPlaneCoverageRegion(state, startY, endY, lines) {
|
|
3018
|
+
const n = Math.trunc(lines);
|
|
3019
|
+
if (n === 0 || state.coverage.length === 0) return;
|
|
3020
|
+
const start = Math.max(0, Math.min(state.coverage.length, Math.floor(startY)));
|
|
3021
|
+
const end = Math.max(0, Math.min(state.coverage.length, Math.floor(endY)));
|
|
3022
|
+
const height = end - start;
|
|
3023
|
+
if (height <= 0) return;
|
|
3024
|
+
const cols = state.buffer.cols;
|
|
3025
|
+
if (Math.abs(n) >= height) {
|
|
3026
|
+
for (let y = start; y < end; y++) state.coverage[y] = new Uint8Array(cols);
|
|
3027
|
+
return;
|
|
3028
|
+
}
|
|
3029
|
+
const region = state.coverage.slice(start, end);
|
|
3030
|
+
const next = Array.from({ length: height }, () => new Uint8Array(0));
|
|
3031
|
+
if (n > 0) {
|
|
3032
|
+
const movedCount = height - n;
|
|
3033
|
+
for (let i = 0; i < movedCount; i++) next[i] = region[i + n];
|
|
3034
|
+
for (let i = 0; i < n; i++) next[movedCount + i] = new Uint8Array(cols);
|
|
3035
|
+
} else {
|
|
3036
|
+
const insertedCount = -n;
|
|
3037
|
+
const movedCount = height - insertedCount;
|
|
3038
|
+
for (let i = 0; i < insertedCount; i++) next[i] = new Uint8Array(cols);
|
|
3039
|
+
for (let i = 0; i < movedCount; i++) next[insertedCount + i] = region[i];
|
|
3040
|
+
}
|
|
3041
|
+
for (let i = 0; i < height; i++) state.coverage[start + i] = next[i];
|
|
3042
|
+
}
|
|
2877
3043
|
function resizePlaneState(state, cols, rows) {
|
|
2878
3044
|
resizeBuffer(state.buffer, cols, rows);
|
|
2879
3045
|
state.coverage = resizeCoverage(state.coverage, state.buffer.cols, state.buffer.rows);
|
|
@@ -2902,6 +3068,14 @@ function resetPlaneRowsForRender(terminal, plane, dirtyRows) {
|
|
|
2902
3068
|
const internals = terminal[TERMINAL_PLANE_INTERNALS];
|
|
2903
3069
|
internals === null || internals === void 0 || internals.resetRowsForRender(plane, dirtyRows);
|
|
2904
3070
|
}
|
|
3071
|
+
function getPlaneRowCoverageKind(terminal, plane, y) {
|
|
3072
|
+
const internals = terminal[TERMINAL_PLANE_INTERNALS];
|
|
3073
|
+
return (internals === null || internals === void 0 ? void 0 : internals.getRowCoverageKind(plane, y)) ?? 0;
|
|
3074
|
+
}
|
|
3075
|
+
function scrollPlaneRows(terminal, plane, startY, endY, lines) {
|
|
3076
|
+
const internals = terminal[TERMINAL_PLANE_INTERNALS];
|
|
3077
|
+
internals === null || internals === void 0 || internals.scrollRows(plane, startY, endY, lines);
|
|
3078
|
+
}
|
|
2905
3079
|
function createTerminal(opts) {
|
|
2906
3080
|
const emitter = new Emitter();
|
|
2907
3081
|
const compositeBuffer = createGridBuffer(opts.cols, opts.rows);
|
|
@@ -2911,6 +3085,7 @@ function createTerminal(opts) {
|
|
|
2911
3085
|
let pendingCommit = false;
|
|
2912
3086
|
let pendingCommitAllPlanes = false;
|
|
2913
3087
|
let pendingCommitPlanes = null;
|
|
3088
|
+
const pendingPlaneScrollOps = new Map();
|
|
2914
3089
|
const planeTerminals = new Map();
|
|
2915
3090
|
let base;
|
|
2916
3091
|
compositeBuffer.cursorVisible = false;
|
|
@@ -3031,8 +3206,145 @@ function createTerminal(opts) {
|
|
|
3031
3206
|
scrollBuffer(state.buffer, lines);
|
|
3032
3207
|
scrollPlaneCoverage(state, lines);
|
|
3033
3208
|
}
|
|
3209
|
+
function normalizeScrollOperation(startY, endY, delta, totalRows) {
|
|
3210
|
+
const start = Math.max(0, Math.min(totalRows, Math.floor(startY)));
|
|
3211
|
+
const end = Math.max(0, Math.min(totalRows, Math.floor(endY)));
|
|
3212
|
+
const height = end - start;
|
|
3213
|
+
const lines = Math.trunc(delta);
|
|
3214
|
+
if (height <= 0 || lines === 0 || Math.abs(lines) >= height) return null;
|
|
3215
|
+
return {
|
|
3216
|
+
startY: start,
|
|
3217
|
+
endY: end,
|
|
3218
|
+
delta: lines
|
|
3219
|
+
};
|
|
3220
|
+
}
|
|
3221
|
+
function recordPendingScrollOp(plane, op) {
|
|
3222
|
+
const prev = pendingPlaneScrollOps.get(plane);
|
|
3223
|
+
if (prev && prev.startY === op.startY && prev.endY === op.endY) {
|
|
3224
|
+
const nextDelta = prev.delta + op.delta;
|
|
3225
|
+
if (nextDelta === 0) {
|
|
3226
|
+
pendingPlaneScrollOps.delete(plane);
|
|
3227
|
+
return;
|
|
3228
|
+
}
|
|
3229
|
+
const next = normalizeScrollOperation(op.startY, op.endY, nextDelta, compositeBuffer.rows);
|
|
3230
|
+
if (!next) {
|
|
3231
|
+
pendingPlaneScrollOps.delete(plane);
|
|
3232
|
+
return;
|
|
3233
|
+
}
|
|
3234
|
+
pendingPlaneScrollOps.set(plane, next);
|
|
3235
|
+
return;
|
|
3236
|
+
}
|
|
3237
|
+
pendingPlaneScrollOps.set(plane, op);
|
|
3238
|
+
}
|
|
3239
|
+
function takePendingScrollOps(planes) {
|
|
3240
|
+
const planesToTake = (planes === null || planes === void 0 ? void 0 : planes.length) ? planes : TERMINAL_RENDER_PLANES;
|
|
3241
|
+
const out = [];
|
|
3242
|
+
for (const plane of planesToTake) {
|
|
3243
|
+
const op = pendingPlaneScrollOps.get(plane);
|
|
3244
|
+
if (!op) continue;
|
|
3245
|
+
pendingPlaneScrollOps.delete(plane);
|
|
3246
|
+
out.push({
|
|
3247
|
+
plane,
|
|
3248
|
+
...op
|
|
3249
|
+
});
|
|
3250
|
+
}
|
|
3251
|
+
return out.length ? out : null;
|
|
3252
|
+
}
|
|
3253
|
+
function higherPlanesFor(plane) {
|
|
3254
|
+
const planeIndex = TERMINAL_RENDER_PLANES.indexOf(plane);
|
|
3255
|
+
if (planeIndex < 0) return [];
|
|
3256
|
+
return TERMINAL_RENDER_PLANES.slice(planeIndex + 1);
|
|
3257
|
+
}
|
|
3258
|
+
function higherPlaneCoverageKind(plane, y) {
|
|
3259
|
+
const higherPlanes = higherPlanesFor(plane);
|
|
3260
|
+
if (!higherPlanes.length || y < 0 || y >= compositeBuffer.rows) return 0;
|
|
3261
|
+
let covered = 0;
|
|
3262
|
+
for (let x = 0; x < compositeBuffer.cols; x++) {
|
|
3263
|
+
let cellCovered = false;
|
|
3264
|
+
for (const higherPlane of higherPlanes) {
|
|
3265
|
+
var _state$coverage$y2;
|
|
3266
|
+
const state = planeStates.get(higherPlane);
|
|
3267
|
+
if (state === null || state === void 0 || (_state$coverage$y2 = state.coverage[y]) === null || _state$coverage$y2 === void 0 ? void 0 : _state$coverage$y2[x]) {
|
|
3268
|
+
cellCovered = true;
|
|
3269
|
+
break;
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
if (cellCovered) covered++;
|
|
3273
|
+
}
|
|
3274
|
+
if (covered === 0) return 0;
|
|
3275
|
+
if (covered >= compositeBuffer.cols) return 2;
|
|
3276
|
+
return 1;
|
|
3277
|
+
}
|
|
3278
|
+
function prepareCompositeScrollOps(pendingOps) {
|
|
3279
|
+
if (!(pendingOps === null || pendingOps === void 0 ? void 0 : pendingOps.length)) return {
|
|
3280
|
+
scrollOperations: null,
|
|
3281
|
+
extraDirtyRows: []
|
|
3282
|
+
};
|
|
3283
|
+
const scrollOperations = [];
|
|
3284
|
+
const extraDirtyRows = new Set();
|
|
3285
|
+
for (const pending of pendingOps) {
|
|
3286
|
+
const blockedRows = new Set();
|
|
3287
|
+
const partiallyBlockedRows = new Set();
|
|
3288
|
+
for (let y = pending.startY; y < pending.endY; y++) {
|
|
3289
|
+
const coverageKind = higherPlaneCoverageKind(pending.plane, y);
|
|
3290
|
+
if (coverageKind === 0) continue;
|
|
3291
|
+
blockedRows.add(y);
|
|
3292
|
+
if (coverageKind === 1) partiallyBlockedRows.add(y);
|
|
3293
|
+
}
|
|
3294
|
+
if (!blockedRows.size) {
|
|
3295
|
+
scrollOperations.push({
|
|
3296
|
+
startY: pending.startY,
|
|
3297
|
+
endY: pending.endY,
|
|
3298
|
+
delta: pending.delta
|
|
3299
|
+
});
|
|
3300
|
+
continue;
|
|
3301
|
+
}
|
|
3302
|
+
const absDelta = Math.abs(pending.delta);
|
|
3303
|
+
for (let y = pending.startY; y < pending.endY; y++) if (partiallyBlockedRows.has(y)) extraDirtyRows.add(y);
|
|
3304
|
+
let bandStart = -1;
|
|
3305
|
+
const flushBand = (bandEnd) => {
|
|
3306
|
+
if (bandStart < 0 || bandEnd <= bandStart) return;
|
|
3307
|
+
const bandHeight = bandEnd - bandStart;
|
|
3308
|
+
if (absDelta >= bandHeight) {
|
|
3309
|
+
for (let y = bandStart; y < bandEnd; y++) extraDirtyRows.add(y);
|
|
3310
|
+
bandStart = -1;
|
|
3311
|
+
return;
|
|
3312
|
+
}
|
|
3313
|
+
scrollOperations.push({
|
|
3314
|
+
startY: bandStart,
|
|
3315
|
+
endY: bandEnd,
|
|
3316
|
+
delta: pending.delta
|
|
3317
|
+
});
|
|
3318
|
+
if (pending.delta > 0) for (let y = bandEnd - absDelta; y < bandEnd; y++) extraDirtyRows.add(y);
|
|
3319
|
+
else for (let y = bandStart; y < bandStart + absDelta; y++) extraDirtyRows.add(y);
|
|
3320
|
+
bandStart = -1;
|
|
3321
|
+
};
|
|
3322
|
+
for (let y = pending.startY; y < pending.endY; y++) {
|
|
3323
|
+
if (blockedRows.has(y)) {
|
|
3324
|
+
flushBand(y);
|
|
3325
|
+
continue;
|
|
3326
|
+
}
|
|
3327
|
+
if (bandStart < 0) bandStart = y;
|
|
3328
|
+
}
|
|
3329
|
+
flushBand(pending.endY);
|
|
3330
|
+
}
|
|
3331
|
+
return {
|
|
3332
|
+
scrollOperations: scrollOperations.length ? scrollOperations : null,
|
|
3333
|
+
extraDirtyRows: Array.from(extraDirtyRows).sort((a, b) => a - b)
|
|
3334
|
+
};
|
|
3335
|
+
}
|
|
3336
|
+
function scrollRowsForPlane(plane, startY, endY, lines) {
|
|
3337
|
+
const state = getPlaneState(plane);
|
|
3338
|
+
const op = normalizeScrollOperation(startY, endY, lines, state.buffer.rows);
|
|
3339
|
+
if (!op) return;
|
|
3340
|
+
scrollBufferRegion(state.buffer, op.startY, op.endY, op.delta);
|
|
3341
|
+
scrollPlaneCoverageRegion(state, op.startY, op.endY, op.delta);
|
|
3342
|
+
recordPendingScrollOp(plane, op);
|
|
3343
|
+
}
|
|
3034
3344
|
function composeRows(rows) {
|
|
3035
3345
|
const blank = createBlankCell();
|
|
3346
|
+
const fpFn = compositeBuffer.fingerprintFn;
|
|
3347
|
+
const fpArr = compositeBuffer.soaFingerprints;
|
|
3036
3348
|
const rowList = rows ?? Array.from({ length: compositeBuffer.rows }, (_, index) => index);
|
|
3037
3349
|
for (const y of rowList) {
|
|
3038
3350
|
if (y < 0 || y >= compositeBuffer.rows) continue;
|
|
@@ -3056,6 +3368,14 @@ function createTerminal(opts) {
|
|
|
3056
3368
|
if (x === 0 || dst[x - 1].width !== 2 || dst[x - 1].continuation) dst[x] = blank;
|
|
3057
3369
|
}
|
|
3058
3370
|
}
|
|
3371
|
+
if (fpFn && fpArr) {
|
|
3372
|
+
const physY = (compositeBuffer.gridStart + y) % compositeBuffer.rows;
|
|
3373
|
+
const base$1 = physY * cols;
|
|
3374
|
+
for (let x = 0; x < cols; x++) {
|
|
3375
|
+
const cell = dst[x];
|
|
3376
|
+
fpArr[base$1 + x] = fpFn(cell.ch, cell.style);
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3059
3379
|
markDirty(compositeBuffer, y);
|
|
3060
3380
|
}
|
|
3061
3381
|
}
|
|
@@ -3228,6 +3548,14 @@ function createTerminal(opts) {
|
|
|
3228
3548
|
const all = state.buffer.scrollback.map((row) => row.map((cell) => cell.continuation ? " " : cell.ch || " ").join(""));
|
|
3229
3549
|
if (count == null) return all;
|
|
3230
3550
|
return all.slice(Math.max(0, all.length - Math.max(0, Math.floor(count))));
|
|
3551
|
+
},
|
|
3552
|
+
setFingerprintFn(fn) {
|
|
3553
|
+
assertNotDisposed();
|
|
3554
|
+
base.setFingerprintFn(fn);
|
|
3555
|
+
},
|
|
3556
|
+
getRowFingerprints(y) {
|
|
3557
|
+
assertNotDisposed();
|
|
3558
|
+
return base.getRowFingerprints(y);
|
|
3231
3559
|
}
|
|
3232
3560
|
};
|
|
3233
3561
|
planeTerminals.set(plane, api);
|
|
@@ -3302,6 +3630,9 @@ function createTerminal(opts) {
|
|
|
3302
3630
|
return pendingDirtyRowsForPlanes((meta === null || meta === void 0 ? void 0 : meta.planes) ?? null);
|
|
3303
3631
|
}
|
|
3304
3632
|
const planesToCompose = (meta === null || meta === void 0 || (_meta$planes2 = meta.planes) === null || _meta$planes2 === void 0 ? void 0 : _meta$planes2.length) ? meta.planes : TERMINAL_RENDER_PLANES;
|
|
3633
|
+
const pendingScrollOps = takePendingScrollOps(planesToCompose);
|
|
3634
|
+
const preparedScroll = prepareCompositeScrollOps(pendingScrollOps);
|
|
3635
|
+
const scrollOperations = preparedScroll.scrollOperations;
|
|
3305
3636
|
let composeAllRows = false;
|
|
3306
3637
|
const dirtyRows = new Set();
|
|
3307
3638
|
for (const plane of planesToCompose) {
|
|
@@ -3314,13 +3645,17 @@ function createTerminal(opts) {
|
|
|
3314
3645
|
}
|
|
3315
3646
|
for (const y of rows) dirtyRows.add(y);
|
|
3316
3647
|
}
|
|
3648
|
+
for (const y of preparedScroll.extraDirtyRows) dirtyRows.add(y);
|
|
3317
3649
|
const normalizedDirtyRows = composeAllRows ? null : Array.from(dirtyRows).sort((a, b) => a - b);
|
|
3650
|
+
if (scrollOperations) for (const op of scrollOperations) scrollBufferRegion(compositeBuffer, op.startY, op.endY, op.delta);
|
|
3318
3651
|
if (normalizedDirtyRows !== null && normalizedDirtyRows.length === 0) {
|
|
3319
3652
|
const pendingCompositeRows = collectAndClearDirtyRows(compositeBuffer);
|
|
3320
3653
|
if (pendingCompositeRows !== null && pendingCompositeRows.length === 0) return pendingCompositeRows;
|
|
3321
3654
|
emitter.emit("commit", {
|
|
3322
3655
|
dirtyRows: pendingCompositeRows,
|
|
3323
|
-
planes: (meta === null || meta === void 0 ? void 0 : meta.planes) ?? null
|
|
3656
|
+
planes: (meta === null || meta === void 0 ? void 0 : meta.planes) ?? null,
|
|
3657
|
+
sync: meta === null || meta === void 0 ? void 0 : meta.sync,
|
|
3658
|
+
scrollOperations
|
|
3324
3659
|
});
|
|
3325
3660
|
return pendingCompositeRows;
|
|
3326
3661
|
}
|
|
@@ -3331,7 +3666,9 @@ function createTerminal(opts) {
|
|
|
3331
3666
|
if (committedRows !== null && committedRows.length === 0) return committedRows;
|
|
3332
3667
|
emitter.emit("commit", {
|
|
3333
3668
|
dirtyRows: committedRows,
|
|
3334
|
-
planes: (meta === null || meta === void 0 ? void 0 : meta.planes) ?? null
|
|
3669
|
+
planes: (meta === null || meta === void 0 ? void 0 : meta.planes) ?? null,
|
|
3670
|
+
sync: meta === null || meta === void 0 ? void 0 : meta.sync,
|
|
3671
|
+
scrollOperations
|
|
3335
3672
|
});
|
|
3336
3673
|
return committedRows;
|
|
3337
3674
|
},
|
|
@@ -3386,6 +3723,14 @@ function createTerminal(opts) {
|
|
|
3386
3723
|
const all = state.buffer.scrollback.map((row) => row.map((cell) => cell.continuation ? " " : cell.ch || " ").join(""));
|
|
3387
3724
|
if (count == null) return all;
|
|
3388
3725
|
return all.slice(Math.max(0, all.length - Math.max(0, Math.floor(count))));
|
|
3726
|
+
},
|
|
3727
|
+
setFingerprintFn(fn) {
|
|
3728
|
+
assertNotDisposed();
|
|
3729
|
+
setFingerprintFn(compositeBuffer, fn);
|
|
3730
|
+
},
|
|
3731
|
+
getRowFingerprints(y) {
|
|
3732
|
+
assertNotDisposed();
|
|
3733
|
+
return getRowFingerprints(compositeBuffer, y);
|
|
3389
3734
|
}
|
|
3390
3735
|
};
|
|
3391
3736
|
base[TERMINAL_PLANE_INTERNALS] = {
|
|
@@ -3398,6 +3743,20 @@ function createTerminal(opts) {
|
|
|
3398
3743
|
return;
|
|
3399
3744
|
}
|
|
3400
3745
|
for (const y of rows) clearPlaneCoverageRow(state, y);
|
|
3746
|
+
},
|
|
3747
|
+
getRowCoverageKind(plane, y) {
|
|
3748
|
+
const state = getPlaneState(plane);
|
|
3749
|
+
if (y < 0 || y >= state.coverage.length) return 0;
|
|
3750
|
+
const row = state.coverage[y];
|
|
3751
|
+
if (!(row === null || row === void 0 ? void 0 : row.length)) return 0;
|
|
3752
|
+
let covered = 0;
|
|
3753
|
+
for (let x = 0; x < row.length; x++) if (row[x]) covered++;
|
|
3754
|
+
if (covered === 0) return 0;
|
|
3755
|
+
if (covered >= row.length) return 2;
|
|
3756
|
+
return 1;
|
|
3757
|
+
},
|
|
3758
|
+
scrollRows(plane, startY, endY, lines) {
|
|
3759
|
+
scrollRowsForPlane(plane, startY, endY, lines);
|
|
3401
3760
|
}
|
|
3402
3761
|
};
|
|
3403
3762
|
return base;
|
|
@@ -3719,7 +4078,7 @@ function createCliEventManager(options) {
|
|
|
3719
4078
|
handler(event);
|
|
3720
4079
|
} catch (err) {
|
|
3721
4080
|
try {
|
|
3722
|
-
const env = process === null || process === void 0 ? void 0 : process.env;
|
|
4081
|
+
const env = process$1 === null || process$1 === void 0 ? void 0 : process$1.env;
|
|
3723
4082
|
if ((env === null || env === void 0 ? void 0 : env.DIMCODE_DEBUG) === "1") {
|
|
3724
4083
|
const timestamp = new Date().toISOString().split("T")[1].slice(0, -1);
|
|
3725
4084
|
appendFileSync("/tmp/goatchain-debug.log", `[${timestamp}] [EVENT-MGR] ERROR in handler ${node.id}.${handlerKey}: ${err}\n`);
|
|
@@ -5057,7 +5416,7 @@ function formatClockTime(ms) {
|
|
|
5057
5416
|
}
|
|
5058
5417
|
function createTuiProfiler(name) {
|
|
5059
5418
|
var _unref;
|
|
5060
|
-
const env = process === null || process === void 0 ? void 0 : process.env;
|
|
5419
|
+
const env = process$1 === null || process$1 === void 0 ? void 0 : process$1.env;
|
|
5061
5420
|
if (!parseEnabled(env === null || env === void 0 ? void 0 : env.DIMCODE_PROFILE_TUI)) return null;
|
|
5062
5421
|
const format = parseLogFormat(env === null || env === void 0 ? void 0 : env.DIMCODE_PROFILE_TUI_FORMAT);
|
|
5063
5422
|
const logDest = parseLogDest(env === null || env === void 0 ? void 0 : env.DIMCODE_PROFILE_TUI_LOG_DEST);
|
|
@@ -5536,7 +5895,7 @@ function write(data) {
|
|
|
5536
5895
|
* Check if debug logging is enabled via environment variable
|
|
5537
5896
|
*/
|
|
5538
5897
|
function isDebugEnabled() {
|
|
5539
|
-
const env = process === null || process === void 0 ? void 0 : process.env;
|
|
5898
|
+
const env = process$1 === null || process$1 === void 0 ? void 0 : process$1.env;
|
|
5540
5899
|
return (env === null || env === void 0 ? void 0 : env.DIMCODE_DEBUG) === "1" || (env === null || env === void 0 ? void 0 : env.DEBUG) === "1";
|
|
5541
5900
|
}
|
|
5542
5901
|
|
|
@@ -6012,6 +6371,26 @@ function createRenderManager(terminal) {
|
|
|
6012
6371
|
if (y > state.dirtyMaxY) state.dirtyMaxY = y;
|
|
6013
6372
|
}
|
|
6014
6373
|
}
|
|
6374
|
+
function markRows(plane, rows) {
|
|
6375
|
+
if (!rows.length) return;
|
|
6376
|
+
const state = getDirtyState(plane);
|
|
6377
|
+
for (let i = 0; i < rows.length; i++) {
|
|
6378
|
+
const y = Math.floor(rows[i] ?? -1);
|
|
6379
|
+
if (y < 0 || y >= terminalRows) continue;
|
|
6380
|
+
if (state.dirtyRowBits[y] === 0) {
|
|
6381
|
+
state.dirtyRowBits[y] = 1;
|
|
6382
|
+
state.dirtyRowCount++;
|
|
6383
|
+
if (y < state.dirtyMinY) state.dirtyMinY = y;
|
|
6384
|
+
if (y > state.dirtyMaxY) state.dirtyMaxY = y;
|
|
6385
|
+
}
|
|
6386
|
+
}
|
|
6387
|
+
}
|
|
6388
|
+
function scrollPlane(plane, startY, endY, delta) {
|
|
6389
|
+
scrollPlaneRows(terminal, plane, startY, endY, delta);
|
|
6390
|
+
}
|
|
6391
|
+
function invalidatePlane(plane) {
|
|
6392
|
+
getDirtyState(plane).allRowsDirty = true;
|
|
6393
|
+
}
|
|
6015
6394
|
function register(node) {
|
|
6016
6395
|
const id = `r${nextNodeId++}`;
|
|
6017
6396
|
const rect = node.rect ?? null;
|
|
@@ -6039,8 +6418,13 @@ function createRenderManager(terminal) {
|
|
|
6039
6418
|
const nextPlane = next.plane ?? prev.plane;
|
|
6040
6419
|
const nextRect = next.rect ?? prev.rect;
|
|
6041
6420
|
const { y0, y1 } = rectToYBounds(nextRect);
|
|
6042
|
-
|
|
6043
|
-
|
|
6421
|
+
const dirtyRowsHint = next.dirtyRowsHint;
|
|
6422
|
+
const canUseDirtyRowsHint = nextPlane === prev.plane && dirtyRowsHint != null && dirtyRowsHint.length > 0;
|
|
6423
|
+
if (canUseDirtyRowsHint) markRows(nextPlane, dirtyRowsHint);
|
|
6424
|
+
else {
|
|
6425
|
+
markRect(prev.plane, prev.rect);
|
|
6426
|
+
markRect(nextPlane, nextRect);
|
|
6427
|
+
}
|
|
6044
6428
|
const full = Object.freeze({
|
|
6045
6429
|
...prev,
|
|
6046
6430
|
stack: next.stack ?? prev.stack,
|
|
@@ -6102,10 +6486,11 @@ function createRenderManager(terminal) {
|
|
|
6102
6486
|
return false;
|
|
6103
6487
|
}
|
|
6104
6488
|
function render(options) {
|
|
6489
|
+
var _process;
|
|
6105
6490
|
const renderStart = profiler === null || profiler === void 0 ? void 0 : profiler.now();
|
|
6106
6491
|
const activePlanes = (options === null || options === void 0 ? void 0 : options.activePlanes) ?? null;
|
|
6107
6492
|
const requestedPlanes = activePlanes ?? TERMINAL_RENDER_PLANES;
|
|
6108
|
-
const env = process === null ||
|
|
6493
|
+
const env = (_process = process) === null || _process === void 0 ? void 0 : _process.env;
|
|
6109
6494
|
if ((env === null || env === void 0 ? void 0 : env.DIMCODE_DEBUG) === "1") renderMgrDebugLog.render("[RENDER-MANAGER] render() called");
|
|
6110
6495
|
if (!hasPendingDirtyWork(requestedPlanes)) {
|
|
6111
6496
|
if ((env === null || env === void 0 ? void 0 : env.DIMCODE_DEBUG) === "1") renderMgrDebugLog.render("[RENDER-MANAGER] render() skipped (no dirty rows)");
|
|
@@ -6213,6 +6598,8 @@ function createRenderManager(terminal) {
|
|
|
6213
6598
|
return {
|
|
6214
6599
|
rootStack,
|
|
6215
6600
|
createStack,
|
|
6601
|
+
invalidatePlane,
|
|
6602
|
+
scrollPlane,
|
|
6216
6603
|
register,
|
|
6217
6604
|
update,
|
|
6218
6605
|
unregister,
|
|
@@ -6295,9 +6682,10 @@ function createTerminalApp(options) {
|
|
|
6295
6682
|
let lastFlushAtMs = 0;
|
|
6296
6683
|
let scheduledAtMs = 0;
|
|
6297
6684
|
let timer = null;
|
|
6685
|
+
let pendingInvalidateAfterFlush = false;
|
|
6298
6686
|
let pendingInvalidateAllPlanes = false;
|
|
6299
6687
|
const pendingInvalidatePlanes = new Set();
|
|
6300
|
-
const env = (process === null || process === void 0 ? void 0 : process.env) ?? {};
|
|
6688
|
+
const env = (process$1 === null || process$1 === void 0 ? void 0 : process$1.env) ?? {};
|
|
6301
6689
|
const isGhostty = "GHOSTTY_RESOURCES_DIR" in env;
|
|
6302
6690
|
const throttleMs = (() => {
|
|
6303
6691
|
const raw = env.DIMCODE_TUI_THROTTLE_MS;
|
|
@@ -6307,7 +6695,7 @@ function createTerminalApp(options) {
|
|
|
6307
6695
|
})();
|
|
6308
6696
|
const frameThrottleMs = (() => {
|
|
6309
6697
|
var _process$stdout;
|
|
6310
|
-
if (!(process === null || process === void 0 || (_process$stdout = process.stdout) === null || _process$stdout === void 0 ? void 0 : _process$stdout.isTTY)) return 0;
|
|
6698
|
+
if (!(process$1 === null || process$1 === void 0 || (_process$stdout = process$1.stdout) === null || _process$stdout === void 0 ? void 0 : _process$stdout.isTTY)) return 0;
|
|
6311
6699
|
return isGhostty ? 24 : 16;
|
|
6312
6700
|
})();
|
|
6313
6701
|
function queueInvalidatePlane(plane) {
|
|
@@ -6330,16 +6718,23 @@ function createTerminalApp(options) {
|
|
|
6330
6718
|
pendingInvalidatePlanes.clear();
|
|
6331
6719
|
return activePlanes;
|
|
6332
6720
|
}
|
|
6333
|
-
function flush() {
|
|
6721
|
+
function flush(sync) {
|
|
6334
6722
|
if (disposed) return;
|
|
6335
6723
|
scheduled = false;
|
|
6336
6724
|
flushing = true;
|
|
6337
6725
|
const activePlanes = takeActivePlanes();
|
|
6338
6726
|
render.render({ activePlanes });
|
|
6339
|
-
terminal.commit({
|
|
6727
|
+
terminal.commit({
|
|
6728
|
+
planes: activePlanes,
|
|
6729
|
+
sync
|
|
6730
|
+
});
|
|
6340
6731
|
flushing = false;
|
|
6341
6732
|
lastFlushAtMs = Date.now();
|
|
6342
6733
|
scheduledAtMs = 0;
|
|
6734
|
+
if (pendingInvalidateAfterFlush) {
|
|
6735
|
+
pendingInvalidateAfterFlush = false;
|
|
6736
|
+
flush(true);
|
|
6737
|
+
}
|
|
6343
6738
|
}
|
|
6344
6739
|
function clearScheduledTimer() {
|
|
6345
6740
|
if (!timer) return;
|
|
@@ -6360,7 +6755,7 @@ function createTerminalApp(options) {
|
|
|
6360
6755
|
}
|
|
6361
6756
|
clearScheduledTimer();
|
|
6362
6757
|
scheduledAtMs = nowMs;
|
|
6363
|
-
if (typeof process.nextTick === "function") process.nextTick(() => {
|
|
6758
|
+
if (typeof process$1.nextTick === "function") process$1.nextTick(() => {
|
|
6364
6759
|
flush();
|
|
6365
6760
|
});
|
|
6366
6761
|
else if (typeof globalThis.setImmediate === "function") globalThis.setImmediate(() => {
|
|
@@ -6375,14 +6770,22 @@ function createTerminalApp(options) {
|
|
|
6375
6770
|
if (flushing) return;
|
|
6376
6771
|
clearScheduledTimer();
|
|
6377
6772
|
scheduled = false;
|
|
6378
|
-
flush();
|
|
6773
|
+
flush(true);
|
|
6379
6774
|
}
|
|
6380
6775
|
function invalidate(options$1) {
|
|
6381
6776
|
if (disposed) return;
|
|
6382
|
-
if (flushing)
|
|
6777
|
+
if (flushing) {
|
|
6778
|
+
queueInvalidatePlane(options$1 === null || options$1 === void 0 ? void 0 : options$1.plane);
|
|
6779
|
+
pendingInvalidateAfterFlush = true;
|
|
6780
|
+
return;
|
|
6781
|
+
}
|
|
6383
6782
|
const priority = (options$1 === null || options$1 === void 0 ? void 0 : options$1.priority) ?? "normal";
|
|
6384
6783
|
queueInvalidatePlane(options$1 === null || options$1 === void 0 ? void 0 : options$1.plane);
|
|
6385
6784
|
profiler === null || profiler === void 0 || profiler.recordInvalidate({ plane: (options$1 === null || options$1 === void 0 ? void 0 : options$1.plane) ?? null });
|
|
6785
|
+
if (priority === "high") {
|
|
6786
|
+
flushNow();
|
|
6787
|
+
return;
|
|
6788
|
+
}
|
|
6386
6789
|
const nowMs = Date.now();
|
|
6387
6790
|
const throttleDelayMs = throttleMs > 0 ? Math.max(0, lastFlushAtMs + throttleMs - nowMs) : 0;
|
|
6388
6791
|
const laneDelayMs = priority === "low" ? Math.max(throttleDelayMs, frameThrottleMs || 16) : priority === "normal" ? Math.max(throttleDelayMs, frameThrottleMs) : 0;
|
|
@@ -6519,6 +6922,7 @@ function createTerminalApp(options) {
|
|
|
6519
6922
|
dispose() {
|
|
6520
6923
|
if (disposed) return;
|
|
6521
6924
|
disposed = true;
|
|
6925
|
+
clearScheduledTimer();
|
|
6522
6926
|
if (mounted) app.unmount();
|
|
6523
6927
|
offResize === null || offResize === void 0 || offResize();
|
|
6524
6928
|
offCommit === null || offCommit === void 0 || offCommit();
|
|
@@ -6602,7 +7006,7 @@ function parseWriteMode(raw) {
|
|
|
6602
7006
|
}
|
|
6603
7007
|
function createStdoutRenderer(terminal, options) {
|
|
6604
7008
|
var _ref3;
|
|
6605
|
-
const output = (options === null || options === void 0 ? void 0 : options.output) ?? process.stdout;
|
|
7009
|
+
const output = (options === null || options === void 0 ? void 0 : options.output) ?? process$1.stdout;
|
|
6606
7010
|
if (!output) throw new Error("createStdoutRenderer requires a Node stdout-like output");
|
|
6607
7011
|
const out = output;
|
|
6608
7012
|
const clear = (options === null || options === void 0 ? void 0 : options.clear) ?? true;
|
|
@@ -6615,7 +7019,7 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6615
7019
|
const profiler = createTuiProfiler("stdout-renderer");
|
|
6616
7020
|
function resolveUseSyncOutput() {
|
|
6617
7021
|
if ((options === null || options === void 0 ? void 0 : options.useSyncOutput) != null) return options.useSyncOutput;
|
|
6618
|
-
const env$1 = (process === null || process === void 0 ? void 0 : process.env) ?? {};
|
|
7022
|
+
const env$1 = (process$1 === null || process$1 === void 0 ? void 0 : process$1.env) ?? {};
|
|
6619
7023
|
const envValue = env$1.DIMCODE_SYNC_OUTPUT;
|
|
6620
7024
|
if (envValue != null) {
|
|
6621
7025
|
const v = String(envValue).trim().toLowerCase();
|
|
@@ -6647,8 +7051,8 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6647
7051
|
return 0;
|
|
6648
7052
|
}
|
|
6649
7053
|
const useSyncOutput = resolveUseSyncOutput();
|
|
6650
|
-
const isGhostty = "GHOSTTY_RESOURCES_DIR" in ((process === null || process === void 0 ? void 0 : process.env) ?? {});
|
|
6651
|
-
const env = (process === null || process === void 0 ? void 0 : process.env) ?? {};
|
|
7054
|
+
const isGhostty = "GHOSTTY_RESOURCES_DIR" in ((process$1 === null || process$1 === void 0 ? void 0 : process$1.env) ?? {});
|
|
7055
|
+
const env = (process$1 === null || process$1 === void 0 ? void 0 : process$1.env) ?? {};
|
|
6652
7056
|
const forcedWriteMode = parseWriteMode(env.DIMCODE_TUI_WRITE_MODE ?? env.VUE_TUI_WRITE_MODE);
|
|
6653
7057
|
const forcedChunkSize = Number(env.DIMCODE_TUI_CHUNK_SIZE ?? env.VUE_TUI_CHUNK_SIZE);
|
|
6654
7058
|
const chunkSize = Number.isFinite(forcedChunkSize) ? Math.max(512, Math.floor(forcedChunkSize)) : 8 * 1024;
|
|
@@ -6663,12 +7067,12 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6663
7067
|
if (Number.isFinite(n)) return Math.min(1, Math.max(.05, n));
|
|
6664
7068
|
return .6;
|
|
6665
7069
|
})();
|
|
6666
|
-
const disableCursorPos = isGhostty && (process === null || process === void 0 || (_ref3 = process.env) === null || _ref3 === void 0 ? void 0 : _ref3.DIMCODE_DISABLE_CURSOR_POS) === "1";
|
|
6667
|
-
const
|
|
7070
|
+
const disableCursorPos = isGhostty && (process$1 === null || process$1 === void 0 || (_ref3 = process$1.env) === null || _ref3 === void 0 ? void 0 : _ref3.DIMCODE_DISABLE_CURSOR_POS) === "1";
|
|
7071
|
+
const isVscodeTerminal = String(env.TERM_PROGRAM ?? "").trim().toLowerCase() === "vscode" || "VSCODE_PID" in env || "VSCODE_IPC_HOOK_CLI" in env;
|
|
6668
7072
|
const enableOsc8Links = (() => {
|
|
6669
7073
|
if (!out.isTTY) return false;
|
|
6670
7074
|
const raw = String(env.DIMCODE_TUI_LINKS ?? "").trim().toLowerCase();
|
|
6671
|
-
if (!raw) return !
|
|
7075
|
+
if (!raw) return !isVscodeTerminal;
|
|
6672
7076
|
return !(raw === "0" || raw === "false" || raw === "no");
|
|
6673
7077
|
})();
|
|
6674
7078
|
let disposed = false;
|
|
@@ -6676,11 +7080,15 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6676
7080
|
let pendingRender = false;
|
|
6677
7081
|
let renderTimer = null;
|
|
6678
7082
|
let writeEmaMs = 0;
|
|
7083
|
+
let lastCursorX = null;
|
|
7084
|
+
let lastCursorY = null;
|
|
6679
7085
|
let accumulatedAllRows = false;
|
|
6680
7086
|
let accumulatedDirtyBits = null;
|
|
6681
7087
|
let accumulatedDirtyCount = 0;
|
|
6682
7088
|
let accumulatedDirtyMin = Number.POSITIVE_INFINITY;
|
|
6683
7089
|
let accumulatedDirtyMax = -1;
|
|
7090
|
+
let accumulatedScrollOperations = null;
|
|
7091
|
+
let accumulatedSkipUnchangedDirtyRows = true;
|
|
6684
7092
|
const MIN_FRAME_MS = !out.isTTY ? 0 : isGhostty ? 24 : 16;
|
|
6685
7093
|
function clampCellToViewport(cell, size) {
|
|
6686
7094
|
const maxX = Math.max(0, Math.floor(size.cols) - 1);
|
|
@@ -6697,25 +7105,43 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6697
7105
|
function resolveColorMode() {
|
|
6698
7106
|
const opt = (options === null || options === void 0 ? void 0 : options.colorMode) ?? "auto";
|
|
6699
7107
|
if (opt !== "auto") return opt;
|
|
6700
|
-
const env$1 = (process === null || process === void 0 ? void 0 : process.env) ?? {};
|
|
7108
|
+
const env$1 = (process$1 === null || process$1 === void 0 ? void 0 : process$1.env) ?? {};
|
|
6701
7109
|
return detectTerminalColorCapability({
|
|
6702
7110
|
env: env$1,
|
|
6703
7111
|
isTTY: Boolean(out.isTTY),
|
|
6704
|
-
platform: String((process === null || process === void 0 ? void 0 : process.platform) ?? "")
|
|
7112
|
+
platform: String((process$1 === null || process$1 === void 0 ? void 0 : process$1.platform) ?? "")
|
|
6705
7113
|
}).mode;
|
|
6706
7114
|
}
|
|
6707
7115
|
const colorMode = resolveColorMode();
|
|
6708
7116
|
const enableDim = colorMode === "truecolor";
|
|
7117
|
+
const COLOR_INDEX = {
|
|
7118
|
+
black: 1,
|
|
7119
|
+
red: 2,
|
|
7120
|
+
green: 3,
|
|
7121
|
+
yellow: 4,
|
|
7122
|
+
blue: 5,
|
|
7123
|
+
magenta: 6,
|
|
7124
|
+
cyan: 7,
|
|
7125
|
+
white: 8,
|
|
7126
|
+
blackBright: 9,
|
|
7127
|
+
redBright: 10,
|
|
7128
|
+
greenBright: 11,
|
|
7129
|
+
yellowBright: 12,
|
|
7130
|
+
blueBright: 13,
|
|
7131
|
+
magentaBright: 14,
|
|
7132
|
+
cyanBright: 15,
|
|
7133
|
+
whiteBright: 16
|
|
7134
|
+
};
|
|
6709
7135
|
let styleKeyCache$1 = new WeakMap();
|
|
6710
7136
|
function styleKey$1(style) {
|
|
6711
7137
|
const cached = styleKeyCache$1.get(style);
|
|
6712
|
-
if (cached) return cached;
|
|
6713
|
-
const key =
|
|
7138
|
+
if (cached !== void 0) return cached;
|
|
7139
|
+
const key = (COLOR_INDEX[style.fg] ?? 0) | (COLOR_INDEX[style.bg ?? defaultBg] ?? 0) << 5 | (style.bold ? 1024 : 0) | (enableDim && style.dim ? 2048 : 0) | (style.italic ? 4096 : 0) | (style.underline ? 8192 : 0) | (style.inverse ? 16384 : 0) | (style.href ? 32768 : 0);
|
|
6714
7140
|
styleKeyCache$1.set(style, key);
|
|
6715
7141
|
return key;
|
|
6716
7142
|
}
|
|
6717
7143
|
function styleKeyFromParts(style) {
|
|
6718
|
-
return
|
|
7144
|
+
return (COLOR_INDEX[style.fg] ?? 0) | (COLOR_INDEX[style.bg ?? defaultBg] ?? 0) << 5 | (style.bold ? 1024 : 0) | (enableDim && style.dim ? 2048 : 0) | (style.italic ? 4096 : 0) | (style.underline ? 8192 : 0) | (style.inverse ? 16384 : 0) | (style.href ? 32768 : 0);
|
|
6719
7145
|
}
|
|
6720
7146
|
function openColor(fg) {
|
|
6721
7147
|
if (!fg) return "";
|
|
@@ -6747,7 +7173,45 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6747
7173
|
return result;
|
|
6748
7174
|
}
|
|
6749
7175
|
let lastRenderedRows = 0;
|
|
6750
|
-
let
|
|
7176
|
+
let fpCols = 0;
|
|
7177
|
+
let fpRows = 0;
|
|
7178
|
+
let currentFP = new Uint32Array(0);
|
|
7179
|
+
let prevFP = new Uint32Array(0);
|
|
7180
|
+
let fpPrevValid = false;
|
|
7181
|
+
let prevOverlayBlockedRows = [];
|
|
7182
|
+
let prevOverlayPartialRows = [];
|
|
7183
|
+
function ensureFingerprints(cols, rows) {
|
|
7184
|
+
if (cols === fpCols && rows === fpRows) return;
|
|
7185
|
+
fpCols = cols;
|
|
7186
|
+
fpRows = rows;
|
|
7187
|
+
const len = cols * rows;
|
|
7188
|
+
currentFP = new Uint32Array(len);
|
|
7189
|
+
prevFP = new Uint32Array(len);
|
|
7190
|
+
fpPrevValid = false;
|
|
7191
|
+
prevOverlayBlockedRows = [];
|
|
7192
|
+
prevOverlayPartialRows = [];
|
|
7193
|
+
}
|
|
7194
|
+
function charHash16(ch) {
|
|
7195
|
+
if (ch.length <= 1) return ch.charCodeAt(0) || 0;
|
|
7196
|
+
let h$1 = 33052;
|
|
7197
|
+
for (let i = 0; i < ch.length; i++) {
|
|
7198
|
+
h$1 ^= ch.charCodeAt(i);
|
|
7199
|
+
h$1 = h$1 * 257 & 65535;
|
|
7200
|
+
}
|
|
7201
|
+
return h$1;
|
|
7202
|
+
}
|
|
7203
|
+
function fingerprintRow(row, y, cols) {
|
|
7204
|
+
const rowFP = terminal.getRowFingerprints(y);
|
|
7205
|
+
if (rowFP && rowFP.length >= cols) {
|
|
7206
|
+
currentFP.set(rowFP.subarray(0, cols), y * fpCols);
|
|
7207
|
+
return;
|
|
7208
|
+
}
|
|
7209
|
+
const base = y * fpCols;
|
|
7210
|
+
for (let x = 0; x < cols; x++) {
|
|
7211
|
+
const cell = row[x];
|
|
7212
|
+
currentFP[base + x] = styleKey$1(cell.style) << 16 | charHash16(cell.ch);
|
|
7213
|
+
}
|
|
7214
|
+
}
|
|
6751
7215
|
const rowCursorToCol1 = [];
|
|
6752
7216
|
const rowClearToEol = [];
|
|
6753
7217
|
const rowTextPartsScratch = [];
|
|
@@ -6765,13 +7229,6 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6765
7229
|
rowClearToEol[y] = `\u001B[${y + 1};1H\u001B[K`;
|
|
6766
7230
|
}
|
|
6767
7231
|
};
|
|
6768
|
-
const ensureRenderedRowCache = (rows) => {
|
|
6769
|
-
if (renderedRowCache.length > rows) {
|
|
6770
|
-
renderedRowCache.length = rows;
|
|
6771
|
-
return;
|
|
6772
|
-
}
|
|
6773
|
-
while (renderedRowCache.length < rows) renderedRowCache.push([]);
|
|
6774
|
-
};
|
|
6775
7232
|
const expandSpanStart = (row, startX) => {
|
|
6776
7233
|
var _row$x;
|
|
6777
7234
|
let x = Math.max(0, Math.min(row.length, startX));
|
|
@@ -6788,30 +7245,279 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6788
7245
|
}
|
|
6789
7246
|
return x;
|
|
6790
7247
|
};
|
|
6791
|
-
const resolveChangedSpan = (row,
|
|
6792
|
-
if (!
|
|
7248
|
+
const resolveChangedSpan = (row, y, cols) => {
|
|
7249
|
+
if (!fpCols || y >= fpRows || !fpPrevValid) return row.length ? {
|
|
6793
7250
|
startX: 0,
|
|
6794
7251
|
endXExclusive: row.length
|
|
6795
7252
|
} : null;
|
|
7253
|
+
const base = y * fpCols;
|
|
6796
7254
|
let startX = -1;
|
|
6797
7255
|
let endXExclusive = -1;
|
|
6798
|
-
for (let x = 0; x <
|
|
6799
|
-
if (
|
|
7256
|
+
for (let x = 0; x < cols; x++) {
|
|
7257
|
+
if (currentFP[base + x] === prevFP[base + x]) continue;
|
|
6800
7258
|
if (startX === -1) startX = x;
|
|
6801
7259
|
endXExclusive = x + 1;
|
|
6802
7260
|
}
|
|
6803
|
-
if (startX === -1
|
|
6804
|
-
const expandedStart =
|
|
6805
|
-
const expandedEnd =
|
|
7261
|
+
if (startX === -1) return null;
|
|
7262
|
+
const expandedStart = expandSpanStart(row, startX);
|
|
7263
|
+
const expandedEnd = expandSpanEnd(row, endXExclusive);
|
|
6806
7264
|
return expandedEnd > expandedStart ? {
|
|
6807
7265
|
startX: expandedStart,
|
|
6808
7266
|
endXExclusive: expandedEnd
|
|
6809
7267
|
} : null;
|
|
6810
7268
|
};
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
7269
|
+
const resolveChangedSpanAgainstFill = (row, y, cols, fillFingerprint) => {
|
|
7270
|
+
if (!fpCols || y >= fpRows) return row.length ? {
|
|
7271
|
+
startX: 0,
|
|
7272
|
+
endXExclusive: row.length
|
|
7273
|
+
} : null;
|
|
7274
|
+
const base = y * fpCols;
|
|
7275
|
+
let startX = -1;
|
|
7276
|
+
let endXExclusive = -1;
|
|
7277
|
+
for (let x = 0; x < cols; x++) {
|
|
7278
|
+
if (currentFP[base + x] === fillFingerprint) continue;
|
|
7279
|
+
if (startX === -1) startX = x;
|
|
7280
|
+
endXExclusive = x + 1;
|
|
7281
|
+
}
|
|
7282
|
+
if (startX === -1) return null;
|
|
7283
|
+
const expandedStart = expandSpanStart(row, startX);
|
|
7284
|
+
const expandedEnd = expandSpanEnd(row, endXExclusive);
|
|
7285
|
+
return expandedEnd > expandedStart ? {
|
|
7286
|
+
startX: expandedStart,
|
|
7287
|
+
endXExclusive: expandedEnd
|
|
7288
|
+
} : null;
|
|
7289
|
+
};
|
|
7290
|
+
const resolveChangedSpanAgainstReference = (row, y, cols) => {
|
|
7291
|
+
if (!fpCols || y >= fpRows) return row.length ? {
|
|
7292
|
+
startX: 0,
|
|
7293
|
+
endXExclusive: row.length
|
|
7294
|
+
} : null;
|
|
7295
|
+
const rowFP = terminal.getRowFingerprints(y);
|
|
7296
|
+
const base = y * fpCols;
|
|
7297
|
+
let startX = -1;
|
|
7298
|
+
let endXExclusive = -1;
|
|
7299
|
+
for (let x = 0; x < cols; x++) {
|
|
7300
|
+
const fingerprint = rowFP && rowFP.length >= cols ? rowFP[x] : styleKey$1(row[x].style) << 16 | charHash16(row[x].ch);
|
|
7301
|
+
if (fingerprint === currentFP[base + x]) continue;
|
|
7302
|
+
if (startX === -1) startX = x;
|
|
7303
|
+
endXExclusive = x + 1;
|
|
7304
|
+
}
|
|
7305
|
+
if (startX === -1) return null;
|
|
7306
|
+
const expandedStart = expandSpanStart(row, startX);
|
|
7307
|
+
const expandedEnd = expandSpanEnd(row, endXExclusive);
|
|
7308
|
+
return expandedEnd > expandedStart ? {
|
|
7309
|
+
startX: expandedStart,
|
|
7310
|
+
endXExclusive: expandedEnd
|
|
7311
|
+
} : null;
|
|
7312
|
+
};
|
|
7313
|
+
const rowMatchesPreviousFrame = (y, cols) => {
|
|
7314
|
+
if (!fpCols || y < 0 || y >= fpRows || !fpPrevValid) return false;
|
|
7315
|
+
const rowFP = terminal.getRowFingerprints(y);
|
|
7316
|
+
const row = rowFP && rowFP.length >= cols ? null : terminal.getRow(y);
|
|
7317
|
+
const base = y * fpCols;
|
|
7318
|
+
for (let x = 0; x < cols; x++) {
|
|
7319
|
+
const fingerprint = rowFP && rowFP.length >= cols ? rowFP[x] : styleKey$1(row[x].style) << 16 | charHash16(row[x].ch);
|
|
7320
|
+
if (fingerprint !== prevFP[base + x]) return false;
|
|
7321
|
+
}
|
|
7322
|
+
return true;
|
|
7323
|
+
};
|
|
7324
|
+
const rowHasNonDefaultBlankCell = (source, y, cols) => {
|
|
7325
|
+
if (!fpCols || y < 0 || y >= fpRows) return false;
|
|
7326
|
+
const blankFP = styleKeyFromParts({ bg: defaultBg }) << 16 | charHash16(" ");
|
|
7327
|
+
const base = y * fpCols;
|
|
7328
|
+
const limit = Math.min(cols, fpCols);
|
|
7329
|
+
for (let x = 0; x < limit; x++) if (source[base + x] !== blankFP) return true;
|
|
6814
7330
|
return false;
|
|
7331
|
+
};
|
|
7332
|
+
function overlayPlaneCoverageRows(totalRows) {
|
|
7333
|
+
const blockedRows = [];
|
|
7334
|
+
const partialRows = [];
|
|
7335
|
+
for (let y = 0; y < totalRows; y++) {
|
|
7336
|
+
const kind = getPlaneRowCoverageKind(terminal, "overlay", y);
|
|
7337
|
+
if (!kind) continue;
|
|
7338
|
+
blockedRows.push(y);
|
|
7339
|
+
if (kind === 1) partialRows.push(y);
|
|
7340
|
+
}
|
|
7341
|
+
return {
|
|
7342
|
+
blockedRows,
|
|
7343
|
+
partialRows
|
|
7344
|
+
};
|
|
7345
|
+
}
|
|
7346
|
+
const enableScrollRegions = (() => {
|
|
7347
|
+
const raw = String(env.DIMCODE_TUI_SCROLL_REGIONS ?? "").trim();
|
|
7348
|
+
if (raw === "0" || raw === "false") return false;
|
|
7349
|
+
if (isGhostty || isVscodeTerminal) return false;
|
|
7350
|
+
return out.isTTY !== false;
|
|
7351
|
+
})();
|
|
7352
|
+
function prepareExplicitScrollOperations(operations, blockedRows) {
|
|
7353
|
+
if (!operations.length || !(blockedRows === null || blockedRows === void 0 ? void 0 : blockedRows.size)) return {
|
|
7354
|
+
operations,
|
|
7355
|
+
hiddenRows: new Set(),
|
|
7356
|
+
trimmed: false,
|
|
7357
|
+
blockedInterior: false
|
|
7358
|
+
};
|
|
7359
|
+
const hiddenRows = new Set();
|
|
7360
|
+
const prepared = [];
|
|
7361
|
+
let trimmed = false;
|
|
7362
|
+
for (const op of operations) {
|
|
7363
|
+
let startY = op.startY;
|
|
7364
|
+
let endY = op.endY;
|
|
7365
|
+
while (startY < endY && blockedRows.has(startY)) {
|
|
7366
|
+
hiddenRows.add(startY);
|
|
7367
|
+
startY++;
|
|
7368
|
+
trimmed = true;
|
|
7369
|
+
}
|
|
7370
|
+
while (endY > startY && blockedRows.has(endY - 1)) {
|
|
7371
|
+
hiddenRows.add(endY - 1);
|
|
7372
|
+
endY--;
|
|
7373
|
+
trimmed = true;
|
|
7374
|
+
}
|
|
7375
|
+
for (let y = startY; y < endY; y++) {
|
|
7376
|
+
if (!blockedRows.has(y)) continue;
|
|
7377
|
+
return {
|
|
7378
|
+
operations: null,
|
|
7379
|
+
hiddenRows,
|
|
7380
|
+
trimmed,
|
|
7381
|
+
blockedInterior: true
|
|
7382
|
+
};
|
|
7383
|
+
}
|
|
7384
|
+
if (endY <= startY || Math.abs(op.delta) >= endY - startY) return {
|
|
7385
|
+
operations: null,
|
|
7386
|
+
hiddenRows,
|
|
7387
|
+
trimmed,
|
|
7388
|
+
blockedInterior: false
|
|
7389
|
+
};
|
|
7390
|
+
prepared.push(startY === op.startY && endY === op.endY ? op : {
|
|
7391
|
+
startY,
|
|
7392
|
+
endY,
|
|
7393
|
+
delta: op.delta
|
|
7394
|
+
});
|
|
7395
|
+
}
|
|
7396
|
+
return {
|
|
7397
|
+
operations: prepared,
|
|
7398
|
+
hiddenRows,
|
|
7399
|
+
trimmed,
|
|
7400
|
+
blockedInterior: false
|
|
7401
|
+
};
|
|
7402
|
+
}
|
|
7403
|
+
/**
|
|
7404
|
+
* Detect if the current frame represents a pure vertical scroll by comparing
|
|
7405
|
+
* current fingerprints against previous fingerprints with various shift offsets.
|
|
7406
|
+
* Returns the shift delta and which rows are newly revealed, or null if no
|
|
7407
|
+
* scroll pattern is detected.
|
|
7408
|
+
*/
|
|
7409
|
+
function largestDirtyBand(rows, blockedRows) {
|
|
7410
|
+
if (rows.length === 0) return null;
|
|
7411
|
+
const blocked = (blockedRows === null || blockedRows === void 0 ? void 0 : blockedRows.length) ? new Set(blockedRows) : null;
|
|
7412
|
+
let bestStart = -1;
|
|
7413
|
+
let bestEnd = -1;
|
|
7414
|
+
let bandStart = -1;
|
|
7415
|
+
let prev = -1;
|
|
7416
|
+
for (let i = 0; i < rows.length; i++) {
|
|
7417
|
+
const y = rows[i];
|
|
7418
|
+
if (blocked === null || blocked === void 0 ? void 0 : blocked.has(y)) {
|
|
7419
|
+
if (bandStart !== -1 && prev + 1 - bandStart > bestEnd - bestStart) {
|
|
7420
|
+
bestStart = bandStart;
|
|
7421
|
+
bestEnd = prev + 1;
|
|
7422
|
+
}
|
|
7423
|
+
bandStart = -1;
|
|
7424
|
+
prev = -1;
|
|
7425
|
+
continue;
|
|
7426
|
+
}
|
|
7427
|
+
if (bandStart === -1) {
|
|
7428
|
+
bandStart = y;
|
|
7429
|
+
prev = y;
|
|
7430
|
+
if (bestStart === -1) {
|
|
7431
|
+
bestStart = y;
|
|
7432
|
+
bestEnd = y + 1;
|
|
7433
|
+
}
|
|
7434
|
+
continue;
|
|
7435
|
+
}
|
|
7436
|
+
if (y === prev + 1) {
|
|
7437
|
+
prev = y;
|
|
7438
|
+
continue;
|
|
7439
|
+
}
|
|
7440
|
+
if (prev + 1 - bandStart > bestEnd - bestStart) {
|
|
7441
|
+
bestStart = bandStart;
|
|
7442
|
+
bestEnd = prev + 1;
|
|
7443
|
+
}
|
|
7444
|
+
bandStart = y;
|
|
7445
|
+
prev = y;
|
|
7446
|
+
}
|
|
7447
|
+
if (bandStart !== -1 && prev + 1 - bandStart > bestEnd - bestStart) {
|
|
7448
|
+
bestStart = bandStart;
|
|
7449
|
+
bestEnd = prev + 1;
|
|
7450
|
+
}
|
|
7451
|
+
if (bestStart === -1) return null;
|
|
7452
|
+
const outsideRows = [];
|
|
7453
|
+
for (const y of rows) if ((blocked === null || blocked === void 0 ? void 0 : blocked.has(y)) || y < bestStart || y >= bestEnd) outsideRows.push(y);
|
|
7454
|
+
return {
|
|
7455
|
+
start: bestStart,
|
|
7456
|
+
end: bestEnd,
|
|
7457
|
+
outsideRows
|
|
7458
|
+
};
|
|
7459
|
+
}
|
|
7460
|
+
function detectScrollShift(cols, dirtyRows, blockedRows) {
|
|
7461
|
+
if (!fpPrevValid || !fpCols || cols !== fpCols) return null;
|
|
7462
|
+
const band = largestDirtyBand(dirtyRows, blockedRows);
|
|
7463
|
+
if (!band || band.end - band.start < 3) return null;
|
|
7464
|
+
const maxDelta = Math.min(12, Math.max(5, band.end - band.start - 1));
|
|
7465
|
+
for (let delta = -maxDelta; delta <= maxDelta; delta++) {
|
|
7466
|
+
if (delta === 0) continue;
|
|
7467
|
+
let matches = 0;
|
|
7468
|
+
let checked = 0;
|
|
7469
|
+
let mismatches = 0;
|
|
7470
|
+
for (let y = band.start; y < band.end; y++) {
|
|
7471
|
+
const srcY = y + delta;
|
|
7472
|
+
if (srcY < band.start || srcY >= band.end) continue;
|
|
7473
|
+
const informative = rowHasNonDefaultBlankCell(currentFP, y, cols) || rowHasNonDefaultBlankCell(prevFP, srcY, cols);
|
|
7474
|
+
if (!informative) continue;
|
|
7475
|
+
checked++;
|
|
7476
|
+
const curBase = y * fpCols;
|
|
7477
|
+
const prevBase = srcY * fpCols;
|
|
7478
|
+
let rowMatch = true;
|
|
7479
|
+
for (let x = 0; x < cols; x++) if (currentFP[curBase + x] !== prevFP[prevBase + x]) {
|
|
7480
|
+
rowMatch = false;
|
|
7481
|
+
break;
|
|
7482
|
+
}
|
|
7483
|
+
if (rowMatch) matches++;
|
|
7484
|
+
else mismatches++;
|
|
7485
|
+
}
|
|
7486
|
+
if (checked > 0 && matches >= 3 && mismatches <= Math.ceil(checked * .2)) {
|
|
7487
|
+
const absDelta = Math.abs(delta);
|
|
7488
|
+
let newRowStart;
|
|
7489
|
+
let newRowEnd;
|
|
7490
|
+
if (delta > 0) {
|
|
7491
|
+
newRowStart = Math.max(band.start, band.end - absDelta);
|
|
7492
|
+
newRowEnd = band.end;
|
|
7493
|
+
} else {
|
|
7494
|
+
newRowStart = band.start;
|
|
7495
|
+
newRowEnd = Math.min(band.end, band.start + absDelta);
|
|
7496
|
+
}
|
|
7497
|
+
const extraDirty = [...band.outsideRows];
|
|
7498
|
+
for (let y = band.start; y < band.end; y++) {
|
|
7499
|
+
const srcY = y + delta;
|
|
7500
|
+
if (srcY < band.start || srcY >= band.end) continue;
|
|
7501
|
+
const curBase = y * fpCols;
|
|
7502
|
+
const prevBase = srcY * fpCols;
|
|
7503
|
+
let rowMatch = true;
|
|
7504
|
+
for (let x = 0; x < cols; x++) if (currentFP[curBase + x] !== prevFP[prevBase + x]) {
|
|
7505
|
+
rowMatch = false;
|
|
7506
|
+
break;
|
|
7507
|
+
}
|
|
7508
|
+
if (!rowMatch) extraDirty.push(y);
|
|
7509
|
+
}
|
|
7510
|
+
return {
|
|
7511
|
+
regionStart: band.start,
|
|
7512
|
+
regionEnd: band.end,
|
|
7513
|
+
delta,
|
|
7514
|
+
newRowStart,
|
|
7515
|
+
newRowEnd,
|
|
7516
|
+
extraDirtyRows: extraDirty
|
|
7517
|
+
};
|
|
7518
|
+
}
|
|
7519
|
+
}
|
|
7520
|
+
return null;
|
|
6815
7521
|
}
|
|
6816
7522
|
/**
|
|
6817
7523
|
* Write data in chunks to avoid overwhelming terminal buffers.
|
|
@@ -6849,7 +7555,7 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6849
7555
|
* Internal function that actually renders the frame to stdout.
|
|
6850
7556
|
* When dirtyRows is provided, only those rows are repainted.
|
|
6851
7557
|
*/
|
|
6852
|
-
function doRender(dirtyRows) {
|
|
7558
|
+
function doRender(dirtyRows, scrollOperations, skipUnchangedDirtyRows = false) {
|
|
6853
7559
|
if (isDebugEnabled()) getDebugLog().render(`doRender() START: dirtyRows=${(dirtyRows === null || dirtyRows === void 0 ? void 0 : dirtyRows.length) ?? "null"}`);
|
|
6854
7560
|
if (disposed) return;
|
|
6855
7561
|
pendingRender = false;
|
|
@@ -6858,15 +7564,50 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6858
7564
|
accumulatedDirtyCount = 0;
|
|
6859
7565
|
accumulatedDirtyMin = Number.POSITIVE_INFINITY;
|
|
6860
7566
|
accumulatedDirtyMax = -1;
|
|
7567
|
+
accumulatedScrollOperations = null;
|
|
7568
|
+
accumulatedSkipUnchangedDirtyRows = true;
|
|
6861
7569
|
lastFrameTime = Date.now();
|
|
6862
7570
|
const renderStart = performance.now();
|
|
6863
7571
|
const size = terminal.size();
|
|
6864
7572
|
ensureRowEscapes(Math.max(size.rows, lastRenderedRows));
|
|
6865
|
-
|
|
7573
|
+
ensureFingerprints(size.cols, size.rows);
|
|
6866
7574
|
const bgSeq = openBg(defaultBg);
|
|
6867
7575
|
const bgOnlyStyle = { bg: defaultBg };
|
|
6868
7576
|
const bgKey = styleKeyFromParts({ bg: defaultBg });
|
|
7577
|
+
const blankFP = bgKey << 16 | charHash16(" ");
|
|
7578
|
+
const cellFingerprint = (cell) => styleKey$1(cell.style) << 16 | charHash16(cell.ch);
|
|
7579
|
+
const lastOccupiedColumnInRow = (row, cols) => {
|
|
7580
|
+
const limit = Math.min(row.length, cols);
|
|
7581
|
+
for (let x = limit - 1; x >= 0; x--) if (cellFingerprint(row[x]) !== blankFP) return x;
|
|
7582
|
+
return -1;
|
|
7583
|
+
};
|
|
7584
|
+
const lastOccupiedColumnInReference = (source, y, cols) => {
|
|
7585
|
+
if (!fpCols || y < 0 || y >= fpRows) return -1;
|
|
7586
|
+
const limit = Math.min(fpCols, cols);
|
|
7587
|
+
const base = y * fpCols;
|
|
7588
|
+
for (let x = limit - 1; x >= 0; x--) if (source[base + x] !== blankFP) return x;
|
|
7589
|
+
return -1;
|
|
7590
|
+
};
|
|
7591
|
+
const shouldRewriteRowTail = (row, y, cols, reference) => lastOccupiedColumnInRow(row, cols) < lastOccupiedColumnInReference(reference, y, cols);
|
|
6869
7592
|
let dirtySorted = true;
|
|
7593
|
+
const normalizedScrollOperations = (() => {
|
|
7594
|
+
if (!(scrollOperations === null || scrollOperations === void 0 ? void 0 : scrollOperations.length)) return null;
|
|
7595
|
+
const outOps = [];
|
|
7596
|
+
for (const op of scrollOperations) {
|
|
7597
|
+
const startY = Math.max(0, Math.min(size.rows, Math.floor(op.startY)));
|
|
7598
|
+
const endY = Math.max(0, Math.min(size.rows, Math.floor(op.endY)));
|
|
7599
|
+
const delta = Math.trunc(op.delta);
|
|
7600
|
+
if (endY <= startY || delta === 0 || Math.abs(delta) >= endY - startY) continue;
|
|
7601
|
+
outOps.push({
|
|
7602
|
+
startY,
|
|
7603
|
+
endY,
|
|
7604
|
+
delta
|
|
7605
|
+
});
|
|
7606
|
+
}
|
|
7607
|
+
if (!outOps.length) return null;
|
|
7608
|
+
outOps.sort((a, b) => a.startY - b.startY);
|
|
7609
|
+
return outOps;
|
|
7610
|
+
})();
|
|
6870
7611
|
let rowsToRender = (() => {
|
|
6871
7612
|
if (!dirtyRows || dirtyRows.length === 0) return null;
|
|
6872
7613
|
const outRows = [];
|
|
@@ -6887,11 +7628,13 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6887
7628
|
if (!sorted) outRows.sort((a, b) => a - b);
|
|
6888
7629
|
return outRows;
|
|
6889
7630
|
})();
|
|
6890
|
-
if (rowsToRender && rowsToRender.length >= size.rows * dirtyFullThreshold) rowsToRender = null;
|
|
6891
7631
|
const frameParts = [];
|
|
6892
7632
|
frameParts.push(!isGhostty && useSyncOutput ? SYNC_START : "");
|
|
6893
7633
|
frameParts.push("\x1B[?7l");
|
|
6894
7634
|
frameParts.push(SGR_RESET, bgSeq);
|
|
7635
|
+
let lastRenderedY = -1;
|
|
7636
|
+
let lastRenderWasFullRow = false;
|
|
7637
|
+
let hasFrameOutput = false;
|
|
6895
7638
|
let activeStyleKey = null;
|
|
6896
7639
|
let activeStyle = {
|
|
6897
7640
|
fg: null,
|
|
@@ -6942,11 +7685,10 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6942
7685
|
const renderRow$1 = (y, row, startX = 0, endXExclusive = row.length, clearToEol = true) => {
|
|
6943
7686
|
const spanStart = Math.max(0, Math.min(row.length, Math.floor(startX)));
|
|
6944
7687
|
const spanEnd = Math.max(spanStart, Math.min(row.length, Math.floor(endXExclusive)));
|
|
6945
|
-
if (spanStart >= spanEnd && !clearToEol)
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
}
|
|
6949
|
-
if (!disableCursorPos) frameParts.push(spanStart === 0 ? rowCursorToCol1[y] : `\u001B[${y + 1};${spanStart + 1}H`);
|
|
7688
|
+
if (spanStart >= spanEnd && !clearToEol) return;
|
|
7689
|
+
hasFrameOutput = true;
|
|
7690
|
+
if (!disableCursorPos) if (spanStart === 0 && lastRenderWasFullRow && y === lastRenderedY + 1) frameParts.push("\r\n");
|
|
7691
|
+
else frameParts.push(spanStart === 0 ? rowCursorToCol1[y] : `\u001B[${y + 1};${spanStart + 1}H`);
|
|
6950
7692
|
let currentKey = null;
|
|
6951
7693
|
let currentStyle = null;
|
|
6952
7694
|
const currentTextParts = rowTextPartsScratch;
|
|
@@ -6964,7 +7706,7 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6964
7706
|
if (needsWideCursorFix(cell, ch)) currentTextParts.push(`\u001B[${y + 1};${x + 1 + (cell.width ?? 1)}H`);
|
|
6965
7707
|
continue;
|
|
6966
7708
|
}
|
|
6967
|
-
if (key === currentKey) {
|
|
7709
|
+
if (key === currentKey && !(key & 32768 && nextStyle.href !== (currentStyle === null || currentStyle === void 0 ? void 0 : currentStyle.href))) {
|
|
6968
7710
|
currentTextParts.push(ch);
|
|
6969
7711
|
if (needsWideCursorFix(cell, ch)) currentTextParts.push(`\u001B[${y + 1};${x + 1 + (cell.width ?? 1)}H`);
|
|
6970
7712
|
continue;
|
|
@@ -6985,29 +7727,233 @@ function createStdoutRenderer(terminal, options) {
|
|
|
6985
7727
|
if (activeStyleKey !== bgKey) emitStyle(bgOnlyStyle, bgKey);
|
|
6986
7728
|
frameParts.push("\x1B[K");
|
|
6987
7729
|
}
|
|
6988
|
-
|
|
7730
|
+
lastRenderedY = y;
|
|
7731
|
+
lastRenderWasFullRow = spanStart === 0 && clearToEol;
|
|
6989
7732
|
};
|
|
6990
|
-
|
|
7733
|
+
const overlayCoverage = overlayPlaneCoverageRows(size.rows);
|
|
7734
|
+
const overlayRows = Array.from(new Set([...overlayCoverage.blockedRows, ...prevOverlayBlockedRows])).sort((a, b) => a - b);
|
|
7735
|
+
const overlayRowSet = overlayRows.length ? new Set(overlayRows) : null;
|
|
7736
|
+
const overlayPartialRows = Array.from(new Set([...overlayCoverage.partialRows, ...prevOverlayPartialRows])).sort((a, b) => a - b);
|
|
7737
|
+
const overlayPartialRowSet = overlayPartialRows.length ? new Set(overlayPartialRows) : null;
|
|
7738
|
+
let explicitScrollOperations = normalizedScrollOperations;
|
|
7739
|
+
let hiddenExplicitDirtyRows = null;
|
|
7740
|
+
let allowInferredScrollRegions = true;
|
|
7741
|
+
if (explicitScrollOperations && overlayRows.length) {
|
|
7742
|
+
const preparedExplicit = prepareExplicitScrollOperations(explicitScrollOperations, overlayRowSet);
|
|
7743
|
+
hiddenExplicitDirtyRows = preparedExplicit.hiddenRows.size ? preparedExplicit.hiddenRows : null;
|
|
7744
|
+
if (preparedExplicit.operations) {
|
|
7745
|
+
explicitScrollOperations = preparedExplicit.operations;
|
|
7746
|
+
if (preparedExplicit.trimmed && isDebugEnabled()) getDebugLog().render(` Explicit scroll ops clipped around overlay rows: ${normalizedScrollOperations.map((op, index) => `${op.startY}-${op.endY - 1}:${op.delta}->${explicitScrollOperations[index].startY}-${explicitScrollOperations[index].endY - 1}:${explicitScrollOperations[index].delta}`).join(", ")}`);
|
|
7747
|
+
} else {
|
|
7748
|
+
allowInferredScrollRegions = false;
|
|
7749
|
+
const expandedRows = new Set(rowsToRender ?? []);
|
|
7750
|
+
for (const op of explicitScrollOperations) for (let y = op.startY; y < op.endY; y++) expandedRows.add(y);
|
|
7751
|
+
rowsToRender = Array.from(expandedRows).sort((a, b) => a - b);
|
|
7752
|
+
dirtySorted = true;
|
|
7753
|
+
explicitScrollOperations = null;
|
|
7754
|
+
hiddenExplicitDirtyRows = null;
|
|
7755
|
+
if (isDebugEnabled()) getDebugLog().render(preparedExplicit.blockedInterior ? " Explicit scroll ops split by interior overlay rows; falling back to region repaint" : " Explicit scroll ops could not be clipped safely; falling back to region repaint");
|
|
7756
|
+
}
|
|
7757
|
+
}
|
|
7758
|
+
const scrollRowsCandidate = rowsToRender;
|
|
7759
|
+
if (explicitScrollOperations && rowsToRender && (!enableScrollRegions || !fpPrevValid)) {
|
|
7760
|
+
const expandedRows = new Set(rowsToRender);
|
|
7761
|
+
for (const op of explicitScrollOperations) for (let y = op.startY; y < op.endY; y++) {
|
|
7762
|
+
if (hiddenExplicitDirtyRows === null || hiddenExplicitDirtyRows === void 0 ? void 0 : hiddenExplicitDirtyRows.has(y)) continue;
|
|
7763
|
+
expandedRows.add(y);
|
|
7764
|
+
}
|
|
7765
|
+
rowsToRender = Array.from(expandedRows).sort((a, b) => a - b);
|
|
7766
|
+
dirtySorted = true;
|
|
7767
|
+
explicitScrollOperations = null;
|
|
7768
|
+
hiddenExplicitDirtyRows = null;
|
|
7769
|
+
if (isDebugEnabled()) getDebugLog().render(enableScrollRegions ? " Explicit scroll ops fell back to region repaint because previous fingerprints are unavailable" : " Explicit scroll ops fell back to region repaint because scroll regions are disabled");
|
|
7770
|
+
}
|
|
7771
|
+
const denseDirtyRows = Boolean(rowsToRender && rowsToRender.length >= size.rows * dirtyFullThreshold);
|
|
7772
|
+
if (denseDirtyRows) rowsToRender = null;
|
|
7773
|
+
let profiledRowCount = rowsToRender ? rowsToRender.length : size.rows;
|
|
7774
|
+
const useScrollRegions = enableScrollRegions && fpPrevValid && scrollRowsCandidate && scrollRowsCandidate.length >= 3 && allowInferredScrollRegions;
|
|
7775
|
+
let scrollHandled = false;
|
|
7776
|
+
if (enableScrollRegions && explicitScrollOperations && scrollRowsCandidate && fpPrevValid) {
|
|
7777
|
+
if (currentFP.length === prevFP.length) currentFP.set(prevFP);
|
|
7778
|
+
const insertedRows = new Set();
|
|
7779
|
+
const explicitRowsToRender = new Set();
|
|
7780
|
+
for (const y of scrollRowsCandidate) {
|
|
7781
|
+
if (hiddenExplicitDirtyRows === null || hiddenExplicitDirtyRows === void 0 ? void 0 : hiddenExplicitDirtyRows.has(y)) continue;
|
|
7782
|
+
explicitRowsToRender.add(y);
|
|
7783
|
+
}
|
|
7784
|
+
if (isDebugEnabled()) getDebugLog().render(` Explicit scroll ops: ${explicitScrollOperations.map((op) => `${op.startY}-${op.endY - 1}:${op.delta}`).join(", ")}`);
|
|
7785
|
+
for (const op of explicitScrollOperations) {
|
|
7786
|
+
hasFrameOutput = true;
|
|
7787
|
+
frameParts.push(`\u001B[${op.startY + 1};${op.endY}r`);
|
|
7788
|
+
if (op.delta > 0) {
|
|
7789
|
+
frameParts.push(`\u001B[${op.endY};1H`);
|
|
7790
|
+
frameParts.push(`\u001B[${op.delta}S`);
|
|
7791
|
+
for (let y = op.startY; y < op.endY - op.delta; y++) {
|
|
7792
|
+
const dstBase = y * fpCols;
|
|
7793
|
+
const srcBase = (y + op.delta) * fpCols;
|
|
7794
|
+
for (let x = 0; x < size.cols; x++) currentFP[dstBase + x] = prevFP[srcBase + x];
|
|
7795
|
+
}
|
|
7796
|
+
for (let y = op.endY - op.delta; y < op.endY; y++) {
|
|
7797
|
+
const base = y * fpCols;
|
|
7798
|
+
insertedRows.add(y);
|
|
7799
|
+
explicitRowsToRender.add(y);
|
|
7800
|
+
for (let x = 0; x < size.cols; x++) currentFP[base + x] = blankFP;
|
|
7801
|
+
}
|
|
7802
|
+
} else {
|
|
7803
|
+
const absDelta = -op.delta;
|
|
7804
|
+
frameParts.push(`\u001B[${op.startY + 1};1H`);
|
|
7805
|
+
frameParts.push(`\u001B[${absDelta}T`);
|
|
7806
|
+
for (let y = op.endY - 1; y >= op.startY + absDelta; y--) {
|
|
7807
|
+
const dstBase = y * fpCols;
|
|
7808
|
+
const srcBase = (y - absDelta) * fpCols;
|
|
7809
|
+
for (let x = 0; x < size.cols; x++) currentFP[dstBase + x] = prevFP[srcBase + x];
|
|
7810
|
+
}
|
|
7811
|
+
for (let y = op.startY; y < op.startY + absDelta; y++) {
|
|
7812
|
+
const base = y * fpCols;
|
|
7813
|
+
insertedRows.add(y);
|
|
7814
|
+
explicitRowsToRender.add(y);
|
|
7815
|
+
for (let x = 0; x < size.cols; x++) currentFP[base + x] = blankFP;
|
|
7816
|
+
}
|
|
7817
|
+
}
|
|
7818
|
+
frameParts.push("\x1B[r");
|
|
7819
|
+
}
|
|
7820
|
+
const explicitDirtyRows = Array.from(explicitRowsToRender).sort((a, b) => a - b);
|
|
7821
|
+
const overlayDirtyRows = overlayRowSet ? explicitDirtyRows.filter((y) => overlayRowSet.has(y)) : [];
|
|
7822
|
+
const paintedExplicitRows = [];
|
|
7823
|
+
for (const y of explicitDirtyRows) {
|
|
7824
|
+
const row = terminal.getRow(y);
|
|
7825
|
+
const overlayRow = overlayRowSet === null || overlayRowSet === void 0 ? void 0 : overlayRowSet.has(y);
|
|
7826
|
+
if (overlayRow) {
|
|
7827
|
+
fingerprintRow(row, y, size.cols);
|
|
7828
|
+
renderRow$1(y, row);
|
|
7829
|
+
paintedExplicitRows.push(y);
|
|
7830
|
+
continue;
|
|
7831
|
+
}
|
|
7832
|
+
const span = (() => {
|
|
7833
|
+
if (insertedRows.has(y)) {
|
|
7834
|
+
fingerprintRow(row, y, size.cols);
|
|
7835
|
+
return resolveChangedSpanAgainstFill(row, y, size.cols, blankFP);
|
|
7836
|
+
}
|
|
7837
|
+
return resolveChangedSpanAgainstReference(row, y, size.cols);
|
|
7838
|
+
})();
|
|
7839
|
+
if (!span) {
|
|
7840
|
+
if (!skipUnchangedDirtyRows) fingerprintRow(row, y, size.cols);
|
|
7841
|
+
if (!skipUnchangedDirtyRows) {
|
|
7842
|
+
renderRow$1(y, row);
|
|
7843
|
+
paintedExplicitRows.push(y);
|
|
7844
|
+
}
|
|
7845
|
+
continue;
|
|
7846
|
+
}
|
|
7847
|
+
const rewriteTail = !insertedRows.has(y) && shouldRewriteRowTail(row, y, size.cols, currentFP);
|
|
7848
|
+
fingerprintRow(row, y, size.cols);
|
|
7849
|
+
renderRow$1(y, row, span.startX, rewriteTail ? row.length : span.endXExclusive, rewriteTail || span.endXExclusive >= row.length);
|
|
7850
|
+
paintedExplicitRows.push(y);
|
|
7851
|
+
}
|
|
7852
|
+
if (isDebugEnabled() && overlayDirtyRows.length) getDebugLog().render(` Explicit scroll ops overlay rows: [${overlayDirtyRows.join(", ")}]`);
|
|
7853
|
+
profiledRowCount = explicitDirtyRows.length;
|
|
7854
|
+
scrollHandled = true;
|
|
7855
|
+
} else if (useScrollRegions && scrollRowsCandidate) {
|
|
7856
|
+
for (let y = 0; y < size.rows; y++) fingerprintRow(terminal.getRow(y), y, size.cols);
|
|
7857
|
+
const shift = detectScrollShift(size.cols, scrollRowsCandidate, overlayRows);
|
|
7858
|
+
if (shift) {
|
|
7859
|
+
if (currentFP.length === prevFP.length) currentFP.set(prevFP);
|
|
7860
|
+
hasFrameOutput = true;
|
|
7861
|
+
if (isDebugEnabled()) getDebugLog().render(` Scroll region: delta=${shift.delta}, region=${shift.regionStart}-${shift.regionEnd - 1}, new rows=${shift.newRowStart}-${shift.newRowEnd - 1}`);
|
|
7862
|
+
frameParts.push(`\u001B[${shift.regionStart + 1};${shift.regionEnd}r`);
|
|
7863
|
+
if (shift.delta > 0) {
|
|
7864
|
+
frameParts.push(`\u001B[${shift.regionEnd};1H`);
|
|
7865
|
+
frameParts.push(`\u001B[${shift.delta}S`);
|
|
7866
|
+
} else {
|
|
7867
|
+
frameParts.push(`\u001B[${shift.regionStart + 1};1H`);
|
|
7868
|
+
frameParts.push(`\u001B[${-shift.delta}T`);
|
|
7869
|
+
}
|
|
7870
|
+
frameParts.push("\x1B[r");
|
|
7871
|
+
if (shift.delta > 0) {
|
|
7872
|
+
for (let y = shift.regionStart; y < shift.regionEnd - shift.delta; y++) {
|
|
7873
|
+
const dstBase = y * fpCols;
|
|
7874
|
+
const srcBase = (y + shift.delta) * fpCols;
|
|
7875
|
+
for (let x = 0; x < size.cols; x++) currentFP[dstBase + x] = prevFP[srcBase + x];
|
|
7876
|
+
}
|
|
7877
|
+
for (let y = shift.regionEnd - shift.delta; y < shift.regionEnd; y++) {
|
|
7878
|
+
const base = y * fpCols;
|
|
7879
|
+
for (let x = 0; x < size.cols; x++) currentFP[base + x] = blankFP;
|
|
7880
|
+
}
|
|
7881
|
+
} else {
|
|
7882
|
+
const absDelta = -shift.delta;
|
|
7883
|
+
for (let y = shift.regionEnd - 1; y >= shift.regionStart + absDelta; y--) {
|
|
7884
|
+
const dstBase = y * fpCols;
|
|
7885
|
+
const srcBase = (y - absDelta) * fpCols;
|
|
7886
|
+
for (let x = 0; x < size.cols; x++) currentFP[dstBase + x] = prevFP[srcBase + x];
|
|
7887
|
+
}
|
|
7888
|
+
for (let y = shift.regionStart; y < shift.regionStart + absDelta; y++) {
|
|
7889
|
+
const base = y * fpCols;
|
|
7890
|
+
for (let x = 0; x < size.cols; x++) currentFP[base + x] = blankFP;
|
|
7891
|
+
}
|
|
7892
|
+
}
|
|
7893
|
+
for (let y = shift.newRowStart; y < shift.newRowEnd; y++) {
|
|
7894
|
+
const row = terminal.getRow(y);
|
|
7895
|
+
fingerprintRow(row, y, size.cols);
|
|
7896
|
+
renderRow$1(y, row);
|
|
7897
|
+
}
|
|
7898
|
+
const extraDirtyRows = overlayRowSet ? shift.extraDirtyRows.filter((y) => !overlayRowSet.has(y) || Boolean(overlayPartialRowSet === null || overlayPartialRowSet === void 0 ? void 0 : overlayPartialRowSet.has(y))) : shift.extraDirtyRows;
|
|
7899
|
+
for (const y of extraDirtyRows) {
|
|
7900
|
+
const row = terminal.getRow(y);
|
|
7901
|
+
const overlayRow = overlayRowSet === null || overlayRowSet === void 0 ? void 0 : overlayRowSet.has(y);
|
|
7902
|
+
if (overlayRow) {
|
|
7903
|
+
renderRow$1(y, row);
|
|
7904
|
+
fingerprintRow(row, y, size.cols);
|
|
7905
|
+
continue;
|
|
7906
|
+
}
|
|
7907
|
+
const span = resolveChangedSpanAgainstReference(row, y, size.cols);
|
|
7908
|
+
if (!span) {
|
|
7909
|
+
if (!skipUnchangedDirtyRows) {
|
|
7910
|
+
fingerprintRow(row, y, size.cols);
|
|
7911
|
+
renderRow$1(y, row);
|
|
7912
|
+
}
|
|
7913
|
+
continue;
|
|
7914
|
+
}
|
|
7915
|
+
const rewriteTail = shouldRewriteRowTail(row, y, size.cols, currentFP);
|
|
7916
|
+
renderRow$1(y, row, span.startX, rewriteTail ? row.length : span.endXExclusive, rewriteTail || span.endXExclusive >= row.length);
|
|
7917
|
+
fingerprintRow(row, y, size.cols);
|
|
7918
|
+
}
|
|
7919
|
+
for (let y = shift.newRowStart; y < shift.newRowEnd; y++) fingerprintRow(terminal.getRow(y), y, size.cols);
|
|
7920
|
+
const renderedRows = new Set();
|
|
7921
|
+
for (let y = shift.newRowStart; y < shift.newRowEnd; y++) renderedRows.add(y);
|
|
7922
|
+
for (const y of extraDirtyRows) renderedRows.add(y);
|
|
7923
|
+
profiledRowCount = renderedRows.size;
|
|
7924
|
+
scrollHandled = true;
|
|
7925
|
+
}
|
|
7926
|
+
}
|
|
7927
|
+
if (!scrollHandled && denseDirtyRows && scrollRowsCandidate && useScrollRegions) {
|
|
7928
|
+
rowsToRender = scrollRowsCandidate;
|
|
7929
|
+
profiledRowCount = rowsToRender.length;
|
|
7930
|
+
if (isDebugEnabled()) getDebugLog().render(` Dense dirty rows fell back to partial render: ${rowsToRender.length} rows`);
|
|
7931
|
+
}
|
|
7932
|
+
if (scrollHandled) {} else if (!rowsToRender) {
|
|
6991
7933
|
if (isDebugEnabled()) getDebugLog().render(` Full render: ${size.rows} rows`);
|
|
6992
7934
|
for (let y = 0; y < size.rows; y++) {
|
|
6993
7935
|
const row = terminal.getRow(y);
|
|
7936
|
+
fingerprintRow(row, y, size.cols);
|
|
6994
7937
|
renderRow$1(y, row);
|
|
6995
7938
|
}
|
|
6996
7939
|
} else {
|
|
6997
|
-
const
|
|
6998
|
-
if (isDebugEnabled()) getDebugLog().render(` Partial render: ${rowsToRender.length} dirty rows: [${rowsToRender.join(", ")}]${
|
|
7940
|
+
const overlayDirtyRows = overlayRowSet ? rowsToRender.filter((y) => overlayRowSet.has(y)) : [];
|
|
7941
|
+
if (isDebugEnabled()) getDebugLog().render(` Partial render: ${rowsToRender.length} dirty rows: [${rowsToRender.join(", ")}]${overlayDirtyRows.length ? ` (overlay-full-row: [${overlayDirtyRows.join(", ")}])` : ""}`);
|
|
6999
7942
|
for (const y of rowsToRender) {
|
|
7000
7943
|
const row = terminal.getRow(y);
|
|
7001
|
-
|
|
7944
|
+
fingerprintRow(row, y, size.cols);
|
|
7945
|
+
const overlayRow = overlayRowSet === null || overlayRowSet === void 0 ? void 0 : overlayRowSet.has(y);
|
|
7946
|
+
if (overlayRow) {
|
|
7002
7947
|
renderRow$1(y, row);
|
|
7003
7948
|
continue;
|
|
7004
7949
|
}
|
|
7005
|
-
const span = resolveChangedSpan(row,
|
|
7950
|
+
const span = resolveChangedSpan(row, y, size.cols);
|
|
7006
7951
|
if (!span) {
|
|
7007
|
-
renderRow$1(y, row);
|
|
7952
|
+
if (!skipUnchangedDirtyRows) renderRow$1(y, row);
|
|
7008
7953
|
continue;
|
|
7009
7954
|
}
|
|
7010
|
-
|
|
7955
|
+
const rewriteTail = shouldRewriteRowTail(row, y, size.cols, prevFP);
|
|
7956
|
+
renderRow$1(y, row, span.startX, rewriteTail ? row.length : span.endXExclusive, rewriteTail || span.endXExclusive >= row.length);
|
|
7011
7957
|
}
|
|
7012
7958
|
}
|
|
7013
7959
|
if (!rowsToRender && lastRenderedRows > size.rows) {
|
|
@@ -7016,17 +7962,37 @@ function createStdoutRenderer(terminal, options) {
|
|
|
7016
7962
|
frameParts.push(SGR_RESET, bgSeq);
|
|
7017
7963
|
activeStyleKey = bgKey;
|
|
7018
7964
|
}
|
|
7019
|
-
for (let i = 0; i < extraRows; i++)
|
|
7965
|
+
for (let i = 0; i < extraRows; i++) {
|
|
7966
|
+
hasFrameOutput = true;
|
|
7967
|
+
frameParts.push(rowClearToEol[size.rows + i]);
|
|
7968
|
+
}
|
|
7020
7969
|
}
|
|
7021
7970
|
if (!rowsToRender) lastRenderedRows = size.rows;
|
|
7022
|
-
|
|
7971
|
+
const tmpFP = prevFP;
|
|
7972
|
+
prevFP = currentFP;
|
|
7973
|
+
currentFP = tmpFP;
|
|
7974
|
+
fpPrevValid = true;
|
|
7975
|
+
prevOverlayBlockedRows = overlayCoverage.blockedRows;
|
|
7976
|
+
prevOverlayPartialRows = overlayCoverage.partialRows;
|
|
7977
|
+
let emittedCursorPos = null;
|
|
7023
7978
|
if (getImeAnchor) {
|
|
7024
7979
|
const anchor = getImeAnchor();
|
|
7025
7980
|
if (anchor) {
|
|
7026
7981
|
const { x, y } = clampCellToViewport(anchor, size);
|
|
7027
|
-
|
|
7982
|
+
if (hasFrameOutput || x !== lastCursorX || y !== lastCursorY) {
|
|
7983
|
+
hasFrameOutput = true;
|
|
7984
|
+
emittedCursorPos = {
|
|
7985
|
+
x,
|
|
7986
|
+
y
|
|
7987
|
+
};
|
|
7988
|
+
frameParts.push(`\u001B[${y + 1};${x + 1}H`);
|
|
7989
|
+
}
|
|
7028
7990
|
}
|
|
7029
7991
|
}
|
|
7992
|
+
if (!hasFrameOutput) {
|
|
7993
|
+
if (isDebugEnabled()) getDebugLog().render(" No-op frame skipped");
|
|
7994
|
+
return;
|
|
7995
|
+
}
|
|
7030
7996
|
if (enableOsc8Links && activeStyle.href) frameParts.push(OSC8_CLOSE);
|
|
7031
7997
|
frameParts.push(SGR_RESET);
|
|
7032
7998
|
frameParts.push("\x1B[?7h");
|
|
@@ -7034,9 +8000,9 @@ function createStdoutRenderer(terminal, options) {
|
|
|
7034
8000
|
const frame = frameParts.join("");
|
|
7035
8001
|
if (profiler) profiler.recordRender({
|
|
7036
8002
|
durationMs: profiler.now() - renderStart,
|
|
7037
|
-
rows:
|
|
8003
|
+
rows: profiledRowCount,
|
|
7038
8004
|
nodes: 0,
|
|
7039
|
-
fullRepaint: !rowsToRender,
|
|
8005
|
+
fullRepaint: !rowsToRender && !scrollHandled,
|
|
7040
8006
|
sorted: dirtySorted
|
|
7041
8007
|
});
|
|
7042
8008
|
if (isDebugEnabled()) {
|
|
@@ -7134,6 +8100,13 @@ function createStdoutRenderer(terminal, options) {
|
|
|
7134
8100
|
{
|
|
7135
8101
|
const writeMs = performance.now() - writeStart;
|
|
7136
8102
|
writeEmaMs = writeEmaMs === 0 ? writeMs : writeEmaMs * .85 + writeMs * .15;
|
|
8103
|
+
if (emittedCursorPos) {
|
|
8104
|
+
lastCursorX = emittedCursorPos.x;
|
|
8105
|
+
lastCursorY = emittedCursorPos.y;
|
|
8106
|
+
} else {
|
|
8107
|
+
lastCursorX = null;
|
|
8108
|
+
lastCursorY = null;
|
|
8109
|
+
}
|
|
7137
8110
|
recordStdoutFrame({
|
|
7138
8111
|
at: Date.now(),
|
|
7139
8112
|
bytes: frame.length,
|
|
@@ -7158,9 +8131,20 @@ function createStdoutRenderer(terminal, options) {
|
|
|
7158
8131
|
* Prevents excessive renders that cause flickering in Bun binaries.
|
|
7159
8132
|
* Accumulates dirty rows while waiting for next frame to ensure no updates are lost.
|
|
7160
8133
|
*/
|
|
7161
|
-
function render(dirtyRows) {
|
|
8134
|
+
function render(dirtyRows, sync, scrollOperations, skipUnchangedDirtyRows = false) {
|
|
7162
8135
|
if (disposed) return;
|
|
7163
8136
|
if (isDebugEnabled()) getDebugLog().render(`render() called: dirtyRows=${(dirtyRows === null || dirtyRows === void 0 ? void 0 : dirtyRows.length) ?? "null"}, pending=${pendingRender}, elapsed=${Date.now() - lastFrameTime}ms`);
|
|
8137
|
+
const isSmallSyncPatch = Boolean(sync && (dirtyRows === null || dirtyRows === void 0 ? void 0 : dirtyRows.length) && dirtyRows.length <= 12 && !(scrollOperations === null || scrollOperations === void 0 ? void 0 : scrollOperations.length));
|
|
8138
|
+
if (isSmallSyncPatch) skipUnchangedDirtyRows = false;
|
|
8139
|
+
if ((dirtyRows === null || dirtyRows === void 0 ? void 0 : dirtyRows.length) && skipUnchangedDirtyRows && fpPrevValid && !(scrollOperations === null || scrollOperations === void 0 ? void 0 : scrollOperations.length) && dirtyRows.length < terminal.size().rows) {
|
|
8140
|
+
const cols = terminal.size().cols;
|
|
8141
|
+
const nextDirtyRows = dirtyRows.filter((y) => !rowMatchesPreviousFrame(y, cols));
|
|
8142
|
+
if (nextDirtyRows.length === 0) {
|
|
8143
|
+
if (isDebugEnabled()) getDebugLog().render(`Skipped unchanged dirty commit: ${dirtyRows.length} rows`);
|
|
8144
|
+
return;
|
|
8145
|
+
}
|
|
8146
|
+
dirtyRows = nextDirtyRows;
|
|
8147
|
+
}
|
|
7164
8148
|
const ensureDirtyBits = (rowCount) => {
|
|
7165
8149
|
if (!accumulatedDirtyBits || accumulatedDirtyBits.length !== rowCount) {
|
|
7166
8150
|
accumulatedDirtyBits = new Uint8Array(rowCount);
|
|
@@ -7182,12 +8166,43 @@ function createStdoutRenderer(terminal, options) {
|
|
|
7182
8166
|
out$1.length = outLen;
|
|
7183
8167
|
return outLen ? out$1 : null;
|
|
7184
8168
|
};
|
|
8169
|
+
const buildAccumulatedScrollOperations = () => {
|
|
8170
|
+
return (accumulatedScrollOperations === null || accumulatedScrollOperations === void 0 ? void 0 : accumulatedScrollOperations.length) ? accumulatedScrollOperations : null;
|
|
8171
|
+
};
|
|
8172
|
+
const mergeScrollOperations = (next) => {
|
|
8173
|
+
if (!(next === null || next === void 0 ? void 0 : next.length) || accumulatedAllRows) return;
|
|
8174
|
+
const merged = accumulatedScrollOperations ? accumulatedScrollOperations.slice() : [];
|
|
8175
|
+
for (const op of next) {
|
|
8176
|
+
const startY = Math.floor(op.startY);
|
|
8177
|
+
const endY = Math.floor(op.endY);
|
|
8178
|
+
const delta = Math.trunc(op.delta);
|
|
8179
|
+
if (endY <= startY || delta === 0) continue;
|
|
8180
|
+
const existingIndex = merged.findIndex((existing) => existing.startY === startY && existing.endY === endY);
|
|
8181
|
+
if (existingIndex >= 0) {
|
|
8182
|
+
const existing = merged[existingIndex];
|
|
8183
|
+
const nextDelta = existing.delta + delta;
|
|
8184
|
+
if (nextDelta === 0) merged.splice(existingIndex, 1);
|
|
8185
|
+
else merged[existingIndex] = {
|
|
8186
|
+
startY,
|
|
8187
|
+
endY,
|
|
8188
|
+
delta: nextDelta
|
|
8189
|
+
};
|
|
8190
|
+
} else merged.push({
|
|
8191
|
+
startY,
|
|
8192
|
+
endY,
|
|
8193
|
+
delta
|
|
8194
|
+
});
|
|
8195
|
+
}
|
|
8196
|
+
accumulatedScrollOperations = merged.length ? merged : null;
|
|
8197
|
+
};
|
|
7185
8198
|
if (!dirtyRows || dirtyRows.length === 0) {
|
|
7186
8199
|
accumulatedAllRows = true;
|
|
7187
8200
|
accumulatedDirtyBits = null;
|
|
7188
8201
|
accumulatedDirtyCount = 0;
|
|
7189
8202
|
accumulatedDirtyMin = Number.POSITIVE_INFINITY;
|
|
7190
8203
|
accumulatedDirtyMax = -1;
|
|
8204
|
+
accumulatedScrollOperations = null;
|
|
8205
|
+
accumulatedSkipUnchangedDirtyRows = false;
|
|
7191
8206
|
} else if (!accumulatedAllRows) {
|
|
7192
8207
|
const rowCount = terminal.size().rows;
|
|
7193
8208
|
const bits = ensureDirtyBits(rowCount);
|
|
@@ -7201,13 +8216,29 @@ function createStdoutRenderer(terminal, options) {
|
|
|
7201
8216
|
if (y > accumulatedDirtyMax) accumulatedDirtyMax = y;
|
|
7202
8217
|
}
|
|
7203
8218
|
}
|
|
8219
|
+
mergeScrollOperations(scrollOperations);
|
|
8220
|
+
accumulatedSkipUnchangedDirtyRows && (accumulatedSkipUnchangedDirtyRows = skipUnchangedDirtyRows);
|
|
7204
8221
|
}
|
|
7205
|
-
if (pendingRender) return;
|
|
8222
|
+
if (pendingRender && !sync) return;
|
|
7206
8223
|
const now$2 = Date.now();
|
|
7207
8224
|
const elapsed = now$2 - lastFrameTime;
|
|
8225
|
+
if (sync) {
|
|
8226
|
+
if (pendingRender) {
|
|
8227
|
+
pendingRender = false;
|
|
8228
|
+
if (renderTimer) {
|
|
8229
|
+
clearTimeout(renderTimer);
|
|
8230
|
+
renderTimer = null;
|
|
8231
|
+
}
|
|
8232
|
+
}
|
|
8233
|
+
const rows = buildAccumulatedRows();
|
|
8234
|
+
const pendingScrolls = buildAccumulatedScrollOperations();
|
|
8235
|
+
doRender(rows, pendingScrolls, accumulatedSkipUnchangedDirtyRows);
|
|
8236
|
+
return;
|
|
8237
|
+
}
|
|
7208
8238
|
if (elapsed >= MIN_FRAME_MS) {
|
|
7209
8239
|
const rows = buildAccumulatedRows();
|
|
7210
|
-
|
|
8240
|
+
const pendingScrolls = buildAccumulatedScrollOperations();
|
|
8241
|
+
doRender(rows, pendingScrolls, accumulatedSkipUnchangedDirtyRows);
|
|
7211
8242
|
} else {
|
|
7212
8243
|
pendingRender = true;
|
|
7213
8244
|
if (renderTimer) clearTimeout(renderTimer);
|
|
@@ -7215,19 +8246,23 @@ function createStdoutRenderer(terminal, options) {
|
|
|
7215
8246
|
renderTimer = null;
|
|
7216
8247
|
if (!disposed) {
|
|
7217
8248
|
const rows = buildAccumulatedRows();
|
|
7218
|
-
|
|
8249
|
+
const pendingScrolls = buildAccumulatedScrollOperations();
|
|
8250
|
+
doRender(rows, pendingScrolls, accumulatedSkipUnchangedDirtyRows);
|
|
7219
8251
|
}
|
|
7220
8252
|
}, MIN_FRAME_MS - elapsed);
|
|
7221
8253
|
}
|
|
7222
8254
|
}
|
|
8255
|
+
terminal.setFingerprintFn((ch, style) => {
|
|
8256
|
+
return styleKey$1(style) << 16 | charHash16(ch);
|
|
8257
|
+
});
|
|
7223
8258
|
if (altScreen && out.isTTY) out.write("\x1B[?1049h");
|
|
7224
8259
|
if (hideCursor) out.write("\x1B[?25l");
|
|
7225
8260
|
if (clear) out.write(`${SGR_RESET}${openBg(defaultBg)}\u001B[2J\u001B[H${SGR_RESET}`);
|
|
7226
|
-
const off = terminal.on("commit", ({ dirtyRows }) => {
|
|
7227
|
-
if (isDebugEnabled()) getDebugLog().render(`Commit event: dirtyRows=${(dirtyRows === null || dirtyRows === void 0 ? void 0 : dirtyRows.length) ?? "null"}, rows=${(dirtyRows === null || dirtyRows === void 0 ? void 0 : dirtyRows.join(",")) ?? "all"}`);
|
|
7228
|
-
render(dirtyRows);
|
|
8261
|
+
const off = terminal.on("commit", ({ dirtyRows, scrollOperations, sync }) => {
|
|
8262
|
+
if (isDebugEnabled()) getDebugLog().render(`Commit event: dirtyRows=${(dirtyRows === null || dirtyRows === void 0 ? void 0 : dirtyRows.length) ?? "null"}, rows=${(dirtyRows === null || dirtyRows === void 0 ? void 0 : dirtyRows.join(",")) ?? "all"}${(scrollOperations === null || scrollOperations === void 0 ? void 0 : scrollOperations.length) ? `, scrollOps=${scrollOperations.map((op) => `${op.startY}-${op.endY - 1}:${op.delta}`).join("|")}` : ""}${sync ? " (sync)" : ""}`);
|
|
8263
|
+
render(dirtyRows, sync, scrollOperations, true);
|
|
7229
8264
|
});
|
|
7230
|
-
const resizeSource = (options === null || options === void 0 ? void 0 : options.output) ?? process.stdout;
|
|
8265
|
+
const resizeSource = (options === null || options === void 0 ? void 0 : options.output) ?? process$1.stdout;
|
|
7231
8266
|
const canTrackResize = Boolean(trackResize && out.isTTY && typeof (resizeSource === null || resizeSource === void 0 ? void 0 : resizeSource.on) === "function");
|
|
7232
8267
|
const onResize = () => {
|
|
7233
8268
|
const cols = Number(resizeSource === null || resizeSource === void 0 ? void 0 : resizeSource.columns);
|
|
@@ -7255,6 +8290,8 @@ function createStdoutRenderer(terminal, options) {
|
|
|
7255
8290
|
rows: size.rows
|
|
7256
8291
|
});
|
|
7257
8292
|
out.write(`\u001B[${cy + 1};${cx + 1}H`);
|
|
8293
|
+
lastCursorX = cx;
|
|
8294
|
+
lastCursorY = cy;
|
|
7258
8295
|
}
|
|
7259
8296
|
/** Show or hide the terminal cursor */
|
|
7260
8297
|
function showCursor(visible) {
|
|
@@ -7288,7 +8325,10 @@ function createStdoutRenderer(terminal, options) {
|
|
|
7288
8325
|
if (next.defaultBg && next.defaultBg !== defaultBg) defaultBg = next.defaultBg;
|
|
7289
8326
|
if ("palette" in next) palette = next.palette;
|
|
7290
8327
|
styleKeyCache$1 = new WeakMap();
|
|
7291
|
-
|
|
8328
|
+
fpRows = 0;
|
|
8329
|
+
fpPrevValid = false;
|
|
8330
|
+
prevOverlayBlockedRows = [];
|
|
8331
|
+
prevOverlayPartialRows = [];
|
|
7292
8332
|
render();
|
|
7293
8333
|
};
|
|
7294
8334
|
return {
|
|
@@ -7592,7 +8632,7 @@ function createDomRenderer(terminal, container) {
|
|
|
7592
8632
|
//#region src/runtime/index.ts
|
|
7593
8633
|
function isNodeLike() {
|
|
7594
8634
|
var _process$versions;
|
|
7595
|
-
return typeof (process === null || process === void 0 || (_process$versions = process.versions) === null || _process$versions === void 0 ? void 0 : _process$versions.node) === "string";
|
|
8635
|
+
return typeof (process$1 === null || process$1 === void 0 || (_process$versions = process$1.versions) === null || _process$versions === void 0 ? void 0 : _process$versions.node) === "string";
|
|
7596
8636
|
}
|
|
7597
8637
|
function detectEnv() {
|
|
7598
8638
|
const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
@@ -7732,26 +8772,39 @@ function useTerminal() {
|
|
|
7732
8772
|
//#endregion
|
|
7733
8773
|
//#region src/vue/composables/use-render-node.ts
|
|
7734
8774
|
const pendingInvalidateByScheduler = new WeakMap();
|
|
7735
|
-
function
|
|
8775
|
+
function mergePriority(prev, next) {
|
|
8776
|
+
if (prev === "high" || next === "high") return "high";
|
|
8777
|
+
if (prev === "normal" || next === "normal") return "normal";
|
|
8778
|
+
return "low";
|
|
8779
|
+
}
|
|
8780
|
+
function requestBatchedInvalidate(scheduler, plane, priority) {
|
|
7736
8781
|
let state = pendingInvalidateByScheduler.get(scheduler);
|
|
7737
8782
|
if (!state) {
|
|
7738
8783
|
state = {
|
|
7739
8784
|
queued: false,
|
|
7740
|
-
plane: null
|
|
8785
|
+
plane: null,
|
|
8786
|
+
priority: "low"
|
|
7741
8787
|
};
|
|
7742
8788
|
pendingInvalidateByScheduler.set(scheduler, state);
|
|
7743
8789
|
}
|
|
7744
8790
|
if (state.queued) {
|
|
7745
8791
|
state.plane = state.plane == null || state.plane === plane ? plane : null;
|
|
8792
|
+
state.priority = mergePriority(state.priority, priority);
|
|
7746
8793
|
return;
|
|
7747
8794
|
}
|
|
7748
8795
|
state.plane = plane;
|
|
8796
|
+
state.priority = priority;
|
|
7749
8797
|
state.queued = true;
|
|
7750
8798
|
queueMicrotask(() => {
|
|
7751
8799
|
state.queued = false;
|
|
7752
8800
|
const queuedPlane = state.plane;
|
|
8801
|
+
const queuedPriority = state.priority;
|
|
7753
8802
|
state.plane = null;
|
|
7754
|
-
|
|
8803
|
+
state.priority = "low";
|
|
8804
|
+
scheduler.invalidate(queuedPlane || queuedPriority !== "normal" ? {
|
|
8805
|
+
plane: queuedPlane ?? void 0,
|
|
8806
|
+
priority: queuedPriority
|
|
8807
|
+
} : void 0);
|
|
7755
8808
|
});
|
|
7756
8809
|
}
|
|
7757
8810
|
function useRenderNode(getOptions) {
|
|
@@ -7759,11 +8812,13 @@ function useRenderNode(getOptions) {
|
|
|
7759
8812
|
const parentStack = useRenderStack();
|
|
7760
8813
|
const plane = inject(RenderPlaneContextKey, ref("default"));
|
|
7761
8814
|
const id = ref(null);
|
|
8815
|
+
const lastPlane = ref(plane.value);
|
|
7762
8816
|
const options = computed(() => getOptions());
|
|
7763
8817
|
const stop = watchEffect(() => {
|
|
7764
8818
|
const opt = options.value;
|
|
7765
8819
|
opt.deps;
|
|
7766
8820
|
const stack = opt.stack ?? parentStack.value;
|
|
8821
|
+
lastPlane.value = plane.value;
|
|
7767
8822
|
if (!stack) return;
|
|
7768
8823
|
if (!id.value) {
|
|
7769
8824
|
const node = render.register({
|
|
@@ -7774,23 +8829,24 @@ function useRenderNode(getOptions) {
|
|
|
7774
8829
|
paint: opt.paint
|
|
7775
8830
|
});
|
|
7776
8831
|
id.value = node.id;
|
|
7777
|
-
requestBatchedInvalidate(scheduler, plane.value);
|
|
8832
|
+
requestBatchedInvalidate(scheduler, plane.value, opt.priority ?? "normal");
|
|
7778
8833
|
return;
|
|
7779
8834
|
}
|
|
7780
8835
|
render.update(id.value, {
|
|
7781
8836
|
stack,
|
|
7782
8837
|
zIndex: opt.zIndex ?? 0,
|
|
7783
8838
|
rect: opt.rect ?? null,
|
|
8839
|
+
dirtyRowsHint: opt.dirtyRowsHint,
|
|
7784
8840
|
plane: plane.value,
|
|
7785
8841
|
paint: opt.paint
|
|
7786
8842
|
});
|
|
7787
|
-
requestBatchedInvalidate(scheduler, plane.value);
|
|
8843
|
+
requestBatchedInvalidate(scheduler, plane.value, opt.priority ?? "normal");
|
|
7788
8844
|
});
|
|
7789
8845
|
onBeforeUnmount(() => {
|
|
7790
8846
|
stop();
|
|
7791
8847
|
if (id.value) {
|
|
7792
8848
|
render.unregister(id.value);
|
|
7793
|
-
requestBatchedInvalidate(scheduler,
|
|
8849
|
+
requestBatchedInvalidate(scheduler, lastPlane.value, "normal");
|
|
7794
8850
|
}
|
|
7795
8851
|
});
|
|
7796
8852
|
return { id };
|
|
@@ -8981,6 +10037,8 @@ function createPromptMentionPlugin(options = {}) {
|
|
|
8981
10037
|
install: (ctx) => {
|
|
8982
10038
|
const getProps = () => ctx.getProps();
|
|
8983
10039
|
const promptOverlayStack = ctx.render.createStack(ctx.render.rootStack, 1e4);
|
|
10040
|
+
let lastTopClampedRect = null;
|
|
10041
|
+
let lastPromptRect = null;
|
|
8984
10042
|
const derivedStyleCache = new WeakMap();
|
|
8985
10043
|
const reactiveProps = reactive({
|
|
8986
10044
|
promptSuggestions: getProps().promptSuggestions,
|
|
@@ -9028,6 +10086,20 @@ function createPromptMentionPlugin(options = {}) {
|
|
|
9028
10086
|
multilineToken: "",
|
|
9029
10087
|
mentionToken: ctx.mentionToken
|
|
9030
10088
|
});
|
|
10089
|
+
watch(() => {
|
|
10090
|
+
if (!ctx.visible.value || !promptMention.promptVisible.value) return null;
|
|
10091
|
+
const rect = promptMention.promptRect.value;
|
|
10092
|
+
return [
|
|
10093
|
+
Math.floor(rect.x),
|
|
10094
|
+
Math.floor(rect.y),
|
|
10095
|
+
Math.floor(rect.w),
|
|
10096
|
+
Math.floor(rect.h)
|
|
10097
|
+
].join(":");
|
|
10098
|
+
}, (nextRectKey, prevRectKey) => {
|
|
10099
|
+
if (!prevRectKey || nextRectKey === prevRectKey) return;
|
|
10100
|
+
ctx.render.invalidatePlane("default");
|
|
10101
|
+
ctx.scheduler.invalidate({ priority: "high" });
|
|
10102
|
+
});
|
|
9031
10103
|
ctx.registerChipStyleProvider({
|
|
9032
10104
|
getStyle: (baseStyle, chip) => {
|
|
9033
10105
|
if (chip.kind !== "mention") return null;
|
|
@@ -9203,6 +10275,20 @@ function createPromptMentionPlugin(options = {}) {
|
|
|
9203
10275
|
useRenderNode(() => ({
|
|
9204
10276
|
zIndex: getProps().zIndex + 5,
|
|
9205
10277
|
stack: promptOverlayStack,
|
|
10278
|
+
dirtyRowsHint: (() => {
|
|
10279
|
+
const currentRect = ctx.visible.value && promptMention.promptVisible.value ? {
|
|
10280
|
+
y: Math.floor(promptMention.promptRect.value.y),
|
|
10281
|
+
h: Math.max(0, Math.floor(promptMention.promptRect.value.h))
|
|
10282
|
+
} : null;
|
|
10283
|
+
const rects = [lastPromptRect, currentRect].filter(Boolean);
|
|
10284
|
+
if (!rects.length) return void 0;
|
|
10285
|
+
const maxRows = ctx.terminal.size().rows;
|
|
10286
|
+
const start = Math.max(0, Math.min(...rects.map((rect) => rect.y)) - 1);
|
|
10287
|
+
const end = Math.min(maxRows, Math.max(...rects.map((rect) => rect.y + rect.h)) + 1);
|
|
10288
|
+
if (end <= start) return void 0;
|
|
10289
|
+
return Array.from({ length: end - start }, (_, index) => start + index);
|
|
10290
|
+
})(),
|
|
10291
|
+
priority: "high",
|
|
9206
10292
|
rect: ctx.visible.value && promptMention.promptVisible.value ? promptMention.promptRect.value : {
|
|
9207
10293
|
x: 0,
|
|
9208
10294
|
y: 0,
|
|
@@ -9229,6 +10315,10 @@ function createPromptMentionPlugin(options = {}) {
|
|
|
9229
10315
|
if (!ctx.visible.value || !promptMention.promptVisible.value) return;
|
|
9230
10316
|
const r = promptMention.promptRect.value;
|
|
9231
10317
|
if (r.w < 3 || r.h < 3) return;
|
|
10318
|
+
lastPromptRect = {
|
|
10319
|
+
y: Math.floor(r.y),
|
|
10320
|
+
h: Math.max(0, Math.floor(r.h))
|
|
10321
|
+
};
|
|
9232
10322
|
const base = getProps().style ?? ctx.defaultStyle.value;
|
|
9233
10323
|
const selectedOverride = { bg: "blue" };
|
|
9234
10324
|
const styleKey$1 = base && typeof base === "object" ? base : null;
|
|
@@ -9278,6 +10368,19 @@ function createPromptMentionPlugin(options = {}) {
|
|
|
9278
10368
|
const contentW = Math.max(0, innerW - sidePad * 2);
|
|
9279
10369
|
const contentX = x0 + 1 + sidePad;
|
|
9280
10370
|
const borderStyle = derived.borderStyle;
|
|
10371
|
+
if (lastTopClampedRect && y0 > 0) {
|
|
10372
|
+
ctx.terminal.write(spaces(lastTopClampedRect.w), {
|
|
10373
|
+
x: lastTopClampedRect.x,
|
|
10374
|
+
y: 0,
|
|
10375
|
+
style: getProps().style ?? ctx.defaultStyle.value
|
|
10376
|
+
});
|
|
10377
|
+
lastTopClampedRect = null;
|
|
10378
|
+
}
|
|
10379
|
+
if (y0 === 0) lastTopClampedRect = {
|
|
10380
|
+
x: x0,
|
|
10381
|
+
w
|
|
10382
|
+
};
|
|
10383
|
+
else lastTopClampedRect = null;
|
|
9281
10384
|
ctx.terminal.write(`┌${repeatChar("─", innerW)}┐`, {
|
|
9282
10385
|
x: x0,
|
|
9283
10386
|
y: y0,
|
|
@@ -11543,6 +12646,8 @@ const TerminalProvider = defineComponent({
|
|
|
11543
12646
|
let rafToken = 0;
|
|
11544
12647
|
let pendingInvalidate = false;
|
|
11545
12648
|
let timer = null;
|
|
12649
|
+
let holdNormalInvalidates = false;
|
|
12650
|
+
let holdReleaseToken = 0;
|
|
11546
12651
|
let pendingInvalidateAllPlanes = false;
|
|
11547
12652
|
const pendingInvalidatePlanes = new Set();
|
|
11548
12653
|
let imeComposing = false;
|
|
@@ -11571,11 +12676,14 @@ const TerminalProvider = defineComponent({
|
|
|
11571
12676
|
pendingInvalidatePlanes.clear();
|
|
11572
12677
|
return activePlanes;
|
|
11573
12678
|
}
|
|
11574
|
-
function flush() {
|
|
12679
|
+
function flush(sync = false) {
|
|
11575
12680
|
if (unmounting) return;
|
|
11576
12681
|
const activePlanes = takeActivePlanes();
|
|
11577
12682
|
render.render({ activePlanes });
|
|
11578
|
-
terminal.commit({
|
|
12683
|
+
terminal.commit({
|
|
12684
|
+
planes: activePlanes,
|
|
12685
|
+
sync
|
|
12686
|
+
});
|
|
11579
12687
|
updateImePositionAfterFlush === null || updateImePositionAfterFlush === void 0 || updateImePositionAfterFlush();
|
|
11580
12688
|
}
|
|
11581
12689
|
function clearTimer() {
|
|
@@ -11583,6 +12691,16 @@ const TerminalProvider = defineComponent({
|
|
|
11583
12691
|
clearTimeout(timer);
|
|
11584
12692
|
timer = null;
|
|
11585
12693
|
}
|
|
12694
|
+
function scheduleNormalInvalidateRelease() {
|
|
12695
|
+
const token = ++holdReleaseToken;
|
|
12696
|
+
nextTick(() => {
|
|
12697
|
+
if (token !== holdReleaseToken) return;
|
|
12698
|
+
holdNormalInvalidates = false;
|
|
12699
|
+
if (unmounting || !pendingInvalidate) return;
|
|
12700
|
+
pendingInvalidate = false;
|
|
12701
|
+
invalidate({ priority: "normal" });
|
|
12702
|
+
});
|
|
12703
|
+
}
|
|
11586
12704
|
function flushNow() {
|
|
11587
12705
|
if (unmounting) return;
|
|
11588
12706
|
pendingInvalidate = false;
|
|
@@ -11592,7 +12710,9 @@ const TerminalProvider = defineComponent({
|
|
|
11592
12710
|
raf = 0;
|
|
11593
12711
|
}
|
|
11594
12712
|
clearTimer();
|
|
11595
|
-
|
|
12713
|
+
holdNormalInvalidates = true;
|
|
12714
|
+
scheduleNormalInvalidateRelease();
|
|
12715
|
+
flush(true);
|
|
11596
12716
|
}
|
|
11597
12717
|
function invalidate(options) {
|
|
11598
12718
|
if (unmounting) return;
|
|
@@ -11603,6 +12723,10 @@ const TerminalProvider = defineComponent({
|
|
|
11603
12723
|
flushNow();
|
|
11604
12724
|
return;
|
|
11605
12725
|
}
|
|
12726
|
+
if (holdNormalInvalidates) {
|
|
12727
|
+
pendingInvalidate = true;
|
|
12728
|
+
return;
|
|
12729
|
+
}
|
|
11606
12730
|
if (priority === "low") {
|
|
11607
12731
|
if (timer || raf) return;
|
|
11608
12732
|
profiler === null || profiler === void 0 || profiler.recordInvalidate({ plane: (options === null || options === void 0 ? void 0 : options.plane) ?? null });
|
|
@@ -12145,6 +13269,8 @@ const TerminalProvider = defineComponent({
|
|
|
12145
13269
|
onBeforeUnmount(() => {
|
|
12146
13270
|
unmounting = true;
|
|
12147
13271
|
offCommit === null || offCommit === void 0 || offCommit();
|
|
13272
|
+
clearTimer();
|
|
13273
|
+
holdReleaseToken++;
|
|
12148
13274
|
if (raf > 0) cancelAnimationFrame(raf);
|
|
12149
13275
|
raf = 0;
|
|
12150
13276
|
scope.stop();
|
|
@@ -13073,7 +14199,10 @@ const TInput = defineComponent({
|
|
|
13073
14199
|
emit("update:modelValue", nextValue);
|
|
13074
14200
|
emit("input", nextValue);
|
|
13075
14201
|
if (commit) emit("change", nextValue);
|
|
13076
|
-
scheduler.
|
|
14202
|
+
scheduler.flushNow();
|
|
14203
|
+
nextTick(() => {
|
|
14204
|
+
scheduler.flushNow();
|
|
14205
|
+
});
|
|
13077
14206
|
}
|
|
13078
14207
|
function applyMove(nextCursor, extend) {
|
|
13079
14208
|
const prev = cursor.value;
|
|
@@ -13090,7 +14219,7 @@ const TInput = defineComponent({
|
|
|
13090
14219
|
} else desiredCol.value = indexToLineCellColInline(value, props.multilineTexts, props.mentions, cursor.value).col;
|
|
13091
14220
|
ensureCursorVisible();
|
|
13092
14221
|
syncImeAnchorNow();
|
|
13093
|
-
scheduler.
|
|
14222
|
+
scheduler.flushNow();
|
|
13094
14223
|
}
|
|
13095
14224
|
watch([
|
|
13096
14225
|
() => absRect.value.w,
|
|
@@ -13209,7 +14338,11 @@ const TInput = defineComponent({
|
|
|
13209
14338
|
terminal,
|
|
13210
14339
|
scheduler,
|
|
13211
14340
|
defaultStyle,
|
|
13212
|
-
render
|
|
14341
|
+
render: {
|
|
14342
|
+
rootStack: render.rootStack,
|
|
14343
|
+
createStack: render.createStack,
|
|
14344
|
+
invalidatePlane: render.invalidatePlane
|
|
14345
|
+
},
|
|
13213
14346
|
visible,
|
|
13214
14347
|
rawAbsRect,
|
|
13215
14348
|
eventZ,
|
|
@@ -13306,7 +14439,7 @@ const TInput = defineComponent({
|
|
|
13306
14439
|
emitMentions(nextMentions);
|
|
13307
14440
|
ensureCursorVisible();
|
|
13308
14441
|
syncImeAnchorNow();
|
|
13309
|
-
scheduler.
|
|
14442
|
+
scheduler.flushNow();
|
|
13310
14443
|
}
|
|
13311
14444
|
function removePendingPasteImage(placeholderPath) {
|
|
13312
14445
|
const current = getCurrentMentions();
|
|
@@ -13966,10 +15099,12 @@ const TInput = defineComponent({
|
|
|
13966
15099
|
clearAll();
|
|
13967
15100
|
return;
|
|
13968
15101
|
}
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
15102
|
+
const manager = events.value;
|
|
15103
|
+
if (manager && manager.getFocused()) {
|
|
15104
|
+
manager.focus(null);
|
|
15105
|
+
return;
|
|
15106
|
+
}
|
|
15107
|
+
applyBlur();
|
|
13973
15108
|
return;
|
|
13974
15109
|
}
|
|
13975
15110
|
if (isPrintableKey(e)) {
|
|
@@ -14207,6 +15342,7 @@ const TInput = defineComponent({
|
|
|
14207
15342
|
var _chipStyleProvider$va;
|
|
14208
15343
|
return {
|
|
14209
15344
|
zIndex: props.zIndex,
|
|
15345
|
+
priority: pendingValue.value != null ? "high" : "normal",
|
|
14210
15346
|
rect: visible.value ? absRect.value : {
|
|
14211
15347
|
x: 0,
|
|
14212
15348
|
y: 0,
|
|
@@ -14239,6 +15375,7 @@ const TInput = defineComponent({
|
|
|
14239
15375
|
blinkOn.value,
|
|
14240
15376
|
defaultStyle.value,
|
|
14241
15377
|
((_chipStyleProvider$va = chipStyleProvider.value) === null || _chipStyleProvider$va === void 0 ? void 0 : _chipStyleProvider$va.version.value) ?? 0,
|
|
15378
|
+
pendingValue.value,
|
|
14242
15379
|
props.skillHighlightStyle,
|
|
14243
15380
|
props.skillTrigger
|
|
14244
15381
|
],
|
|
@@ -14857,19 +15994,23 @@ const TJsonEditor = defineComponent({
|
|
|
14857
15994
|
//#endregion
|
|
14858
15995
|
//#region src/vue/utils/wheel-scroll.ts
|
|
14859
15996
|
const LINE_UNIT_THRESHOLD = 3;
|
|
14860
|
-
const PIXELS_PER_LINE =
|
|
15997
|
+
const PIXELS_PER_LINE = .75;
|
|
14861
15998
|
const ACCEL_WINDOW_MS = 120;
|
|
14862
|
-
const MAX_ACCEL =
|
|
15999
|
+
const MAX_ACCEL = 26;
|
|
14863
16000
|
const EDGE_BOUNCE_MS = 120;
|
|
14864
16001
|
const MIN_TICK_INTERVAL_MS = 6;
|
|
14865
16002
|
function clamp$3(n, min, max) {
|
|
14866
16003
|
return Math.max(min, Math.min(max, n));
|
|
14867
16004
|
}
|
|
14868
|
-
function isLineUnitDelta(deltaY) {
|
|
16005
|
+
function isLineUnitDelta(deltaY, mode = "auto") {
|
|
16006
|
+
if (mode === "line") return true;
|
|
16007
|
+
if (mode === "pixel") return false;
|
|
14869
16008
|
const abs = Math.abs(deltaY);
|
|
14870
16009
|
return abs > 0 && abs <= LINE_UNIT_THRESHOLD && Number.isInteger(deltaY);
|
|
14871
16010
|
}
|
|
14872
|
-
function normalizeDelta(deltaY) {
|
|
16011
|
+
function normalizeDelta(deltaY, mode = "auto") {
|
|
16012
|
+
if (mode === "line") return deltaY;
|
|
16013
|
+
if (mode === "pixel") return deltaY / PIXELS_PER_LINE;
|
|
14873
16014
|
const abs = Math.abs(deltaY);
|
|
14874
16015
|
if (abs <= LINE_UNIT_THRESHOLD && Number.isInteger(deltaY)) return deltaY;
|
|
14875
16016
|
return deltaY / PIXELS_PER_LINE;
|
|
@@ -14888,7 +16029,7 @@ function createWheelScrollState() {
|
|
|
14888
16029
|
lastEdgeAt: 0
|
|
14889
16030
|
};
|
|
14890
16031
|
}
|
|
14891
|
-
function applyWheelScroll(state, deltaY, scrollTop, maxTop, now$2 = Date.now()) {
|
|
16032
|
+
function applyWheelScroll(state, deltaY, scrollTop, maxTop, now$2 = Date.now(), deltaMode = "auto") {
|
|
14892
16033
|
if (!Number.isFinite(deltaY) || deltaY === 0 || maxTop <= 0) {
|
|
14893
16034
|
if (maxTop <= 0) {
|
|
14894
16035
|
state.accumulator = 0;
|
|
@@ -14902,7 +16043,7 @@ function applyWheelScroll(state, deltaY, scrollTop, maxTop, now$2 = Date.now())
|
|
|
14902
16043
|
};
|
|
14903
16044
|
}
|
|
14904
16045
|
const dt = state.lastAt ? now$2 - state.lastAt : Infinity;
|
|
14905
|
-
const lineUnits = isLineUnitDelta(deltaY);
|
|
16046
|
+
const lineUnits = isLineUnitDelta(deltaY, deltaMode);
|
|
14906
16047
|
if (lineUnits && dt !== Infinity && dt >= 0 && dt < MIN_TICK_INTERVAL_MS) return {
|
|
14907
16048
|
nextTop: scrollTop,
|
|
14908
16049
|
dir: 0,
|
|
@@ -14910,7 +16051,7 @@ function applyWheelScroll(state, deltaY, scrollTop, maxTop, now$2 = Date.now())
|
|
|
14910
16051
|
};
|
|
14911
16052
|
const accel = lineUnits ? 1 : state.lastAt ? accelFactor(now$2, state.lastAt) : 1;
|
|
14912
16053
|
state.lastAt = now$2;
|
|
14913
|
-
state.accumulator += normalizeDelta(deltaY) * accel;
|
|
16054
|
+
state.accumulator += normalizeDelta(deltaY, deltaMode) * accel;
|
|
14914
16055
|
const lines = Math.trunc(state.accumulator);
|
|
14915
16056
|
if (lines === 0) return {
|
|
14916
16057
|
nextTop: scrollTop,
|
|
@@ -14960,6 +16101,26 @@ function applyWheelScroll(state, deltaY, scrollTop, maxTop, now$2 = Date.now())
|
|
|
14960
16101
|
function clamp$2(n, min, max) {
|
|
14961
16102
|
return Math.max(min, Math.min(max, n));
|
|
14962
16103
|
}
|
|
16104
|
+
function getWheelScrollInput$1(e) {
|
|
16105
|
+
const deltaY = Number(e.deltaY ?? 0);
|
|
16106
|
+
const deltaMode = typeof e.deltaMode === "number" ? e.deltaMode : void 0;
|
|
16107
|
+
if (Number.isInteger(deltaY) && deltaY !== 0 && Math.abs(deltaY) >= 100 && Math.abs(deltaY) % 100 === 0 && (deltaMode == null || deltaMode === 0)) return {
|
|
16108
|
+
deltaY: deltaY / 100,
|
|
16109
|
+
mode: "line"
|
|
16110
|
+
};
|
|
16111
|
+
if (deltaMode === 1) return {
|
|
16112
|
+
deltaY,
|
|
16113
|
+
mode: "line"
|
|
16114
|
+
};
|
|
16115
|
+
if (deltaMode === 0) return {
|
|
16116
|
+
deltaY,
|
|
16117
|
+
mode: "pixel"
|
|
16118
|
+
};
|
|
16119
|
+
return {
|
|
16120
|
+
deltaY,
|
|
16121
|
+
mode: "auto"
|
|
16122
|
+
};
|
|
16123
|
+
}
|
|
14963
16124
|
const TList = defineComponent({
|
|
14964
16125
|
name: "TList",
|
|
14965
16126
|
props: {
|
|
@@ -15152,11 +16313,12 @@ const TList = defineComponent({
|
|
|
15152
16313
|
if (idx >= 0 && idx < props.items.length) commit(idx);
|
|
15153
16314
|
},
|
|
15154
16315
|
wheel: (e) => {
|
|
15155
|
-
const
|
|
16316
|
+
const { deltaY, mode } = getWheelScrollInput$1(e);
|
|
16317
|
+
const delta = deltaY;
|
|
15156
16318
|
if (!delta) return;
|
|
15157
16319
|
const h$1 = Math.max(0, props.h);
|
|
15158
16320
|
const maxTop = Math.max(0, props.items.length - h$1);
|
|
15159
|
-
const { nextTop, dir } = applyWheelScroll(wheelState, delta, scrollTop.value, maxTop);
|
|
16321
|
+
const { nextTop, dir } = applyWheelScroll(wheelState, delta, scrollTop.value, maxTop, Date.now(), mode);
|
|
15160
16322
|
if (!dir || nextTop === scrollTop.value) return;
|
|
15161
16323
|
scrollTop.value = nextTop;
|
|
15162
16324
|
const visibleStart = nextTop;
|
|
@@ -15493,6 +16655,26 @@ const TMultilineModal = defineComponent({
|
|
|
15493
16655
|
function clamp$1(n, min, max) {
|
|
15494
16656
|
return Math.max(min, Math.min(max, n));
|
|
15495
16657
|
}
|
|
16658
|
+
function getWheelScrollInput(e) {
|
|
16659
|
+
const deltaY = Number(e.deltaY ?? 0);
|
|
16660
|
+
const deltaMode = typeof e.deltaMode === "number" ? e.deltaMode : void 0;
|
|
16661
|
+
if (Number.isInteger(deltaY) && deltaY !== 0 && Math.abs(deltaY) >= 100 && Math.abs(deltaY) % 100 === 0 && (deltaMode == null || deltaMode === 0)) return {
|
|
16662
|
+
deltaY: deltaY / 100,
|
|
16663
|
+
mode: "line"
|
|
16664
|
+
};
|
|
16665
|
+
if (deltaMode === 1) return {
|
|
16666
|
+
deltaY,
|
|
16667
|
+
mode: "line"
|
|
16668
|
+
};
|
|
16669
|
+
if (deltaMode === 0) return {
|
|
16670
|
+
deltaY,
|
|
16671
|
+
mode: "pixel"
|
|
16672
|
+
};
|
|
16673
|
+
return {
|
|
16674
|
+
deltaY,
|
|
16675
|
+
mode: "auto"
|
|
16676
|
+
};
|
|
16677
|
+
}
|
|
15496
16678
|
function isCtrlLike(e) {
|
|
15497
16679
|
return Boolean(e.ctrlKey || e.metaKey);
|
|
15498
16680
|
}
|
|
@@ -15910,11 +17092,12 @@ const TPathPicker = defineComponent({
|
|
|
15910
17092
|
await trySelect(s.absPath);
|
|
15911
17093
|
},
|
|
15912
17094
|
wheel: (e) => {
|
|
15913
|
-
const
|
|
17095
|
+
const { deltaY, mode } = getWheelScrollInput(e);
|
|
17096
|
+
const delta = deltaY;
|
|
15914
17097
|
if (!delta) return;
|
|
15915
17098
|
const h$1 = Math.max(0, listH.value);
|
|
15916
17099
|
const maxTop = Math.max(0, suggestions.value.length - h$1);
|
|
15917
|
-
const { nextTop, dir } = applyWheelScroll(wheelState, delta, scrollTop.value, maxTop);
|
|
17100
|
+
const { nextTop, dir } = applyWheelScroll(wheelState, delta, scrollTop.value, maxTop, Date.now(), mode);
|
|
15918
17101
|
if (!dir || nextTop === scrollTop.value) return;
|
|
15919
17102
|
scrollTop.value = nextTop;
|
|
15920
17103
|
const visibleStart = nextTop;
|