diff --git a/dist/components/VirtualizedFile.js b/dist/components/VirtualizedFile.js index 89e2d37f700c20b9a824cf85922439416d7683e9..a2383b5fab5e6a9e086de040b74c14764a4dc0f0 100644 --- a/dist/components/VirtualizedFile.js +++ b/dist/components/VirtualizedFile.js @@ -556,12 +556,17 @@ var VirtualizedFile = class extends File { const startingLine = Math.max(0, Math.min(idealStartHunk, totalHunksInFile)) * hunkLineCount; const clampedTotalLines = idealStartHunk < 0 ? totalLines + idealStartHunk * hunkLineCount : totalLines; const bufferBefore = startingLine === 0 ? 0 : fileAnnotationHeight + startingLine * lineHeight; - const renderedLines = Math.min(clampedTotalLines, lineCount - startingLine); + // tangled patch: the hunk-centered window under-allocates at the very end of + // content — render every remaining line when the item ends at the window bottom + const atContentEnd = sourceRowsBottom <= bottom + lineHeight; + const renderedLines = atContentEnd + ? lineCount - startingLine + : Math.min(clampedTotalLines, lineCount - startingLine); return { startingLine, - totalLines: clampedTotalLines, + totalLines: atContentEnd ? lineCount - startingLine : clampedTotalLines, bufferBefore, - bufferAfter: Math.max(0, (lineCount - startingLine - renderedLines) * lineHeight) + bufferAfter: atContentEnd ? 0 : Math.max(0, (lineCount - startingLine - renderedLines) * lineHeight) }; } const overflowHunks = totalHunks; diff --git a/dist/components/VirtualizedFileDiff.js b/dist/components/VirtualizedFileDiff.js index e268d0076b69a3e623846de82b3020c64916522a..5bce3dfa4a6c3ab4571eea7e7c2e52b53fc38054 100644 --- a/dist/components/VirtualizedFileDiff.js +++ b/dist/components/VirtualizedFileDiff.js @@ -1038,13 +1038,18 @@ var VirtualizedFileDiff = class extends FileDiff { const clampedTotalLines = idealStartHunk < 0 ? totalLines + idealStartHunk * hunkLineCount : totalLines; const codeBufferBefore = hunkOffsets[startHunk] ?? 0; const bufferBefore = startingLine === 0 ? 0 : fileAnnotationHeight + codeBufferBefore; + // tangled patch: at the very end of content the hunk-centered window + // under-allocates and leaves the final lines permanently unrendered at max + // scroll (12M+ px mega-diffs). when the item's rows end within a line-height + // of the window bottom, render every remaining line. + const atContentEnd = fileTop + codeRegionTop + codeHeight <= bottom + lineHeight; const finalHunkIndex = startHunk + clampedTotalLines / hunkLineCount; const bufferAfter = finalHunkIndex < hunkOffsets.length ? codeHeight - hunkOffsets[finalHunkIndex] : codeHeight - (absoluteLineTop - fileTop - codeRegionTop); return { startingLine, - totalLines: clampedTotalLines, + totalLines: atContentEnd ? lineCount - startingLine : clampedTotalLines, bufferBefore, - bufferAfter: Math.max(0, bufferAfter) + bufferAfter: atContentEnd ? 0 : Math.max(0, bufferAfter) }; } }; diff --git a/dist/editor/tokenizer.js b/dist/editor/tokenizer.js index 804fb157d278ec26787fc0aede422ad205096780..8da1f56f3a672aee29046e0feab4c5b74b5163c8 100644 --- a/dist/editor/tokenizer.js +++ b/dist/editor/tokenizer.js @@ -170,12 +170,12 @@ var EditorTokenizer = class { }`); this.#themeName = themeName; this.#themeType = themeType ?? theme.type; - this.#colorMap = colorMap; + this.#colorMap = resolveColorMap(colorMap, theme); } #ensureActiveTheme() { if (this.#themeName === "") return; - const { colorMap } = this.#highlighter.setTheme(this.#themeName); - this.#colorMap = colorMap; + const { theme, colorMap } = this.#highlighter.setTheme(this.#themeName); + this.#colorMap = resolveColorMap(colorMap, theme); } cleanUp() { this.#isCleanedUp = true; @@ -544,6 +544,15 @@ var EditorTokenizer = class { this.#postTokenizeMessage(jobId); } }; +// tangled patch: shiki encodes a css-variable theme's colors as sentinel hexes +// and keeps the reverse map on theme.colorReplacements; codeToHast applies it +// through applyColorReplacements, while this tokenizer wrote the sentinels +// straight into inline styles and painted rgba(0, 0, 0, 0.004) +function resolveColorMap(colorMap, theme) { + const replacements = theme?.colorReplacements; + if (replacements == null) return colorMap; + return colorMap.map((color) => replacements[color?.toLowerCase()] ?? color); +} function tokenizeLine(grammar, colorMap, lineText, stateStack, timeLimit, collectBracketIgnoredRanges = true, resolveTokens = true) { const result = grammar.tokenizeLine2(lineText, stateStack, timeLimit); if (result.stoppedEarly) console.warn(`[diffs] Time limit reached when tokenizing line: ${lineText.substring(0, 100)}`);