@pierre/diffs 1.3.6 → 1.4.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 (260) hide show
  1. package/dist/components/CodeView.d.ts +115 -68
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +189 -59
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts +79 -15
  6. package/dist/components/File.d.ts.map +1 -1
  7. package/dist/components/File.js +244 -66
  8. package/dist/components/File.js.map +1 -1
  9. package/dist/components/FileDiff.d.ts +101 -21
  10. package/dist/components/FileDiff.d.ts.map +1 -1
  11. package/dist/components/FileDiff.js +432 -102
  12. package/dist/components/FileDiff.js.map +1 -1
  13. package/dist/components/FileStream.js +1 -1
  14. package/dist/components/UnresolvedFile.d.ts +2 -2
  15. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  16. package/dist/components/UnresolvedFile.js +2 -2
  17. package/dist/components/UnresolvedFile.js.map +1 -1
  18. package/dist/components/VirtualizedFile.d.ts +17 -7
  19. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  20. package/dist/components/VirtualizedFile.js +142 -53
  21. package/dist/components/VirtualizedFile.js.map +1 -1
  22. package/dist/components/VirtualizedFileDiff.d.ts +15 -8
  23. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  24. package/dist/components/VirtualizedFileDiff.js +186 -96
  25. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  26. package/dist/components/VirtulizerDevelopment.d.ts +1 -1
  27. package/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
  28. package/dist/edit/index.d.ts +7 -4
  29. package/dist/edit/index.js +5 -1
  30. package/dist/editor/EditStateManager.d.ts +56 -0
  31. package/dist/editor/EditStateManager.d.ts.map +1 -0
  32. package/dist/editor/EditStateManager.js +135 -0
  33. package/dist/editor/EditStateManager.js.map +1 -0
  34. package/dist/editor/cloneRetainedDiffSessionSnapshot.d.ts +7 -0
  35. package/dist/editor/cloneRetainedDiffSessionSnapshot.d.ts.map +1 -0
  36. package/dist/editor/cloneRetainedDiffSessionSnapshot.js +16 -0
  37. package/dist/editor/cloneRetainedDiffSessionSnapshot.js.map +1 -0
  38. package/dist/editor/editPrediction.d.ts +76 -0
  39. package/dist/editor/editPrediction.d.ts.map +1 -0
  40. package/dist/editor/editPrediction.js +365 -0
  41. package/dist/editor/editPrediction.js.map +1 -0
  42. package/dist/editor/editStack.d.ts +19 -40
  43. package/dist/editor/editStack.d.ts.map +1 -1
  44. package/dist/editor/editStack.js +67 -4
  45. package/dist/editor/editStack.js.map +1 -1
  46. package/dist/editor/editor.d.ts +118 -29
  47. package/dist/editor/editor.d.ts.map +1 -1
  48. package/dist/editor/editor.js +1108 -384
  49. package/dist/editor/editor.js.map +1 -1
  50. package/dist/editor/editor2.js +1 -1
  51. package/dist/editor/languages.d.ts +3 -3
  52. package/dist/editor/languages.d.ts.map +1 -1
  53. package/dist/editor/languages.js.map +1 -1
  54. package/dist/editor/lineAnnotations.d.ts +3 -3
  55. package/dist/editor/lineAnnotations.d.ts.map +1 -1
  56. package/dist/editor/lineAnnotations.js +16 -7
  57. package/dist/editor/lineAnnotations.js.map +1 -1
  58. package/dist/editor/marker.d.ts +2 -2
  59. package/dist/editor/marker.d.ts.map +1 -1
  60. package/dist/editor/marker.js.map +1 -1
  61. package/dist/editor/matchBrackets.d.ts +2 -2
  62. package/dist/editor/matchBrackets.d.ts.map +1 -1
  63. package/dist/editor/matchBrackets.js.map +1 -1
  64. package/dist/editor/pieceTable.d.ts +1 -1
  65. package/dist/editor/pieceTable.js.map +1 -1
  66. package/dist/editor/searchPanel.d.ts +2 -2
  67. package/dist/editor/searchPanel.js +1 -1
  68. package/dist/editor/searchPanel.js.map +1 -1
  69. package/dist/editor/selection.d.ts +32 -23
  70. package/dist/editor/selection.d.ts.map +1 -1
  71. package/dist/editor/selection.js +3 -3
  72. package/dist/editor/selection.js.map +1 -1
  73. package/dist/editor/selectionAction.d.ts +3 -3
  74. package/dist/editor/selectionAction.d.ts.map +1 -1
  75. package/dist/editor/selectionAction.js.map +1 -1
  76. package/dist/editor/textDocument.d.ts +11 -8
  77. package/dist/editor/textDocument.d.ts.map +1 -1
  78. package/dist/editor/textDocument.js +28 -5
  79. package/dist/editor/textDocument.js.map +1 -1
  80. package/dist/editor/textDocumentChangeTransaction.d.ts +15 -0
  81. package/dist/editor/textDocumentChangeTransaction.d.ts.map +1 -0
  82. package/dist/editor/textDocumentChangeTransaction.js +12 -0
  83. package/dist/editor/textDocumentChangeTransaction.js.map +1 -0
  84. package/dist/editor/textMeasure.d.ts +5 -0
  85. package/dist/editor/textMeasure.d.ts.map +1 -1
  86. package/dist/editor/textMeasure.js +10 -0
  87. package/dist/editor/textMeasure.js.map +1 -1
  88. package/dist/editor/tokenizer.d.ts +1 -1
  89. package/dist/editor/tokenizer.js.map +1 -1
  90. package/dist/editor/types.d.ts +267 -0
  91. package/dist/editor/types.d.ts.map +1 -0
  92. package/dist/editor/types.js +0 -0
  93. package/dist/editor/utils.d.ts +2 -1
  94. package/dist/editor/utils.d.ts.map +1 -1
  95. package/dist/editor/utils.js +4 -1
  96. package/dist/editor/utils.js.map +1 -1
  97. package/dist/highlighter/shared_highlighter.d.ts +6 -2
  98. package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
  99. package/dist/highlighter/shared_highlighter.js +7 -3
  100. package/dist/highlighter/shared_highlighter.js.map +1 -1
  101. package/dist/highlighter/themes/areThemesAttached.js +1 -1
  102. package/dist/index.d.ts +8 -6
  103. package/dist/index.js +22 -21
  104. package/dist/managers/InteractionManager.d.ts.map +1 -1
  105. package/dist/managers/InteractionManager.js +7 -0
  106. package/dist/managers/InteractionManager.js.map +1 -1
  107. package/dist/react/CodeView.d.ts +36 -25
  108. package/dist/react/CodeView.d.ts.map +1 -1
  109. package/dist/react/CodeView.js +15 -14
  110. package/dist/react/CodeView.js.map +1 -1
  111. package/dist/react/EditContext.d.ts +8 -11
  112. package/dist/react/EditContext.d.ts.map +1 -1
  113. package/dist/react/EditContext.js +2 -9
  114. package/dist/react/EditContext.js.map +1 -1
  115. package/dist/react/File.d.ts +10 -6
  116. package/dist/react/File.d.ts.map +1 -1
  117. package/dist/react/File.js +8 -4
  118. package/dist/react/File.js.map +1 -1
  119. package/dist/react/FileDiff.d.ts +10 -5
  120. package/dist/react/FileDiff.d.ts.map +1 -1
  121. package/dist/react/FileDiff.js +8 -4
  122. package/dist/react/FileDiff.js.map +1 -1
  123. package/dist/react/MultiFileDiff.d.ts +8 -5
  124. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  125. package/dist/react/MultiFileDiff.js +8 -12
  126. package/dist/react/MultiFileDiff.js.map +1 -1
  127. package/dist/react/PatchDiff.d.ts +7 -4
  128. package/dist/react/PatchDiff.d.ts.map +1 -1
  129. package/dist/react/PatchDiff.js +8 -4
  130. package/dist/react/PatchDiff.js.map +1 -1
  131. package/dist/react/UnresolvedFile.d.ts +3 -3
  132. package/dist/react/UnresolvedFile.d.ts.map +1 -1
  133. package/dist/react/UnresolvedFile.js.map +1 -1
  134. package/dist/react/index.d.ts +8 -5
  135. package/dist/react/types.d.ts +46 -9
  136. package/dist/react/types.d.ts.map +1 -1
  137. package/dist/react/utils/renderDiffChildren.d.ts +14 -12
  138. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  139. package/dist/react/utils/renderDiffChildren.js +2 -2
  140. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  141. package/dist/react/utils/renderFileChildren.d.ts +14 -12
  142. package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
  143. package/dist/react/utils/renderFileChildren.js +2 -2
  144. package/dist/react/utils/renderFileChildren.js.map +1 -1
  145. package/dist/react/utils/useFileDiffInstance.d.ts +22 -10
  146. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  147. package/dist/react/utils/useFileDiffInstance.js +112 -22
  148. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  149. package/dist/react/utils/useFileInstance.d.ts +15 -9
  150. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  151. package/dist/react/utils/useFileInstance.js +84 -25
  152. package/dist/react/utils/useFileInstance.js.map +1 -1
  153. package/dist/renderers/DiffHunksRenderer.d.ts +30 -15
  154. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  155. package/dist/renderers/DiffHunksRenderer.js +172 -109
  156. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  157. package/dist/renderers/FileRenderer.d.ts +27 -11
  158. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  159. package/dist/renderers/FileRenderer.js +141 -67
  160. package/dist/renderers/FileRenderer.js.map +1 -1
  161. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts +2 -2
  162. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
  163. package/dist/renderers/UnresolvedFileHunksRenderer.js +2 -2
  164. package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
  165. package/dist/shiki-stream/tokenizer.d.ts.map +1 -1
  166. package/dist/shiki-stream/tokenizer.js +2 -1
  167. package/dist/shiki-stream/tokenizer.js.map +1 -1
  168. package/dist/ssr/index.d.ts +2 -2
  169. package/dist/ssr/preloadDiffs.d.ts +21 -21
  170. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  171. package/dist/ssr/preloadDiffs.js +1 -1
  172. package/dist/ssr/preloadDiffs.js.map +1 -1
  173. package/dist/ssr/preloadFile.d.ts +6 -6
  174. package/dist/ssr/preloadFile.d.ts.map +1 -1
  175. package/dist/ssr/preloadFile.js.map +1 -1
  176. package/dist/ssr/preloadPatchFile.d.ts +4 -4
  177. package/dist/ssr/preloadPatchFile.d.ts.map +1 -1
  178. package/dist/ssr/preloadPatchFile.js.map +1 -1
  179. package/dist/style.js +1 -1
  180. package/dist/types.d.ts +13 -263
  181. package/dist/types.d.ts.map +1 -1
  182. package/dist/utils/appendItems.d.ts +5 -0
  183. package/dist/utils/appendItems.d.ts.map +1 -0
  184. package/dist/utils/appendItems.js +8 -0
  185. package/dist/utils/appendItems.js.map +1 -0
  186. package/dist/utils/areDiffTargetsEqual.js +1 -1
  187. package/dist/utils/areDiffTargetsEqual.js.map +1 -1
  188. package/dist/utils/areFileTargetsEqual.d.ts +7 -0
  189. package/dist/utils/areFileTargetsEqual.d.ts.map +1 -0
  190. package/dist/utils/areFileTargetsEqual.js +8 -0
  191. package/dist/utils/areFileTargetsEqual.js.map +1 -0
  192. package/dist/utils/areManagedSnapshotsEqual.d.ts +1 -1
  193. package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
  194. package/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
  195. package/dist/utils/areOptionsEqual.d.ts +3 -3
  196. package/dist/utils/areOptionsEqual.d.ts.map +1 -1
  197. package/dist/utils/areOptionsEqual.js.map +1 -1
  198. package/dist/utils/cloneFileDiffMetadata.d.ts +3 -2
  199. package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -1
  200. package/dist/utils/cloneFileDiffMetadata.js +8 -5
  201. package/dist/utils/cloneFileDiffMetadata.js.map +1 -1
  202. package/dist/utils/composeCacheKey.d.ts +6 -0
  203. package/dist/utils/composeCacheKey.d.ts.map +1 -0
  204. package/dist/utils/composeCacheKey.js +10 -0
  205. package/dist/utils/composeCacheKey.js.map +1 -0
  206. package/dist/utils/editSessionAnnotations.d.ts +69 -0
  207. package/dist/utils/editSessionAnnotations.d.ts.map +1 -0
  208. package/dist/utils/editSessionAnnotations.js +64 -0
  209. package/dist/utils/editSessionAnnotations.js.map +1 -0
  210. package/dist/utils/editSessionHunks.d.ts +5 -3
  211. package/dist/utils/editSessionHunks.d.ts.map +1 -1
  212. package/dist/utils/editSessionHunks.js +7 -5
  213. package/dist/utils/editSessionHunks.js.map +1 -1
  214. package/dist/utils/getDiffHunksRendererOptions.d.ts +1 -1
  215. package/dist/utils/getDiffHunksRendererOptions.d.ts.map +1 -1
  216. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  217. package/dist/utils/getFileRendererOptions.d.ts +1 -1
  218. package/dist/utils/getFileRendererOptions.d.ts.map +1 -1
  219. package/dist/utils/getFileRendererOptions.js.map +1 -1
  220. package/dist/utils/hydratePartialDiff.d.ts.map +1 -1
  221. package/dist/utils/hydratePartialDiff.js +2 -1
  222. package/dist/utils/hydratePartialDiff.js.map +1 -1
  223. package/dist/utils/lineAnnotationIdentity.d.ts +16 -0
  224. package/dist/utils/lineAnnotationIdentity.d.ts.map +1 -0
  225. package/dist/utils/lineAnnotationIdentity.js +17 -0
  226. package/dist/utils/lineAnnotationIdentity.js.map +1 -0
  227. package/dist/utils/parseDiffFromFile.d.ts +2 -2
  228. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  229. package/dist/utils/parseDiffFromFile.js +6 -6
  230. package/dist/utils/parseDiffFromFile.js.map +1 -1
  231. package/dist/utils/parsePatchFiles.d.ts +6 -3
  232. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  233. package/dist/utils/parsePatchFiles.js +34 -9
  234. package/dist/utils/parsePatchFiles.js.map +1 -1
  235. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  236. package/dist/utils/renderDiffWithHighlighter.js +6 -5
  237. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  238. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  239. package/dist/utils/renderFileWithHighlighter.js +7 -4
  240. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  241. package/dist/utils/trimPatchContext.d.ts.map +1 -1
  242. package/dist/utils/trimPatchContext.js +3 -2
  243. package/dist/utils/trimPatchContext.js.map +1 -1
  244. package/dist/utils/updateDiffHunks.js +1 -1
  245. package/dist/utils/virtualDiffLayout.js +1 -1
  246. package/dist/worker/WorkerPoolManager.d.ts +4 -3
  247. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  248. package/dist/worker/WorkerPoolManager.js +44 -6
  249. package/dist/worker/WorkerPoolManager.js.map +1 -1
  250. package/dist/worker/types.d.ts +5 -0
  251. package/dist/worker/types.d.ts.map +1 -1
  252. package/dist/worker/worker-portable.js +14 -6
  253. package/dist/worker/worker-portable.js.map +1 -1
  254. package/dist/worker/worker.js +14 -6
  255. package/dist/worker/worker.js.map +1 -1
  256. package/package.json +9 -1
  257. package/dist/editor/stateStorage.d.ts +0 -15
  258. package/dist/editor/stateStorage.d.ts.map +0 -1
  259. package/dist/editor/stateStorage.js +0 -65
  260. package/dist/editor/stateStorage.js.map +0 -1
@@ -1,12 +1,13 @@
1
1
  import { DEFAULT_VIRTUAL_FILE_METRICS } from "../constants.js";
2
2
  import { areObjectsEqual } from "../utils/areObjectsEqual.js";
3
3
  import { areOptionsEqual } from "../utils/areOptionsEqual.js";
4
+ import { areFileTargetsEqual } from "../utils/areFileTargetsEqual.js";
4
5
  import { computeVirtualFileMetrics, getVirtualFileHeaderRegion, getVirtualFilePaddingBottom } from "../utils/computeVirtualFileMetrics.js";
5
- import { areFilesEqual } from "../utils/areFilesEqual.js";
6
6
  import { FILE_ANNOTATION_DOM_KEY, includesFileAnnotations, shouldRenderFileAnnotations } from "../utils/includesFileAnnotations.js";
7
7
  import { File } from "./File.js";
8
8
  //#region src/components/VirtualizedFile.ts
9
9
  const LAYOUT_CHECKPOINT_INTERVAL = 5e3;
10
+ const NO_GHOST_TEXT_ROWS = /* @__PURE__ */ new Map();
10
11
  let instanceId = -1;
11
12
  function hasFileLayoutOptionChanged(previousOptions, nextOptions) {
12
13
  return (previousOptions.overflow ?? "scroll") !== (nextOptions.overflow ?? "scroll") || (previousOptions.collapsed ?? false) !== (nextOptions.collapsed ?? false) || (previousOptions.disableLineNumbers ?? false) !== (nextOptions.disableLineNumbers ?? false) || (previousOptions.disableFileHeader ?? false) !== (nextOptions.disableFileHeader ?? false) || previousOptions.unsafeCSS !== nextOptions.unsafeCSS;
@@ -15,13 +16,16 @@ var VirtualizedFile = class extends File {
15
16
  virtualizer;
16
17
  metrics;
17
18
  __id = `virtualized-file:${++instanceId}`;
19
+ renderType = "virtualized";
18
20
  top;
19
21
  height = 0;
20
22
  cache = {
21
23
  heights: /* @__PURE__ */ new Map(),
22
24
  checkpoints: [],
23
- fileAnnotationHeight: 0
25
+ fileAnnotationHeight: 0,
26
+ ghostTextRows: NO_GHOST_TEXT_ROWS
24
27
  };
28
+ pendingRender;
25
29
  isVisible = false;
26
30
  isSetup = false;
27
31
  layoutDirty = true;
@@ -42,13 +46,24 @@ var VirtualizedFile = class extends File {
42
46
  if (this.syncLineAnnotations(lineAnnotations)) this.resetLayoutCache();
43
47
  }
44
48
  syncLineAnnotations(lineAnnotations) {
45
- if (lineAnnotations == null || lineAnnotations === this.lineAnnotations) return false;
46
- if (lineAnnotations.length === 0 && this.lineAnnotations.length === 0) return false;
49
+ if (lineAnnotations == null || !this.isNewAnnotations(lineAnnotations)) return false;
50
+ if (lineAnnotations.length === 0 && this.getLatestAnnotations().length === 0) return false;
47
51
  super.setLineAnnotations(lineAnnotations);
48
52
  return true;
49
53
  }
54
+ syncEditSessionAnnotationsFromEditor(lineAnnotations) {
55
+ if (super.syncEditSessionAnnotationsFromEditor(lineAnnotations)) {
56
+ this.resetLayoutCache();
57
+ return true;
58
+ }
59
+ return false;
60
+ }
50
61
  hasLineAnnotations() {
51
- return this.lineAnnotations.some((annotation) => annotation.lineNumber > 0);
62
+ return this.getLatestAnnotations().some((annotation) => annotation.lineNumber > 0);
63
+ }
64
+ hasUniformLineHeights() {
65
+ const { overflow = "scroll" } = this.options;
66
+ return overflow === "scroll" && !this.hasLineAnnotations() && this.cache.heights.size === 0;
52
67
  }
53
68
  getLineHeight(lineIndex, hasMetadataLine = false) {
54
69
  const cached = this.cache.heights.get(lineIndex);
@@ -76,23 +91,47 @@ var VirtualizedFile = class extends File {
76
91
  this.cache.fileAnnotationHeight = 0;
77
92
  if (this.cache.heights.size > 0) this.cache.heights.clear();
78
93
  if (this.cache.checkpoints.length > 0) this.cache.checkpoints.length = 0;
94
+ this.cache.ghostTextRows = NO_GHOST_TEXT_ROWS;
79
95
  if (this.renderRange != null && resetRenderRange) this.renderRange = void 0;
80
96
  if (recompute && this.isSimpleMode()) this.computeApproximateSize();
81
97
  }
98
+ applyGhostTextRows(ghostTextRows) {
99
+ const { heights, ghostTextRows: previous } = this.cache;
100
+ if (previous === ghostTextRows) return false;
101
+ const { lineHeight } = this.metrics;
102
+ let changed = false;
103
+ for (const lineIndex of /* @__PURE__ */ new Set([...previous.keys(), ...ghostTextRows.keys()])) {
104
+ const previousRows = previous.get(lineIndex) ?? 0;
105
+ const rows = ghostTextRows.get(lineIndex) ?? 0;
106
+ if (rows === previousRows) continue;
107
+ const height = (heights.get(lineIndex) ?? lineHeight) - previousRows * lineHeight + rows * lineHeight;
108
+ if (height === lineHeight) heights.delete(lineIndex);
109
+ else heights.set(lineIndex, height);
110
+ changed = true;
111
+ }
112
+ this.cache.ghostTextRows = ghostTextRows;
113
+ return changed;
114
+ }
82
115
  reconcileHeights() {
83
116
  let hasHeightChange = false;
84
- if (this.fileContainer == null || this.file == null) {
117
+ if (this.fileContainer == null || this.getLayoutFile() == null) {
85
118
  if (this.height !== 0) hasHeightChange = true;
86
119
  this.height = 0;
87
120
  return hasHeightChange;
88
121
  }
89
122
  const { overflow = "scroll" } = this.options;
90
123
  this.top = this.getVirtualizedTop();
91
- if (overflow === "scroll" && this.lineAnnotations.length === 0 && !this.isResizeDebuggingEnabled()) return hasHeightChange;
124
+ const ghostTextRows = this.editor?.__getGhostTextRows() ?? NO_GHOST_TEXT_ROWS;
125
+ hasHeightChange = this.applyGhostTextRows(ghostTextRows);
126
+ if (overflow === "scroll" && this.getLatestAnnotations().length === 0 && !this.isResizeDebuggingEnabled()) {
127
+ if (hasHeightChange) this.computeApproximateSize(true);
128
+ return hasHeightChange;
129
+ }
130
+ const { lineHeight } = this.metrics;
92
131
  if (this.code == null) return hasHeightChange;
93
132
  const content = this.code.children[1];
94
133
  if (!(content instanceof HTMLElement)) return hasHeightChange;
95
- const hasFileAnnotations = includesFileAnnotations(this.lineAnnotations);
134
+ const hasFileAnnotations = includesFileAnnotations(this.getLatestAnnotations());
96
135
  if (this.renderRange != null && hasFileAnnotations && shouldRenderFileAnnotations(this.renderRange)) {
97
136
  const nextFileAnnotationHeight = measureFileAnnotationHeight(content) ?? 0;
98
137
  if (nextFileAnnotationHeight !== this.cache.fileAnnotationHeight) {
@@ -108,7 +147,7 @@ var VirtualizedFile = class extends File {
108
147
  const lineIndexAttr = line.dataset.lineIndex;
109
148
  if (lineIndexAttr == null) continue;
110
149
  const lineIndex = Number(lineIndexAttr);
111
- let measuredHeight = line.getBoundingClientRect().height;
150
+ let measuredHeight = line.getBoundingClientRect().height + (ghostTextRows.get(lineIndex) ?? 0) * lineHeight;
112
151
  let hasMetadata = false;
113
152
  if (line.nextElementSibling instanceof HTMLElement && ("lineAnnotation" in line.nextElementSibling.dataset || "noNewline" in line.nextElementSibling.dataset)) {
114
153
  if ("noNewline" in line.nextElementSibling.dataset) hasMetadata = true;
@@ -128,10 +167,11 @@ var VirtualizedFile = class extends File {
128
167
  if (dirty) this.top = this.getVirtualizedTop();
129
168
  return this.render({ file: this.file });
130
169
  };
131
- prepareCodeViewItem(file, top, reset, lineAnnotations) {
132
- const annotationsChanged = this.syncLineAnnotations(lineAnnotations);
133
- const targetChanged = !areFilesEqual(this.file, file) || this.fileRenderer.hasUnkeyedFileContentsChanged(file);
134
- let shouldResetLayoutCache = reset?.resetFileLayoutCache === true || targetChanged || annotationsChanged;
170
+ updateCodeViewLayout(file, top, reset, lineAnnotations) {
171
+ const targetChanged = !areFileTargetsEqual(this.file, file);
172
+ if (targetChanged) this.updateExternalFile(file, lineAnnotations);
173
+ const { pendingRenderFile, layoutFileChanged, renderedFileChanged, annotationsChanged } = this.updatePendingRender(file, lineAnnotations);
174
+ let shouldResetLayoutCache = reset?.resetFileLayoutCache === true || layoutFileChanged || annotationsChanged;
135
175
  if (reset?.metrics != null) {
136
176
  this.metrics = reset.metrics;
137
177
  shouldResetLayoutCache = true;
@@ -142,26 +182,29 @@ var VirtualizedFile = class extends File {
142
182
  shouldResetLayoutCache = true;
143
183
  }
144
184
  if (shouldResetLayoutCache) this.resetLayoutCache();
145
- if (this.file !== file) this.layoutDirty = true;
146
- this.file = file;
185
+ if (targetChanged) this.layoutDirty = true;
186
+ if (!this.forceRenderOverride && (targetChanged || renderedFileChanged || annotationsChanged)) this.forceRenderOverride = true;
147
187
  this.top = top;
148
- this.computeApproximateSize();
188
+ this.computeApproximateSize(false, pendingRenderFile);
149
189
  return this.height;
150
190
  }
191
+ getLayoutFile() {
192
+ return this.pendingRender?.file ?? this.getRenderedFile();
193
+ }
151
194
  getLinePosition(lineNumber) {
152
- if (this.file == null || lineNumber < 1) return;
195
+ const file = this.getLayoutFile();
196
+ if (file == null || lineNumber < 1) return;
153
197
  const { disableFileHeader = false, collapsed = false } = this.options;
154
- const lastLineIndex = this.fileRenderer.getLineCount(this.file) - 1;
198
+ const lastLineIndex = this.fileRenderer.getLineCount(file) - 1;
155
199
  let top = getVirtualFileHeaderRegion(this.metrics, disableFileHeader);
156
200
  if (collapsed || lastLineIndex < 0) return {
157
201
  top,
158
202
  height: 0
159
203
  };
160
204
  const clampedLineIndex = Math.min(Math.max(lineNumber - 1, 0), lastLineIndex);
161
- const { overflow = "scroll" } = this.options;
162
205
  const { lineHeight } = this.metrics;
163
206
  top += this.cache.fileAnnotationHeight;
164
- if (overflow === "scroll" && !this.hasLineAnnotations()) return {
207
+ if (this.hasUniformLineHeights()) return {
165
208
  top: top + clampedLineIndex * lineHeight,
166
209
  height: lineHeight
167
210
  };
@@ -177,17 +220,18 @@ var VirtualizedFile = class extends File {
177
220
  return this.virtualizer.type === "simple" ? this.virtualizer.getRoot() : this.virtualizer.getContainerElement();
178
221
  }
179
222
  getNumericScrollAnchor(localViewportTop) {
180
- if (this.file == null || this.renderRange == null) return;
181
- const { disableFileHeader = false, collapsed = false, overflow = "scroll" } = this.options;
223
+ const file = this.getLayoutFile();
224
+ if (file == null || this.renderRange == null) return;
225
+ const { disableFileHeader = false, collapsed = false } = this.options;
182
226
  if (collapsed || this.renderRange.totalLines <= 0) return;
183
- const lastLineIndex = this.fileRenderer.getLineCount(this.file) - 1;
227
+ const lastLineIndex = this.fileRenderer.getLineCount(file) - 1;
184
228
  if (lastLineIndex < 0) return;
185
229
  const headerRegion = getVirtualFileHeaderRegion(this.metrics, disableFileHeader);
186
230
  const firstRenderedLineIndex = Math.min(this.renderRange.startingLine, lastLineIndex);
187
231
  const lastRenderedLineIndex = Math.min(firstRenderedLineIndex + this.renderRange.totalLines - 1, lastLineIndex);
188
232
  if (lastRenderedLineIndex < firstRenderedLineIndex) return;
189
233
  const { fileAnnotationHeight } = this.cache;
190
- if (overflow === "scroll" && !this.hasLineAnnotations()) {
234
+ if (this.hasUniformLineHeights()) {
191
235
  const { lineHeight } = this.metrics;
192
236
  const firstRenderedLineTop = headerRegion + (firstRenderedLineIndex === 0 ? fileAnnotationHeight : this.renderRange.bufferBefore);
193
237
  const lineIndex = firstRenderedLineIndex + Math.max(Math.ceil((localViewportTop - firstRenderedLineTop) / lineHeight), 0);
@@ -210,12 +254,13 @@ var VirtualizedFile = class extends File {
210
254
  return this.height;
211
255
  }
212
256
  getAdvancedStickySpecs(windowSpecs) {
213
- if (this.top == null || this.file == null) return;
257
+ const file = this.getLayoutFile();
258
+ if (this.top == null || file == null) return;
214
259
  if (this.options.collapsed === true) return {
215
260
  topOffset: this.top,
216
261
  height: this.height
217
262
  };
218
- const renderRange = windowSpecs != null ? this.computeRenderRangeFromWindow(this.file, this.top, windowSpecs) : this.renderRange;
263
+ const renderRange = windowSpecs != null ? this.computeRenderRangeFromWindow(file, this.top, windowSpecs) : this.renderRange;
219
264
  if (renderRange == null) return;
220
265
  const { bufferBefore, bufferAfter, totalLines } = renderRange;
221
266
  let headerOnlyOffset = 0;
@@ -229,12 +274,17 @@ var VirtualizedFile = class extends File {
229
274
  };
230
275
  }
231
276
  cleanUp(recycle = false) {
277
+ const hadGhostTextRows = this.cache.ghostTextRows.size > 0;
278
+ if (hadGhostTextRows) this.layoutDirty = true;
279
+ const shouldRecomputeLayout = recycle && this.isAdvancedMode() && this.fileContainer != null && (hadGhostTextRows || !areFileTargetsEqual(this.getRenderedFile(), this.getLatestFile()));
232
280
  if (this.fileContainer != null && this.isSimpleMode()) this.getSimpleVirtualizer()?.disconnect(this.fileContainer);
233
281
  if (!recycle) this.resetLayoutCache();
282
+ this.pendingRender = void 0;
234
283
  this.isSetup = false;
235
284
  super.cleanUp(recycle);
285
+ if (shouldRecomputeLayout) this.virtualizer.instanceChanged(this, true);
236
286
  }
237
- computeApproximateSize(force = false, file = this.file) {
287
+ computeApproximateSize(force = false, file = this.getLayoutFile()) {
238
288
  const shouldValidateSize = this.isResizeDebuggingEnabled();
239
289
  if (!force && !this.layoutDirty && !shouldValidateSize) return;
240
290
  const isFirstCompute = this.height === 0;
@@ -244,7 +294,8 @@ var VirtualizedFile = class extends File {
244
294
  this.layoutDirty = false;
245
295
  return;
246
296
  }
247
- const { disableFileHeader = false, collapsed = false, overflow = "scroll" } = this.options;
297
+ this.applyGhostTextRows(this.editor?.__getGhostTextRows() ?? NO_GHOST_TEXT_ROWS);
298
+ const { disableFileHeader = false, collapsed = false } = this.options;
248
299
  const { lineHeight } = this.metrics;
249
300
  const lineCount = this.fileRenderer.getLineCount(file);
250
301
  const headerRegion = getVirtualFileHeaderRegion(this.metrics, disableFileHeader);
@@ -255,7 +306,7 @@ var VirtualizedFile = class extends File {
255
306
  return;
256
307
  }
257
308
  this.height += this.cache.fileAnnotationHeight;
258
- if (overflow === "scroll" && !this.hasLineAnnotations()) this.height += lineCount * lineHeight;
309
+ if (this.hasUniformLineHeights()) this.height += lineCount * lineHeight;
259
310
  else for (let lineIndex = 0; lineIndex < lineCount; lineIndex++) {
260
311
  this.addLayoutCheckpoint(lineIndex, this.height);
261
312
  this.height += this.getLineHeight(lineIndex, false);
@@ -285,8 +336,19 @@ var VirtualizedFile = class extends File {
285
336
  }
286
337
  rerender() {
287
338
  if (!this.enabled || this.file == null) return;
339
+ const latestFile = this.getLatestFile();
340
+ const nextRenderFile = latestFile == null ? void 0 : this.fileRenderer.getFileForNextRender(latestFile);
341
+ if (this.isSimpleMode()) this.pendingRender = void 0;
288
342
  this.forceRenderOverride = true;
289
- this.virtualizer.instanceChanged(this, false);
343
+ this.virtualizer.instanceChanged(this, !areFileTargetsEqual(this.getRenderedFile(), nextRenderFile));
344
+ }
345
+ syncGhostTextRows() {
346
+ const codeView = this.getAdvancedVirtualizer();
347
+ if (codeView != null) {
348
+ codeView.capturePendingLayoutAnchor();
349
+ this.layoutDirty = true;
350
+ codeView.instanceChanged(this, true);
351
+ } else this.getSimpleVirtualizer()?.requestHeightReconcile(this);
290
352
  }
291
353
  applyDocumentChange(textDocument, newLineAnnotations, shouldUpdateBuffer = false) {
292
354
  const { renderRange: previousRenderRange } = this;
@@ -294,28 +356,37 @@ var VirtualizedFile = class extends File {
294
356
  super.applyDocumentChange(textDocument, newLineAnnotations);
295
357
  this.getSimpleVirtualizer()?.markDOMDirty();
296
358
  this.resetLayoutCache(this.isSimpleMode(), false);
359
+ const file = this.getRenderedFile();
297
360
  if (!this.isSimpleMode()) this.computeApproximateSize(true);
298
- else if (shouldUpdateBuffer && previousRenderRange !== void 0 && this.file !== void 0) {
361
+ else if (shouldUpdateBuffer && previousRenderRange != null && file != null) {
299
362
  const windowSpecs = this.virtualizer.getWindowSpecs();
300
- const renderRange = this.computeRenderRangeFromWindow(this.file, this.top ?? 0, windowSpecs);
363
+ const renderRange = this.computeRenderRangeFromWindow(file, this.top ?? 0, windowSpecs);
301
364
  if (renderRange.bufferAfter !== previousRenderRange.bufferAfter) this.updateBuffers(renderRange);
302
365
  }
303
366
  this.forceRenderOverride = true;
304
367
  this.virtualizer.instanceChanged(this, true);
305
368
  }
306
- renderPreparedFile({ fileContainer, file, forceRender = false, lineAnnotations, ...props }) {
307
- const didFileChange = this.file == null || !areFilesEqual(this.file, file) || this.fileRenderer.hasUnkeyedFileContentsChanged(file);
369
+ render({ fileContainer, file, forceRender = false, lineAnnotations, ...props }) {
370
+ const didFileChange = !areFileTargetsEqual(this.file, file);
371
+ if (didFileChange) {
372
+ this.updateExternalFile(file, lineAnnotations);
373
+ this.cachedHeaderHTML = void 0;
374
+ }
375
+ const { pendingRenderFile, layoutFileChanged, renderedFileChanged, annotationsChanged } = (() => {
376
+ if (this.pendingRender != null && this.pendingRender.latestFile === (this.getLatestFile(file) ?? file)) return {
377
+ pendingRenderFile: this.pendingRender.file,
378
+ layoutFileChanged: false,
379
+ renderedFileChanged: false,
380
+ annotationsChanged: false
381
+ };
382
+ return this.updatePendingRender(file, lineAnnotations);
383
+ })();
308
384
  const { forceRenderOverride, isSetup } = this;
309
385
  this.forceRenderOverride = void 0;
310
- const annotationsChanged = this.syncLineAnnotations(lineAnnotations);
311
- if (annotationsChanged) this.resetLayoutCache();
386
+ if (annotationsChanged || layoutFileChanged) this.resetLayoutCache();
312
387
  fileContainer = this.getOrCreateFileContainerNode(fileContainer);
313
- if (file == null) {
314
- console.error("VirtualizedFile.render: attempting to virtually render when we dont have file");
315
- return false;
316
- }
317
388
  if (!isSetup) {
318
- this.computeApproximateSize(false, file);
389
+ this.computeApproximateSize(false, pendingRenderFile);
319
390
  const virtualizer = this.getSimpleVirtualizer();
320
391
  this.top ??= this.getVirtualizedTop();
321
392
  if (this.isAdvancedMode()) this.isVisible = true;
@@ -327,30 +398,48 @@ var VirtualizedFile = class extends File {
327
398
  this.isSetup = true;
328
399
  } else {
329
400
  this.top ??= this.getVirtualizedTop();
330
- if (didFileChange && this.isSimpleMode()) {
401
+ if (layoutFileChanged && this.isSimpleMode()) {
331
402
  this.getSimpleVirtualizer()?.markDOMDirty();
332
403
  this.resetLayoutCache(false);
333
- this.computeApproximateSize(false, file);
404
+ this.computeApproximateSize(false, pendingRenderFile);
334
405
  }
335
406
  }
336
407
  if (!this.isVisible && this.isSimpleMode() && (!didFileChange || !isSetup)) {
337
- this.file = file;
338
- if (didFileChange) this.cachedHeaderHTML = void 0;
408
+ this.pendingRender = void 0;
339
409
  return this.renderPlaceholder(this.height);
340
410
  }
341
411
  const windowSpecs = this.virtualizer.getWindowSpecs();
342
412
  const fileTop = this.top ?? 0;
343
- const renderRange = this.computeRenderRangeFromWindow(file, fileTop, windowSpecs);
344
- const rendered = super.renderPreparedFile({
413
+ const renderRange = this.computeRenderRangeFromWindow(pendingRenderFile, fileTop, windowSpecs);
414
+ return super.render({
345
415
  file,
346
416
  fileContainer,
347
417
  renderRange,
348
418
  lineAnnotations,
349
- forceRender: (forceRenderOverride ?? forceRender) || annotationsChanged || didFileChange,
419
+ forceRender: (forceRenderOverride ?? forceRender) || annotationsChanged || renderedFileChanged || didFileChange,
350
420
  ...props
351
421
  });
352
- if (this.isSimpleMode() && rendered) this.getSimpleVirtualizer()?.requestHeightReconcile(this);
353
- return rendered;
422
+ }
423
+ finalizeRender() {
424
+ if (this.getRenderedFile() !== this.pendingRender?.file) throw new Error("VirtualizedFile.render: rendered a different file than its prepared layout");
425
+ this.pendingRender = void 0;
426
+ if (this.isSimpleMode()) this.getSimpleVirtualizer()?.requestHeightReconcile(this);
427
+ }
428
+ updatePendingRender(nextFile, lineAnnotations) {
429
+ const latestFile = this.getLatestFile(nextFile) ?? nextFile;
430
+ const previousRenderedFile = this.getRenderedFile();
431
+ const previousLayoutFile = this.pendingRender?.file ?? previousRenderedFile;
432
+ const pendingRenderFile = this.fileRenderer.getFileForNextRender(latestFile);
433
+ this.pendingRender = {
434
+ latestFile,
435
+ file: pendingRenderFile
436
+ };
437
+ return {
438
+ pendingRenderFile,
439
+ annotationsChanged: this.syncLineAnnotations(lineAnnotations),
440
+ layoutFileChanged: !areFileTargetsEqual(previousLayoutFile, pendingRenderFile),
441
+ renderedFileChanged: !areFileTargetsEqual(previousRenderedFile, pendingRenderFile)
442
+ };
354
443
  }
355
444
  syncVirtualizedTop() {
356
445
  this.top = this.getVirtualizedTop();
@@ -424,7 +513,7 @@ var VirtualizedFile = class extends File {
424
513
  return this.getSimpleVirtualizer()?.config.resizeDebugging ?? false;
425
514
  }
426
515
  computeRenderRangeFromWindow(file, fileTop, { top, bottom }) {
427
- const { disableFileHeader = false, overflow = "scroll" } = this.options;
516
+ const { disableFileHeader = false } = this.options;
428
517
  const { hunkLineCount, lineHeight } = this.metrics;
429
518
  const lineCount = this.fileRenderer.getLineCount(file);
430
519
  const fileHeight = this.height;
@@ -433,7 +522,7 @@ var VirtualizedFile = class extends File {
433
522
  const { fileAnnotationHeight } = this.cache;
434
523
  const codeRegionTop = headerRegion + fileAnnotationHeight;
435
524
  const codeRowsHeight = Math.max(0, fileHeight - headerRegion - fileAnnotationHeight - paddingBottom);
436
- const hasFileAnnotations = includesFileAnnotations(this.lineAnnotations);
525
+ const hasFileAnnotations = includesFileAnnotations(this.getLatestAnnotations());
437
526
  const fileAnnotationTop = fileTop + headerRegion;
438
527
  const measuredFileAnnotationVisible = fileAnnotationHeight > 0 && hasFileAnnotations && fileAnnotationTop < bottom && fileAnnotationTop + fileAnnotationHeight > top;
439
528
  if (fileTop < top - fileHeight || fileTop > bottom) return {
@@ -452,7 +541,7 @@ var VirtualizedFile = class extends File {
452
541
  const totalLines = Math.ceil(estimatedTargetLines / hunkLineCount) * hunkLineCount + hunkLineCount;
453
542
  const totalHunks = totalLines / hunkLineCount;
454
543
  const viewportCenter = (top + bottom) / 2;
455
- if (overflow === "scroll" && !this.hasLineAnnotations()) {
544
+ if (this.hasUniformLineHeights()) {
456
545
  const sourceRowsTop = fileTop + codeRegionTop;
457
546
  const sourceRowsBottom = sourceRowsTop + codeRowsHeight;
458
547
  if (!measuredFileAnnotationVisible && !(sourceRowsTop < bottom && sourceRowsBottom > top)) return {