@pierre/diffs 1.3.0-beta.9 → 1.3.0-rc.1

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.
Files changed (219) hide show
  1. package/dist/components/CodeView.d.ts +12 -12
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +49 -42
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts +7 -2
  6. package/dist/components/File.d.ts.map +1 -1
  7. package/dist/components/File.js +36 -8
  8. package/dist/components/File.js.map +1 -1
  9. package/dist/components/FileDiff.d.ts +34 -6
  10. package/dist/components/FileDiff.d.ts.map +1 -1
  11. package/dist/components/FileDiff.js +198 -17
  12. package/dist/components/FileDiff.js.map +1 -1
  13. package/dist/components/VirtualizedFile.d.ts +2 -1
  14. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  15. package/dist/components/VirtualizedFile.js +9 -5
  16. package/dist/components/VirtualizedFile.js.map +1 -1
  17. package/dist/components/VirtualizedFileDiff.d.ts +14 -0
  18. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  19. package/dist/components/VirtualizedFileDiff.js +61 -3
  20. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  21. package/dist/components/Virtualizer.d.ts +14 -2
  22. package/dist/components/Virtualizer.d.ts.map +1 -1
  23. package/dist/components/Virtualizer.js +27 -2
  24. package/dist/components/Virtualizer.js.map +1 -1
  25. package/dist/edit/index.d.ts +5 -0
  26. package/dist/edit/index.js +3 -0
  27. package/dist/editor/command.d.ts +1 -1
  28. package/dist/editor/command.d.ts.map +1 -1
  29. package/dist/editor/command.js +11 -0
  30. package/dist/editor/command.js.map +1 -1
  31. package/dist/editor/editStack.d.ts +6 -2
  32. package/dist/editor/editStack.d.ts.map +1 -1
  33. package/dist/editor/editStack.js +53 -12
  34. package/dist/editor/editStack.js.map +1 -1
  35. package/dist/editor/editor.d.ts +51 -23
  36. package/dist/editor/editor.d.ts.map +1 -1
  37. package/dist/editor/editor.js +978 -238
  38. package/dist/editor/editor.js.map +1 -1
  39. package/dist/editor/editor2.js +1 -1
  40. package/dist/editor/languages.d.ts +26 -0
  41. package/dist/editor/languages.d.ts.map +1 -0
  42. package/dist/editor/languages.js +363 -0
  43. package/dist/editor/languages.js.map +1 -0
  44. package/dist/editor/lineAnnotations.d.ts.map +1 -1
  45. package/dist/editor/lineAnnotations.js +25 -26
  46. package/dist/editor/lineAnnotations.js.map +1 -1
  47. package/dist/editor/marker.d.ts +5 -3
  48. package/dist/editor/marker.d.ts.map +1 -1
  49. package/dist/editor/marker.js +111 -91
  50. package/dist/editor/marker.js.map +1 -1
  51. package/dist/editor/matchBrackets.d.ts +3 -2
  52. package/dist/editor/matchBrackets.d.ts.map +1 -1
  53. package/dist/editor/matchBrackets.js +2 -10
  54. package/dist/editor/matchBrackets.js.map +1 -1
  55. package/dist/editor/pieceTable.d.ts +2 -1
  56. package/dist/editor/pieceTable.d.ts.map +1 -1
  57. package/dist/editor/pieceTable.js +103 -39
  58. package/dist/editor/pieceTable.js.map +1 -1
  59. package/dist/editor/platform.js +2 -0
  60. package/dist/editor/platform.js.map +1 -1
  61. package/dist/editor/popover.d.ts +25 -5
  62. package/dist/editor/popover.d.ts.map +1 -1
  63. package/dist/editor/popover.js +60 -14
  64. package/dist/editor/popover.js.map +1 -1
  65. package/dist/editor/searchPanel.d.ts.map +1 -1
  66. package/dist/editor/searchPanel.js +9 -2
  67. package/dist/editor/searchPanel.js.map +1 -1
  68. package/dist/editor/selection.d.ts +31 -11
  69. package/dist/editor/selection.d.ts.map +1 -1
  70. package/dist/editor/selection.js +198 -70
  71. package/dist/editor/selection.js.map +1 -1
  72. package/dist/editor/selectionAction.d.ts +4 -3
  73. package/dist/editor/selectionAction.d.ts.map +1 -1
  74. package/dist/editor/selectionAction.js +9 -5
  75. package/dist/editor/selectionAction.js.map +1 -1
  76. package/dist/editor/stateStorage.d.ts +15 -0
  77. package/dist/editor/stateStorage.d.ts.map +1 -0
  78. package/dist/editor/stateStorage.js +65 -0
  79. package/dist/editor/stateStorage.js.map +1 -0
  80. package/dist/editor/textDocument.d.ts +12 -77
  81. package/dist/editor/textDocument.d.ts.map +1 -1
  82. package/dist/editor/textDocument.js +76 -34
  83. package/dist/editor/textDocument.js.map +1 -1
  84. package/dist/editor/textMeasure.d.ts +7 -12
  85. package/dist/editor/textMeasure.d.ts.map +1 -1
  86. package/dist/editor/textMeasure.js +40 -32
  87. package/dist/editor/textMeasure.js.map +1 -1
  88. package/dist/editor/{tokenzier.d.ts → tokenizer.d.ts} +3 -3
  89. package/dist/editor/tokenizer.d.ts.map +1 -0
  90. package/dist/editor/{tokenzier.js → tokenizer.js} +91 -26
  91. package/dist/editor/tokenizer.js.map +1 -0
  92. package/dist/editor/utils.js +1 -1
  93. package/dist/editor/utils.js.map +1 -1
  94. package/dist/index.d.ts +4 -3
  95. package/dist/index.js +6 -5
  96. package/dist/managers/InteractionManager.d.ts +18 -7
  97. package/dist/managers/InteractionManager.d.ts.map +1 -1
  98. package/dist/managers/InteractionManager.js +154 -99
  99. package/dist/managers/InteractionManager.js.map +1 -1
  100. package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
  101. package/dist/managers/UniversalRenderingManager.js +1 -2
  102. package/dist/managers/UniversalRenderingManager.js.map +1 -1
  103. package/dist/react/CodeView.d.ts +13 -13
  104. package/dist/react/CodeView.d.ts.map +1 -1
  105. package/dist/react/CodeView.js +38 -29
  106. package/dist/react/CodeView.js.map +1 -1
  107. package/dist/react/EditContext.d.ts +20 -0
  108. package/dist/react/EditContext.d.ts.map +1 -0
  109. package/dist/react/EditContext.js +20 -0
  110. package/dist/react/EditContext.js.map +1 -0
  111. package/dist/react/File.d.ts +2 -1
  112. package/dist/react/File.d.ts.map +1 -1
  113. package/dist/react/File.js +3 -2
  114. package/dist/react/File.js.map +1 -1
  115. package/dist/react/FileDiff.d.ts +2 -2
  116. package/dist/react/FileDiff.d.ts.map +1 -1
  117. package/dist/react/FileDiff.js +3 -2
  118. package/dist/react/FileDiff.js.map +1 -1
  119. package/dist/react/MultiFileDiff.d.ts +2 -2
  120. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  121. package/dist/react/MultiFileDiff.js +3 -2
  122. package/dist/react/MultiFileDiff.js.map +1 -1
  123. package/dist/react/PatchDiff.d.ts +2 -2
  124. package/dist/react/PatchDiff.d.ts.map +1 -1
  125. package/dist/react/PatchDiff.js +3 -2
  126. package/dist/react/PatchDiff.js.map +1 -1
  127. package/dist/react/UnresolvedFile.d.ts +1 -1
  128. package/dist/react/UnresolvedFile.js.map +1 -1
  129. package/dist/react/index.d.ts +4 -4
  130. package/dist/react/index.js +3 -3
  131. package/dist/react/types.d.ts +9 -1
  132. package/dist/react/types.d.ts.map +1 -1
  133. package/dist/react/utils/useFileDiffInstance.d.ts +5 -3
  134. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  135. package/dist/react/utils/useFileDiffInstance.js +28 -27
  136. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  137. package/dist/react/utils/useFileInstance.d.ts +5 -3
  138. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  139. package/dist/react/utils/useFileInstance.js +29 -25
  140. package/dist/react/utils/useFileInstance.js.map +1 -1
  141. package/dist/react/utils/useUnresolvedFileInstance.js +3 -3
  142. package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
  143. package/dist/renderers/DiffHunksRenderer.d.ts +33 -1
  144. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  145. package/dist/renderers/DiffHunksRenderer.js +134 -21
  146. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  147. package/dist/renderers/FileRenderer.d.ts +2 -0
  148. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  149. package/dist/renderers/FileRenderer.js +33 -11
  150. package/dist/renderers/FileRenderer.js.map +1 -1
  151. package/dist/ssr/FileDiffReact.js +1 -1
  152. package/dist/ssr/index.d.ts +2 -2
  153. package/dist/ssr/preloadDiffs.js +1 -1
  154. package/dist/style.js +1 -1
  155. package/dist/types.d.ts +185 -42
  156. package/dist/types.d.ts.map +1 -1
  157. package/dist/utils/annotationHelpers.d.ts +20 -0
  158. package/dist/utils/annotationHelpers.d.ts.map +1 -0
  159. package/dist/utils/annotationHelpers.js +29 -0
  160. package/dist/utils/annotationHelpers.js.map +1 -0
  161. package/dist/utils/computeFileOffsets.d.ts.map +1 -1
  162. package/dist/utils/computeFileOffsets.js +34 -5
  163. package/dist/utils/computeFileOffsets.js.map +1 -1
  164. package/dist/utils/editSessionHunks.d.ts +66 -0
  165. package/dist/utils/editSessionHunks.d.ts.map +1 -0
  166. package/dist/utils/editSessionHunks.js +437 -0
  167. package/dist/utils/editSessionHunks.js.map +1 -0
  168. package/dist/utils/getHunkSideBoundaries.d.ts +7 -0
  169. package/dist/utils/getHunkSideBoundaries.d.ts.map +1 -0
  170. package/dist/utils/getHunkSideBoundaries.js +12 -0
  171. package/dist/utils/getHunkSideBoundaries.js.map +1 -0
  172. package/dist/utils/getTotalLineCountFromHunks.d.ts.map +1 -1
  173. package/dist/utils/getTotalLineCountFromHunks.js +2 -1
  174. package/dist/utils/getTotalLineCountFromHunks.js.map +1 -1
  175. package/dist/utils/hydratePartialDiff.d.ts.map +1 -1
  176. package/dist/utils/hydratePartialDiff.js +4 -3
  177. package/dist/utils/hydratePartialDiff.js.map +1 -1
  178. package/dist/utils/isGutterUtilityPath.d.ts +5 -0
  179. package/dist/utils/isGutterUtilityPath.d.ts.map +1 -0
  180. package/dist/utils/isGutterUtilityPath.js +12 -0
  181. package/dist/utils/isGutterUtilityPath.js.map +1 -0
  182. package/dist/utils/iterateOverDiff.d.ts.map +1 -1
  183. package/dist/utils/iterateOverDiff.js +17 -12
  184. package/dist/utils/iterateOverDiff.js.map +1 -1
  185. package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
  186. package/dist/utils/parseMergeConflictDiffFromFile.js +9 -6
  187. package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
  188. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  189. package/dist/utils/parsePatchFiles.js +6 -3
  190. package/dist/utils/parsePatchFiles.js.map +1 -1
  191. package/dist/utils/realignChangeContent.d.ts +33 -0
  192. package/dist/utils/realignChangeContent.d.ts.map +1 -0
  193. package/dist/utils/realignChangeContent.js +148 -0
  194. package/dist/utils/realignChangeContent.js.map +1 -0
  195. package/dist/utils/renderDiffWithHighlighter.js +1 -1
  196. package/dist/utils/resolveRegion.d.ts.map +1 -1
  197. package/dist/utils/resolveRegion.js +18 -2
  198. package/dist/utils/resolveRegion.js.map +1 -1
  199. package/dist/utils/updateDiffHunks.d.ts +8 -2
  200. package/dist/utils/updateDiffHunks.d.ts.map +1 -1
  201. package/dist/utils/updateDiffHunks.js +9 -7
  202. package/dist/utils/updateDiffHunks.js.map +1 -1
  203. package/dist/utils/virtualDiffLayout.d.ts +42 -2
  204. package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
  205. package/dist/utils/virtualDiffLayout.js +101 -7
  206. package/dist/utils/virtualDiffLayout.js.map +1 -1
  207. package/dist/worker/worker-portable.js +60 -20
  208. package/dist/worker/worker-portable.js.map +1 -1
  209. package/dist/worker/worker.js +61 -19
  210. package/dist/worker/worker.js.map +1 -1
  211. package/package.json +10 -7
  212. package/dist/editor/index.d.ts +0 -3
  213. package/dist/editor/index.js +0 -3
  214. package/dist/editor/tokenzier.d.ts.map +0 -1
  215. package/dist/editor/tokenzier.js.map +0 -1
  216. package/dist/react/EditorContext.d.ts +0 -15
  217. package/dist/react/EditorContext.d.ts.map +0 -1
  218. package/dist/react/EditorContext.js +0 -23
  219. package/dist/react/EditorContext.js.map +0 -1
@@ -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 { 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 { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer';\nimport {\n recomputeDiffHunksForEdit,\n recomputeEmptyDocumentDiff,\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 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 }\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\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 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 public updateRenderCache(\n dirtyLines: Map<number, Array<HighlightedToken>>,\n themeType: 'dark' | 'light'\n ): void {\n if (this.renderCache == null) {\n return;\n }\n const { result, diff } = this.renderCache;\n if (result == null) {\n return;\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 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 }\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: `--diffs-token-${themeType}:${fg};`,\n },\n children: [{ type: 'text', value: text }],\n };\n }),\n };\n }\n\n if (changedAdditionLines.length > 0) {\n Object.assign(\n diff,\n updateDiffHunks(\n diff,\n changedAdditionLines,\n this.options.parseDiffOptions\n )\n );\n }\n\n result.baseThemeType = themeType;\n this.renderCache.isDirty = true;\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\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 diff.additionLines = getEditorDocumentLines(\n textDocument,\n diff.additionLines\n );\n\n const newLength = diff.additionLines.length;\n const additionHastLines = result.code.additionLines;\n const prevLen = additionHastLines.length;\n if (newLength < prevLen) {\n additionHastLines.length = newLength;\n }\n for (let i = prevLen; i < newLength; i++) {\n additionHastLines[i] ??= createPlainAdditionLineElement(i, textDocument);\n }\n if (!diff.isPartial) {\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 (\n diff.additionLines.length <= 1 &&\n diff.additionLines.join('') === ''\n ) {\n Object.assign(\n diff,\n recomputeEmptyDocumentDiff(diff, this.options.parseDiffOptions)\n );\n additionHastLines[0] = createPlainAdditionLineElement(0, textDocument);\n } else {\n Object.assign(\n diff,\n recomputeDiffHunksForEdit(diff, this.options.parseDiffOptions)\n );\n }\n }\n\n this.renderCache.isDirty = 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, this.options)\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 (this.workerManager?.isWorkingPool() === true) {\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 getRenderOptions(diff: FileDiffMetadata): GetRenderOptionsReturn {\n const options: RenderDiffOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getDiffRenderOptions();\n }\n const { theme, tokenizeMaxLineLength, lineDiffType, maxLineDiffLength } =\n this.getOptionsWithDefaults();\n return {\n theme,\n useTokenTransformer: shouldUseTokenTransformer(this.options),\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 (this.workerManager?.isWorkingPool() === true) {\n if (\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.onHighlightSuccess(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.options.theme ?? DEFAULT_THEMES);\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 // 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.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 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 }\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\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 { shouldUseTokenTransformer } from '../utils/shouldUseTokenTransformer';\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.\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. Called on every editor attach,\n * including 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 * 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 (workerManager?.isWorkingPool() === true && diff.cacheKey != null) {\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, this.options)\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 (this.workerManager?.isWorkingPool() === true) {\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 getRenderOptions(diff: FileDiffMetadata): GetRenderOptionsReturn {\n const options: RenderDiffOptions = (() => {\n if (this.workerManager?.isWorkingPool() === true) {\n return this.workerManager.getDiffRenderOptions();\n }\n const { theme, tokenizeMaxLineLength, lineDiffType, maxLineDiffLength } =\n this.getOptionsWithDefaults();\n return {\n theme,\n useTokenTransformer: shouldUseTokenTransformer(this.options),\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 (this.workerManager?.isWorkingPool() === true) {\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.onHighlightSuccess(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.options.theme ?? DEFAULT_THEMES);\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 // 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 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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"}
@@ -36,6 +36,8 @@ declare class FileRenderer<LAnnotation = undefined> {
36
36
  cleanUp(): void;
37
37
  recycle(): void;
38
38
  private syncEditedContentsToFile;
39
+ hasUnkeyedFileContentsChanged(file: FileContents): boolean;
40
+ private invalidateChangedUnkeyedFile;
39
41
  clearRenderCache(): void;
40
42
  hydrate(file: FileContents): void;
41
43
  private getRenderOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"FileRenderer.d.ts","names":[],"sources":["../../src/renderers/FileRenderer.ts"],"mappings":";;;;UAsEiB,gBAAA;EACf,SAAA,EAAW,cAAA;EACX,UAAA,EAAY,cAAA;EACZ,MAAA,EAAQ,OAAA;EACR,SAAA,EAAW,OAAA;EACX,GAAA;EACA,UAAA;EACA,WAAA;EACA,aAAA;EACA,QAAA;EACA,YAAA;EACA,WAAA;AAAA;AAAA,UAQe,mBAAA,SAA4B,eAAe;EAC1D,gBAAA,GAAmB,oBAAA;AAAA;AAAA,cAKR,YAAA;EAWF,OAAA,EAAS,mBAAA;EAAA,QACR,cAAA;EAAA,QACA,aAAA;EAAA,SAZD,IAAA;EAAA,QAED,WAAA;EAAA,QACA,WAAA;EAAA,QACA,YAAA;EAAA,QACA,eAAA;EAAA,QACA,SAAA;EAAA,QACA,iBAAA;EAER,WAAA,CACS,OAAA,GAAS,mBAAA,EACR,cAAA,gCACA,aAAA,GAAgB,iBAAA;EASnB,UAAA,CAAW,OAAA,EAAS,mBAAA;EAIpB,YAAA,CAAa,OAAA,EAAS,OAAA,CAAQ,mBAAA;EAI9B,kBAAA,CACL,eAAA,EAAiB,cAAA,CAAe,WAAA;EAU3B,OAAA;EAMA,OAAA;EAAA,QAqBC,wBAAA;EAaD,gBAAA;EAcA,OAAA,CAAQ,IAAA,EAAM,YAAA;EAAA,QAgCb,gBAAA;EA0BD,oBAAA,CAAqB,IAAA,EAAM,YAAA;EAqB3B,YAAA,CAAa,IAAA,EAAM,YAAA;EAOnB,iBAAA,CACL,UAAA,EAAY,GAAA,SAAY,KAAA,CAAM,gBAAA,IAC9B,SAAA;EAmEK,mBAAA,CAAoB,YAAA,EAAc,iBAAA;EAuDlC,UAAA,CACL,IAAA,GAAM,YAAA,cACN,WAAA,GAAa,WAAA,GACZ,gBAAA;EA4HG,WAAA,CACJ,IAAA,EAAM,YAAA,EACN,WAAA,GAAa,WAAA,GACZ,OAAA,CAAQ,gBAAA;EAAA,QAKG,cAAA;EAAA,QA2BN,yBAAA;EAAA,QAYA,iBAAA;EAAA,QA8FA,YAAA;EASD,cAAA,CAAe,MAAA,EAAQ,gBAAA;EAIvB,aAAA,CACL,MAAA,EAAQ,gBAAA,EACR,QAAA,GAAU,cAAA,KACT,OAAA;EAWI,aAAA,CAAc,MAAA,EAAQ,gBAAA,GAAmB,cAAA;EAWzC,iBAAA,CACL,QAAA,EAAU,cAAA,IACV,eAAA;EAcW,qBAAA,IAAyB,OAAA,CAAQ,gBAAA;EAOvC,kBAAA,CACL,IAAA,EAAM,YAAA,EACN,MAAA,EAAQ,gBAAA,EACR,OAAA,EAAS,iBAAA,EACT,WAAA;EAAA,QAuBM,4BAAA;EAAA,QAWA,yBAAA;EAaD,gBAAA,CAAiB,KAAA;EAAA,QAIhB,oBAAA;EAAA,QAIA,gBAAA;AAAA"}
1
+ {"version":3,"file":"FileRenderer.d.ts","names":[],"sources":["../../src/renderers/FileRenderer.ts"],"mappings":";;;;UAsEiB,gBAAA;EACf,SAAA,EAAW,cAAA;EACX,UAAA,EAAY,cAAA;EACZ,MAAA,EAAQ,OAAA;EACR,SAAA,EAAW,OAAA;EACX,GAAA;EACA,UAAA;EACA,WAAA;EACA,aAAA;EACA,QAAA;EACA,YAAA;EACA,WAAA;AAAA;AAAA,UAkBe,mBAAA,SAA4B,eAAe;EAC1D,gBAAA,GAAmB,oBAAA;AAAA;AAAA,cAKR,YAAA;EAWF,OAAA,EAAS,mBAAA;EAAA,QACR,cAAA;EAAA,QACA,aAAA;EAAA,SAZD,IAAA;EAAA,QAED,WAAA;EAAA,QACA,WAAA;EAAA,QACA,YAAA;EAAA,QACA,eAAA;EAAA,QACA,SAAA;EAAA,QACA,iBAAA;EAER,WAAA,CACS,OAAA,GAAS,mBAAA,EACR,cAAA,gCACA,aAAA,GAAgB,iBAAA;EASnB,UAAA,CAAW,OAAA,EAAS,mBAAA;EAIpB,YAAA,CAAa,OAAA,EAAS,OAAA,CAAQ,mBAAA;EAI9B,kBAAA,CACL,eAAA,EAAiB,cAAA,CAAe,WAAA;EAU3B,OAAA;EAMA,OAAA;EAAA,QAoBC,wBAAA;EAcD,6BAAA,CAA8B,IAAA,EAAM,YAAA;EAAA,QAUnC,4BAAA;EAQD,gBAAA;EAeA,OAAA,CAAQ,IAAA,EAAM,YAAA;EAAA,QAgCb,gBAAA;EA0BD,oBAAA,CAAqB,IAAA,EAAM,YAAA;EAiB3B,YAAA,CAAa,IAAA,EAAM,YAAA;EAKnB,iBAAA,CACL,UAAA,EAAY,GAAA,SAAY,KAAA,CAAM,gBAAA,IAC9B,SAAA;EAiEK,mBAAA,CAAoB,YAAA,EAAc,iBAAA;EAuDlC,UAAA,CACL,IAAA,GAAM,YAAA,cACN,WAAA,GAAa,WAAA,GACZ,gBAAA;EAqIG,WAAA,CACJ,IAAA,EAAM,YAAA,EACN,WAAA,GAAa,WAAA,GACZ,OAAA,CAAQ,gBAAA;EAAA,QAKG,cAAA;EAAA,QA2BN,yBAAA;EAAA,QAYA,iBAAA;EAAA,QA8FA,YAAA;EASD,cAAA,CAAe,MAAA,EAAQ,gBAAA;EAIvB,aAAA,CACL,MAAA,EAAQ,gBAAA,EACR,QAAA,GAAU,cAAA,KACT,OAAA;EAWI,aAAA,CAAc,MAAA,EAAQ,gBAAA,GAAmB,cAAA;EAWzC,iBAAA,CACL,QAAA,EAAU,cAAA,IACV,eAAA;EAcW,qBAAA,IAAyB,OAAA,CAAQ,gBAAA;EAOvC,kBAAA,CACL,IAAA,EAAM,YAAA,EACN,MAAA,EAAQ,gBAAA,EACR,OAAA,EAAS,iBAAA,EACT,WAAA;EAAA,QAuBM,4BAAA;EAAA,QAWA,yBAAA;EAaD,gBAAA,CAAiB,KAAA;EAAA,QAIhB,oBAAA;EAAA,QAIA,gBAAA;AAAA"}
@@ -23,6 +23,9 @@ import { renderFileWithHighlighter } from "../utils/renderFileWithHighlighter.js
23
23
  import { shouldUseTokenTransformer } from "../utils/shouldUseTokenTransformer.js";
24
24
  import { toHtml } from "hast-util-to-html";
25
25
  //#region src/renderers/FileRenderer.ts
26
+ function isLineCacheForFile(lineCache, file) {
27
+ return file.cacheKey == null ? lineCache.file === file && lineCache.sourceContents === file.contents : lineCache.cacheKey === file.cacheKey;
28
+ }
26
29
  let instanceId = -1;
27
30
  var FileRenderer = class {
28
31
  options;
@@ -64,7 +67,6 @@ var FileRenderer = class {
64
67
  this.onRenderUpdate = void 0;
65
68
  }
66
69
  recycle() {
67
- this.syncEditedContentsToFile();
68
70
  this.clearRenderCache();
69
71
  this.highlighter = void 0;
70
72
  this.workerManager?.cleanUpTasks(this);
@@ -73,10 +75,22 @@ var FileRenderer = class {
73
75
  }
74
76
  syncEditedContentsToFile() {
75
77
  const { renderCache, lineCache } = this;
76
- if (renderCache?.isDirty !== true || lineCache == null || renderCache.file.cacheKey == null || renderCache.file.cacheKey !== lineCache.cacheKey) return;
78
+ if (renderCache?.isDirty !== true || lineCache == null || !isLineCacheForFile(lineCache, renderCache.file)) return;
77
79
  renderCache.file.contents = lineCache.lines.join("");
78
80
  }
81
+ hasUnkeyedFileContentsChanged(file) {
82
+ const { lineCache } = this;
83
+ return file.cacheKey == null && lineCache != null && lineCache.file === file && lineCache.sourceContents !== file.contents;
84
+ }
85
+ invalidateChangedUnkeyedFile(file) {
86
+ if (!this.hasUnkeyedFileContentsChanged(file)) return;
87
+ this.workerManager?.cleanUpTasks(this);
88
+ this.clearRenderCache();
89
+ this.lineCache = void 0;
90
+ this.textDocumentCache = /* @__PURE__ */ new WeakMap();
91
+ }
79
92
  clearRenderCache() {
93
+ this.syncEditedContentsToFile();
80
94
  const renderCache = this.renderCache;
81
95
  this.renderCache = void 0;
82
96
  if (renderCache != null && renderCache.isDirty === true && renderCache.file.cacheKey != null) this.workerManager?.evictFileFromCache(renderCache.file.cacheKey);
@@ -125,26 +139,26 @@ var FileRenderer = class {
125
139
  };
126
140
  }
127
141
  getOrCreateLineCache(file) {
128
- if (file.cacheKey == null) {
129
- this.lineCache = void 0;
130
- return linesFromFileContents(file.contents);
131
- }
142
+ this.invalidateChangedUnkeyedFile(file);
132
143
  let { lineCache } = this;
133
- if (lineCache == null || lineCache.cacheKey !== file.cacheKey) lineCache = {
144
+ if (lineCache == null || !isLineCacheForFile(lineCache, file)) lineCache = {
134
145
  cacheKey: file.cacheKey,
146
+ file,
147
+ sourceContents: file.contents,
135
148
  lines: linesFromFileContents(file.contents)
136
149
  };
137
150
  this.lineCache = lineCache;
138
151
  return lineCache.lines;
139
152
  }
140
153
  getLineCount(file) {
141
- return this.textDocumentCache.get(file)?.lineCount ?? this.getOrCreateLineCache(file).length;
154
+ const lines = this.getOrCreateLineCache(file);
155
+ return this.textDocumentCache.get(file)?.lineCount ?? lines.length;
142
156
  }
143
157
  updateRenderCache(dirtyLines, themeType) {
144
158
  if (this.renderCache == null) return;
145
159
  const { file, result } = this.renderCache;
146
160
  if (result == null) return;
147
- const lineCache = this.lineCache != null && file.cacheKey != null && this.lineCache.cacheKey === file.cacheKey ? this.lineCache : void 0;
161
+ const lineCache = this.lineCache != null && isLineCacheForFile(this.lineCache, file) ? this.lineCache : void 0;
148
162
  for (const [line, tokens] of dirtyLines) {
149
163
  if (lineCache != null && line < lineCache.lines.length) {
150
164
  const lineText = tokens.map((token) => token[2]).join("");
@@ -176,7 +190,7 @@ var FileRenderer = class {
176
190
  tagName: "span",
177
191
  properties: {
178
192
  "data-char": char,
179
- style: `--diffs-token-${themeType}:${fg};`
193
+ style: `color:${fg};`
180
194
  },
181
195
  children: [{
182
196
  type: "text",
@@ -215,14 +229,22 @@ var FileRenderer = class {
215
229
  });
216
230
  this.renderCache.isDirty = true;
217
231
  }
218
- if (file.cacheKey != null) this.lineCache = {
232
+ this.lineCache = {
219
233
  cacheKey: file.cacheKey,
234
+ file,
235
+ sourceContents: file.contents,
220
236
  lines: linesFromFileContents(textDocument.getText())
221
237
  };
222
238
  this.textDocumentCache.set(file, textDocument);
223
239
  }
224
240
  renderFile(file = this.renderCache?.file, renderRange = DEFAULT_RENDER_RANGE) {
225
241
  if (file == null) return;
242
+ this.invalidateChangedUnkeyedFile(file);
243
+ if (this.renderCache?.isDirty === true && !areFilesEqual(file, this.renderCache.file)) {
244
+ this.clearRenderCache();
245
+ this.lineCache = void 0;
246
+ this.textDocumentCache = /* @__PURE__ */ new WeakMap();
247
+ }
226
248
  let { options, forceHighlight } = this.getRenderOptions(file);
227
249
  const cache = this.getMatchingWorkerResultCache(file, options);
228
250
  if (cache != null && !this.hasHighlightedRenderCache(file, options)) {