@toddzheng024/dscode-bundle 0.7.11 → 0.7.13
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/THIRD_PARTY_NOTICES.md +3 -3
- package/cordis.patch.yml +1 -1
- package/package.json +5 -4
- package/plugins/i18n/messages.mjs +6 -6
- package/plugins/session-metrics/view.mjs +16 -5
- package/plugins/tui-tools/index.mjs +14 -1
- package/vendor/tui/lib/app.mjs +6674 -0
- package/vendor/tui/lib/approval.mjs +122 -0
- package/vendor/tui/lib/attachments.mjs +218 -0
- package/vendor/tui/lib/authorization-panel.mjs +242 -0
- package/vendor/tui/lib/authorization.mjs +111 -0
- package/vendor/tui/lib/commands.mjs +123 -0
- package/vendor/tui/lib/dscode/chat.mjs +64 -0
- package/vendor/tui/lib/dscode/flags.mjs +32 -0
- package/vendor/tui/lib/dscode/model-search.mjs +68 -0
- package/vendor/tui/lib/dscode/paste.mjs +87 -0
- package/vendor/tui/lib/dscode/telemetry.mjs +82 -0
- package/vendor/tui/lib/dscode/welcome.mjs +100 -0
- package/vendor/tui/lib/editor-keys.mjs +346 -0
- package/vendor/tui/lib/editor.mjs +50 -0
- package/vendor/tui/lib/fork.mjs +24 -0
- package/vendor/tui/lib/git-workflow.mjs +278 -0
- package/vendor/tui/{types/history.d.ts → lib/history.mjs} +69 -26
- package/vendor/tui/{types/i18n.d.ts → lib/i18n.mjs} +23 -15
- package/vendor/tui/lib/index.mjs +2198 -0
- package/vendor/tui/lib/input-split.mjs +170 -0
- package/vendor/tui/lib/internals.mjs +90 -0
- package/vendor/tui/lib/invariant.mjs +22 -0
- package/vendor/tui/lib/kernel-panels.mjs +1265 -0
- package/vendor/tui/lib/keyboard.mjs +283 -0
- package/vendor/tui/lib/language-panel.mjs +41 -0
- package/vendor/tui/lib/locales/en.mjs +495 -0
- package/vendor/tui/lib/locales/zh.mjs +495 -0
- package/vendor/tui/lib/mentions.mjs +150 -0
- package/vendor/tui/lib/model-capabilities.mjs +245 -0
- package/vendor/tui/lib/models.mjs +215 -0
- package/vendor/tui/{types/panel-accent.d.ts → lib/panel-accent.mjs} +11 -7
- package/vendor/tui/lib/permissions.mjs +45 -0
- package/vendor/tui/lib/plugin-inventory.mjs +27 -0
- package/vendor/tui/lib/presets.mjs +46 -0
- package/vendor/tui/lib/provider-settings.mjs +600 -0
- package/vendor/tui/lib/questions.mjs +116 -0
- package/vendor/tui/lib/rainbow.mjs +181 -0
- package/vendor/tui/lib/render/animations.mjs +665 -0
- package/vendor/tui/lib/render/editor.mjs +437 -0
- package/vendor/tui/lib/render/export.mjs +119 -0
- package/vendor/tui/lib/render/fuzzy.mjs +79 -0
- package/vendor/tui/lib/render/ime-cursor.mjs +135 -0
- package/vendor/tui/lib/render/inspector.mjs +93 -0
- package/vendor/tui/lib/render/lines.mjs +538 -0
- package/vendor/tui/lib/render/markdown.mjs +592 -0
- package/vendor/tui/lib/render/projection.mjs +1862 -0
- package/vendor/tui/lib/render/status.mjs +591 -0
- package/vendor/tui/lib/render/text.mjs +157 -0
- package/vendor/tui/lib/render/tool-detail.mjs +187 -0
- package/vendor/tui/lib/render/tool-preview.mjs +79 -0
- package/vendor/tui/lib/render/usage.mjs +336 -0
- package/vendor/tui/lib/render/width.mjs +191 -0
- package/vendor/tui/lib/session-directory.mjs +329 -0
- package/vendor/tui/lib/session-query.mjs +184 -0
- package/vendor/tui/lib/session-switch.mjs +51 -0
- package/vendor/tui/lib/settings-file.mjs +75 -0
- package/vendor/tui/lib/skills.mjs +119 -0
- package/vendor/tui/lib/startup.mjs +111 -0
- package/vendor/tui/lib/store.mjs +129 -0
- package/vendor/tui/lib/subagents.mjs +200 -0
- package/vendor/tui/lib/terminal-title.mjs +186 -0
- package/vendor/tui/lib/theme-panel.mjs +60 -0
- package/vendor/tui/lib/theme.mjs +379 -0
- package/vendor/tui/lib/update-panel.mjs +239 -0
- package/vendor/tui/lib/update.mjs +101 -0
- package/vendor/tui/lib/version.mjs +105 -0
- package/vendor/tui/lib/whale-glyph.mjs +20 -0
- package/vendor/tui/LICENSE +0 -21
- package/vendor/tui/devtools-CdTl3MNy.mjs +0 -3643
- package/vendor/tui/dscode-email/cli.mjs +0 -32
- package/vendor/tui/dscode-email/contacts.mjs +0 -36
- package/vendor/tui/dscode-email/gmail-oauth.mjs +0 -69
- package/vendor/tui/dscode-email/gmail-store.mjs +0 -2
- package/vendor/tui/dscode-email/gmail.mjs +0 -194
- package/vendor/tui/dscode-email/imap.mjs +0 -136
- package/vendor/tui/dscode-email/inbox.d.mts +0 -25
- package/vendor/tui/dscode-email/inbox.mjs +0 -76
- package/vendor/tui/dscode-email/smtp.mjs +0 -69
- package/vendor/tui/dscode-email/store.mjs +0 -32
- package/vendor/tui/dscode-providers/catalog.mjs +0 -136
- package/vendor/tui/dscode-providers/effort.mjs +0 -35
- package/vendor/tui/dscode-providers/openrouter-account.mjs +0 -171
- package/vendor/tui/index.mjs +0 -44483
- package/vendor/tui/invariant.mjs +0 -21
- package/vendor/tui/rolldown-runtime-CMFfr-1z.mjs +0 -26
- package/vendor/tui/session-query.mjs +0 -150
- package/vendor/tui/startup.mjs +0 -109
- package/vendor/tui/theme-7u5Qo3dF.mjs +0 -1265
- package/vendor/tui/types/app.d.ts +0 -348
- package/vendor/tui/types/approval.d.ts +0 -59
- package/vendor/tui/types/attachments.d.ts +0 -52
- package/vendor/tui/types/authorization-panel.d.ts +0 -22
- package/vendor/tui/types/authorization.d.ts +0 -36
- package/vendor/tui/types/commands.d.ts +0 -52
- package/vendor/tui/types/editor-keys.d.ts +0 -105
- package/vendor/tui/types/editor.d.ts +0 -6
- package/vendor/tui/types/fork.d.ts +0 -8
- package/vendor/tui/types/git-workflow.d.ts +0 -121
- package/vendor/tui/types/index.d.ts +0 -223
- package/vendor/tui/types/input-split.d.ts +0 -54
- package/vendor/tui/types/internals.d.ts +0 -26
- package/vendor/tui/types/invariant.d.ts +0 -15
- package/vendor/tui/types/kernel-panels.d.ts +0 -245
- package/vendor/tui/types/keyboard.d.ts +0 -80
- package/vendor/tui/types/language-panel.d.ts +0 -12
- package/vendor/tui/types/locales/en.d.ts +0 -450
- package/vendor/tui/types/locales/zh.d.ts +0 -9
- package/vendor/tui/types/mentions.d.ts +0 -85
- package/vendor/tui/types/model-capabilities.d.ts +0 -82
- package/vendor/tui/types/models.d.ts +0 -133
- package/vendor/tui/types/permissions.d.ts +0 -27
- package/vendor/tui/types/plugin-inventory.d.ts +0 -11
- package/vendor/tui/types/presets.d.ts +0 -22
- package/vendor/tui/types/provider-settings.d.ts +0 -239
- package/vendor/tui/types/questions.d.ts +0 -54
- package/vendor/tui/types/rainbow.d.ts +0 -69
- package/vendor/tui/types/render/animations.d.ts +0 -307
- package/vendor/tui/types/render/editor.d.ts +0 -163
- package/vendor/tui/types/render/export.d.ts +0 -9
- package/vendor/tui/types/render/fuzzy.d.ts +0 -21
- package/vendor/tui/types/render/ime-cursor.d.ts +0 -60
- package/vendor/tui/types/render/inspector.d.ts +0 -62
- package/vendor/tui/types/render/lines.d.ts +0 -86
- package/vendor/tui/types/render/markdown.d.ts +0 -29
- package/vendor/tui/types/render/projection.d.ts +0 -587
- package/vendor/tui/types/render/status.d.ts +0 -196
- package/vendor/tui/types/render/text.d.ts +0 -64
- package/vendor/tui/types/render/tool-detail.d.ts +0 -94
- package/vendor/tui/types/render/tool-preview.d.ts +0 -28
- package/vendor/tui/types/render/usage.d.ts +0 -113
- package/vendor/tui/types/render/width.d.ts +0 -29
- package/vendor/tui/types/session-directory.d.ts +0 -190
- package/vendor/tui/types/session-query.d.ts +0 -92
- package/vendor/tui/types/session-switch.d.ts +0 -17
- package/vendor/tui/types/settings-file.d.ts +0 -41
- package/vendor/tui/types/skills.d.ts +0 -47
- package/vendor/tui/types/startup.d.ts +0 -65
- package/vendor/tui/types/store.d.ts +0 -58
- package/vendor/tui/types/subagents.d.ts +0 -70
- package/vendor/tui/types/terminal-title.d.ts +0 -66
- package/vendor/tui/types/theme-panel.d.ts +0 -24
- package/vendor/tui/types/theme.d.ts +0 -434
- package/vendor/tui/types/update-panel.d.ts +0 -49
- package/vendor/tui/types/update.d.ts +0 -75
- package/vendor/tui/types/version.d.ts +0 -19
- package/vendor/tui/types/whale-glyph.d.ts +0 -6
- /package/vendor/tui/{dscode-clipboard-image → lib/dscode/clipboard-image}/clipboard-image.swift +0 -0
- /package/vendor/tui/{dscode-clipboard-image → lib/dscode/clipboard-image}/index.mjs +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IME cursor anchoring for the composer.
|
|
3
|
+
*
|
|
4
|
+
* Ink keeps the real terminal cursor hidden and parks it just below the
|
|
5
|
+
* dynamic tree (after the status row). IME composition text and candidate
|
|
6
|
+
* windows anchor to that real cursor cell - VS Code's integrated terminal
|
|
7
|
+
* positions its hidden IME textarea there, and Windows consoles behave the
|
|
8
|
+
* same - so CJK input appeared at the bottom of the screen instead of at the
|
|
9
|
+
* caret. The anchor moves the real cursor onto the caret cell without
|
|
10
|
+
* touching Ink's relative erase ledger:
|
|
11
|
+
*
|
|
12
|
+
* - the displacement is owned: before any foreign write or re-anchor, the
|
|
13
|
+
* wrapper cancels it (cursor down, column 1), so every writer - Ink's
|
|
14
|
+
* log-update rewrites, the resize replay, protocol pushes - keeps seeing
|
|
15
|
+
* the cursor exactly where it was left;
|
|
16
|
+
* - log-update frame chunks (which start with the erase-line sequence) get
|
|
17
|
+
* the anchor re-appended inside the same write, so a repaint can never
|
|
18
|
+
* leave the cursor behind - in particular the caret blink keeps the anchor
|
|
19
|
+
* stable while an IME composition is open, because the terminal parses the
|
|
20
|
+
* rewrite and the re-anchor as one atomic update.
|
|
21
|
+
*
|
|
22
|
+
* @module @deepseek-ai/dsh-code/render/ime-cursor
|
|
23
|
+
*/
|
|
24
|
+
import { useEffect, useRef } from 'react';
|
|
25
|
+
import { useStdout } from 'ink';
|
|
26
|
+
/** Cancel `rows` of owned upward displacement and return to column 1. */
|
|
27
|
+
export function imeCursorRestore(rows) {
|
|
28
|
+
return rows > 0 ? `\x1b[${rows}B\r` : '';
|
|
29
|
+
}
|
|
30
|
+
/** Move onto the caret cell: `rows` up from Ink's parked row, 0-based column. */
|
|
31
|
+
export function imeCursorMove(rows, column) {
|
|
32
|
+
return rows > 0 ? `\x1b[${rows}A\x1b[${column + 1}G` : '';
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Rows between the caret cell and Ink's parked cursor row: the band's bottom
|
|
36
|
+
* blank row, the editor window rows below the caret, the status footer, and
|
|
37
|
+
* Ink's own below-frame row. Rows above the composer (gutter, live content)
|
|
38
|
+
* never enter this distance.
|
|
39
|
+
*/
|
|
40
|
+
export function imeCursorRowsUp(input) {
|
|
41
|
+
return Math.max(1, input.editorWindowRows - input.caretRowInWindow + input.rowsBelowComposer);
|
|
42
|
+
}
|
|
43
|
+
/** log-update chunks start with the erase-line sequence; a chunk without it
|
|
44
|
+
* leaves no frame behind, so the next commit re-applies the anchor. */
|
|
45
|
+
const FRAME_CHUNK_MARKER = '\x1b[2K';
|
|
46
|
+
const ANCHOR_STATE = Symbol.for('dsh-code.ime-cursor-anchor');
|
|
47
|
+
/**
|
|
48
|
+
* Take over `stream.write` so the anchor displacement stays invisible to every
|
|
49
|
+
* other writer. Idempotent per stream: a second install returns the live
|
|
50
|
+
* handle. Returns `undefined` on non-TTY streams where anchoring is meaningless.
|
|
51
|
+
*/
|
|
52
|
+
export function installImeCursorAnchor(stream) {
|
|
53
|
+
if (stream?.isTTY !== true)
|
|
54
|
+
return undefined;
|
|
55
|
+
const target = stream;
|
|
56
|
+
const installed = target[ANCHOR_STATE];
|
|
57
|
+
if (installed !== undefined)
|
|
58
|
+
return installed;
|
|
59
|
+
const originalWrite = target.write.bind(target);
|
|
60
|
+
let rows = 0;
|
|
61
|
+
let column = -1;
|
|
62
|
+
let detached = false;
|
|
63
|
+
const anchor = {
|
|
64
|
+
anchor(nextRows, nextColumn) {
|
|
65
|
+
if (detached)
|
|
66
|
+
return;
|
|
67
|
+
if (nextRows <= 0) {
|
|
68
|
+
if (rows !== 0)
|
|
69
|
+
originalWrite(imeCursorRestore(rows));
|
|
70
|
+
rows = 0;
|
|
71
|
+
column = -1;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (rows === nextRows && column === nextColumn)
|
|
75
|
+
return;
|
|
76
|
+
originalWrite(imeCursorRestore(rows) + imeCursorMove(nextRows, nextColumn));
|
|
77
|
+
rows = nextRows;
|
|
78
|
+
column = nextColumn;
|
|
79
|
+
},
|
|
80
|
+
release() {
|
|
81
|
+
if (detached)
|
|
82
|
+
return;
|
|
83
|
+
detached = true;
|
|
84
|
+
if (rows !== 0)
|
|
85
|
+
originalWrite(imeCursorRestore(rows));
|
|
86
|
+
rows = 0;
|
|
87
|
+
column = -1;
|
|
88
|
+
target.write = originalWrite;
|
|
89
|
+
delete target[ANCHOR_STATE];
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
target.write = ((chunk, ...rest) => {
|
|
93
|
+
const ownedRows = rows;
|
|
94
|
+
const ownedColumn = column;
|
|
95
|
+
if (ownedRows === 0 || typeof chunk !== 'string') {
|
|
96
|
+
if (ownedRows !== 0) {
|
|
97
|
+
originalWrite(imeCursorRestore(ownedRows));
|
|
98
|
+
rows = 0;
|
|
99
|
+
column = -1;
|
|
100
|
+
}
|
|
101
|
+
return originalWrite(chunk, ...rest);
|
|
102
|
+
}
|
|
103
|
+
const reanchor = chunk.startsWith(FRAME_CHUNK_MARKER);
|
|
104
|
+
rows = reanchor ? ownedRows : 0;
|
|
105
|
+
column = reanchor ? ownedColumn : -1;
|
|
106
|
+
return originalWrite(imeCursorRestore(ownedRows) + chunk + (reanchor ? imeCursorMove(ownedRows, ownedColumn) : ''), ...rest);
|
|
107
|
+
});
|
|
108
|
+
target[ANCHOR_STATE] = anchor;
|
|
109
|
+
return anchor;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Keep the real terminal cursor on the composer's caret cell while `active`
|
|
113
|
+
* (the editable composer). The second effect runs after every commit without
|
|
114
|
+
* a dep list: frame rewrites restore the anchor themselves, but any other
|
|
115
|
+
* write (protocol push, resize replay) leaves the cursor at Ink's parked
|
|
116
|
+
* position, and the next commit re-anchors it.
|
|
117
|
+
*/
|
|
118
|
+
export function useImeCursorAnchor(active, rows, column) {
|
|
119
|
+
const { stdout } = useStdout();
|
|
120
|
+
const anchorRef = useRef(undefined);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (stdout === undefined)
|
|
123
|
+
return undefined;
|
|
124
|
+
const installed = installImeCursorAnchor(stdout);
|
|
125
|
+
anchorRef.current = installed;
|
|
126
|
+
return () => {
|
|
127
|
+
installed?.release();
|
|
128
|
+
if (anchorRef.current === installed)
|
|
129
|
+
anchorRef.current = undefined;
|
|
130
|
+
};
|
|
131
|
+
}, [stdout]);
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
anchorRef.current?.anchor(active && rows > 0 ? rows : 0, column);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/** Pure viewport, selection, and scrolling rules for exclusive TUI panels. */
|
|
2
|
+
/** Composer (3) + two-row status chrome, plus one optional fixed-height local notice row. */
|
|
3
|
+
const INSPECTOR_CHROME_ROWS = 6;
|
|
4
|
+
/** One transcript-to-composer gutter, collapsed on short terminals. */
|
|
5
|
+
export function layoutGutterRows(rows) {
|
|
6
|
+
return Math.max(1, Math.floor(rows)) >= 14 ? 1 : 0;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Rows left for live transcript and streaming after pinning the composer and
|
|
10
|
+
* status at the bottom. Variable chrome (menu, notice, todos, agents, extra
|
|
11
|
+
* status row, extra editor rows) is deducted here so those rows cover the
|
|
12
|
+
* live region instead of growing the tree and moving the bottom bar.
|
|
13
|
+
*/
|
|
14
|
+
export function liveRegionBudget(chrome) {
|
|
15
|
+
const terminal = Math.max(1, Math.floor(chrome.terminalRows));
|
|
16
|
+
const editor = Math.max(1, Math.floor(chrome.composerRows));
|
|
17
|
+
const band = editor + 2;
|
|
18
|
+
const status = chrome.statusBarRows === 2 ? 2 : 1;
|
|
19
|
+
const menu = Math.max(0, Math.floor(chrome.menuRows));
|
|
20
|
+
const gutter = chrome.gutterRows;
|
|
21
|
+
const notice = chrome.notice ? 1 : 0;
|
|
22
|
+
const todo = chrome.todo ? 1 : 0;
|
|
23
|
+
const agents = chrome.agents ? 1 : 0;
|
|
24
|
+
// Two spare rows: Ink's parked cursor, plus one so the painted tree never
|
|
25
|
+
// reaches stdout.rows (equality takes the full-terminal clear path).
|
|
26
|
+
const inkSpare = 2;
|
|
27
|
+
return Math.max(1, terminal - band - status - menu - gutter - notice - todo - agents - inkSpare);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Keep the inspector plus its persistent status/composer chrome below
|
|
31
|
+
* `stdout.rows`: at equality Ink clears the terminal and rewrites all
|
|
32
|
+
* accumulated `<Static>` output on every frame.
|
|
33
|
+
*/
|
|
34
|
+
export function panelViewport(columns, rows) {
|
|
35
|
+
const safeColumns = Math.max(1, Math.floor(columns));
|
|
36
|
+
const safeRows = Math.max(1, Math.floor(rows));
|
|
37
|
+
// Two spare rows cover Ink's first-frame transition from existing Static
|
|
38
|
+
// scrollback into a tall dynamic panel. A one-row margin is insufficient:
|
|
39
|
+
// the transition can still take the full-terminal rewrite path at rows - 1.
|
|
40
|
+
const maxHeight = Math.max(0, Math.min(safeRows - 2 - INSPECTOR_CHROME_ROWS - layoutGutterRows(safeRows), Math.floor(safeRows / 2)));
|
|
41
|
+
const compact = maxHeight < 5 || safeColumns < 8;
|
|
42
|
+
const gapRows = !compact && maxHeight >= 7 ? 2 : 0;
|
|
43
|
+
// A terminal may autowrap a glyph written into its final column. Ink still
|
|
44
|
+
// accounts for that border as one logical row, so the next dynamic update
|
|
45
|
+
// erases too few physical rows and leaves stacked frames behind. Codex
|
|
46
|
+
// renders overlays within an inset surface; reserve the final column here
|
|
47
|
+
// so every Ink panel follows the same contract.
|
|
48
|
+
const outerColumns = compact ? safeColumns : Math.max(1, safeColumns - 1);
|
|
49
|
+
return {
|
|
50
|
+
maxHeight,
|
|
51
|
+
bodyRows: compact ? 0 : maxHeight - 4 - gapRows,
|
|
52
|
+
gapRows,
|
|
53
|
+
contentColumns: compact ? Math.max(1, safeColumns - 1) : Math.max(1, outerColumns - 4),
|
|
54
|
+
outerColumns,
|
|
55
|
+
compact,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** Backward-compatible name for the Ctrl+O-specific caller and tests. */
|
|
59
|
+
export function inspectorViewport(columns, rows) {
|
|
60
|
+
return panelViewport(columns, rows);
|
|
61
|
+
}
|
|
62
|
+
/** Clamp a first-visible row to the range representable by one viewport. */
|
|
63
|
+
export function clampScroll(offset, totalRows, visibleRows) {
|
|
64
|
+
const total = Math.max(0, Math.floor(totalRows));
|
|
65
|
+
const size = Math.max(0, Math.floor(visibleRows));
|
|
66
|
+
const last = Math.max(0, total - size);
|
|
67
|
+
return Math.max(0, Math.min(Math.floor(offset), last));
|
|
68
|
+
}
|
|
69
|
+
/** Move a viewport by a signed row delta without escaping its content. */
|
|
70
|
+
export function moveScroll(offset, delta, totalRows, visibleRows) {
|
|
71
|
+
return clampScroll(offset + delta, totalRows, visibleRows);
|
|
72
|
+
}
|
|
73
|
+
/** Keep one focused row visible while preserving the current window when possible. */
|
|
74
|
+
export function revealRow(offset, row, totalRows, visibleRows) {
|
|
75
|
+
const size = Math.max(1, Math.floor(visibleRows));
|
|
76
|
+
const target = Math.max(0, Math.min(Math.floor(row), Math.max(0, totalRows - 1)));
|
|
77
|
+
if (target < offset)
|
|
78
|
+
return clampScroll(target, totalRows, size);
|
|
79
|
+
if (target >= offset + size)
|
|
80
|
+
return clampScroll(target - size + 1, totalRows, size);
|
|
81
|
+
return clampScroll(offset, totalRows, size);
|
|
82
|
+
}
|
|
83
|
+
/** Center a selected list row where possible, clamped at both ends. */
|
|
84
|
+
export function selectionWindow(cursor, totalRows, visibleRows) {
|
|
85
|
+
return clampScroll(cursor - Math.floor(Math.max(1, visibleRows) / 2), totalRows, visibleRows);
|
|
86
|
+
}
|
|
87
|
+
/** Follow appended history only while the inspector cursor was at the tail. */
|
|
88
|
+
export function followInspectorCursor(cursor, previousLength, nextLength) {
|
|
89
|
+
const nextLast = Math.max(0, nextLength - 1);
|
|
90
|
+
if (cursor >= Math.max(0, previousLength - 1))
|
|
91
|
+
return nextLast;
|
|
92
|
+
return Math.min(cursor, nextLast);
|
|
93
|
+
}
|