@pierre/diffs 1.3.5 → 1.4.0

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 (257) hide show
  1. package/dist/components/CodeView.d.ts +113 -68
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +153 -58
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts +75 -15
  6. package/dist/components/File.d.ts.map +1 -1
  7. package/dist/components/File.js +223 -62
  8. package/dist/components/File.js.map +1 -1
  9. package/dist/components/FileDiff.d.ts +97 -21
  10. package/dist/components/FileDiff.d.ts.map +1 -1
  11. package/dist/components/FileDiff.js +400 -100
  12. package/dist/components/FileDiff.js.map +1 -1
  13. package/dist/components/UnresolvedFile.d.ts +2 -2
  14. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  15. package/dist/components/UnresolvedFile.js +2 -2
  16. package/dist/components/UnresolvedFile.js.map +1 -1
  17. package/dist/components/VirtualizedFile.d.ts +16 -7
  18. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  19. package/dist/components/VirtualizedFile.js +140 -51
  20. package/dist/components/VirtualizedFile.js.map +1 -1
  21. package/dist/components/VirtualizedFileDiff.d.ts +14 -8
  22. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  23. package/dist/components/VirtualizedFileDiff.js +183 -93
  24. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  25. package/dist/components/VirtulizerDevelopment.d.ts +1 -1
  26. package/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
  27. package/dist/edit/index.d.ts +7 -4
  28. package/dist/edit/index.js +5 -1
  29. package/dist/editor/EditStateManager.d.ts +56 -0
  30. package/dist/editor/EditStateManager.d.ts.map +1 -0
  31. package/dist/editor/EditStateManager.js +135 -0
  32. package/dist/editor/EditStateManager.js.map +1 -0
  33. package/dist/editor/cloneRetainedDiffSessionSnapshot.d.ts +7 -0
  34. package/dist/editor/cloneRetainedDiffSessionSnapshot.d.ts.map +1 -0
  35. package/dist/editor/cloneRetainedDiffSessionSnapshot.js +16 -0
  36. package/dist/editor/cloneRetainedDiffSessionSnapshot.js.map +1 -0
  37. package/dist/editor/editPrediction.d.ts +76 -0
  38. package/dist/editor/editPrediction.d.ts.map +1 -0
  39. package/dist/editor/editPrediction.js +365 -0
  40. package/dist/editor/editPrediction.js.map +1 -0
  41. package/dist/editor/editStack.d.ts +19 -40
  42. package/dist/editor/editStack.d.ts.map +1 -1
  43. package/dist/editor/editStack.js +67 -4
  44. package/dist/editor/editStack.js.map +1 -1
  45. package/dist/editor/editor.d.ts +118 -29
  46. package/dist/editor/editor.d.ts.map +1 -1
  47. package/dist/editor/editor.js +1196 -403
  48. package/dist/editor/editor.js.map +1 -1
  49. package/dist/editor/editor2.js +1 -1
  50. package/dist/editor/languages.d.ts +3 -3
  51. package/dist/editor/languages.d.ts.map +1 -1
  52. package/dist/editor/languages.js.map +1 -1
  53. package/dist/editor/lineAnnotations.d.ts +3 -3
  54. package/dist/editor/lineAnnotations.d.ts.map +1 -1
  55. package/dist/editor/lineAnnotations.js +16 -7
  56. package/dist/editor/lineAnnotations.js.map +1 -1
  57. package/dist/editor/marker.d.ts +2 -2
  58. package/dist/editor/marker.d.ts.map +1 -1
  59. package/dist/editor/marker.js.map +1 -1
  60. package/dist/editor/matchBrackets.d.ts +2 -2
  61. package/dist/editor/matchBrackets.d.ts.map +1 -1
  62. package/dist/editor/matchBrackets.js.map +1 -1
  63. package/dist/editor/pieceTable.d.ts +1 -1
  64. package/dist/editor/pieceTable.js.map +1 -1
  65. package/dist/editor/searchPanel.d.ts +2 -2
  66. package/dist/editor/searchPanel.d.ts.map +1 -1
  67. package/dist/editor/searchPanel.js +3 -2
  68. package/dist/editor/searchPanel.js.map +1 -1
  69. package/dist/editor/selection.d.ts +33 -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.d.ts.map +1 -1
  90. package/dist/editor/tokenizer.js +6 -3
  91. package/dist/editor/tokenizer.js.map +1 -1
  92. package/dist/editor/types.d.ts +267 -0
  93. package/dist/editor/types.d.ts.map +1 -0
  94. package/dist/editor/types.js +0 -0
  95. package/dist/editor/utils.d.ts +2 -1
  96. package/dist/editor/utils.d.ts.map +1 -1
  97. package/dist/editor/utils.js +4 -1
  98. package/dist/editor/utils.js.map +1 -1
  99. package/dist/index.d.ts +8 -6
  100. package/dist/index.js +9 -8
  101. package/dist/managers/InteractionManager.d.ts.map +1 -1
  102. package/dist/managers/InteractionManager.js +7 -0
  103. package/dist/managers/InteractionManager.js.map +1 -1
  104. package/dist/react/CodeView.d.ts +36 -25
  105. package/dist/react/CodeView.d.ts.map +1 -1
  106. package/dist/react/CodeView.js +15 -14
  107. package/dist/react/CodeView.js.map +1 -1
  108. package/dist/react/EditContext.d.ts +8 -11
  109. package/dist/react/EditContext.d.ts.map +1 -1
  110. package/dist/react/EditContext.js +2 -9
  111. package/dist/react/EditContext.js.map +1 -1
  112. package/dist/react/File.d.ts +10 -6
  113. package/dist/react/File.d.ts.map +1 -1
  114. package/dist/react/File.js +8 -4
  115. package/dist/react/File.js.map +1 -1
  116. package/dist/react/FileDiff.d.ts +10 -5
  117. package/dist/react/FileDiff.d.ts.map +1 -1
  118. package/dist/react/FileDiff.js +8 -4
  119. package/dist/react/FileDiff.js.map +1 -1
  120. package/dist/react/MultiFileDiff.d.ts +8 -5
  121. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  122. package/dist/react/MultiFileDiff.js +8 -12
  123. package/dist/react/MultiFileDiff.js.map +1 -1
  124. package/dist/react/PatchDiff.d.ts +7 -4
  125. package/dist/react/PatchDiff.d.ts.map +1 -1
  126. package/dist/react/PatchDiff.js +8 -4
  127. package/dist/react/PatchDiff.js.map +1 -1
  128. package/dist/react/UnresolvedFile.d.ts +3 -3
  129. package/dist/react/UnresolvedFile.d.ts.map +1 -1
  130. package/dist/react/UnresolvedFile.js.map +1 -1
  131. package/dist/react/index.d.ts +8 -5
  132. package/dist/react/types.d.ts +46 -9
  133. package/dist/react/types.d.ts.map +1 -1
  134. package/dist/react/utils/renderDiffChildren.d.ts +14 -12
  135. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  136. package/dist/react/utils/renderDiffChildren.js +2 -2
  137. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  138. package/dist/react/utils/renderFileChildren.d.ts +14 -12
  139. package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
  140. package/dist/react/utils/renderFileChildren.js +2 -2
  141. package/dist/react/utils/renderFileChildren.js.map +1 -1
  142. package/dist/react/utils/useFileDiffInstance.d.ts +22 -10
  143. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  144. package/dist/react/utils/useFileDiffInstance.js +112 -22
  145. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  146. package/dist/react/utils/useFileInstance.d.ts +15 -9
  147. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  148. package/dist/react/utils/useFileInstance.js +84 -25
  149. package/dist/react/utils/useFileInstance.js.map +1 -1
  150. package/dist/renderers/DiffHunksRenderer.d.ts +30 -15
  151. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  152. package/dist/renderers/DiffHunksRenderer.js +172 -108
  153. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  154. package/dist/renderers/FileRenderer.d.ts +27 -11
  155. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  156. package/dist/renderers/FileRenderer.js +138 -64
  157. package/dist/renderers/FileRenderer.js.map +1 -1
  158. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts +2 -2
  159. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
  160. package/dist/renderers/UnresolvedFileHunksRenderer.js +2 -2
  161. package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
  162. package/dist/shiki-stream/tokenizer.d.ts.map +1 -1
  163. package/dist/shiki-stream/tokenizer.js +2 -1
  164. package/dist/shiki-stream/tokenizer.js.map +1 -1
  165. package/dist/ssr/index.d.ts +2 -2
  166. package/dist/ssr/preloadDiffs.d.ts +21 -21
  167. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  168. package/dist/ssr/preloadDiffs.js +1 -1
  169. package/dist/ssr/preloadDiffs.js.map +1 -1
  170. package/dist/ssr/preloadFile.d.ts +6 -6
  171. package/dist/ssr/preloadFile.d.ts.map +1 -1
  172. package/dist/ssr/preloadFile.js.map +1 -1
  173. package/dist/ssr/preloadPatchFile.d.ts +4 -4
  174. package/dist/ssr/preloadPatchFile.d.ts.map +1 -1
  175. package/dist/ssr/preloadPatchFile.js.map +1 -1
  176. package/dist/style.js +1 -1
  177. package/dist/types.d.ts +13 -263
  178. package/dist/types.d.ts.map +1 -1
  179. package/dist/utils/appendItems.d.ts +5 -0
  180. package/dist/utils/appendItems.d.ts.map +1 -0
  181. package/dist/utils/appendItems.js +8 -0
  182. package/dist/utils/appendItems.js.map +1 -0
  183. package/dist/utils/areDiffTargetsEqual.js +1 -1
  184. package/dist/utils/areDiffTargetsEqual.js.map +1 -1
  185. package/dist/utils/areFileTargetsEqual.d.ts +7 -0
  186. package/dist/utils/areFileTargetsEqual.d.ts.map +1 -0
  187. package/dist/utils/areFileTargetsEqual.js +8 -0
  188. package/dist/utils/areFileTargetsEqual.js.map +1 -0
  189. package/dist/utils/areManagedSnapshotsEqual.d.ts +1 -1
  190. package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
  191. package/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
  192. package/dist/utils/areOptionsEqual.d.ts +3 -3
  193. package/dist/utils/areOptionsEqual.d.ts.map +1 -1
  194. package/dist/utils/areOptionsEqual.js.map +1 -1
  195. package/dist/utils/cloneFileDiffMetadata.d.ts +3 -2
  196. package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -1
  197. package/dist/utils/cloneFileDiffMetadata.js +8 -5
  198. package/dist/utils/cloneFileDiffMetadata.js.map +1 -1
  199. package/dist/utils/composeCacheKey.d.ts +6 -0
  200. package/dist/utils/composeCacheKey.d.ts.map +1 -0
  201. package/dist/utils/composeCacheKey.js +10 -0
  202. package/dist/utils/composeCacheKey.js.map +1 -0
  203. package/dist/utils/editSessionAnnotations.d.ts +69 -0
  204. package/dist/utils/editSessionAnnotations.d.ts.map +1 -0
  205. package/dist/utils/editSessionAnnotations.js +64 -0
  206. package/dist/utils/editSessionAnnotations.js.map +1 -0
  207. package/dist/utils/editSessionHunks.d.ts +5 -3
  208. package/dist/utils/editSessionHunks.d.ts.map +1 -1
  209. package/dist/utils/editSessionHunks.js +7 -5
  210. package/dist/utils/editSessionHunks.js.map +1 -1
  211. package/dist/utils/getDiffHunksRendererOptions.d.ts +1 -1
  212. package/dist/utils/getDiffHunksRendererOptions.d.ts.map +1 -1
  213. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  214. package/dist/utils/getFileRendererOptions.d.ts +1 -1
  215. package/dist/utils/getFileRendererOptions.d.ts.map +1 -1
  216. package/dist/utils/getFileRendererOptions.js.map +1 -1
  217. package/dist/utils/hydratePartialDiff.d.ts.map +1 -1
  218. package/dist/utils/hydratePartialDiff.js +2 -1
  219. package/dist/utils/hydratePartialDiff.js.map +1 -1
  220. package/dist/utils/lineAnnotationIdentity.d.ts +16 -0
  221. package/dist/utils/lineAnnotationIdentity.d.ts.map +1 -0
  222. package/dist/utils/lineAnnotationIdentity.js +17 -0
  223. package/dist/utils/lineAnnotationIdentity.js.map +1 -0
  224. package/dist/utils/parseDiffFromFile.d.ts +2 -2
  225. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  226. package/dist/utils/parseDiffFromFile.js +6 -6
  227. package/dist/utils/parseDiffFromFile.js.map +1 -1
  228. package/dist/utils/parsePatchFiles.d.ts +6 -3
  229. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  230. package/dist/utils/parsePatchFiles.js +34 -9
  231. package/dist/utils/parsePatchFiles.js.map +1 -1
  232. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  233. package/dist/utils/renderDiffWithHighlighter.js +6 -5
  234. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  235. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  236. package/dist/utils/renderFileWithHighlighter.js +7 -4
  237. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  238. package/dist/utils/trimPatchContext.d.ts.map +1 -1
  239. package/dist/utils/trimPatchContext.js +3 -2
  240. package/dist/utils/trimPatchContext.js.map +1 -1
  241. package/dist/utils/updateDiffHunks.js +1 -1
  242. package/dist/utils/virtualDiffLayout.js +1 -1
  243. package/dist/worker/WorkerPoolManager.d.ts +4 -3
  244. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  245. package/dist/worker/WorkerPoolManager.js +33 -4
  246. package/dist/worker/WorkerPoolManager.js.map +1 -1
  247. package/dist/worker/types.d.ts +5 -0
  248. package/dist/worker/types.d.ts.map +1 -1
  249. package/dist/worker/worker-portable.js +14 -6
  250. package/dist/worker/worker-portable.js.map +1 -1
  251. package/dist/worker/worker.js +14 -6
  252. package/dist/worker/worker.js.map +1 -1
  253. package/package.json +9 -1
  254. package/dist/editor/stateStorage.d.ts +0 -15
  255. package/dist/editor/stateStorage.d.ts.map +0 -1
  256. package/dist/editor/stateStorage.js +0 -65
  257. 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,18 @@ 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);
288
341
  this.forceRenderOverride = true;
289
- this.virtualizer.instanceChanged(this, false);
342
+ this.virtualizer.instanceChanged(this, !areFileTargetsEqual(this.getRenderedFile(), nextRenderFile));
343
+ }
344
+ syncGhostTextRows() {
345
+ const codeView = this.getAdvancedVirtualizer();
346
+ if (codeView != null) {
347
+ codeView.capturePendingLayoutAnchor();
348
+ this.layoutDirty = true;
349
+ codeView.instanceChanged(this, true);
350
+ } else this.getSimpleVirtualizer()?.requestHeightReconcile(this);
290
351
  }
291
352
  applyDocumentChange(textDocument, newLineAnnotations, shouldUpdateBuffer = false) {
292
353
  const { renderRange: previousRenderRange } = this;
@@ -294,28 +355,37 @@ var VirtualizedFile = class extends File {
294
355
  super.applyDocumentChange(textDocument, newLineAnnotations);
295
356
  this.getSimpleVirtualizer()?.markDOMDirty();
296
357
  this.resetLayoutCache(this.isSimpleMode(), false);
358
+ const file = this.getRenderedFile();
297
359
  if (!this.isSimpleMode()) this.computeApproximateSize(true);
298
- else if (shouldUpdateBuffer && previousRenderRange !== void 0 && this.file !== void 0) {
360
+ else if (shouldUpdateBuffer && previousRenderRange != null && file != null) {
299
361
  const windowSpecs = this.virtualizer.getWindowSpecs();
300
- const renderRange = this.computeRenderRangeFromWindow(this.file, this.top ?? 0, windowSpecs);
362
+ const renderRange = this.computeRenderRangeFromWindow(file, this.top ?? 0, windowSpecs);
301
363
  if (renderRange.bufferAfter !== previousRenderRange.bufferAfter) this.updateBuffers(renderRange);
302
364
  }
303
365
  this.forceRenderOverride = true;
304
366
  this.virtualizer.instanceChanged(this, true);
305
367
  }
306
- renderPreparedFile({ fileContainer, file, forceRender = false, lineAnnotations, ...props }) {
307
- const didFileChange = this.file == null || !areFilesEqual(this.file, file) || this.fileRenderer.hasUnkeyedFileContentsChanged(file);
368
+ render({ fileContainer, file, forceRender = false, lineAnnotations, ...props }) {
369
+ const didFileChange = !areFileTargetsEqual(this.file, file);
370
+ if (didFileChange) {
371
+ this.updateExternalFile(file, lineAnnotations);
372
+ this.cachedHeaderHTML = void 0;
373
+ }
374
+ const { pendingRenderFile, layoutFileChanged, renderedFileChanged, annotationsChanged } = (() => {
375
+ if (this.pendingRender != null && areFileTargetsEqual(this.pendingRender.latestFile, this.getLatestFile(file) ?? file)) return {
376
+ pendingRenderFile: this.pendingRender.file,
377
+ layoutFileChanged: false,
378
+ renderedFileChanged: false,
379
+ annotationsChanged: false
380
+ };
381
+ return this.updatePendingRender(file, lineAnnotations);
382
+ })();
308
383
  const { forceRenderOverride, isSetup } = this;
309
384
  this.forceRenderOverride = void 0;
310
- const annotationsChanged = this.syncLineAnnotations(lineAnnotations);
311
- if (annotationsChanged) this.resetLayoutCache();
385
+ if (annotationsChanged || layoutFileChanged) this.resetLayoutCache();
312
386
  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
387
  if (!isSetup) {
318
- this.computeApproximateSize(false, file);
388
+ this.computeApproximateSize(false, pendingRenderFile);
319
389
  const virtualizer = this.getSimpleVirtualizer();
320
390
  this.top ??= this.getVirtualizedTop();
321
391
  if (this.isAdvancedMode()) this.isVisible = true;
@@ -327,31 +397,50 @@ var VirtualizedFile = class extends File {
327
397
  this.isSetup = true;
328
398
  } else {
329
399
  this.top ??= this.getVirtualizedTop();
330
- if (didFileChange && this.isSimpleMode()) {
400
+ if (layoutFileChanged && this.isSimpleMode()) {
331
401
  this.getSimpleVirtualizer()?.markDOMDirty();
332
402
  this.resetLayoutCache(false);
333
- this.computeApproximateSize(false, file);
403
+ this.computeApproximateSize(false, pendingRenderFile);
334
404
  }
335
405
  }
336
406
  if (!this.isVisible && this.isSimpleMode() && (!didFileChange || !isSetup)) {
337
- this.file = file;
338
- if (didFileChange) this.cachedHeaderHTML = void 0;
407
+ this.pendingRender = void 0;
339
408
  return this.renderPlaceholder(this.height);
340
409
  }
341
410
  const windowSpecs = this.virtualizer.getWindowSpecs();
342
411
  const fileTop = this.top ?? 0;
343
- const renderRange = this.computeRenderRangeFromWindow(file, fileTop, windowSpecs);
344
- const rendered = super.renderPreparedFile({
412
+ const renderRange = this.computeRenderRangeFromWindow(pendingRenderFile, fileTop, windowSpecs);
413
+ const rendered = super.render({
345
414
  file,
346
415
  fileContainer,
347
416
  renderRange,
348
417
  lineAnnotations,
349
- forceRender: (forceRenderOverride ?? forceRender) || annotationsChanged || didFileChange,
418
+ forceRender: (forceRenderOverride ?? forceRender) || annotationsChanged || renderedFileChanged || didFileChange,
350
419
  ...props
351
420
  });
421
+ if (rendered) {
422
+ if (this.getRenderedFile() !== pendingRenderFile) throw new Error("VirtualizedFile.render: rendered a different file than its prepared layout");
423
+ this.pendingRender = void 0;
424
+ }
352
425
  if (this.isSimpleMode() && rendered) this.getSimpleVirtualizer()?.requestHeightReconcile(this);
353
426
  return rendered;
354
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
+ };
443
+ }
355
444
  syncVirtualizedTop() {
356
445
  this.top = this.getVirtualizedTop();
357
446
  }
@@ -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 {