@pierre/diffs 1.3.0-rc.2 → 1.3.0-rc.4
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/components/CodeView.d.ts +1 -1
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +1 -1
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/VirtualizedFile.d.ts +1 -0
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +9 -2
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +1 -0
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +8 -2
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +10 -4
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiffHunksRenderer.js","names":["createDefaultAnnotationElement"],"sources":["../../src/renderers/DiffHunksRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement, Properties } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport {\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n DEFAULT_EXPANDED_REGION,\n DEFAULT_RENDER_RANGE,\n DEFAULT_THEMES,\n DEFAULT_TOKENIZE_MAX_LENGTH,\n} from '../constants';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n} from '../highlighter/shared_highlighter';\nimport { areThemesAttached } from '../highlighter/themes/areThemesAttached';\nimport type {\n AnnotationLineMap,\n AnnotationSpan,\n BaseDiffOptions,\n BaseDiffOptionsWithDefaults,\n CodeColumnType,\n CustomPreProperties,\n DiffLineAnnotation,\n DiffsHighlighter,\n DiffsTextDocument,\n ExpansionDirections,\n FileDiffMetadata,\n FileHeaderRenderMode,\n HighlightedToken,\n HunkData,\n HunkExpansionRegion,\n HunkSeparators,\n LineTypes,\n RenderDiffOptions,\n RenderDiffResult,\n RenderedDiffASTCache,\n RenderRange,\n SupportedLanguages,\n ThemedDiffResult,\n} from '../types';\nimport { applyLineTextWithNewline } from '../utils/applyLineTextWithNewline';\nimport { areDiffRenderOptionsEqual } from '../utils/areDiffRenderOptionsEqual';\nimport { areDiffTargetsEqual } from '../utils/areDiffTargetsEqual';\nimport { areRenderRangesEqual } from '../utils/areRenderRangesEqual';\nimport { cleanLastNewline } from '../utils/cleanLastNewline';\nimport { createAnnotationElement as createDefaultAnnotationElement } from '../utils/createAnnotationElement';\nimport { createContentColumn } from '../utils/createContentColumn';\nimport { createEmptyRowBuffer } from '../utils/createEmptyRowBuffer';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createNoNewlineElement } from '../utils/createNoNewlineElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { createSeparator } from '../utils/createSeparator';\nimport {\n applySessionChangedLines,\n rebuildSessionHunks,\n remapExpandedHunksForRegionChange,\n type SessionRegionChange,\n} from '../utils/editSessionHunks';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getHunkSeparatorSlotName } from '../utils/getHunkSeparatorSlotName';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getTotalLineCountFromHunks } from '../utils/getTotalLineCountFromHunks';\nimport {\n createGutterGap,\n createGutterItem,\n createGutterWrapper,\n createHastElement,\n} from '../utils/hast_utils';\nimport {\n FILE_ANNOTATION_HUNK_INDEX,\n FILE_ANNOTATION_LINE_INDEX,\n getFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\nimport { isDefaultRenderRange } from '../utils/isDefaultRenderRange';\nimport { isDiffPlainText } from '../utils/isDiffPlainText';\nimport type { DiffLineMetadata } from '../utils/iterateOverDiff';\nimport { iterateOverDiff } from '../utils/iterateOverDiff';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport {\n recomputeDiffHunksForEdit,\n recomputeEmptyDocumentDiff,\n recomputeTopAlignedAdditionDiff,\n shouldTopAlignAdditionRecompute,\n updateDiffHunks,\n} from '../utils/updateDiffHunks';\nimport { getTrailingContextRangeSize } from '../utils/virtualDiffLayout';\nimport type { WorkerPoolManager } from '../worker';\n\ninterface PushLineWithAnnotation {\n diffStyle: 'unified' | 'split';\n type: 'context' | 'context-expanded' | 'change';\n\n deletionLine?: ElementContent;\n additionLine?: ElementContent;\n\n unifiedSpan?: AnnotationSpan;\n deletionSpan?: AnnotationSpan;\n additionSpan?: AnnotationSpan;\n\n createAnnotationElement(span: AnnotationSpan): HASTElement;\n context: ProcessContext;\n}\n\ninterface GetRenderOptionsReturn {\n options: RenderDiffOptions;\n forceHighlight: boolean;\n}\n\ninterface PushSeparatorProps {\n hunkIndex: number;\n collapsedLines: number | 'unknown';\n rangeSize: number;\n hunkSpecs: string | undefined;\n isFirstHunk: boolean;\n isLastHunk: boolean;\n isExpandable: boolean;\n}\n\ninterface ProcessContext {\n rowCount: number;\n expansionLineCount: number;\n hunkSeparators: HunkSeparators;\n unifiedContentAST: ElementContent[];\n deletionsContentAST: ElementContent[];\n additionsContentAST: ElementContent[];\n unifiedGutterAST: HASTElement;\n deletionsGutterAST: HASTElement;\n additionsGutterAST: HASTElement;\n hunkData: HunkData[];\n pushToGutter(type: CodeColumnType, element: HASTElement): void;\n incrementRowCount(count?: number): void;\n}\n\nexport interface DiffHunksRendererOptions extends BaseDiffOptions {\n headerRenderMode?: FileHeaderRenderMode;\n}\n\nexport interface DiffHunksRendererOptionsWithDefaults extends Omit<\n BaseDiffOptionsWithDefaults,\n 'themeType'\n> {\n headerRenderMode: FileHeaderRenderMode;\n}\n\nexport interface UnifiedLineDecorationProps {\n type: 'context' | 'context-expanded' | 'change';\n lineType: LineTypes;\n additionLineIndex: number | undefined;\n deletionLineIndex: number | undefined;\n}\n\nexport interface SplitLineDecorationProps {\n side: 'deletions' | 'additions';\n type: 'context' | 'context-expanded' | 'change';\n lineIndex: number | undefined;\n}\n\nexport interface LineDecoration {\n gutterLineType: LineTypes;\n gutterProperties?: Properties;\n contentProperties?: Properties;\n}\n\ninterface PendingSplitContext {\n size: number;\n side: 'additions' | 'deletions' | undefined;\n increment(): void;\n flush(): void;\n}\n\nexport interface RenderedLineContext {\n type: 'context' | 'context-expanded' | 'change';\n hunkIndex: number;\n lineIndex: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n deletionLine?: DiffLineMetadata;\n additionLine?: DiffLineMetadata;\n}\n\nexport interface InjectedRow {\n content: HASTElement;\n gutter: HASTElement;\n}\n\nexport interface SplitInjectedRow {\n deletion: InjectedRow | undefined;\n addition: InjectedRow | undefined;\n}\n\nexport interface UnifiedInjectedRowPlacement {\n before?: InjectedRow[];\n after?: InjectedRow[];\n}\n\nexport interface SplitInjectedRowPlacement {\n before?: SplitInjectedRow[];\n after?: SplitInjectedRow[];\n}\n\nexport interface HunksRenderResult {\n unifiedGutterAST: ElementContent[] | undefined;\n unifiedContentAST: ElementContent[] | undefined;\n deletionsGutterAST: ElementContent[] | undefined;\n deletionsContentAST: ElementContent[] | undefined;\n additionsGutterAST: ElementContent[] | undefined;\n additionsContentAST: ElementContent[] | undefined;\n hunkData: HunkData[];\n css: string;\n preNode: HASTElement;\n headerElement: HASTElement | undefined;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n rowCount: number;\n bufferBefore: number;\n bufferAfter: number;\n}\n\nlet instanceId = -1;\n\nexport class DiffHunksRenderer<LAnnotation = undefined> {\n readonly __id: string = `diff-hunks-renderer:${++instanceId}`;\n\n private highlighter: DiffsHighlighter | undefined;\n private diff: FileDiffMetadata | undefined;\n\n private expandedHunks = new Map<number, HunkExpansionRegion>();\n\n private deletionAnnotations: AnnotationLineMap<LAnnotation> = {};\n private additionAnnotations: AnnotationLineMap<LAnnotation> = {};\n\n private computedLang: SupportedLanguages = 'text';\n private renderCache: RenderedDiffASTCache | undefined;\n\n // Edit-session state: while active, hunk updates go through the frozen\n // region skeleton (editSessionHunks) instead of the full recompute, and\n // rendering stays on the main thread with editor-compatible token markup —\n // the editor's caret/selection mapping needs the token transformer, and\n // the pool's global options are not guaranteed to produce it. The pool\n // keeps serving every surface without a session.\n private editSessionActive = false;\n\n constructor(\n public options: DiffHunksRendererOptions = { theme: DEFAULT_THEMES },\n private onRenderUpdate?: () => unknown,\n private workerManager?: WorkerPoolManager | undefined\n ) {\n if (workerManager?.isWorkingPool() !== true) {\n this.highlighter = areThemesAttached(options.theme ?? DEFAULT_THEMES)\n ? getHighlighterIfLoaded()\n : undefined;\n }\n }\n\n public cleanUp(): void {\n this.recycle();\n this.expandedHunks.clear();\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n public recycle(): void {\n this.highlighter = undefined;\n this.diff = undefined;\n this.clearRenderCache();\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n this.workerManager?.cleanUpTasks(this);\n // Session hunks and the metadata dirty marker survive recycle in the\n // shared FileDiffMetadata; the renderer-local state re-seeds on the next\n // attach (beginEditSession).\n this.endEditSession();\n }\n\n /**\n * Enter edit-session mode: hunk updates preserve the current region\n * skeleton instead of recomputing hunks, and rendering happens locally\n * with the token transformer forced on (worker-pool requests/results are\n * suspended for this renderer). Called on every editor attach, including\n * a re-attach after recycle.\n */\n public beginEditSession(): void {\n this.editSessionActive = true;\n }\n\n /** Leave edit-session mode. The exit recompute is the host's concern. */\n public endEditSession(): void {\n this.editSessionActive = false;\n }\n\n /**\n * Ensures that the DOM is compatible with editor render updates\n */\n public editorRenderReady(): boolean {\n return (\n this.renderCache?.options.useTokenTransformer === true &&\n this.renderCache.highlighted &&\n this.renderCache.result != null\n );\n }\n\n /**\n * Re-highlights the current diff in the background and swaps the fresh\n * result in (with a re-render) once it completes. Needed after an edit\n * session's exit recompute: session passes plain-fill shifted lines in the\n * cached result, and the recompute mutates the diff in place (same object,\n * same cacheKey), so identity/cacheKey checks would otherwise treat the\n * stale highlight as current forever. The current result — content-correct,\n * mostly highlighted — keeps rendering until the fresh one lands, so no\n * interim paint drops highlighting.\n */\n public refreshHighlightedResult(): Promise<void> {\n const { renderCache } = this;\n if (\n renderCache == null ||\n isDiffPlainText(renderCache.diff) ||\n isDiffMassive(renderCache.diff, this.getTokenizeMaxLength())\n ) {\n return Promise.resolve();\n }\n const { diff } = renderCache;\n const { workerManager } = this;\n // The pool's diff cache is keyed by cacheKey, so a worker refresh needs\n // one; a keyless diff uses the local highlighter fallback below instead.\n if (\n !this.editSessionActive &&\n workerManager?.isWorkingPool() === true &&\n diff.cacheKey != null\n ) {\n workerManager.evictDiffFromCache(diff.cacheKey);\n return workerManager\n .primeDiffHighlightCache(diff)\n .then(() => {\n this.applyRefreshedResult(\n diff,\n workerManager.getDiffResultCache(diff)\n );\n })\n .catch((error: unknown) => this.onHighlightError(error));\n }\n return this.asyncHighlight(diff)\n .then((fresh) => this.applyRefreshedResult(diff, fresh))\n .catch((error: unknown) => this.onHighlightError(error));\n }\n\n // Installs a freshly highlighted result for the same diff, unless the\n // renderer moved on while the highlight ran (new diff, options change, or\n // a new edit session whose passes the fresh result wouldn't reflect).\n private applyRefreshedResult(\n diff: FileDiffMetadata,\n fresh: RenderDiffResult | undefined\n ): void {\n if (\n fresh == null ||\n this.renderCache == null ||\n this.renderCache.diff !== diff ||\n this.editSessionActive\n ) {\n return;\n }\n const { options } = this.getRenderOptions(diff);\n if (!areDiffRenderOptionsEqual(options, fresh.options)) {\n return;\n }\n this.renderCache = {\n diff,\n options: fresh.options,\n highlighted: true,\n result: fresh.result,\n renderRange: undefined,\n };\n this.onRenderUpdate?.();\n }\n\n public get diffCache(): FileDiffMetadata | undefined {\n return this.renderCache?.diff ?? this.diff;\n }\n\n public clearRenderCache(): void {\n const renderCache = this.renderCache;\n this.renderCache = undefined;\n if (\n renderCache != null &&\n renderCache.isDirty === true &&\n renderCache.diff.cacheKey != null\n ) {\n // The render cache has been updated by the host, let's purge it\n // from the worker manager cache.\n this.workerManager?.evictDiffFromCache(renderCache.diff.cacheKey);\n }\n }\n\n public setOptions(options: DiffHunksRendererOptions): void {\n this.options = options;\n }\n\n public mergeOptions(options: Partial<DiffHunksRendererOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n public expandHunk(\n index: number,\n direction: ExpansionDirections,\n expansionLineCount: number = this.getOptionsWithDefaults()\n .expansionLineCount\n ): void {\n const region = {\n ...(this.expandedHunks.get(index) ?? {\n fromStart: 0,\n fromEnd: 0,\n }),\n };\n if (direction === 'up' || direction === 'both') {\n region.fromStart += expansionLineCount;\n }\n if (direction === 'down' || direction === 'both') {\n region.fromEnd += expansionLineCount;\n }\n // NOTE(amadeus): If our render cache is not highlighted, we need to clear\n // it, otherwise we won't have the correct AST lines. Clearing is safe\n // mid-edit-session even though the dirty cache carries live edits: both\n // session hunk-update paths keep diff.additionLines current every pass,\n // so the rebuilt AST reproduces the live document.\n if (this.renderCache?.highlighted !== true) {\n this.clearRenderCache();\n }\n this.expandedHunks.set(index, region);\n }\n\n public getExpandedHunk(hunkIndex: number): HunkExpansionRegion {\n return this.expandedHunks.get(hunkIndex) ?? DEFAULT_EXPANDED_REGION;\n }\n\n public getExpandedHunksMap(): Map<number, HunkExpansionRegion> {\n return this.expandedHunks;\n }\n\n /** Replace the whole expansion map (session-exit expansion remapping). */\n public setExpandedHunksMap(\n expandedHunks: Map<number, HunkExpansionRegion>\n ): void {\n this.expandedHunks = expandedHunks;\n }\n\n public setLineAnnotations(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[]\n ): void {\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n for (const annotation of lineAnnotations) {\n const map = ((): AnnotationLineMap<LAnnotation> => {\n switch (annotation.side) {\n case 'deletions':\n return this.deletionAnnotations;\n case 'additions':\n return this.additionAnnotations;\n }\n })();\n const arr = map[annotation.lineNumber] ?? [];\n map[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n /**\n * Returns true when a session-mode pass changed the region skeleton itself\n * (a gap edit synthesized or merged regions), which changes the rendered\n * row set without a line-count change — the host must escalate to a full\n * re-render instead of its cheap refresh path.\n */\n public updateRenderCache(\n dirtyLines: Map<number, Array<HighlightedToken>>,\n themeType: 'dark' | 'light',\n lineCountChangeInFlight = false\n ): boolean {\n if (this.renderCache == null) {\n return false;\n }\n const { result, diff } = this.renderCache;\n if (result == null) {\n return false;\n }\n if (diff.isPartial) {\n throw new Error('Could not update render cache for partial diff');\n }\n\n const hastLines = result.code.additionLines;\n const changedAdditionLines: number[] = [];\n const previousAdditionLines = new Map<number, string>();\n for (const [line, tokens] of dirtyLines) {\n const prev = hastLines[line] as HASTElement | undefined;\n const prevProps = prev?.properties ?? {};\n const lineText = tokens.map((a) => a[2]).join('');\n const canSyncDiffLine = line < diff.additionLines.length;\n const prevLine = canSyncDiffLine ? (diff.additionLines[line] ?? '') : '';\n const prevText = cleanLastNewline(prevLine);\n // The host text document can expose one extra trailing empty line when\n // the file ends with a newline. Deferred tokenization must not grow\n // additionLines from that mismatch or hunk trailing context desyncs.\n if (canSyncDiffLine) {\n diff.additionLines[line] = applyLineTextWithNewline(prevLine, lineText);\n if (prevText !== lineText) {\n changedAdditionLines.push(line);\n previousAdditionLines.set(line, prevLine);\n }\n }\n hastLines[line] = {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': prevProps['data-line'] ?? line + 1,\n 'data-line-index': prevProps['data-line-index'] ?? line,\n 'data-line-type': prevProps['data-line-type'] ?? 'context',\n },\n children: tokens.map(([char, fg, text]) => {\n if (char === 0 && fg === '') {\n if (text === '') {\n return {\n type: 'element',\n tagName: 'br',\n properties: {},\n children: [],\n };\n }\n return { type: 'text', value: text };\n }\n return {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': char,\n style: `color:${fg};`,\n },\n children: [{ type: 'text', value: text }],\n };\n }),\n };\n }\n\n let regionsChanged = false;\n if (changedAdditionLines.length > 0) {\n if (this.editSessionActive && !diff.isPartial) {\n // On a line-count pass the tokenizer emits shifted-but-unedited lines\n // as dirty and the writes above land at stale indexes, so hunk work\n // must wait for the authoritative applyDocumentChange in this same\n // pass. Otherwise (including deferred background passes, which carry\n // genuine changes and are never followed by applyDocumentChange) the\n // explicit changed indexes are current.\n if (!lineCountChangeInFlight) {\n if (\n diff.additionLines.length <= 1 &&\n diff.additionLines.join('') === ''\n ) {\n Object.assign(\n diff,\n recomputeEmptyDocumentDiff(diff, this.options.parseDiffOptions)\n );\n this.markEditSessionPass(diff);\n regionsChanged = true;\n } else if (\n shouldTopAlignAdditionRecompute(diff, diff.additionLines)\n ) {\n Object.assign(\n diff,\n recomputeTopAlignedAdditionDiff(\n diff,\n diff.additionLines,\n this.options.parseDiffOptions\n )\n );\n this.markEditSessionPass(diff);\n regionsChanged = true;\n } else {\n const change = applySessionChangedLines(\n diff,\n changedAdditionLines,\n this.options.parseDiffOptions,\n previousAdditionLines\n );\n this.applyExpansionRemap(change);\n regionsChanged = change != null;\n }\n }\n } else {\n Object.assign(\n diff,\n updateDiffHunks(\n diff,\n changedAdditionLines,\n this.options.parseDiffOptions\n )\n );\n }\n }\n\n result.baseThemeType = themeType;\n this.renderCache.isDirty = true;\n return regionsChanged;\n }\n\n private applyExpansionRemap(change: SessionRegionChange | undefined): void {\n if (change != null) {\n this.expandedHunks = remapExpandedHunksForRegionChange(\n this.expandedHunks,\n change\n );\n }\n }\n\n // Normally triggered by the host when the document line count changes.\n public applyDocumentChange(textDocument: DiffsTextDocument): void {\n if (this.renderCache == null) {\n return;\n }\n const { diff, result } = this.renderCache;\n if (result == null) {\n return;\n }\n if (diff.isPartial) {\n throw new Error('Could not apply document change for partial diff');\n }\n\n // updateRenderCache may already have extended diff.additionLines for the\n // same edit pass, so never bail out purely on matching lengths here.\n // Read line-by-line from the editor document instead of materializing the\n // entire text. This preserves blank documents and the final editable empty\n // row after a trailing line break.\n const { additionLines: previousAdditionLines } = diff;\n diff.additionLines = getEditorDocumentLines(\n textDocument,\n previousAdditionLines\n );\n result.code.additionLines = realignAdditionHastLines(\n previousAdditionLines,\n diff.additionLines,\n result.code.additionLines,\n textDocument\n );\n // An empty document splits into zero addition lines, which would recompute\n // to a diff with no editable rows and leave the attached host with no\n // line element for its caret (the additions column vanishes in split;\n // unified shows only deletions). Keep one empty editable line instead.\n if (diff.additionLines.length <= 1 && diff.additionLines.join('') === '') {\n Object.assign(\n diff,\n recomputeEmptyDocumentDiff(diff, this.options.parseDiffOptions)\n );\n result.code.additionLines[0] = createPlainAdditionLineElement(\n 0,\n textDocument\n );\n this.markEditSessionPass(diff);\n } else if (this.editSessionActive) {\n this.applySessionDocumentChange(diff);\n } else {\n Object.assign(\n diff,\n recomputeDiffHunksForEdit(diff, this.options.parseDiffOptions)\n );\n }\n\n this.renderCache.isDirty = true;\n }\n\n // Session-mode counterpart of the line-count recompute: derive canonical\n // old/current pairing and rebuild the old-side region skeleton from it.\n private applySessionDocumentChange(diff: FileDiffMetadata): void {\n const { parseDiffOptions } = this.options;\n const rawLines = diff.additionLines;\n if (shouldTopAlignAdditionRecompute(diff, rawLines)) {\n Object.assign(\n diff,\n recomputeTopAlignedAdditionDiff(diff, rawLines, parseDiffOptions)\n );\n this.markEditSessionPass(diff);\n return;\n }\n this.applyExpansionRemap(rebuildSessionHunks(diff, parseDiffOptions));\n }\n\n // Records a session pass that replaced hunks wholesale (empty-document or\n // top-aligned shims).\n private markEditSessionPass(diff: FileDiffMetadata): void {\n if (!this.editSessionActive) {\n return;\n }\n diff.editSessionDirty = true;\n }\n\n protected getUnifiedLineDecoration({\n lineType,\n }: UnifiedLineDecorationProps): LineDecoration {\n return {\n gutterLineType: lineType,\n contentProperties: {\n 'data-line-type': lineType,\n },\n };\n }\n\n protected getSplitLineDecoration({\n side,\n type,\n }: SplitLineDecorationProps): LineDecoration {\n const lineType: LineTypes =\n type === 'change'\n ? side === 'deletions'\n ? 'change-deletion'\n : 'change-addition'\n : type;\n return {\n gutterLineType: lineType,\n contentProperties: {\n 'data-line-type': lineType,\n },\n };\n }\n\n private createAnnotationElement = (span: AnnotationSpan): HASTElement => {\n return createDefaultAnnotationElement(span);\n };\n\n // Unified hook returns extra rows that render before/after the current line.\n declare protected getUnifiedInjectedRowsForLine?: (\n ctx: RenderedLineContext\n ) => UnifiedInjectedRowPlacement | undefined;\n\n // Split hook returns extra rows per side before/after the current line.\n declare protected getSplitInjectedRowsForLine?: (\n ctx: RenderedLineContext\n ) => SplitInjectedRowPlacement | undefined;\n\n protected getOptionsWithDefaults(): DiffHunksRendererOptionsWithDefaults {\n const {\n diffIndicators = 'bars',\n diffStyle = 'split',\n disableBackground = false,\n disableFileHeader = false,\n disableLineNumbers = false,\n disableVirtualizationBuffers = false,\n collapsed = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n expansionLineCount = 100,\n hunkSeparators = 'line-info',\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n overflow = 'scroll',\n stickyHeader = false,\n theme = DEFAULT_THEMES,\n headerRenderMode = 'default',\n tokenizeMaxLineLength = 1000,\n tokenizeMaxLength = DEFAULT_TOKENIZE_MAX_LENGTH,\n useTokenTransformer = false,\n useCSSClasses = false,\n } = this.options;\n return {\n diffIndicators,\n diffStyle,\n disableBackground,\n disableFileHeader,\n disableLineNumbers,\n disableVirtualizationBuffers,\n collapsed,\n expandUnchanged,\n collapsedContextThreshold,\n expansionLineCount,\n hunkSeparators,\n lineDiffType,\n maxLineDiffLength,\n overflow,\n stickyHeader,\n theme: this.workerManager?.getDiffRenderOptions().theme ?? theme,\n headerRenderMode,\n tokenizeMaxLineLength,\n tokenizeMaxLength,\n useTokenTransformer,\n useCSSClasses,\n };\n }\n\n public async initializeHighlighter(): Promise<DiffsHighlighter> {\n this.highlighter = await getSharedHighlighter(\n getHighlighterOptions(this.computedLang, {\n theme: this.getLocalHighlightTheme(),\n preferredHighlighter:\n this.workerManager?.getPreferredHighlighter() ??\n this.options.preferredHighlighter,\n })\n );\n return this.highlighter;\n }\n\n public hydrate(diff: FileDiffMetadata | undefined): void {\n if (diff == null) {\n return;\n }\n this.diff = diff;\n const { options } = this.getRenderOptions(diff);\n const massiveDiff = isDiffMassive(diff, this.getTokenizeMaxLength());\n let cache = this.workerManager?.getDiffResultCache(diff);\n if (cache != null && !areDiffRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n diff,\n highlighted: !massiveDiff && !isDiffPlainText(diff),\n options,\n result: massiveDiff ? undefined : cache?.result,\n renderRange: undefined,\n };\n if (\n !this.editSessionActive &&\n this.workerManager?.isWorkingPool() === true\n ) {\n if (this.renderCache.result == null && !massiveDiff) {\n // We should only kick off a preload of the AST if we have a WorkerPool\n this.workerManager.highlightDiffAST(this, this.diff);\n }\n }\n // Lets attempt to get the highlighter/languages ready immediately\n else if (this.highlighter == null) {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n void this.initializeHighlighter();\n }\n }\n\n private getLocalHighlightTheme(): RenderDiffOptions['theme'] {\n return (\n this.workerManager?.getDiffRenderOptions().theme ??\n this.options.theme ??\n DEFAULT_THEMES\n );\n }\n\n private getRenderOptions(diff: FileDiffMetadata): GetRenderOptionsReturn {\n const options: RenderDiffOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n const poolOptions = this.workerManager.getDiffRenderOptions();\n // Active edit sessions require `useTokenTransformer: true`\n if (\n this.editSessionActive &&\n poolOptions.useTokenTransformer !== true\n ) {\n return { ...poolOptions, useTokenTransformer: true };\n }\n return poolOptions;\n }\n const { theme, tokenizeMaxLineLength, lineDiffType, maxLineDiffLength } =\n this.getOptionsWithDefaults();\n return {\n theme,\n useTokenTransformer:\n this.editSessionActive || this.options.useTokenTransformer === true,\n tokenizeMaxLineLength,\n lineDiffType,\n maxLineDiffLength,\n };\n })();\n this.getOptionsWithDefaults();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceHighlight: true };\n }\n if (\n !areDiffTargetsEqual(diff, renderCache.diff) ||\n !areDiffRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceHighlight: true };\n }\n return { options, forceHighlight: false };\n }\n\n public renderDiff(\n diff: FileDiffMetadata | undefined = this.renderCache?.diff,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): HunksRenderResult | undefined {\n if (diff == null) {\n return undefined;\n }\n const { expandUnchanged, collapsedContextThreshold } =\n this.getOptionsWithDefaults();\n let { options, forceHighlight } = this.getRenderOptions(diff);\n const cache = this.getMatchingWorkerResultCache(diff, options);\n if (cache != null && !this.hasHighlightedRenderCache(diff, options)) {\n this.renderCache = {\n diff,\n highlighted: true,\n renderRange: undefined,\n ...cache,\n };\n forceHighlight = false;\n }\n this.renderCache ??= {\n diff,\n highlighted: false,\n options,\n result: undefined,\n renderRange: undefined,\n };\n const hasContent =\n diff.additionLines.length > 0 || diff.deletionLines.length > 0;\n const forcePlainText =\n !hasContent ||\n isDiffPlainText(diff) ||\n isDiffMassive(diff, this.getTokenizeMaxLength());\n const newContent = !areDiffTargetsEqual(diff, this.renderCache.diff);\n const newRenderRange = !areRenderRangesEqual(\n this.renderCache.renderRange,\n renderRange\n );\n if (\n !this.editSessionActive &&\n this.workerManager?.isWorkingPool() === true\n ) {\n // An already-highlighted view is waiting on a fresh highlight for the\n // same diff. Returning no result keeps the host's current content in\n // place instead of downgrading it to a plain AST; the pending\n // highlight's completion will re-render. A different diff or a\n // sub-range window still paints plain — the current content cannot\n // serve those.\n const highlightPending =\n this.renderCache.result == null &&\n this.renderCache.highlighted &&\n !forcePlainText &&\n !newContent &&\n isDefaultRenderRange(renderRange);\n if (highlightPending) {\n this.renderCache.highlightPending = true;\n }\n if (\n !highlightPending &&\n (forcePlainText ||\n this.renderCache.result == null ||\n (!this.renderCache.highlighted && (newContent || newRenderRange)))\n ) {\n this.renderCache.diff = diff;\n this.renderCache.options = options;\n this.renderCache.highlighted = false;\n if (\n this.renderCache.result == null ||\n newContent ||\n newRenderRange ||\n forceHighlight\n ) {\n this.renderCache.result = this.workerManager.getPlainDiffAST(\n diff,\n renderRange.startingLine,\n renderRange.totalLines,\n // If we aren't using a windowed render, then we need to render\n // everything\n isDefaultRenderRange(renderRange)\n ? true\n : expandUnchanged\n ? true\n : this.expandedHunks,\n collapsedContextThreshold\n );\n }\n this.renderCache.renderRange = renderRange;\n }\n\n // Should we kick off an async highlight process\n if (\n !forcePlainText &&\n hasContent &&\n (!this.renderCache.highlighted || forceHighlight)\n ) {\n this.workerManager.highlightDiffAST(this, diff);\n }\n } else {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n const hasThemes =\n this.highlighter != null && areThemesAttached(options.theme);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n const canHighlight = !forcePlainText && hasLangs;\n\n // If we have any semblance of a highlighter with the correct theme(s)\n // attached, we can kick off some form of rendering. If we don't have\n // the correct language, then we can render plain text and after kick off\n // an async job to get the highlighted AST\n if (\n this.highlighter != null &&\n hasThemes &&\n (forceHighlight ||\n forcePlainText ||\n (!this.renderCache.highlighted && canHighlight) ||\n this.renderCache.result == null)\n ) {\n const { result, options } = this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n forcePlainText || !hasLangs\n );\n this.renderCache = {\n diff,\n options,\n highlighted: canHighlight,\n result,\n renderRange: undefined,\n };\n }\n\n // If we get in here it means we'll have to kick off an async highlight\n // process which will involve initializing the highlighter with new themes\n // and languages\n if (!hasThemes || (!forcePlainText && !hasLangs)) {\n void this.asyncHighlight(diff).then(({ result, options }) => {\n // In this case we need to force a re-render, so we can do that by\n // reaching into renderCache\n if (this.renderCache != null) {\n this.renderCache.highlighted = false;\n }\n this.applyHighlightResult(diff, result, options, !forcePlainText);\n });\n }\n }\n return this.renderCache.result != null\n ? this.processDiffResult(\n this.renderCache.diff,\n renderRange,\n this.renderCache.result\n )\n : undefined;\n }\n\n public async asyncRender(\n diff: FileDiffMetadata,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): Promise<HunksRenderResult> {\n const { result } = await this.asyncHighlight(diff);\n return this.processDiffResult(diff, renderRange, result);\n }\n\n protected createPreElement(\n split: boolean,\n totalLines: number,\n customProperties?: CustomPreProperties\n ): HASTElement {\n const { diffIndicators, disableBackground, disableLineNumbers, overflow } =\n this.getOptionsWithDefaults();\n return createPreElement({\n type: 'diff',\n diffIndicators,\n disableBackground,\n disableLineNumbers,\n overflow,\n split,\n totalLines,\n customProperties,\n });\n }\n\n private async asyncHighlight(\n diff: FileDiffMetadata\n ): Promise<RenderDiffResult> {\n const forcePlainText = isDiffMassive(diff, this.getTokenizeMaxLength());\n this.computedLang = forcePlainText\n ? 'text'\n : (diff.lang ?? getFiletypeFromFileName(diff.name));\n const hasThemes =\n this.highlighter != null &&\n areThemesAttached(this.getLocalHighlightTheme());\n const hasLangs =\n forcePlainText ||\n (this.highlighter != null && areLanguagesAttached(this.computedLang));\n // If we don't have the required langs or themes, then we need to\n // initialize the highlighter to load the appropriate languages and themes\n if (this.highlighter == null || !hasThemes || !hasLangs) {\n this.highlighter = await this.initializeHighlighter();\n }\n return this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n forcePlainText\n );\n }\n\n private renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n forcePlainText = false\n ): RenderDiffResult {\n const { options } = this.getRenderOptions(diff);\n const { collapsedContextThreshold } = this.getOptionsWithDefaults();\n const result = renderDiffWithHighlighter(diff, highlighter, options, {\n forcePlainText,\n expandedHunks: forcePlainText ? true : undefined,\n collapsedContextThreshold,\n });\n return { result, options };\n }\n\n public onHighlightSuccess(\n diff: FileDiffMetadata,\n result: ThemedDiffResult,\n options: RenderDiffOptions,\n highlighted = true\n ): void {\n if (this.editSessionActive) {\n return;\n }\n this.applyHighlightResult(diff, result, options, highlighted);\n }\n\n private applyHighlightResult(\n diff: FileDiffMetadata,\n result: ThemedDiffResult,\n options: RenderDiffOptions,\n highlighted = true\n ): void {\n // NOTE(amadeus): This is a bad assumption, and I should figure out\n // something better... If renderCache was blown away, we can assume we've\n // run cleanUp()\n if (this.renderCache == null) {\n return;\n }\n\n const triggerRenderUpdate =\n this.renderCache.highlightPending === true ||\n !this.renderCache.highlighted ||\n !areDiffRenderOptionsEqual(this.renderCache.options, options) ||\n !areDiffTargetsEqual(this.renderCache.diff, diff);\n\n this.renderCache = {\n diff,\n options,\n highlighted,\n result,\n renderRange: undefined,\n };\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n private getMatchingWorkerResultCache(\n diff: FileDiffMetadata,\n options: RenderDiffOptions\n ): RenderDiffResult | undefined {\n if (this.editSessionActive) {\n return undefined;\n }\n const cache = this.workerManager?.getDiffResultCache(diff);\n if (cache == null || !areDiffRenderOptionsEqual(options, cache.options)) {\n return undefined;\n }\n return cache;\n }\n\n private hasHighlightedRenderCache(\n diff: FileDiffMetadata,\n options: RenderDiffOptions\n ): boolean {\n const { renderCache } = this;\n return (\n renderCache?.result != null &&\n renderCache.highlighted &&\n areDiffTargetsEqual(diff, renderCache.diff) &&\n areDiffRenderOptionsEqual(options, renderCache.options)\n );\n }\n\n public onHighlightError(error: unknown): void {\n console.error(error);\n }\n\n private getTokenizeMaxLength(): number {\n return this.options.tokenizeMaxLength ?? DEFAULT_TOKENIZE_MAX_LENGTH;\n }\n\n private processDiffResult(\n fileDiff: FileDiffMetadata,\n renderRange: RenderRange,\n { code, themeStyles, baseThemeType }: ThemedDiffResult\n ): HunksRenderResult {\n const {\n diffStyle,\n disableFileHeader,\n expandUnchanged,\n expansionLineCount,\n collapsedContextThreshold,\n hunkSeparators,\n } = this.getOptionsWithDefaults();\n const isRenderCacheDirty = this.renderCache?.isDirty ?? false;\n\n this.diff = fileDiff;\n const unified = diffStyle === 'unified';\n const canHydrateContext = canHydrateCollapsedContext(\n fileDiff,\n this.options.loadDiffFiles != null\n );\n const isExpandableDiff = !fileDiff.isPartial || canHydrateContext;\n\n let additionsContentAST: ElementContent[] | undefined = [];\n let deletionsContentAST: ElementContent[] | undefined = [];\n let unifiedContentAST: ElementContent[] | undefined = [];\n\n const hunkData: HunkData[] = [];\n const { additionLines, deletionLines } = code;\n const context: ProcessContext = {\n rowCount: 0,\n hunkSeparators,\n additionsContentAST,\n deletionsContentAST,\n unifiedContentAST,\n unifiedGutterAST: createGutterWrapper(),\n deletionsGutterAST: createGutterWrapper(),\n additionsGutterAST: createGutterWrapper(),\n expansionLineCount,\n hunkData,\n incrementRowCount(count = 1) {\n context.rowCount += count;\n },\n pushToGutter(type: CodeColumnType, element: HASTElement) {\n switch (type) {\n case 'unified': {\n context.unifiedGutterAST.children.push(element);\n break;\n }\n case 'deletions': {\n context.deletionsGutterAST.children.push(element);\n break;\n }\n case 'additions': {\n context.additionsGutterAST.children.push(element);\n break;\n }\n }\n },\n };\n const trailingRangeSize = getTrailingContextRangeSize({\n fileDiff,\n errorPrefix: 'DiffHunksRenderer.processDiffResult',\n });\n const pendingSplitContext: PendingSplitContext = {\n size: 0,\n side: undefined,\n increment() {\n this.size += 1;\n },\n flush() {\n if (diffStyle === 'unified') {\n return;\n }\n if (this.size <= 0 || this.side == null) {\n this.side = undefined;\n this.size = 0;\n return;\n }\n if (this.side === 'additions') {\n context.pushToGutter(\n 'additions',\n createGutterGap(undefined, 'buffer', this.size)\n );\n additionsContentAST?.push(createEmptyRowBuffer(this.size));\n } else {\n context.pushToGutter(\n 'deletions',\n createGutterGap(undefined, 'buffer', this.size)\n );\n deletionsContentAST?.push(createEmptyRowBuffer(this.size));\n }\n this.size = 0;\n this.side = undefined;\n },\n };\n\n const pushGutterLineNumber = (\n type: CodeColumnType,\n lineType: LineTypes | 'buffer' | 'separator' | 'annotation',\n lineNumber: number,\n lineIndex: string,\n gutterProperties: Properties | undefined\n ) => {\n context.pushToGutter(\n type,\n createGutterItem(lineType, lineNumber, lineIndex, gutterProperties)\n );\n };\n\n function pushSeparators(props: PushSeparatorProps) {\n pendingSplitContext.flush();\n if (diffStyle === 'unified') {\n pushSeparator('unified', props, context);\n } else {\n pushSeparator('deletions', props, context);\n pushSeparator('additions', props, context);\n }\n }\n\n this.pushFileLevelAnnotations(fileDiff, diffStyle, renderRange, context);\n\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: renderRange.startingLine,\n totalLines: renderRange.totalLines,\n expandedHunks: expandUnchanged ? true : this.expandedHunks,\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n additionLine,\n deletionLine,\n type,\n }) => {\n const splitLineIndex =\n deletionLine != null\n ? deletionLine.splitLineIndex\n : additionLine.splitLineIndex;\n const unifiedLineIndex =\n additionLine != null\n ? additionLine.unifiedLineIndex\n : deletionLine.unifiedLineIndex;\n\n if (diffStyle === 'split' && type !== 'change') {\n pendingSplitContext.flush();\n }\n\n if (collapsedBefore > 0) {\n pushSeparators({\n hunkIndex,\n collapsedLines: collapsedBefore,\n rangeSize: Math.max(hunk?.collapsedBefore ?? 0, 0),\n hunkSpecs: hunk?.hunkSpecs,\n isFirstHunk: hunkIndex === 0,\n isLastHunk: false,\n isExpandable: isExpandableDiff,\n });\n }\n\n const lineIndex =\n diffStyle === 'unified' ? unifiedLineIndex : splitLineIndex;\n const renderedLineContext: RenderedLineContext = {\n type,\n hunkIndex,\n lineIndex,\n unifiedLineIndex,\n splitLineIndex,\n deletionLine,\n additionLine,\n };\n\n if (diffStyle === 'unified') {\n const injectedRows =\n this.getUnifiedInjectedRowsForLine?.(renderedLineContext);\n if (injectedRows?.before != null) {\n pushUnifiedInjectedRows(injectedRows.before, context);\n }\n let deletionLineContent =\n deletionLine != null\n ? deletionLines[deletionLine.lineIndex]\n : undefined;\n let additionLineContent =\n additionLine != null\n ? additionLines[additionLine.lineIndex]\n : undefined;\n if (deletionLineContent == null && additionLineContent == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n const lineType =\n type === 'change'\n ? additionLine != null\n ? 'change-addition'\n : 'change-deletion'\n : type;\n const lineDecoration = this.getUnifiedLineDecoration({\n // NOTE: This function gets extended so don't remove\n // these extra props\n type,\n lineType,\n additionLineIndex: additionLine?.lineIndex,\n deletionLineIndex: deletionLine?.lineIndex,\n });\n pushGutterLineNumber(\n 'unified',\n lineDecoration.gutterLineType,\n additionLine != null\n ? additionLine.lineNumber\n : deletionLine.lineNumber,\n `${unifiedLineIndex},${splitLineIndex}`,\n lineDecoration.gutterProperties\n );\n if (additionLineContent != null) {\n additionLineContent = withContentProperties(\n additionLineContent,\n lineDecoration.contentProperties,\n isRenderCacheDirty && additionLine != null\n ? {\n 'data-line': additionLine.lineNumber,\n 'data-line-index': `${unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n } else if (deletionLineContent != null) {\n deletionLineContent = withContentProperties(\n deletionLineContent,\n lineDecoration.contentProperties,\n isRenderCacheDirty && deletionLine != null\n ? {\n 'data-line': deletionLine.lineNumber,\n 'data-line-index': `${unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n }\n pushLineWithAnnotation({\n diffStyle: 'unified',\n type: type,\n deletionLine: deletionLineContent,\n additionLine: additionLineContent,\n unifiedSpan: this.getAnnotations(\n 'unified',\n deletionLine?.lineNumber,\n additionLine?.lineNumber,\n hunkIndex,\n lineIndex\n ),\n createAnnotationElement: (span) =>\n this.createAnnotationElement(span),\n context,\n });\n if (injectedRows?.after != null) {\n pushUnifiedInjectedRows(injectedRows.after, context);\n }\n } else {\n const injectedRows =\n this.getSplitInjectedRowsForLine?.(renderedLineContext);\n if (injectedRows?.before != null) {\n pushSplitInjectedRows(\n injectedRows.before,\n context,\n pendingSplitContext\n );\n }\n\n let deletionLineContent =\n deletionLine != null\n ? deletionLines[deletionLine.lineIndex]\n : undefined;\n let additionLineContent =\n additionLine != null\n ? additionLines[additionLine.lineIndex]\n : undefined;\n const deletionLineDecoration = this.getSplitLineDecoration({\n side: 'deletions',\n type,\n lineIndex: deletionLine?.lineIndex,\n });\n const additionLineDecoration = this.getSplitLineDecoration({\n side: 'additions',\n type,\n lineIndex: additionLine?.lineIndex,\n });\n\n if (deletionLineContent == null && additionLineContent == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n\n const missingSide = (() => {\n if (type === 'change') {\n if (additionLineContent == null) {\n return 'additions';\n } else if (deletionLineContent == null) {\n return 'deletions';\n }\n }\n return undefined;\n })();\n if (missingSide != null) {\n if (\n pendingSplitContext.side != null &&\n pendingSplitContext.side !== missingSide\n ) {\n pendingSplitContext.flush();\n }\n pendingSplitContext.side = missingSide;\n pendingSplitContext.increment();\n } else if (type === 'change') {\n // A change row with both sides fills the column a pending\n // one-sided buffer was holding open (an insert/delete block\n // directly followed by a paired block, from similarity\n // realignment); flush first so the buffer lands above this row.\n pendingSplitContext.flush();\n }\n\n const annotationSpans = this.getAnnotations(\n 'split',\n deletionLine?.lineNumber,\n additionLine?.lineNumber,\n hunkIndex,\n lineIndex\n );\n if (annotationSpans != null && pendingSplitContext.size > 0) {\n pendingSplitContext.flush();\n }\n\n if (deletionLine != null) {\n const deletionLineDecorated = withContentProperties(\n deletionLineContent,\n deletionLineDecoration.contentProperties,\n isRenderCacheDirty\n ? {\n 'data-line': deletionLine.lineNumber,\n 'data-line-index': `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n pushGutterLineNumber(\n 'deletions',\n deletionLineDecoration.gutterLineType,\n deletionLine.lineNumber,\n `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n deletionLineDecoration.gutterProperties\n );\n if (deletionLineDecorated != null) {\n deletionLineContent = deletionLineDecorated;\n }\n }\n if (additionLine != null) {\n const additionLineDecorated = withContentProperties(\n additionLineContent,\n additionLineDecoration.contentProperties,\n isRenderCacheDirty\n ? {\n 'data-line': additionLine.lineNumber,\n 'data-line-index': `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n pushGutterLineNumber(\n 'additions',\n additionLineDecoration.gutterLineType,\n additionLine.lineNumber,\n `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n additionLineDecoration.gutterProperties\n );\n if (additionLineDecorated != null) {\n additionLineContent = additionLineDecorated;\n }\n }\n pushLineWithAnnotation({\n diffStyle: 'split',\n type: type,\n additionLine: additionLineContent,\n deletionLine: deletionLineContent,\n ...annotationSpans,\n createAnnotationElement: (span) =>\n this.createAnnotationElement(span),\n context,\n });\n if (injectedRows?.after != null) {\n pushSplitInjectedRows(\n injectedRows.after,\n context,\n pendingSplitContext\n );\n }\n }\n\n const isFinalSplitHunkRow =\n diffStyle === 'split' &&\n hunk != null &&\n splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1;\n const isFinalHunkRow =\n hunkIndex === fileDiff.hunks.length - 1 &&\n hunk != null &&\n (diffStyle === 'split'\n ? splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1\n : unifiedLineIndex ===\n hunk.unifiedLineStart + hunk.unifiedLineCount - 1);\n const splitNoEOFCRDeletion = isFinalSplitHunkRow\n ? hunk.noEOFCRDeletions\n : false;\n const splitNoEOFCRAddition = isFinalSplitHunkRow\n ? hunk.noEOFCRAdditions\n : false;\n const noEOFCRDeletion =\n (deletionLine?.noEOFCR ?? false) || splitNoEOFCRDeletion;\n const noEOFCRAddition =\n (additionLine?.noEOFCR ?? false) || splitNoEOFCRAddition;\n if (noEOFCRAddition || noEOFCRDeletion) {\n if (diffStyle === 'split') {\n pendingSplitContext.flush();\n }\n if (noEOFCRDeletion) {\n const noEOFType =\n type === 'context' || type === 'context-expanded'\n ? type\n : 'change-deletion';\n if (diffStyle === 'unified') {\n context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n context.pushToGutter(\n 'unified',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n } else {\n context.deletionsContentAST.push(\n createNoNewlineElement(noEOFType)\n );\n context.pushToGutter(\n 'deletions',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n if (!noEOFCRAddition) {\n context.pushToGutter(\n 'additions',\n createGutterGap(undefined, 'buffer', 1)\n );\n context.additionsContentAST.push(createEmptyRowBuffer(1));\n }\n }\n }\n if (noEOFCRAddition) {\n const noEOFType =\n type === 'context' || type === 'context-expanded'\n ? type\n : 'change-addition';\n if (diffStyle === 'unified') {\n context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n context.pushToGutter(\n 'unified',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n } else {\n context.additionsContentAST.push(\n createNoNewlineElement(noEOFType)\n );\n context.pushToGutter(\n 'additions',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n if (!noEOFCRDeletion) {\n context.pushToGutter(\n 'deletions',\n createGutterGap(undefined, 'buffer', 1)\n );\n context.deletionsContentAST.push(createEmptyRowBuffer(1));\n }\n }\n }\n context.incrementRowCount(1);\n }\n\n if (\n hunkSeparators !== 'simple' &&\n hunkSeparators !== 'metadata' &&\n (collapsedAfter > 0 || (isFinalHunkRow && canHydrateContext))\n ) {\n pushSeparators({\n hunkIndex: type === 'context-expanded' ? hunkIndex : hunkIndex + 1,\n collapsedLines:\n isFinalHunkRow && canHydrateContext ? 'unknown' : collapsedAfter,\n rangeSize: trailingRangeSize,\n hunkSpecs: undefined,\n isFirstHunk: false,\n isLastHunk: true,\n isExpandable: isExpandableDiff,\n });\n }\n context.incrementRowCount(1);\n },\n });\n\n if (diffStyle === 'split') {\n pendingSplitContext.flush();\n }\n\n const totalLines = Math.max(\n getTotalLineCountFromHunks(fileDiff.hunks),\n fileDiff.additionLines.length ?? 0,\n fileDiff.deletionLines.length ?? 0\n );\n\n const hasBuffer =\n renderRange.bufferBefore > 0 || renderRange.bufferAfter > 0;\n // Determine which ASTs to include based on diff style and file type\n const shouldIncludeAdditions = !unified && fileDiff.type !== 'deleted';\n const shouldIncludeDeletions = !unified && fileDiff.type !== 'new';\n const hasContent = context.rowCount > 0 || hasBuffer;\n\n additionsContentAST =\n shouldIncludeAdditions && hasContent ? additionsContentAST : undefined;\n deletionsContentAST =\n shouldIncludeDeletions && hasContent ? deletionsContentAST : undefined;\n unifiedContentAST = unified && hasContent ? unifiedContentAST : undefined;\n\n const preNode = this.createPreElement(\n deletionsContentAST != null && additionsContentAST != null,\n totalLines\n );\n\n return {\n unifiedGutterAST:\n unified && hasContent ? context.unifiedGutterAST.children : undefined,\n unifiedContentAST,\n deletionsGutterAST:\n shouldIncludeDeletions && hasContent\n ? context.deletionsGutterAST.children\n : undefined,\n deletionsContentAST,\n additionsGutterAST:\n shouldIncludeAdditions && hasContent\n ? context.additionsGutterAST.children\n : undefined,\n additionsContentAST,\n hunkData,\n preNode,\n themeStyles,\n baseThemeType,\n headerElement: !disableFileHeader\n ? this.renderHeader(this.diff)\n : undefined,\n totalLines,\n rowCount: context.rowCount,\n bufferBefore: renderRange.bufferBefore,\n bufferAfter: renderRange.bufferAfter,\n // FIXME\n css: '',\n };\n }\n\n public renderCodeAST(\n type: 'unified' | 'deletions' | 'additions',\n result: HunksRenderResult\n ): ElementContent[] | undefined {\n const gutterAST =\n type === 'unified'\n ? result.unifiedGutterAST\n : type === 'deletions'\n ? result.deletionsGutterAST\n : result.additionsGutterAST;\n\n const contentAST =\n type === 'unified'\n ? result.unifiedContentAST\n : type === 'deletions'\n ? result.deletionsContentAST\n : result.additionsContentAST;\n\n if (gutterAST == null || contentAST == null) {\n return undefined;\n }\n\n const gutter = createGutterWrapper(gutterAST);\n gutter.properties.style = `grid-row: span ${result.rowCount}`;\n const contentColumn = createContentColumn(contentAST, result.rowCount);\n return [gutter, contentColumn];\n }\n\n public renderFullAST(\n result: HunksRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n const containerSize =\n this.getOptionsWithDefaults().hunkSeparators === 'line-info';\n const unifiedAST = this.renderCodeAST('unified', result);\n if (unifiedAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: unifiedAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-unified': '',\n },\n })\n );\n return { ...result.preNode, children };\n }\n\n const deletionsAST = this.renderCodeAST('deletions', result);\n if (deletionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: deletionsAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-deletions': '',\n },\n })\n );\n }\n const additionsAST = this.renderCodeAST('additions', result);\n if (additionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: additionsAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-additions': '',\n },\n })\n );\n }\n return { ...result.preNode, children };\n }\n\n public renderFullHTML(\n result: HunksRenderResult,\n tempChildren: ElementContent[] = []\n ): string {\n return toHtml(this.renderFullAST(result, tempChildren));\n }\n\n public renderPartialHTML(\n children: ElementContent[],\n columnType?: 'unified' | 'deletions' | 'additions'\n ): string {\n if (columnType == null) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: {\n 'data-code': '',\n 'data-container-size':\n this.getOptionsWithDefaults().hunkSeparators === 'line-info'\n ? ''\n : undefined,\n [`data-${columnType}`]: '',\n },\n })\n );\n }\n\n private pushFileLevelAnnotations(\n fileDiff: FileDiffMetadata,\n diffStyle: 'unified' | 'split',\n renderRange: RenderRange,\n context: ProcessContext\n ): void {\n if (!shouldRenderFileAnnotations(renderRange)) {\n return;\n }\n\n const deletionAnnotationNames =\n fileDiff.type !== 'new'\n ? getAnnotationNames(getFileAnnotations(this.deletionAnnotations))\n : [];\n const additionAnnotationNames =\n fileDiff.type !== 'deleted'\n ? getAnnotationNames(getFileAnnotations(this.additionAnnotations))\n : [];\n if (\n deletionAnnotationNames.length === 0 &&\n additionAnnotationNames.length === 0\n ) {\n return;\n }\n\n const hunkIndex = FILE_ANNOTATION_HUNK_INDEX;\n const lineIndex = FILE_ANNOTATION_LINE_INDEX;\n const { createAnnotationElement } = this;\n\n if (diffStyle === 'unified') {\n pushLineWithAnnotation({\n diffStyle,\n type: 'context',\n unifiedSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: deletionAnnotationNames.concat(additionAnnotationNames),\n },\n createAnnotationElement,\n context,\n });\n return;\n }\n\n pushLineWithAnnotation({\n diffStyle,\n type: 'context',\n deletionSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: deletionAnnotationNames,\n },\n additionSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: additionAnnotationNames,\n },\n createAnnotationElement,\n context,\n });\n }\n\n private getAnnotations(\n type: 'unified',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): AnnotationSpan | undefined;\n private getAnnotations(\n type: 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan } | undefined;\n private getAnnotations(\n type: 'unified' | 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ):\n | AnnotationSpan\n | { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan }\n | undefined {\n const deletionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (deletionLineNumber != null) {\n for (const anno of this.deletionAnnotations[deletionLineNumber] ?? []) {\n deletionSpan.annotations.push(getLineAnnotationName(anno));\n }\n }\n const additionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (additionLineNumber != null) {\n for (const anno of this.additionAnnotations[additionLineNumber] ?? []) {\n (type === 'unified' ? deletionSpan : additionSpan).annotations.push(\n getLineAnnotationName(anno)\n );\n }\n }\n if (type === 'unified') {\n if (deletionSpan.annotations.length > 0) {\n return deletionSpan;\n }\n return undefined;\n }\n if (\n additionSpan.annotations.length === 0 &&\n deletionSpan.annotations.length === 0\n ) {\n return undefined;\n }\n return { deletionSpan, additionSpan };\n }\n\n private renderHeader(diff: FileDiffMetadata): HASTElement {\n const { headerRenderMode, stickyHeader } = this.getOptionsWithDefaults();\n return createFileHeaderElement({\n fileOrDiff: diff,\n mode: headerRenderMode,\n stickyHeader,\n });\n }\n}\n\nfunction getAnnotationNames<LAnnotation>(\n annotations: DiffLineAnnotation<LAnnotation>[] | undefined\n): string[] {\n return (\n annotations?.map((annotation) => getLineAnnotationName(annotation)) ?? []\n );\n}\n\n// Use the platform's English plural rules to pick \"line\" vs \"lines\" so a\n// count of 0 reads as \"0 unmodified lines\". en-US returns \"one\" only for 1.\nconst EN_PLURAL_RULES = new Intl.PluralRules('en-US');\n\nfunction getModifiedLinesString(lines: number) {\n const suffix = EN_PLURAL_RULES.select(lines) === 'one' ? '' : 's';\n return `${lines} unmodified line${suffix}`;\n}\n\nfunction pushUnifiedInjectedRows(\n rows: InjectedRow[],\n context: ProcessContext\n): void {\n for (const row of rows) {\n context.unifiedContentAST.push(row.content);\n context.pushToGutter('unified', row.gutter);\n context.incrementRowCount(1);\n }\n}\n\nfunction pushSplitInjectedRows(\n rows: SplitInjectedRow[],\n context: ProcessContext,\n pendingSplitContext: PendingSplitContext\n): void {\n for (const { deletion, addition } of rows) {\n if (deletion == null && addition == null) {\n continue;\n }\n const missingSide =\n deletion != null && addition != null\n ? undefined\n : deletion == null\n ? 'deletions'\n : 'additions';\n\n if (missingSide == null || pendingSplitContext.side !== missingSide) {\n pendingSplitContext.flush();\n }\n\n if (deletion != null) {\n context.deletionsContentAST.push(deletion.content);\n context.pushToGutter('deletions', deletion.gutter);\n }\n\n if (addition != null) {\n context.additionsContentAST.push(addition.content);\n context.pushToGutter('additions', addition.gutter);\n }\n\n if (missingSide != null) {\n pendingSplitContext.side = missingSide;\n pendingSplitContext.increment();\n }\n\n context.incrementRowCount(1);\n }\n}\n\nfunction pushLineWithAnnotation({\n diffStyle,\n type,\n deletionLine,\n additionLine,\n unifiedSpan,\n deletionSpan,\n additionSpan,\n createAnnotationElement,\n context,\n}: PushLineWithAnnotation) {\n let hasAnnotationRow = false;\n if (diffStyle === 'unified') {\n if (additionLine != null) {\n context.unifiedContentAST.push(additionLine);\n } else if (deletionLine != null) {\n context.unifiedContentAST.push(deletionLine);\n }\n if (unifiedSpan != null) {\n const lineType =\n type === 'change'\n ? deletionLine != null\n ? 'change-deletion'\n : 'change-addition'\n : type;\n context.unifiedContentAST.push(createAnnotationElement(unifiedSpan));\n context.pushToGutter(\n 'unified',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n } else if (diffStyle === 'split') {\n if (deletionLine != null) {\n context.deletionsContentAST.push(deletionLine);\n }\n if (additionLine != null) {\n context.additionsContentAST.push(additionLine);\n }\n if (deletionSpan != null) {\n const lineType =\n type === 'change'\n ? deletionLine != null\n ? 'change-deletion'\n : 'context'\n : type;\n context.deletionsContentAST.push(createAnnotationElement(deletionSpan));\n context.pushToGutter(\n 'deletions',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n if (additionSpan != null) {\n const lineType =\n type === 'change'\n ? additionLine != null\n ? 'change-addition'\n : 'context'\n : type;\n context.additionsContentAST.push(createAnnotationElement(additionSpan));\n context.pushToGutter(\n 'additions',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n }\n if (hasAnnotationRow) {\n context.incrementRowCount(1);\n }\n}\n\nfunction pushSeparator(\n type: 'additions' | 'deletions' | 'unified',\n {\n hunkIndex,\n collapsedLines,\n rangeSize,\n hunkSpecs,\n isFirstHunk,\n isLastHunk,\n isExpandable,\n }: PushSeparatorProps,\n context: ProcessContext\n) {\n if (typeof collapsedLines === 'number' && collapsedLines <= 0) {\n return;\n }\n const linesAST =\n type === 'unified'\n ? context.unifiedContentAST\n : type === 'deletions'\n ? context.deletionsContentAST\n : context.additionsContentAST;\n\n if (context.hunkSeparators === 'metadata') {\n if (hunkSpecs != null) {\n context.pushToGutter(\n type,\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n linesAST.push(\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n }\n return;\n }\n if (context.hunkSeparators === 'simple') {\n if (hunkIndex > 0) {\n context.pushToGutter(\n type,\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n linesAST.push(\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n }\n return;\n }\n const slotName = getHunkSeparatorSlotName(type, hunkIndex);\n const chunked = rangeSize > context.expansionLineCount;\n const expandIndex = isExpandable ? hunkIndex : undefined;\n const content =\n typeof collapsedLines === 'number'\n ? getModifiedLinesString(collapsedLines)\n : 'More unchanged context may be available';\n context.pushToGutter(\n type,\n createSeparator({\n type: context.hunkSeparators,\n content,\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n linesAST.push(\n createSeparator({\n type: context.hunkSeparators,\n content,\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n context.hunkData.push({\n slotName,\n hunkIndex,\n lines: typeof collapsedLines === 'number' ? collapsedLines : 0,\n lineCountKnown: typeof collapsedLines === 'number',\n type,\n expandable: isExpandable\n ? { up: !isFirstHunk, down: !isLastHunk, chunked }\n : undefined,\n });\n}\n\nfunction withContentProperties(\n lineNode: ElementContent | undefined,\n contentProperties?: Properties,\n extendProperties?: Properties\n): ElementContent | undefined {\n if (\n lineNode == null ||\n lineNode.type !== 'element' ||\n (contentProperties == null && extendProperties == null)\n ) {\n return lineNode;\n }\n return {\n ...lineNode,\n properties: {\n ...lineNode.properties,\n ...contentProperties,\n ...extendProperties,\n },\n };\n}\n\n// Realigns the cached per-line addition HAST array with an edited document.\n// Cached entries are looked up by line index, so a line inserted or removed\n// mid-document must shift the surviving entries to their new indexes —\n// otherwise rows hidden during the edit (collapsed context) render another\n// line's stale tokens once they become visible. Entries outside the changed\n// window keep their highlighted content; entries inside it become plain-text\n// elements that the editor re-tokenizes on its next background pass.\nfunction realignAdditionHastLines(\n previousLines: string[],\n nextLines: string[],\n hastLines: ElementContent[],\n textDocument: DiffsTextDocument\n): ElementContent[] {\n const maxShared = Math.min(previousLines.length, nextLines.length);\n let prefix = 0;\n while (prefix < maxShared && previousLines[prefix] === nextLines[prefix]) {\n prefix++;\n }\n let suffix = 0;\n while (\n suffix < maxShared - prefix &&\n previousLines[previousLines.length - 1 - suffix] ===\n nextLines[nextLines.length - 1 - suffix]\n ) {\n suffix++;\n }\n\n const realigned: ElementContent[] = new Array(nextLines.length);\n for (let index = 0; index < prefix; index++) {\n realigned[index] = hastLines[index];\n }\n for (let offset = 0; offset < suffix; offset++) {\n realigned[nextLines.length - 1 - offset] =\n hastLines[previousLines.length - 1 - offset];\n }\n // Deferred tokenization can write entries past the previous line count;\n // those were produced with post-edit indexes and are already in place.\n for (let index = previousLines.length; index < nextLines.length; index++) {\n realigned[index] ??= hastLines[index];\n }\n for (let index = prefix; index < nextLines.length - suffix; index++) {\n realigned[index] ??= createPlainAdditionLineElement(index, textDocument);\n }\n return realigned;\n}\n\nfunction createPlainAdditionLineElement(\n lineIndex: number,\n textDocument: DiffsTextDocument\n): HASTElement {\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': lineIndex + 1,\n 'data-line-index': `${lineIndex},${lineIndex}`,\n 'data-line-type': 'context',\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': 0,\n },\n children: [\n {\n type: 'text',\n value: textDocument.getLineText(lineIndex),\n },\n ],\n },\n ],\n };\n}\n\nfunction getEditorDocumentLines(\n textDocument: DiffsTextDocument,\n previousLines: string[]\n): string[] {\n const lines: string[] = [];\n const fallbackLineBreak = getFallbackLineBreak(previousLines);\n for (let line = 0; line < textDocument.lineCount; line++) {\n const lineText = textDocument.getLineText(line, true);\n lines.push(\n line < textDocument.lineCount - 1 && !hasLineBreakSuffix(lineText)\n ? lineText + fallbackLineBreak\n : lineText\n );\n }\n return lines;\n}\n\nfunction hasLineBreakSuffix(line: string): boolean {\n return line.endsWith('\\n') || line.endsWith('\\r');\n}\n\nfunction getFallbackLineBreak(lines: string[]): string {\n for (const line of lines) {\n if (line.endsWith('\\r\\n')) {\n return '\\r\\n';\n }\n if (line.endsWith('\\n')) {\n return '\\n';\n }\n if (line.endsWith('\\r')) {\n return '\\r';\n }\n }\n return '\\n';\n}\n\nfunction isDiffMassive(\n diff: FileDiffMetadata,\n tokenizeMaxLength: number\n): boolean {\n return (\n Math.max(diff.additionLines.length, diff.deletionLines.length) >\n tokenizeMaxLength\n );\n}\n\nfunction canHydrateCollapsedContext(\n fileDiff: FileDiffMetadata,\n hasFileLoader: boolean\n): boolean {\n return (\n fileDiff.isPartial &&\n hasFileLoader &&\n (fileDiff.type === 'change' || fileDiff.type === 'rename-changed')\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DiffHunksRenderer.js","names":["createDefaultAnnotationElement"],"sources":["../../src/renderers/DiffHunksRenderer.ts"],"sourcesContent":["import type { ElementContent, Element as HASTElement, Properties } from 'hast';\nimport { toHtml } from 'hast-util-to-html';\n\nimport {\n DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n DEFAULT_EXPANDED_REGION,\n DEFAULT_RENDER_RANGE,\n DEFAULT_THEMES,\n DEFAULT_TOKENIZE_MAX_LENGTH,\n} from '../constants';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n} from '../highlighter/shared_highlighter';\nimport { areThemesAttached } from '../highlighter/themes/areThemesAttached';\nimport type {\n AnnotationLineMap,\n AnnotationSpan,\n BaseDiffOptions,\n BaseDiffOptionsWithDefaults,\n CodeColumnType,\n CustomPreProperties,\n DiffLineAnnotation,\n DiffsHighlighter,\n DiffsTextDocument,\n ExpansionDirections,\n FileDiffMetadata,\n FileHeaderRenderMode,\n HighlightedToken,\n HunkData,\n HunkExpansionRegion,\n HunkSeparators,\n LineTypes,\n RenderDiffOptions,\n RenderDiffResult,\n RenderedDiffASTCache,\n RenderRange,\n SupportedLanguages,\n ThemedDiffResult,\n} from '../types';\nimport { applyLineTextWithNewline } from '../utils/applyLineTextWithNewline';\nimport { areDiffRenderOptionsEqual } from '../utils/areDiffRenderOptionsEqual';\nimport { areDiffTargetsEqual } from '../utils/areDiffTargetsEqual';\nimport { areRenderRangesEqual } from '../utils/areRenderRangesEqual';\nimport { cleanLastNewline } from '../utils/cleanLastNewline';\nimport { createAnnotationElement as createDefaultAnnotationElement } from '../utils/createAnnotationElement';\nimport { createContentColumn } from '../utils/createContentColumn';\nimport { createEmptyRowBuffer } from '../utils/createEmptyRowBuffer';\nimport { createFileHeaderElement } from '../utils/createFileHeaderElement';\nimport { createNoNewlineElement } from '../utils/createNoNewlineElement';\nimport { createPreElement } from '../utils/createPreElement';\nimport { createSeparator } from '../utils/createSeparator';\nimport {\n applySessionChangedLines,\n rebuildSessionHunks,\n remapExpandedHunksForRegionChange,\n type SessionRegionChange,\n} from '../utils/editSessionHunks';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport { getHighlighterOptions } from '../utils/getHighlighterOptions';\nimport { getHunkSeparatorSlotName } from '../utils/getHunkSeparatorSlotName';\nimport { getLineAnnotationName } from '../utils/getLineAnnotationName';\nimport { getTotalLineCountFromHunks } from '../utils/getTotalLineCountFromHunks';\nimport {\n createGutterGap,\n createGutterItem,\n createGutterWrapper,\n createHastElement,\n} from '../utils/hast_utils';\nimport {\n FILE_ANNOTATION_HUNK_INDEX,\n FILE_ANNOTATION_LINE_INDEX,\n getFileAnnotations,\n shouldRenderFileAnnotations,\n} from '../utils/includesFileAnnotations';\nimport { isDefaultRenderRange } from '../utils/isDefaultRenderRange';\nimport { isDiffPlainText } from '../utils/isDiffPlainText';\nimport type { DiffLineMetadata } from '../utils/iterateOverDiff';\nimport { iterateOverDiff } from '../utils/iterateOverDiff';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport {\n recomputeDiffHunksForEdit,\n recomputeEmptyDocumentDiff,\n recomputeTopAlignedAdditionDiff,\n shouldTopAlignAdditionRecompute,\n updateDiffHunks,\n} from '../utils/updateDiffHunks';\nimport { getTrailingContextRangeSize } from '../utils/virtualDiffLayout';\nimport type { WorkerPoolManager } from '../worker';\n\ninterface PushLineWithAnnotation {\n diffStyle: 'unified' | 'split';\n type: 'context' | 'context-expanded' | 'change';\n\n deletionLine?: ElementContent;\n additionLine?: ElementContent;\n\n unifiedSpan?: AnnotationSpan;\n deletionSpan?: AnnotationSpan;\n additionSpan?: AnnotationSpan;\n\n createAnnotationElement(span: AnnotationSpan): HASTElement;\n context: ProcessContext;\n}\n\ninterface GetRenderOptionsReturn {\n options: RenderDiffOptions;\n forceHighlight: boolean;\n}\n\ninterface PushSeparatorProps {\n hunkIndex: number;\n collapsedLines: number | 'unknown';\n rangeSize: number;\n hunkSpecs: string | undefined;\n isFirstHunk: boolean;\n isLastHunk: boolean;\n isExpandable: boolean;\n}\n\ninterface ProcessContext {\n rowCount: number;\n expansionLineCount: number;\n hunkSeparators: HunkSeparators;\n unifiedContentAST: ElementContent[];\n deletionsContentAST: ElementContent[];\n additionsContentAST: ElementContent[];\n unifiedGutterAST: HASTElement;\n deletionsGutterAST: HASTElement;\n additionsGutterAST: HASTElement;\n hunkData: HunkData[];\n pushToGutter(type: CodeColumnType, element: HASTElement): void;\n incrementRowCount(count?: number): void;\n}\n\nexport interface DiffHunksRendererOptions extends BaseDiffOptions {\n headerRenderMode?: FileHeaderRenderMode;\n}\n\nexport interface DiffHunksRendererOptionsWithDefaults extends Omit<\n BaseDiffOptionsWithDefaults,\n 'themeType'\n> {\n headerRenderMode: FileHeaderRenderMode;\n}\n\nexport interface UnifiedLineDecorationProps {\n type: 'context' | 'context-expanded' | 'change';\n lineType: LineTypes;\n additionLineIndex: number | undefined;\n deletionLineIndex: number | undefined;\n}\n\nexport interface SplitLineDecorationProps {\n side: 'deletions' | 'additions';\n type: 'context' | 'context-expanded' | 'change';\n lineIndex: number | undefined;\n}\n\nexport interface LineDecoration {\n gutterLineType: LineTypes;\n gutterProperties?: Properties;\n contentProperties?: Properties;\n}\n\ninterface PendingSplitContext {\n size: number;\n side: 'additions' | 'deletions' | undefined;\n increment(): void;\n flush(): void;\n}\n\nexport interface RenderedLineContext {\n type: 'context' | 'context-expanded' | 'change';\n hunkIndex: number;\n lineIndex: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n deletionLine?: DiffLineMetadata;\n additionLine?: DiffLineMetadata;\n}\n\nexport interface InjectedRow {\n content: HASTElement;\n gutter: HASTElement;\n}\n\nexport interface SplitInjectedRow {\n deletion: InjectedRow | undefined;\n addition: InjectedRow | undefined;\n}\n\nexport interface UnifiedInjectedRowPlacement {\n before?: InjectedRow[];\n after?: InjectedRow[];\n}\n\nexport interface SplitInjectedRowPlacement {\n before?: SplitInjectedRow[];\n after?: SplitInjectedRow[];\n}\n\nexport interface HunksRenderResult {\n unifiedGutterAST: ElementContent[] | undefined;\n unifiedContentAST: ElementContent[] | undefined;\n deletionsGutterAST: ElementContent[] | undefined;\n deletionsContentAST: ElementContent[] | undefined;\n additionsGutterAST: ElementContent[] | undefined;\n additionsContentAST: ElementContent[] | undefined;\n hunkData: HunkData[];\n css: string;\n preNode: HASTElement;\n headerElement: HASTElement | undefined;\n totalLines: number;\n themeStyles: string;\n baseThemeType: 'light' | 'dark' | undefined;\n rowCount: number;\n bufferBefore: number;\n bufferAfter: number;\n}\n\nlet instanceId = -1;\n\nexport class DiffHunksRenderer<LAnnotation = undefined> {\n readonly __id: string = `diff-hunks-renderer:${++instanceId}`;\n\n private highlighter: DiffsHighlighter | undefined;\n private diff: FileDiffMetadata | undefined;\n\n private expandedHunks = new Map<number, HunkExpansionRegion>();\n\n private deletionAnnotations: AnnotationLineMap<LAnnotation> = {};\n private additionAnnotations: AnnotationLineMap<LAnnotation> = {};\n\n private computedLang: SupportedLanguages = 'text';\n private renderCache: RenderedDiffASTCache | undefined;\n\n // Edit-session state: while active, hunk updates go through the frozen\n // region skeleton (editSessionHunks) instead of the full recompute, and\n // rendering stays on the main thread with editor-compatible token markup —\n // the editor's caret/selection mapping needs the token transformer, and\n // the pool's global options are not guaranteed to produce it. The pool\n // keeps serving every surface without a session.\n private editSessionActive = false;\n\n constructor(\n public options: DiffHunksRendererOptions = { theme: DEFAULT_THEMES },\n private onRenderUpdate?: () => unknown,\n private workerManager?: WorkerPoolManager | undefined\n ) {\n if (workerManager?.isWorkingPool() !== true) {\n this.highlighter = areThemesAttached(options.theme ?? DEFAULT_THEMES)\n ? getHighlighterIfLoaded()\n : undefined;\n }\n }\n\n public cleanUp(): void {\n this.recycle();\n this.expandedHunks.clear();\n this.workerManager = undefined;\n this.onRenderUpdate = undefined;\n }\n\n public recycle(): void {\n this.highlighter = undefined;\n this.diff = undefined;\n this.clearRenderCache();\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n this.workerManager?.cleanUpTasks(this);\n // Session hunks and the metadata dirty marker survive recycle in the\n // shared FileDiffMetadata; the renderer-local state re-seeds on the next\n // attach (beginEditSession).\n this.endEditSession();\n }\n\n /**\n * Enter edit-session mode: hunk updates preserve the current region\n * skeleton instead of recomputing hunks, and rendering happens locally\n * with the token transformer forced on (worker-pool requests/results are\n * suspended for this renderer). Called on every editor attach, including\n * a re-attach after recycle.\n */\n public beginEditSession(): void {\n this.editSessionActive = true;\n }\n\n /** Leave edit-session mode. The exit recompute is the host's concern. */\n public endEditSession(): void {\n this.editSessionActive = false;\n }\n\n /**\n * Ensures that the DOM is compatible with editor render updates\n */\n public editorRenderReady(): boolean {\n return (\n this.renderCache?.options.useTokenTransformer === true &&\n this.renderCache.highlighted &&\n this.renderCache.result != null\n );\n }\n\n /**\n * Re-highlights the current diff in the background and swaps the fresh\n * result in (with a re-render) once it completes. Needed after an edit\n * session's exit recompute: session passes plain-fill shifted lines in the\n * cached result, and the recompute mutates the diff in place (same object,\n * same cacheKey), so identity/cacheKey checks would otherwise treat the\n * stale highlight as current forever. The current result — content-correct,\n * mostly highlighted — keeps rendering until the fresh one lands, so no\n * interim paint drops highlighting.\n */\n public refreshHighlightedResult(): Promise<void> {\n const { renderCache } = this;\n if (\n renderCache == null ||\n isDiffPlainText(renderCache.diff) ||\n isDiffMassive(renderCache.diff, this.getTokenizeMaxLength())\n ) {\n return Promise.resolve();\n }\n const { diff } = renderCache;\n const { workerManager } = this;\n // The pool's diff cache is keyed by cacheKey, so a worker refresh needs\n // one; a keyless diff uses the local highlighter fallback below instead.\n if (\n !this.editSessionActive &&\n workerManager?.isWorkingPool() === true &&\n diff.cacheKey != null\n ) {\n workerManager.evictDiffFromCache(diff.cacheKey);\n return workerManager\n .primeDiffHighlightCache(diff)\n .then(() => {\n this.applyRefreshedResult(\n diff,\n workerManager.getDiffResultCache(diff)\n );\n })\n .catch((error: unknown) => this.onHighlightError(error));\n }\n return this.asyncHighlight(diff)\n .then((fresh) => this.applyRefreshedResult(diff, fresh))\n .catch((error: unknown) => this.onHighlightError(error));\n }\n\n // Installs a freshly highlighted result for the same diff, unless the\n // renderer moved on while the highlight ran (new diff, options change, or\n // a new edit session whose passes the fresh result wouldn't reflect).\n private applyRefreshedResult(\n diff: FileDiffMetadata,\n fresh: RenderDiffResult | undefined\n ): void {\n if (\n fresh == null ||\n this.renderCache == null ||\n this.renderCache.diff !== diff ||\n this.editSessionActive\n ) {\n return;\n }\n const { options } = this.getRenderOptions(diff);\n if (!areDiffRenderOptionsEqual(options, fresh.options)) {\n return;\n }\n this.renderCache = {\n diff,\n options: fresh.options,\n highlighted: true,\n result: fresh.result,\n renderRange: undefined,\n };\n this.onRenderUpdate?.();\n }\n\n public get diffCache(): FileDiffMetadata | undefined {\n return this.renderCache?.diff ?? this.diff;\n }\n\n public clearRenderCache(): void {\n const renderCache = this.renderCache;\n this.renderCache = undefined;\n if (\n renderCache != null &&\n renderCache.isDirty === true &&\n renderCache.diff.cacheKey != null\n ) {\n // The render cache has been updated by the host, let's purge it\n // from the worker manager cache.\n this.workerManager?.evictDiffFromCache(renderCache.diff.cacheKey);\n }\n }\n\n public setOptions(options: DiffHunksRendererOptions): void {\n this.options = options;\n }\n\n public mergeOptions(options: Partial<DiffHunksRendererOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n public expandHunk(\n index: number,\n direction: ExpansionDirections,\n expansionLineCount: number = this.getOptionsWithDefaults()\n .expansionLineCount\n ): void {\n const region = {\n ...(this.expandedHunks.get(index) ?? {\n fromStart: 0,\n fromEnd: 0,\n }),\n };\n if (direction === 'up' || direction === 'both') {\n region.fromStart += expansionLineCount;\n }\n if (direction === 'down' || direction === 'both') {\n region.fromEnd += expansionLineCount;\n }\n // NOTE(amadeus): If our render cache is not highlighted, we need to clear\n // it, otherwise we won't have the correct AST lines. Clearing is safe\n // mid-edit-session even though the dirty cache carries live edits: both\n // session hunk-update paths keep diff.additionLines current every pass,\n // so the rebuilt AST reproduces the live document.\n if (this.renderCache?.highlighted !== true) {\n this.clearRenderCache();\n }\n this.expandedHunks.set(index, region);\n }\n\n public getExpandedHunk(hunkIndex: number): HunkExpansionRegion {\n return this.expandedHunks.get(hunkIndex) ?? DEFAULT_EXPANDED_REGION;\n }\n\n public getExpandedHunksMap(): Map<number, HunkExpansionRegion> {\n return this.expandedHunks;\n }\n\n /** Replace the whole expansion map (session-exit expansion remapping). */\n public setExpandedHunksMap(\n expandedHunks: Map<number, HunkExpansionRegion>\n ): void {\n this.expandedHunks = expandedHunks;\n }\n\n public setLineAnnotations(\n lineAnnotations: DiffLineAnnotation<LAnnotation>[]\n ): void {\n this.additionAnnotations = {};\n this.deletionAnnotations = {};\n for (const annotation of lineAnnotations) {\n const map = ((): AnnotationLineMap<LAnnotation> => {\n switch (annotation.side) {\n case 'deletions':\n return this.deletionAnnotations;\n case 'additions':\n return this.additionAnnotations;\n }\n })();\n const arr = map[annotation.lineNumber] ?? [];\n map[annotation.lineNumber] = arr;\n arr.push(annotation);\n }\n }\n\n /**\n * Returns true when a session-mode pass changed the region skeleton itself\n * (a gap edit synthesized or merged regions), which changes the rendered\n * row set without a line-count change — the host must escalate to a full\n * re-render instead of its cheap refresh path.\n */\n public updateRenderCache(\n dirtyLines: Map<number, Array<HighlightedToken>>,\n themeType: 'dark' | 'light',\n lineCountChangeInFlight = false\n ): boolean {\n if (this.renderCache == null) {\n return false;\n }\n const { result, diff } = this.renderCache;\n if (result == null) {\n return false;\n }\n if (diff.isPartial) {\n throw new Error('Could not update render cache for partial diff');\n }\n\n const hastLines = result.code.additionLines;\n const changedAdditionLines: number[] = [];\n const previousAdditionLines = new Map<number, string>();\n for (const [line, tokens] of dirtyLines) {\n const prev = hastLines[line] as HASTElement | undefined;\n const prevProps = prev?.properties ?? {};\n const lineText = tokens.map((a) => a[2]).join('');\n const canSyncDiffLine = line < diff.additionLines.length;\n const prevLine = canSyncDiffLine ? (diff.additionLines[line] ?? '') : '';\n const prevText = cleanLastNewline(prevLine);\n // The host text document can expose one extra trailing empty line when\n // the file ends with a newline. Deferred tokenization must not grow\n // additionLines from that mismatch or hunk trailing context desyncs.\n if (canSyncDiffLine) {\n diff.additionLines[line] = applyLineTextWithNewline(prevLine, lineText);\n if (prevText !== lineText) {\n changedAdditionLines.push(line);\n previousAdditionLines.set(line, prevLine);\n }\n }\n hastLines[line] = {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': prevProps['data-line'] ?? line + 1,\n 'data-line-index': prevProps['data-line-index'] ?? line,\n 'data-line-type': prevProps['data-line-type'] ?? 'context',\n },\n children: tokens.map(([char, fg, text]) => {\n if (char === 0 && fg === '') {\n if (text === '') {\n return {\n type: 'element',\n tagName: 'br',\n properties: {},\n children: [],\n };\n }\n return { type: 'text', value: text };\n }\n return {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': char,\n style: `color:${fg};`,\n },\n children: [{ type: 'text', value: text }],\n };\n }),\n };\n }\n\n let regionsChanged = false;\n if (changedAdditionLines.length > 0) {\n if (this.editSessionActive && !diff.isPartial) {\n // On a line-count pass the tokenizer emits shifted-but-unedited lines\n // as dirty and the writes above land at stale indexes, so hunk work\n // must wait for the authoritative applyDocumentChange in this same\n // pass. Otherwise (including deferred background passes, which carry\n // genuine changes and are never followed by applyDocumentChange) the\n // explicit changed indexes are current.\n if (!lineCountChangeInFlight) {\n if (\n diff.additionLines.length <= 1 &&\n diff.additionLines.join('') === ''\n ) {\n Object.assign(\n diff,\n recomputeEmptyDocumentDiff(diff, this.options.parseDiffOptions)\n );\n this.markEditSessionPass(diff);\n regionsChanged = true;\n } else if (\n shouldTopAlignAdditionRecompute(diff, diff.additionLines)\n ) {\n Object.assign(\n diff,\n recomputeTopAlignedAdditionDiff(\n diff,\n diff.additionLines,\n this.options.parseDiffOptions\n )\n );\n this.markEditSessionPass(diff);\n regionsChanged = true;\n } else {\n const change = applySessionChangedLines(\n diff,\n changedAdditionLines,\n this.options.parseDiffOptions,\n previousAdditionLines\n );\n this.applyExpansionRemap(change);\n regionsChanged = change != null;\n }\n }\n } else {\n Object.assign(\n diff,\n updateDiffHunks(\n diff,\n changedAdditionLines,\n this.options.parseDiffOptions\n )\n );\n }\n }\n\n result.baseThemeType = themeType;\n this.renderCache.isDirty = true;\n return regionsChanged;\n }\n\n private applyExpansionRemap(change: SessionRegionChange | undefined): void {\n if (change != null) {\n this.expandedHunks = remapExpandedHunksForRegionChange(\n this.expandedHunks,\n change\n );\n }\n }\n\n // Normally triggered by the host when the document line count changes.\n public applyDocumentChange(textDocument: DiffsTextDocument): void {\n if (this.renderCache == null) {\n return;\n }\n const { diff, result } = this.renderCache;\n if (result == null) {\n return;\n }\n if (diff.isPartial) {\n throw new Error('Could not apply document change for partial diff');\n }\n\n // updateRenderCache may already have extended diff.additionLines for the\n // same edit pass, so never bail out purely on matching lengths here.\n // Read line-by-line from the editor document instead of materializing the\n // entire text. This preserves blank documents and the final editable empty\n // row after a trailing line break.\n const { additionLines: previousAdditionLines } = diff;\n diff.additionLines = getEditorDocumentLines(\n textDocument,\n previousAdditionLines\n );\n result.code.additionLines = realignAdditionHastLines(\n previousAdditionLines,\n diff.additionLines,\n result.code.additionLines,\n textDocument\n );\n // An empty document splits into zero addition lines, which would recompute\n // to a diff with no editable rows and leave the attached host with no\n // line element for its caret (the additions column vanishes in split;\n // unified shows only deletions). Keep one empty editable line instead.\n if (diff.additionLines.length <= 1 && diff.additionLines.join('') === '') {\n Object.assign(\n diff,\n recomputeEmptyDocumentDiff(diff, this.options.parseDiffOptions)\n );\n result.code.additionLines[0] = createPlainAdditionLineElement(\n 0,\n textDocument\n );\n this.markEditSessionPass(diff);\n } else if (this.editSessionActive) {\n this.applySessionDocumentChange(diff);\n } else {\n Object.assign(\n diff,\n recomputeDiffHunksForEdit(diff, this.options.parseDiffOptions)\n );\n }\n\n this.renderCache.isDirty = true;\n }\n\n // Session-mode counterpart of the line-count recompute: derive canonical\n // old/current pairing and rebuild the old-side region skeleton from it.\n private applySessionDocumentChange(diff: FileDiffMetadata): void {\n const { parseDiffOptions } = this.options;\n const rawLines = diff.additionLines;\n if (shouldTopAlignAdditionRecompute(diff, rawLines)) {\n Object.assign(\n diff,\n recomputeTopAlignedAdditionDiff(diff, rawLines, parseDiffOptions)\n );\n this.markEditSessionPass(diff);\n return;\n }\n this.applyExpansionRemap(rebuildSessionHunks(diff, parseDiffOptions));\n }\n\n // Records a session pass that replaced hunks wholesale (empty-document or\n // top-aligned shims).\n private markEditSessionPass(diff: FileDiffMetadata): void {\n if (!this.editSessionActive) {\n return;\n }\n diff.editSessionDirty = true;\n }\n\n protected getUnifiedLineDecoration({\n lineType,\n }: UnifiedLineDecorationProps): LineDecoration {\n return {\n gutterLineType: lineType,\n contentProperties: {\n 'data-line-type': lineType,\n },\n };\n }\n\n protected getSplitLineDecoration({\n side,\n type,\n }: SplitLineDecorationProps): LineDecoration {\n const lineType: LineTypes =\n type === 'change'\n ? side === 'deletions'\n ? 'change-deletion'\n : 'change-addition'\n : type;\n return {\n gutterLineType: lineType,\n contentProperties: {\n 'data-line-type': lineType,\n },\n };\n }\n\n private createAnnotationElement = (span: AnnotationSpan): HASTElement => {\n return createDefaultAnnotationElement(span);\n };\n\n // Unified hook returns extra rows that render before/after the current line.\n declare protected getUnifiedInjectedRowsForLine?: (\n ctx: RenderedLineContext\n ) => UnifiedInjectedRowPlacement | undefined;\n\n // Split hook returns extra rows per side before/after the current line.\n declare protected getSplitInjectedRowsForLine?: (\n ctx: RenderedLineContext\n ) => SplitInjectedRowPlacement | undefined;\n\n protected getOptionsWithDefaults(): DiffHunksRendererOptionsWithDefaults {\n const {\n diffIndicators = 'bars',\n diffStyle = 'split',\n disableBackground = false,\n disableFileHeader = false,\n disableLineNumbers = false,\n disableVirtualizationBuffers = false,\n collapsed = false,\n expandUnchanged = false,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n expansionLineCount = 100,\n hunkSeparators = 'line-info',\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n overflow = 'scroll',\n stickyHeader = false,\n theme = DEFAULT_THEMES,\n headerRenderMode = 'default',\n tokenizeMaxLineLength = 1000,\n tokenizeMaxLength = DEFAULT_TOKENIZE_MAX_LENGTH,\n useTokenTransformer = false,\n useCSSClasses = false,\n } = this.options;\n return {\n diffIndicators,\n diffStyle,\n disableBackground,\n disableFileHeader,\n disableLineNumbers,\n disableVirtualizationBuffers,\n collapsed,\n expandUnchanged,\n collapsedContextThreshold,\n expansionLineCount,\n hunkSeparators,\n lineDiffType,\n maxLineDiffLength,\n overflow,\n stickyHeader,\n theme: this.workerManager?.getDiffRenderOptions().theme ?? theme,\n headerRenderMode,\n tokenizeMaxLineLength,\n tokenizeMaxLength,\n useTokenTransformer,\n useCSSClasses,\n };\n }\n\n public async initializeHighlighter(): Promise<DiffsHighlighter> {\n this.highlighter = await getSharedHighlighter(\n getHighlighterOptions(this.computedLang, {\n theme: this.getLocalHighlightTheme(),\n preferredHighlighter:\n this.workerManager?.getPreferredHighlighter() ??\n this.options.preferredHighlighter,\n })\n );\n return this.highlighter;\n }\n\n public hydrate(diff: FileDiffMetadata | undefined): void {\n if (diff == null) {\n return;\n }\n this.diff = diff;\n const { options } = this.getRenderOptions(diff);\n const massiveDiff = isDiffMassive(diff, this.getTokenizeMaxLength());\n let cache = this.workerManager?.getDiffResultCache(diff);\n if (cache != null && !areDiffRenderOptionsEqual(options, cache.options)) {\n cache = undefined;\n }\n this.renderCache ??= {\n diff,\n highlighted: !massiveDiff && !isDiffPlainText(diff),\n options,\n result: massiveDiff ? undefined : cache?.result,\n renderRange: undefined,\n };\n if (\n !this.editSessionActive &&\n this.workerManager?.isWorkingPool() === true\n ) {\n if (this.renderCache.result == null && !massiveDiff) {\n // We should only kick off a preload of the AST if we have a WorkerPool\n this.workerManager.highlightDiffAST(this, this.diff);\n }\n }\n // Lets attempt to get the highlighter/languages ready immediately\n else if (this.highlighter == null) {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n void this.initializeHighlighter();\n }\n }\n\n private getLocalHighlightTheme(): RenderDiffOptions['theme'] {\n return (\n this.workerManager?.getDiffRenderOptions().theme ??\n this.options.theme ??\n DEFAULT_THEMES\n );\n }\n\n private getRenderOptions(diff: FileDiffMetadata): GetRenderOptionsReturn {\n const options: RenderDiffOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n const poolOptions = this.workerManager.getDiffRenderOptions();\n // Active edit sessions require `useTokenTransformer: true`\n if (\n this.editSessionActive &&\n poolOptions.useTokenTransformer !== true\n ) {\n return { ...poolOptions, useTokenTransformer: true };\n }\n return poolOptions;\n }\n const { theme, tokenizeMaxLineLength, lineDiffType, maxLineDiffLength } =\n this.getOptionsWithDefaults();\n return {\n theme,\n useTokenTransformer:\n this.editSessionActive || this.options.useTokenTransformer === true,\n tokenizeMaxLineLength,\n lineDiffType,\n maxLineDiffLength,\n };\n })();\n this.getOptionsWithDefaults();\n const { renderCache } = this;\n if (renderCache?.result == null) {\n return { options, forceHighlight: true };\n }\n if (\n !areDiffTargetsEqual(diff, renderCache.diff) ||\n !areDiffRenderOptionsEqual(options, renderCache.options)\n ) {\n return { options, forceHighlight: true };\n }\n return { options, forceHighlight: false };\n }\n\n public renderDiff(\n diff: FileDiffMetadata | undefined = this.renderCache?.diff,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): HunksRenderResult | undefined {\n if (diff == null) {\n return undefined;\n }\n const { expandUnchanged, collapsedContextThreshold } =\n this.getOptionsWithDefaults();\n let { options, forceHighlight } = this.getRenderOptions(diff);\n const cache = this.getMatchingWorkerResultCache(diff, options);\n if (cache != null && !this.hasHighlightedRenderCache(diff, options)) {\n this.renderCache = {\n diff,\n highlighted: true,\n renderRange: undefined,\n ...cache,\n };\n forceHighlight = false;\n }\n this.renderCache ??= {\n diff,\n highlighted: false,\n options,\n result: undefined,\n renderRange: undefined,\n };\n const hasContent =\n diff.additionLines.length > 0 || diff.deletionLines.length > 0;\n const forcePlainText =\n !hasContent ||\n isDiffPlainText(diff) ||\n isDiffMassive(diff, this.getTokenizeMaxLength());\n const newContent = !areDiffTargetsEqual(diff, this.renderCache.diff);\n const newRenderRange = !areRenderRangesEqual(\n this.renderCache.renderRange,\n renderRange\n );\n if (\n !this.editSessionActive &&\n this.workerManager?.isWorkingPool() === true\n ) {\n // An already-highlighted view is waiting on a fresh highlight for the\n // same diff. Returning no result keeps the host's current content in\n // place instead of downgrading it to a plain AST; the pending\n // highlight's completion will re-render. A different diff or a\n // sub-range window still paints plain — the current content cannot\n // serve those.\n const highlightPending =\n this.renderCache.result == null &&\n this.renderCache.highlighted &&\n !forcePlainText &&\n !newContent &&\n isDefaultRenderRange(renderRange);\n if (highlightPending) {\n this.renderCache.highlightPending = true;\n }\n if (\n !highlightPending &&\n (forcePlainText ||\n this.renderCache.result == null ||\n (!this.renderCache.highlighted && (newContent || newRenderRange)))\n ) {\n this.renderCache.diff = diff;\n this.renderCache.options = options;\n this.renderCache.highlighted = false;\n if (\n this.renderCache.result == null ||\n newContent ||\n newRenderRange ||\n forceHighlight\n ) {\n this.renderCache.result = this.workerManager.getPlainDiffAST(\n diff,\n renderRange.startingLine,\n renderRange.totalLines,\n // If we aren't using a windowed render, then we need to render\n // everything\n isDefaultRenderRange(renderRange)\n ? true\n : expandUnchanged\n ? true\n : this.expandedHunks,\n collapsedContextThreshold\n );\n }\n this.renderCache.renderRange = renderRange;\n }\n\n // Should we kick off an async highlight process\n if (\n !forcePlainText &&\n hasContent &&\n (!this.renderCache.highlighted || forceHighlight)\n ) {\n this.workerManager.highlightDiffAST(this, diff);\n }\n } else {\n this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);\n const hasThemes =\n this.highlighter != null && areThemesAttached(options.theme);\n const hasLangs =\n this.highlighter != null && areLanguagesAttached(this.computedLang);\n const canHighlight = !forcePlainText && hasLangs;\n\n // If we have any semblance of a highlighter with the correct theme(s)\n // attached, we can kick off some form of rendering. If we don't have\n // the correct language, then we can render plain text and after kick off\n // an async job to get the highlighted AST\n if (\n this.highlighter != null &&\n hasThemes &&\n (forceHighlight ||\n forcePlainText ||\n (!this.renderCache.highlighted && canHighlight) ||\n this.renderCache.result == null)\n ) {\n const { result, options } = this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n forcePlainText || !hasLangs\n );\n this.renderCache = {\n diff,\n options,\n highlighted: canHighlight,\n result,\n renderRange: undefined,\n };\n }\n\n // If we get in here it means we'll have to kick off an async highlight\n // process which will involve initializing the highlighter with new themes\n // and languages\n if (!hasThemes || (!forcePlainText && !hasLangs)) {\n void this.asyncHighlight(diff).then(({ result, options }) => {\n // In this case we need to force a re-render, so we can do that by\n // reaching into renderCache\n if (this.renderCache != null) {\n this.renderCache.highlighted = false;\n }\n this.applyHighlightResult(diff, result, options, !forcePlainText);\n });\n }\n }\n return this.renderCache.result != null\n ? this.processDiffResult(\n this.renderCache.diff,\n renderRange,\n this.renderCache.result\n )\n : undefined;\n }\n\n public async asyncRender(\n diff: FileDiffMetadata,\n renderRange: RenderRange = DEFAULT_RENDER_RANGE\n ): Promise<HunksRenderResult> {\n const { result } = await this.asyncHighlight(diff);\n return this.processDiffResult(diff, renderRange, result);\n }\n\n protected createPreElement(\n split: boolean,\n totalLines: number,\n customProperties?: CustomPreProperties\n ): HASTElement {\n const { diffIndicators, disableBackground, disableLineNumbers, overflow } =\n this.getOptionsWithDefaults();\n return createPreElement({\n type: 'diff',\n diffIndicators,\n disableBackground,\n disableLineNumbers,\n overflow,\n split,\n totalLines,\n customProperties,\n });\n }\n\n private async asyncHighlight(\n diff: FileDiffMetadata\n ): Promise<RenderDiffResult> {\n const forcePlainText = isDiffMassive(diff, this.getTokenizeMaxLength());\n this.computedLang = forcePlainText\n ? 'text'\n : (diff.lang ?? getFiletypeFromFileName(diff.name));\n const hasThemes =\n this.highlighter != null &&\n areThemesAttached(this.getLocalHighlightTheme());\n const hasLangs =\n forcePlainText ||\n (this.highlighter != null && areLanguagesAttached(this.computedLang));\n // If we don't have the required langs or themes, then we need to\n // initialize the highlighter to load the appropriate languages and themes\n if (this.highlighter == null || !hasThemes || !hasLangs) {\n this.highlighter = await this.initializeHighlighter();\n }\n return this.renderDiffWithHighlighter(\n diff,\n this.highlighter,\n forcePlainText\n );\n }\n\n private renderDiffWithHighlighter(\n diff: FileDiffMetadata,\n highlighter: DiffsHighlighter,\n forcePlainText = false\n ): RenderDiffResult {\n const { options } = this.getRenderOptions(diff);\n const { collapsedContextThreshold } = this.getOptionsWithDefaults();\n const result = renderDiffWithHighlighter(diff, highlighter, options, {\n forcePlainText,\n expandedHunks: forcePlainText ? true : undefined,\n collapsedContextThreshold,\n });\n return { result, options };\n }\n\n public onHighlightSuccess(\n diff: FileDiffMetadata,\n result: ThemedDiffResult,\n options: RenderDiffOptions,\n highlighted = true\n ): void {\n if (this.editSessionActive) {\n return;\n }\n this.applyHighlightResult(diff, result, options, highlighted);\n }\n\n private applyHighlightResult(\n diff: FileDiffMetadata,\n result: ThemedDiffResult,\n options: RenderDiffOptions,\n highlighted = true\n ): void {\n // NOTE(amadeus): This is a bad assumption, and I should figure out\n // something better... If renderCache was blown away, we can assume we've\n // run cleanUp()\n if (this.renderCache == null) {\n return;\n }\n\n const triggerRenderUpdate =\n this.renderCache.highlightPending === true ||\n !this.renderCache.highlighted ||\n !areDiffRenderOptionsEqual(this.renderCache.options, options) ||\n !areDiffTargetsEqual(this.renderCache.diff, diff);\n\n this.renderCache = {\n diff,\n options,\n highlighted,\n result,\n renderRange: undefined,\n };\n if (triggerRenderUpdate) {\n this.onRenderUpdate?.();\n }\n }\n\n private getMatchingWorkerResultCache(\n diff: FileDiffMetadata,\n options: RenderDiffOptions\n ): RenderDiffResult | undefined {\n if (this.editSessionActive) {\n return undefined;\n }\n const cache = this.workerManager?.getDiffResultCache(diff);\n if (cache == null || !areDiffRenderOptionsEqual(options, cache.options)) {\n return undefined;\n }\n return cache;\n }\n\n private hasHighlightedRenderCache(\n diff: FileDiffMetadata,\n options: RenderDiffOptions\n ): boolean {\n const { renderCache } = this;\n return (\n renderCache?.result != null &&\n renderCache.highlighted &&\n areDiffTargetsEqual(diff, renderCache.diff) &&\n areDiffRenderOptionsEqual(options, renderCache.options)\n );\n }\n\n public onHighlightError(error: unknown): void {\n console.error(error);\n }\n\n private getTokenizeMaxLength(): number {\n return this.options.tokenizeMaxLength ?? DEFAULT_TOKENIZE_MAX_LENGTH;\n }\n\n private processDiffResult(\n fileDiff: FileDiffMetadata,\n renderRange: RenderRange,\n { code, themeStyles, baseThemeType }: ThemedDiffResult\n ): HunksRenderResult {\n const {\n diffStyle,\n disableFileHeader,\n expandUnchanged,\n expansionLineCount,\n collapsedContextThreshold,\n hunkSeparators,\n } = this.getOptionsWithDefaults();\n const isRenderCacheDirty = this.renderCache?.isDirty ?? false;\n\n this.diff = fileDiff;\n const unified = diffStyle === 'unified';\n const canHydrateContext = canHydrateCollapsedContext(\n fileDiff,\n this.options.loadDiffFiles != null\n );\n const isExpandableDiff = !fileDiff.isPartial || canHydrateContext;\n\n let additionsContentAST: ElementContent[] | undefined = [];\n let deletionsContentAST: ElementContent[] | undefined = [];\n let unifiedContentAST: ElementContent[] | undefined = [];\n\n const hunkData: HunkData[] = [];\n const { additionLines, deletionLines } = code;\n const context: ProcessContext = {\n rowCount: 0,\n hunkSeparators,\n additionsContentAST,\n deletionsContentAST,\n unifiedContentAST,\n unifiedGutterAST: createGutterWrapper(),\n deletionsGutterAST: createGutterWrapper(),\n additionsGutterAST: createGutterWrapper(),\n expansionLineCount,\n hunkData,\n incrementRowCount(count = 1) {\n context.rowCount += count;\n },\n pushToGutter(type: CodeColumnType, element: HASTElement) {\n switch (type) {\n case 'unified': {\n context.unifiedGutterAST.children.push(element);\n break;\n }\n case 'deletions': {\n context.deletionsGutterAST.children.push(element);\n break;\n }\n case 'additions': {\n context.additionsGutterAST.children.push(element);\n break;\n }\n }\n },\n };\n const trailingRangeSize = getTrailingContextRangeSize({\n fileDiff,\n errorPrefix: 'DiffHunksRenderer.processDiffResult',\n });\n const pendingSplitContext: PendingSplitContext = {\n size: 0,\n side: undefined,\n increment() {\n this.size += 1;\n },\n flush() {\n if (diffStyle === 'unified') {\n return;\n }\n if (this.size <= 0 || this.side == null) {\n this.side = undefined;\n this.size = 0;\n return;\n }\n if (this.side === 'additions') {\n context.pushToGutter(\n 'additions',\n createGutterGap(undefined, 'buffer', this.size)\n );\n additionsContentAST?.push(createEmptyRowBuffer(this.size));\n } else {\n context.pushToGutter(\n 'deletions',\n createGutterGap(undefined, 'buffer', this.size)\n );\n deletionsContentAST?.push(createEmptyRowBuffer(this.size));\n }\n this.size = 0;\n this.side = undefined;\n },\n };\n\n const pushGutterLineNumber = (\n type: CodeColumnType,\n lineType: LineTypes | 'buffer' | 'separator' | 'annotation',\n lineNumber: number,\n lineIndex: string,\n gutterProperties: Properties | undefined\n ) => {\n context.pushToGutter(\n type,\n createGutterItem(lineType, lineNumber, lineIndex, gutterProperties)\n );\n };\n\n function pushSeparators(props: PushSeparatorProps) {\n pendingSplitContext.flush();\n if (diffStyle === 'unified') {\n pushSeparator('unified', props, context);\n } else {\n pushSeparator('deletions', props, context);\n pushSeparator('additions', props, context);\n }\n }\n\n this.pushFileLevelAnnotations(fileDiff, diffStyle, renderRange, context);\n\n iterateOverDiff({\n diff: fileDiff,\n diffStyle,\n startingLine: renderRange.startingLine,\n totalLines: renderRange.totalLines,\n expandedHunks: expandUnchanged ? true : this.expandedHunks,\n collapsedContextThreshold,\n callback: ({\n hunkIndex,\n hunk,\n collapsedBefore,\n collapsedAfter,\n additionLine,\n deletionLine,\n type,\n }) => {\n const splitLineIndex =\n deletionLine != null\n ? deletionLine.splitLineIndex\n : additionLine.splitLineIndex;\n const unifiedLineIndex =\n additionLine != null\n ? additionLine.unifiedLineIndex\n : deletionLine.unifiedLineIndex;\n\n if (diffStyle === 'split' && type !== 'change') {\n pendingSplitContext.flush();\n }\n\n if (collapsedBefore > 0) {\n pushSeparators({\n hunkIndex,\n collapsedLines: collapsedBefore,\n rangeSize: Math.max(hunk?.collapsedBefore ?? 0, 0),\n hunkSpecs: hunk?.hunkSpecs,\n isFirstHunk: hunkIndex === 0,\n isLastHunk: false,\n isExpandable: isExpandableDiff,\n });\n }\n\n const lineIndex =\n diffStyle === 'unified' ? unifiedLineIndex : splitLineIndex;\n const renderedLineContext: RenderedLineContext = {\n type,\n hunkIndex,\n lineIndex,\n unifiedLineIndex,\n splitLineIndex,\n deletionLine,\n additionLine,\n };\n\n if (diffStyle === 'unified') {\n const injectedRows =\n this.getUnifiedInjectedRowsForLine?.(renderedLineContext);\n if (injectedRows?.before != null) {\n pushUnifiedInjectedRows(injectedRows.before, context);\n }\n let deletionLineContent =\n deletionLine != null\n ? deletionLines[deletionLine.lineIndex]\n : undefined;\n let additionLineContent =\n additionLine != null\n ? additionLines[additionLine.lineIndex]\n : undefined;\n if (deletionLineContent == null && additionLineContent == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n const lineType =\n type === 'change'\n ? additionLine != null\n ? 'change-addition'\n : 'change-deletion'\n : type;\n const lineDecoration = this.getUnifiedLineDecoration({\n // NOTE: This function gets extended so don't remove\n // these extra props\n type,\n lineType,\n additionLineIndex: additionLine?.lineIndex,\n deletionLineIndex: deletionLine?.lineIndex,\n });\n pushGutterLineNumber(\n 'unified',\n lineDecoration.gutterLineType,\n additionLine != null\n ? additionLine.lineNumber\n : deletionLine.lineNumber,\n `${unifiedLineIndex},${splitLineIndex}`,\n lineDecoration.gutterProperties\n );\n if (additionLineContent != null) {\n additionLineContent = withContentProperties(\n additionLineContent,\n lineDecoration.contentProperties,\n isRenderCacheDirty && additionLine != null\n ? {\n 'data-line': additionLine.lineNumber,\n 'data-line-index': `${unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n } else if (deletionLineContent != null) {\n deletionLineContent = withContentProperties(\n deletionLineContent,\n lineDecoration.contentProperties,\n isRenderCacheDirty && deletionLine != null\n ? {\n 'data-line': deletionLine.lineNumber,\n 'data-line-index': `${unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n }\n pushLineWithAnnotation({\n diffStyle: 'unified',\n type: type,\n deletionLine: deletionLineContent,\n additionLine: additionLineContent,\n unifiedSpan: this.getAnnotations(\n 'unified',\n deletionLine?.lineNumber,\n additionLine?.lineNumber,\n hunkIndex,\n lineIndex\n ),\n createAnnotationElement: (span) =>\n this.createAnnotationElement(span),\n context,\n });\n if (injectedRows?.after != null) {\n pushUnifiedInjectedRows(injectedRows.after, context);\n }\n } else {\n const injectedRows =\n this.getSplitInjectedRowsForLine?.(renderedLineContext);\n if (injectedRows?.before != null) {\n pushSplitInjectedRows(\n injectedRows.before,\n context,\n pendingSplitContext\n );\n }\n\n let deletionLineContent =\n deletionLine != null\n ? deletionLines[deletionLine.lineIndex]\n : undefined;\n let additionLineContent =\n additionLine != null\n ? additionLines[additionLine.lineIndex]\n : undefined;\n const deletionLineDecoration = this.getSplitLineDecoration({\n side: 'deletions',\n type,\n lineIndex: deletionLine?.lineIndex,\n });\n const additionLineDecoration = this.getSplitLineDecoration({\n side: 'additions',\n type,\n lineIndex: additionLine?.lineIndex,\n });\n\n if (deletionLineContent == null && additionLineContent == null) {\n const errorMessage =\n 'DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong';\n console.error(errorMessage, { file: fileDiff.name });\n throw new Error(errorMessage);\n }\n\n const missingSide = (() => {\n if (type === 'change') {\n if (additionLineContent == null) {\n return 'additions';\n } else if (deletionLineContent == null) {\n return 'deletions';\n }\n }\n return undefined;\n })();\n if (missingSide != null) {\n if (\n pendingSplitContext.side != null &&\n pendingSplitContext.side !== missingSide\n ) {\n pendingSplitContext.flush();\n }\n pendingSplitContext.side = missingSide;\n pendingSplitContext.increment();\n } else if (type === 'change') {\n // A change row with both sides fills the column a pending\n // one-sided buffer was holding open (an insert/delete block\n // directly followed by a paired block, from similarity\n // realignment); flush first so the buffer lands above this row.\n pendingSplitContext.flush();\n }\n\n const annotationSpans = this.getAnnotations(\n 'split',\n deletionLine?.lineNumber,\n additionLine?.lineNumber,\n hunkIndex,\n lineIndex\n );\n if (annotationSpans != null && pendingSplitContext.size > 0) {\n pendingSplitContext.flush();\n }\n\n if (deletionLine != null) {\n const deletionLineDecorated = withContentProperties(\n deletionLineContent,\n deletionLineDecoration.contentProperties,\n isRenderCacheDirty\n ? {\n 'data-line': deletionLine.lineNumber,\n 'data-line-index': `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n pushGutterLineNumber(\n 'deletions',\n deletionLineDecoration.gutterLineType,\n deletionLine.lineNumber,\n `${deletionLine.unifiedLineIndex},${splitLineIndex}`,\n deletionLineDecoration.gutterProperties\n );\n if (deletionLineDecorated != null) {\n deletionLineContent = deletionLineDecorated;\n }\n }\n if (additionLine != null) {\n const additionLineDecorated = withContentProperties(\n additionLineContent,\n additionLineDecoration.contentProperties,\n isRenderCacheDirty\n ? {\n 'data-line': additionLine.lineNumber,\n 'data-line-index': `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n }\n : undefined\n );\n pushGutterLineNumber(\n 'additions',\n additionLineDecoration.gutterLineType,\n additionLine.lineNumber,\n `${additionLine.unifiedLineIndex},${splitLineIndex}`,\n additionLineDecoration.gutterProperties\n );\n if (additionLineDecorated != null) {\n additionLineContent = additionLineDecorated;\n }\n }\n pushLineWithAnnotation({\n diffStyle: 'split',\n type: type,\n additionLine: additionLineContent,\n deletionLine: deletionLineContent,\n ...annotationSpans,\n createAnnotationElement: (span) =>\n this.createAnnotationElement(span),\n context,\n });\n if (injectedRows?.after != null) {\n pushSplitInjectedRows(\n injectedRows.after,\n context,\n pendingSplitContext\n );\n }\n }\n\n const isFinalSplitHunkRow =\n diffStyle === 'split' &&\n hunk != null &&\n splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1;\n const isFinalHunkRow =\n hunkIndex === fileDiff.hunks.length - 1 &&\n hunk != null &&\n (diffStyle === 'split'\n ? splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1\n : unifiedLineIndex ===\n hunk.unifiedLineStart + hunk.unifiedLineCount - 1);\n const splitNoEOFCRDeletion = isFinalSplitHunkRow\n ? hunk.noEOFCRDeletions\n : false;\n const splitNoEOFCRAddition = isFinalSplitHunkRow\n ? hunk.noEOFCRAdditions\n : false;\n const noEOFCRDeletion =\n (deletionLine?.noEOFCR ?? false) || splitNoEOFCRDeletion;\n const noEOFCRAddition =\n (additionLine?.noEOFCR ?? false) || splitNoEOFCRAddition;\n if (noEOFCRAddition || noEOFCRDeletion) {\n if (diffStyle === 'split') {\n pendingSplitContext.flush();\n }\n if (noEOFCRDeletion) {\n const noEOFType =\n type === 'context' || type === 'context-expanded'\n ? type\n : 'change-deletion';\n if (diffStyle === 'unified') {\n context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n context.pushToGutter(\n 'unified',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n } else {\n context.deletionsContentAST.push(\n createNoNewlineElement(noEOFType)\n );\n context.pushToGutter(\n 'deletions',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n if (!noEOFCRAddition) {\n context.pushToGutter(\n 'additions',\n createGutterGap(undefined, 'buffer', 1)\n );\n context.additionsContentAST.push(createEmptyRowBuffer(1));\n }\n }\n }\n if (noEOFCRAddition) {\n const noEOFType =\n type === 'context' || type === 'context-expanded'\n ? type\n : 'change-addition';\n if (diffStyle === 'unified') {\n context.unifiedContentAST.push(createNoNewlineElement(noEOFType));\n context.pushToGutter(\n 'unified',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n } else {\n context.additionsContentAST.push(\n createNoNewlineElement(noEOFType)\n );\n context.pushToGutter(\n 'additions',\n createGutterGap(noEOFType, 'metadata', 1)\n );\n if (!noEOFCRDeletion) {\n context.pushToGutter(\n 'deletions',\n createGutterGap(undefined, 'buffer', 1)\n );\n context.deletionsContentAST.push(createEmptyRowBuffer(1));\n }\n }\n }\n context.incrementRowCount(1);\n }\n\n if (\n hunkSeparators !== 'simple' &&\n hunkSeparators !== 'metadata' &&\n (collapsedAfter > 0 || (isFinalHunkRow && canHydrateContext))\n ) {\n pushSeparators({\n hunkIndex: type === 'context-expanded' ? hunkIndex : hunkIndex + 1,\n collapsedLines:\n isFinalHunkRow && canHydrateContext ? 'unknown' : collapsedAfter,\n rangeSize: trailingRangeSize,\n hunkSpecs: undefined,\n isFirstHunk: false,\n isLastHunk: true,\n isExpandable: isExpandableDiff,\n });\n }\n context.incrementRowCount(1);\n },\n });\n\n if (diffStyle === 'split') {\n pendingSplitContext.flush();\n }\n\n const totalLines = Math.max(\n getTotalLineCountFromHunks(fileDiff.hunks),\n fileDiff.additionLines.length ?? 0,\n fileDiff.deletionLines.length ?? 0\n );\n\n const hasBuffer =\n renderRange.bufferBefore > 0 || renderRange.bufferAfter > 0;\n // Determine which ASTs to include based on diff style and file type\n const shouldIncludeAdditions = !unified && fileDiff.type !== 'deleted';\n const shouldIncludeDeletions = !unified && fileDiff.type !== 'new';\n const hasContent = context.rowCount > 0 || hasBuffer;\n\n additionsContentAST =\n shouldIncludeAdditions && hasContent ? additionsContentAST : undefined;\n deletionsContentAST =\n shouldIncludeDeletions && hasContent ? deletionsContentAST : undefined;\n unifiedContentAST = unified && hasContent ? unifiedContentAST : undefined;\n\n const preNode = this.createPreElement(\n deletionsContentAST != null && additionsContentAST != null,\n totalLines\n );\n\n return {\n unifiedGutterAST:\n unified && hasContent ? context.unifiedGutterAST.children : undefined,\n unifiedContentAST,\n deletionsGutterAST:\n shouldIncludeDeletions && hasContent\n ? context.deletionsGutterAST.children\n : undefined,\n deletionsContentAST,\n additionsGutterAST:\n shouldIncludeAdditions && hasContent\n ? context.additionsGutterAST.children\n : undefined,\n additionsContentAST,\n hunkData,\n preNode,\n themeStyles,\n baseThemeType,\n headerElement: !disableFileHeader\n ? this.renderHeader(this.diff)\n : undefined,\n totalLines,\n rowCount: context.rowCount,\n bufferBefore: renderRange.bufferBefore,\n bufferAfter: renderRange.bufferAfter,\n // FIXME\n css: '',\n };\n }\n\n public renderCodeAST(\n type: 'unified' | 'deletions' | 'additions',\n result: HunksRenderResult\n ): ElementContent[] | undefined {\n const gutterAST =\n type === 'unified'\n ? result.unifiedGutterAST\n : type === 'deletions'\n ? result.deletionsGutterAST\n : result.additionsGutterAST;\n\n const contentAST =\n type === 'unified'\n ? result.unifiedContentAST\n : type === 'deletions'\n ? result.deletionsContentAST\n : result.additionsContentAST;\n\n if (gutterAST == null || contentAST == null) {\n return undefined;\n }\n\n const gutter = createGutterWrapper(gutterAST);\n gutter.properties.style = `grid-row: span ${result.rowCount}`;\n const contentColumn = createContentColumn(contentAST, result.rowCount);\n return [gutter, contentColumn];\n }\n\n public renderFullAST(\n result: HunksRenderResult,\n children: ElementContent[] = []\n ): HASTElement {\n const containerSize =\n this.getOptionsWithDefaults().hunkSeparators === 'line-info';\n const unifiedAST = this.renderCodeAST('unified', result);\n if (unifiedAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: unifiedAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-unified': '',\n },\n })\n );\n return { ...result.preNode, children };\n }\n\n const deletionsAST = this.renderCodeAST('deletions', result);\n if (deletionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: deletionsAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-deletions': '',\n },\n })\n );\n }\n const additionsAST = this.renderCodeAST('additions', result);\n if (additionsAST != null) {\n children.push(\n createHastElement({\n tagName: 'code',\n children: additionsAST,\n properties: {\n 'data-code': '',\n 'data-container-size': containerSize ? '' : undefined,\n 'data-additions': '',\n },\n })\n );\n }\n return { ...result.preNode, children };\n }\n\n public renderFullHTML(\n result: HunksRenderResult,\n tempChildren: ElementContent[] = []\n ): string {\n return toHtml(this.renderFullAST(result, tempChildren));\n }\n\n public renderPartialHTML(\n children: ElementContent[],\n columnType?: 'unified' | 'deletions' | 'additions'\n ): string {\n if (columnType == null) {\n return toHtml(children);\n }\n return toHtml(\n createHastElement({\n tagName: 'code',\n children,\n properties: {\n 'data-code': '',\n 'data-container-size':\n this.getOptionsWithDefaults().hunkSeparators === 'line-info'\n ? ''\n : undefined,\n [`data-${columnType}`]: '',\n },\n })\n );\n }\n\n private pushFileLevelAnnotations(\n fileDiff: FileDiffMetadata,\n diffStyle: 'unified' | 'split',\n renderRange: RenderRange,\n context: ProcessContext\n ): void {\n if (!shouldRenderFileAnnotations(renderRange)) {\n return;\n }\n\n const deletionAnnotationNames =\n fileDiff.type !== 'new'\n ? getAnnotationNames(getFileAnnotations(this.deletionAnnotations))\n : [];\n const additionAnnotationNames =\n fileDiff.type !== 'deleted'\n ? getAnnotationNames(getFileAnnotations(this.additionAnnotations))\n : [];\n if (\n deletionAnnotationNames.length === 0 &&\n additionAnnotationNames.length === 0\n ) {\n return;\n }\n\n const hunkIndex = FILE_ANNOTATION_HUNK_INDEX;\n const lineIndex = FILE_ANNOTATION_LINE_INDEX;\n const { createAnnotationElement } = this;\n\n if (diffStyle === 'unified') {\n pushLineWithAnnotation({\n diffStyle,\n type: 'context',\n unifiedSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: deletionAnnotationNames.concat(additionAnnotationNames),\n },\n createAnnotationElement,\n context,\n });\n return;\n }\n\n pushLineWithAnnotation({\n diffStyle,\n type: 'context',\n deletionSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: deletionAnnotationNames,\n },\n additionSpan: {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: additionAnnotationNames,\n },\n createAnnotationElement,\n context,\n });\n }\n\n private getAnnotations(\n type: 'unified',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): AnnotationSpan | undefined;\n private getAnnotations(\n type: 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ): { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan } | undefined;\n private getAnnotations(\n type: 'unified' | 'split',\n deletionLineNumber: number | undefined,\n additionLineNumber: number | undefined,\n hunkIndex: number,\n lineIndex: number\n ):\n | AnnotationSpan\n | { deletionSpan: AnnotationSpan; additionSpan: AnnotationSpan }\n | undefined {\n const deletionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (deletionLineNumber != null) {\n for (const anno of this.deletionAnnotations[deletionLineNumber] ?? []) {\n deletionSpan.annotations.push(getLineAnnotationName(anno));\n }\n }\n const additionSpan: AnnotationSpan = {\n type: 'annotation',\n hunkIndex,\n lineIndex,\n annotations: [],\n };\n if (additionLineNumber != null) {\n for (const anno of this.additionAnnotations[additionLineNumber] ?? []) {\n (type === 'unified' ? deletionSpan : additionSpan).annotations.push(\n getLineAnnotationName(anno)\n );\n }\n }\n if (type === 'unified') {\n if (deletionSpan.annotations.length > 0) {\n return deletionSpan;\n }\n return undefined;\n }\n if (\n additionSpan.annotations.length === 0 &&\n deletionSpan.annotations.length === 0\n ) {\n return undefined;\n }\n return { deletionSpan, additionSpan };\n }\n\n private renderHeader(diff: FileDiffMetadata): HASTElement {\n const { headerRenderMode, stickyHeader } = this.getOptionsWithDefaults();\n return createFileHeaderElement({\n fileOrDiff: diff,\n mode: headerRenderMode,\n stickyHeader,\n });\n }\n}\n\nfunction getAnnotationNames<LAnnotation>(\n annotations: DiffLineAnnotation<LAnnotation>[] | undefined\n): string[] {\n return (\n annotations?.map((annotation) => getLineAnnotationName(annotation)) ?? []\n );\n}\n\n// Use the platform's English plural rules to pick \"line\" vs \"lines\" so a\n// count of 0 reads as \"0 unmodified lines\". en-US returns \"one\" only for 1.\nconst EN_PLURAL_RULES = new Intl.PluralRules('en-US');\n\nfunction getModifiedLinesString(lines: number) {\n const suffix = EN_PLURAL_RULES.select(lines) === 'one' ? '' : 's';\n return `${lines} unmodified line${suffix}`;\n}\n\nfunction pushUnifiedInjectedRows(\n rows: InjectedRow[],\n context: ProcessContext\n): void {\n for (const row of rows) {\n context.unifiedContentAST.push(row.content);\n context.pushToGutter('unified', row.gutter);\n context.incrementRowCount(1);\n }\n}\n\nfunction pushSplitInjectedRows(\n rows: SplitInjectedRow[],\n context: ProcessContext,\n pendingSplitContext: PendingSplitContext\n): void {\n for (const { deletion, addition } of rows) {\n if (deletion == null && addition == null) {\n continue;\n }\n const missingSide =\n deletion != null && addition != null\n ? undefined\n : deletion == null\n ? 'deletions'\n : 'additions';\n\n if (missingSide == null || pendingSplitContext.side !== missingSide) {\n pendingSplitContext.flush();\n }\n\n if (deletion != null) {\n context.deletionsContentAST.push(deletion.content);\n context.pushToGutter('deletions', deletion.gutter);\n }\n\n if (addition != null) {\n context.additionsContentAST.push(addition.content);\n context.pushToGutter('additions', addition.gutter);\n }\n\n if (missingSide != null) {\n pendingSplitContext.side = missingSide;\n pendingSplitContext.increment();\n }\n\n context.incrementRowCount(1);\n }\n}\n\nfunction pushLineWithAnnotation({\n diffStyle,\n type,\n deletionLine,\n additionLine,\n unifiedSpan,\n deletionSpan,\n additionSpan,\n createAnnotationElement,\n context,\n}: PushLineWithAnnotation) {\n let hasAnnotationRow = false;\n if (diffStyle === 'unified') {\n if (additionLine != null) {\n context.unifiedContentAST.push(additionLine);\n } else if (deletionLine != null) {\n context.unifiedContentAST.push(deletionLine);\n }\n if (unifiedSpan != null) {\n const lineType =\n type === 'change'\n ? deletionLine != null\n ? 'change-deletion'\n : 'change-addition'\n : type;\n context.unifiedContentAST.push(createAnnotationElement(unifiedSpan));\n context.pushToGutter(\n 'unified',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n } else if (diffStyle === 'split') {\n if (deletionLine != null) {\n context.deletionsContentAST.push(deletionLine);\n }\n if (additionLine != null) {\n context.additionsContentAST.push(additionLine);\n }\n if (deletionSpan != null) {\n const lineType =\n type === 'change'\n ? deletionLine != null\n ? 'change-deletion'\n : 'context'\n : type;\n context.deletionsContentAST.push(createAnnotationElement(deletionSpan));\n context.pushToGutter(\n 'deletions',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n if (additionSpan != null) {\n const lineType =\n type === 'change'\n ? additionLine != null\n ? 'change-addition'\n : 'context'\n : type;\n context.additionsContentAST.push(createAnnotationElement(additionSpan));\n context.pushToGutter(\n 'additions',\n createGutterGap(lineType, 'annotation', 1)\n );\n hasAnnotationRow = true;\n }\n }\n if (hasAnnotationRow) {\n context.incrementRowCount(1);\n }\n}\n\nfunction pushSeparator(\n type: 'additions' | 'deletions' | 'unified',\n {\n hunkIndex,\n collapsedLines,\n rangeSize,\n hunkSpecs,\n isFirstHunk,\n isLastHunk,\n isExpandable,\n }: PushSeparatorProps,\n context: ProcessContext\n) {\n if (typeof collapsedLines === 'number' && collapsedLines <= 0) {\n return;\n }\n const linesAST =\n type === 'unified'\n ? context.unifiedContentAST\n : type === 'deletions'\n ? context.deletionsContentAST\n : context.additionsContentAST;\n\n if (context.hunkSeparators === 'metadata') {\n if (hunkSpecs != null) {\n context.pushToGutter(\n type,\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n linesAST.push(\n createSeparator({\n type: 'metadata',\n content: hunkSpecs,\n isFirstHunk,\n isLastHunk,\n })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n }\n return;\n }\n if (context.hunkSeparators === 'simple') {\n if (hunkIndex > 0) {\n context.pushToGutter(\n type,\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n linesAST.push(\n createSeparator({ type: 'simple', isFirstHunk, isLastHunk: false })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n }\n return;\n }\n const slotName = getHunkSeparatorSlotName(type, hunkIndex);\n const chunked = rangeSize > context.expansionLineCount;\n const expandIndex = isExpandable ? hunkIndex : undefined;\n const content =\n typeof collapsedLines === 'number'\n ? getModifiedLinesString(collapsedLines)\n : 'More unchanged context may be available';\n context.pushToGutter(\n type,\n createSeparator({\n type: context.hunkSeparators,\n content,\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n linesAST.push(\n createSeparator({\n type: context.hunkSeparators,\n content,\n expandIndex,\n chunked,\n slotName,\n isFirstHunk,\n isLastHunk,\n })\n );\n if (type !== 'additions') {\n context.incrementRowCount(1);\n }\n context.hunkData.push({\n slotName,\n hunkIndex,\n lines: typeof collapsedLines === 'number' ? collapsedLines : 0,\n lineCountKnown: typeof collapsedLines === 'number',\n type,\n expandable: isExpandable\n ? { up: !isFirstHunk, down: !isLastHunk, chunked }\n : undefined,\n });\n}\n\nfunction withContentProperties(\n lineNode: ElementContent | undefined,\n contentProperties?: Properties,\n extendProperties?: Properties\n): ElementContent | undefined {\n if (\n lineNode == null ||\n lineNode.type !== 'element' ||\n (contentProperties == null && extendProperties == null)\n ) {\n return lineNode;\n }\n return {\n ...lineNode,\n properties: {\n ...lineNode.properties,\n ...contentProperties,\n ...extendProperties,\n },\n };\n}\n\n// Number of entries in a split-line array that hold document content. A\n// document ending in a line break is represented two ways during a session:\n// the parsed-diff shape (`splitFileContents`) has no entry for the empty line\n// that final break implies, while the editor-document shape\n// (`getEditorDocumentLines`) exposes it as a trailing `''` entry. Only that\n// representational tail is ever `''` — every other entry keeps its line break\n// or is the raw final line — so trimming it yields comparable content lines.\nfunction contentLineCount(lines: string[]): number {\n return lines.length > 0 && lines[lines.length - 1] === ''\n ? lines.length - 1\n : lines.length;\n}\n\n// Realigns the cached per-line addition HAST array with an edited document.\n// Cached entries are looked up by line index, so a line inserted or removed\n// mid-document must shift the surviving entries to their new indexes —\n// otherwise rows hidden during the edit (collapsed context) render another\n// line's stale tokens once they become visible. Entries outside the changed\n// window keep their highlighted content; entries inside it become plain-text\n// elements that the editor re-tokenizes on its next background pass.\n//\n// The bottom-up scan runs over content lines only: a session's first\n// line-count edit still has `previousLines` in the parsed-diff shape while\n// `nextLines` is editor-shaped, and comparing the raw tails would mismatch on\n// the representational trailing `''`, zero out the suffix, and plain-fill\n// every line below the tokenizer's render window.\nfunction realignAdditionHastLines(\n previousLines: string[],\n nextLines: string[],\n hastLines: ElementContent[],\n textDocument: DiffsTextDocument\n): ElementContent[] {\n const previousContentLength = contentLineCount(previousLines);\n const nextContentLength = contentLineCount(nextLines);\n const maxShared = Math.min(previousContentLength, nextContentLength);\n let prefix = 0;\n while (prefix < maxShared && previousLines[prefix] === nextLines[prefix]) {\n prefix++;\n }\n let suffix = 0;\n while (\n suffix < maxShared - prefix &&\n previousLines[previousContentLength - 1 - suffix] ===\n nextLines[nextContentLength - 1 - suffix]\n ) {\n suffix++;\n }\n\n const realigned: ElementContent[] = new Array(nextLines.length);\n for (let index = 0; index < prefix; index++) {\n realigned[index] = hastLines[index];\n }\n for (let offset = 0; offset < suffix; offset++) {\n realigned[nextContentLength - 1 - offset] =\n hastLines[previousContentLength - 1 - offset];\n }\n // A trailing empty entry present on both sides keeps its cached row.\n if (\n previousContentLength < previousLines.length &&\n nextContentLength < nextLines.length\n ) {\n realigned[nextLines.length - 1] = hastLines[previousLines.length - 1];\n }\n // Deferred tokenization can write entries past the previous line count;\n // those were produced with post-edit indexes and are already in place.\n for (let index = previousLines.length; index < nextLines.length; index++) {\n realigned[index] ??= hastLines[index];\n }\n for (let index = prefix; index < nextLines.length; index++) {\n realigned[index] ??= createPlainAdditionLineElement(index, textDocument);\n }\n return realigned;\n}\n\nfunction createPlainAdditionLineElement(\n lineIndex: number,\n textDocument: DiffsTextDocument\n): HASTElement {\n return {\n type: 'element',\n tagName: 'div',\n properties: {\n 'data-line': lineIndex + 1,\n 'data-line-index': `${lineIndex},${lineIndex}`,\n 'data-line-type': 'context',\n },\n children: [\n {\n type: 'element',\n tagName: 'span',\n properties: {\n 'data-char': 0,\n },\n children: [\n {\n type: 'text',\n value: textDocument.getLineText(lineIndex),\n },\n ],\n },\n ],\n };\n}\n\nfunction getEditorDocumentLines(\n textDocument: DiffsTextDocument,\n previousLines: string[]\n): string[] {\n const lines: string[] = [];\n const fallbackLineBreak = getFallbackLineBreak(previousLines);\n for (let line = 0; line < textDocument.lineCount; line++) {\n const lineText = textDocument.getLineText(line, true);\n lines.push(\n line < textDocument.lineCount - 1 && !hasLineBreakSuffix(lineText)\n ? lineText + fallbackLineBreak\n : lineText\n );\n }\n return lines;\n}\n\nfunction hasLineBreakSuffix(line: string): boolean {\n return line.endsWith('\\n') || line.endsWith('\\r');\n}\n\nfunction getFallbackLineBreak(lines: string[]): string {\n for (const line of lines) {\n if (line.endsWith('\\r\\n')) {\n return '\\r\\n';\n }\n if (line.endsWith('\\n')) {\n return '\\n';\n }\n if (line.endsWith('\\r')) {\n return '\\r';\n }\n }\n return '\\n';\n}\n\nfunction isDiffMassive(\n diff: FileDiffMetadata,\n tokenizeMaxLength: number\n): boolean {\n return (\n Math.max(diff.additionLines.length, diff.deletionLines.length) >\n tokenizeMaxLength\n );\n}\n\nfunction canHydrateCollapsedContext(\n fileDiff: FileDiffMetadata,\n hasFileLoader: boolean\n): boolean {\n return (\n fileDiff.isPartial &&\n hasFileLoader &&\n (fileDiff.type === 'change' || fileDiff.type === 'rename-changed')\n );\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pierre/diffs",
|
|
3
|
-
"version": "1.3.0-rc.
|
|
3
|
+
"version": "1.3.0-rc.4",
|
|
4
4
|
"license": "apache-2.0",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"hast-util-to-html": "9.0.5",
|
|
71
71
|
"lru_map": "0.4.1",
|
|
72
72
|
"shiki": "^3.0.0 || ^4.0.0",
|
|
73
|
-
"@pierre/
|
|
74
|
-
"@pierre/
|
|
73
|
+
"@pierre/theme": "2.0.0",
|
|
74
|
+
"@pierre/theming": "1.0.0"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@arethetypeswrong/core": "0.18.2",
|