@pierre/diffs 1.2.12 → 1.3.0-beta.10

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 (288) hide show
  1. package/dist/components/CodeView.d.ts +91 -6
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +300 -38
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts +14 -3
  6. package/dist/components/File.d.ts.map +1 -1
  7. package/dist/components/File.js +98 -12
  8. package/dist/components/File.js.map +1 -1
  9. package/dist/components/FileDiff.d.ts +68 -19
  10. package/dist/components/FileDiff.d.ts.map +1 -1
  11. package/dist/components/FileDiff.js +363 -25
  12. package/dist/components/FileDiff.js.map +1 -1
  13. package/dist/components/FileStream.d.ts.map +1 -1
  14. package/dist/components/FileStream.js +2 -1
  15. package/dist/components/FileStream.js.map +1 -1
  16. package/dist/components/UnresolvedFile.d.ts +2 -2
  17. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  18. package/dist/components/UnresolvedFile.js +2 -2
  19. package/dist/components/UnresolvedFile.js.map +1 -1
  20. package/dist/components/VirtualizedFile.d.ts +4 -2
  21. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  22. package/dist/components/VirtualizedFile.js +59 -47
  23. package/dist/components/VirtualizedFile.js.map +1 -1
  24. package/dist/components/VirtualizedFileDiff.d.ts +27 -5
  25. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  26. package/dist/components/VirtualizedFileDiff.js +262 -56
  27. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  28. package/dist/components/Virtualizer.d.ts +4 -1
  29. package/dist/components/Virtualizer.d.ts.map +1 -1
  30. package/dist/components/Virtualizer.js +21 -4
  31. package/dist/components/Virtualizer.js.map +1 -1
  32. package/dist/constants.d.ts +4 -1
  33. package/dist/constants.d.ts.map +1 -1
  34. package/dist/constants.js +4 -1
  35. package/dist/constants.js.map +1 -1
  36. package/dist/editor/command.d.ts +7 -0
  37. package/dist/editor/command.d.ts.map +1 -0
  38. package/dist/editor/command.js +54 -0
  39. package/dist/editor/command.js.map +1 -0
  40. package/dist/editor/editStack.d.ts +71 -0
  41. package/dist/editor/editStack.d.ts.map +1 -0
  42. package/dist/editor/editStack.js +218 -0
  43. package/dist/editor/editStack.js.map +1 -0
  44. package/dist/editor/editor.d.ts +105 -0
  45. package/dist/editor/editor.d.ts.map +1 -0
  46. package/dist/editor/editor.js +2545 -0
  47. package/dist/editor/editor.js.map +1 -0
  48. package/dist/editor/editor2.js +6 -0
  49. package/dist/editor/editor2.js.map +1 -0
  50. package/dist/editor/index.d.ts +5 -0
  51. package/dist/editor/index.js +3 -0
  52. package/dist/editor/languages.d.ts +26 -0
  53. package/dist/editor/languages.d.ts.map +1 -0
  54. package/dist/editor/languages.js +363 -0
  55. package/dist/editor/languages.js.map +1 -0
  56. package/dist/editor/lineAnnotations.d.ts +9 -0
  57. package/dist/editor/lineAnnotations.d.ts.map +1 -0
  58. package/dist/editor/lineAnnotations.js +212 -0
  59. package/dist/editor/lineAnnotations.js.map +1 -0
  60. package/dist/editor/marker.d.ts +38 -0
  61. package/dist/editor/marker.d.ts.map +1 -0
  62. package/dist/editor/marker.js +245 -0
  63. package/dist/editor/marker.js.map +1 -0
  64. package/dist/editor/matchBrackets.d.ts +9 -0
  65. package/dist/editor/matchBrackets.d.ts.map +1 -0
  66. package/dist/editor/matchBrackets.js +138 -0
  67. package/dist/editor/matchBrackets.js.map +1 -0
  68. package/dist/editor/pieceTable.d.ts +41 -0
  69. package/dist/editor/pieceTable.d.ts.map +1 -0
  70. package/dist/editor/pieceTable.js +671 -0
  71. package/dist/editor/pieceTable.js.map +1 -0
  72. package/dist/editor/platform.d.ts +19 -0
  73. package/dist/editor/platform.d.ts.map +1 -0
  74. package/dist/editor/platform.js +57 -0
  75. package/dist/editor/platform.js.map +1 -0
  76. package/dist/editor/popover.d.ts +65 -0
  77. package/dist/editor/popover.d.ts.map +1 -0
  78. package/dist/editor/popover.js +187 -0
  79. package/dist/editor/popover.js.map +1 -0
  80. package/dist/editor/searchPanel.d.ts +40 -0
  81. package/dist/editor/searchPanel.d.ts.map +1 -0
  82. package/dist/editor/searchPanel.js +318 -0
  83. package/dist/editor/searchPanel.js.map +1 -0
  84. package/dist/editor/selection.d.ts +211 -0
  85. package/dist/editor/selection.d.ts.map +1 -0
  86. package/dist/editor/selection.js +1626 -0
  87. package/dist/editor/selection.js.map +1 -0
  88. package/dist/editor/selectionAction.d.ts +46 -0
  89. package/dist/editor/selectionAction.d.ts.map +1 -0
  90. package/dist/editor/selectionAction.js +64 -0
  91. package/dist/editor/selectionAction.js.map +1 -0
  92. package/dist/editor/sprite.d.ts +8 -0
  93. package/dist/editor/sprite.d.ts.map +1 -0
  94. package/dist/editor/sprite.js +45 -0
  95. package/dist/editor/sprite.js.map +1 -0
  96. package/dist/editor/stateStorage.d.ts +15 -0
  97. package/dist/editor/stateStorage.d.ts.map +1 -0
  98. package/dist/editor/stateStorage.js +65 -0
  99. package/dist/editor/stateStorage.js.map +1 -0
  100. package/dist/editor/textDocument.d.ts +77 -0
  101. package/dist/editor/textDocument.d.ts.map +1 -0
  102. package/dist/editor/textDocument.js +271 -0
  103. package/dist/editor/textDocument.js.map +1 -0
  104. package/dist/editor/textMeasure.d.ts +61 -0
  105. package/dist/editor/textMeasure.d.ts.map +1 -0
  106. package/dist/editor/textMeasure.js +209 -0
  107. package/dist/editor/textMeasure.js.map +1 -0
  108. package/dist/editor/tokenizer.d.ts +41 -0
  109. package/dist/editor/tokenizer.d.ts.map +1 -0
  110. package/dist/editor/tokenizer.js +513 -0
  111. package/dist/editor/tokenizer.js.map +1 -0
  112. package/dist/editor/utils.d.ts +21 -0
  113. package/dist/editor/utils.d.ts.map +1 -0
  114. package/dist/editor/utils.js +68 -0
  115. package/dist/editor/utils.js.map +1 -0
  116. package/dist/index.d.ts +10 -8
  117. package/dist/index.js +12 -10
  118. package/dist/managers/InteractionManager.d.ts +7 -0
  119. package/dist/managers/InteractionManager.d.ts.map +1 -1
  120. package/dist/managers/InteractionManager.js +22 -1
  121. package/dist/managers/InteractionManager.js.map +1 -1
  122. package/dist/managers/ResizeManager.d.ts +10 -2
  123. package/dist/managers/ResizeManager.d.ts.map +1 -1
  124. package/dist/managers/ResizeManager.js +33 -13
  125. package/dist/managers/ResizeManager.js.map +1 -1
  126. package/dist/managers/UniversalRenderingManager.d.ts +2 -1
  127. package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
  128. package/dist/managers/UniversalRenderingManager.js +6 -1
  129. package/dist/managers/UniversalRenderingManager.js.map +1 -1
  130. package/dist/react/CodeView.d.ts +26 -1
  131. package/dist/react/CodeView.d.ts.map +1 -1
  132. package/dist/react/CodeView.js +82 -19
  133. package/dist/react/CodeView.js.map +1 -1
  134. package/dist/react/EditContext.d.ts +15 -0
  135. package/dist/react/EditContext.d.ts.map +1 -0
  136. package/dist/react/EditContext.js +23 -0
  137. package/dist/react/EditContext.js.map +1 -0
  138. package/dist/react/File.d.ts +3 -1
  139. package/dist/react/File.d.ts.map +1 -1
  140. package/dist/react/File.js +4 -2
  141. package/dist/react/File.js.map +1 -1
  142. package/dist/react/FileDiff.d.ts +4 -1
  143. package/dist/react/FileDiff.d.ts.map +1 -1
  144. package/dist/react/FileDiff.js +4 -2
  145. package/dist/react/FileDiff.js.map +1 -1
  146. package/dist/react/MultiFileDiff.d.ts +7 -5
  147. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  148. package/dist/react/MultiFileDiff.js +4 -2
  149. package/dist/react/MultiFileDiff.js.map +1 -1
  150. package/dist/react/PatchDiff.d.ts +4 -1
  151. package/dist/react/PatchDiff.d.ts.map +1 -1
  152. package/dist/react/PatchDiff.js +4 -2
  153. package/dist/react/PatchDiff.js.map +1 -1
  154. package/dist/react/UnresolvedFile.d.ts +1 -0
  155. package/dist/react/UnresolvedFile.d.ts.map +1 -1
  156. package/dist/react/UnresolvedFile.js +2 -1
  157. package/dist/react/UnresolvedFile.js.map +1 -1
  158. package/dist/react/index.d.ts +3 -2
  159. package/dist/react/index.js +2 -1
  160. package/dist/react/types.d.ts +3 -0
  161. package/dist/react/types.d.ts.map +1 -1
  162. package/dist/react/utils/renderDiffChildren.d.ts +2 -0
  163. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  164. package/dist/react/utils/renderDiffChildren.js +16 -8
  165. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  166. package/dist/react/utils/renderFileChildren.d.ts +2 -0
  167. package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
  168. package/dist/react/utils/renderFileChildren.js +16 -8
  169. package/dist/react/utils/renderFileChildren.js.map +1 -1
  170. package/dist/react/utils/useFileDiffInstance.d.ts +3 -1
  171. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  172. package/dist/react/utils/useFileDiffInstance.js +30 -6
  173. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  174. package/dist/react/utils/useFileInstance.d.ts +4 -1
  175. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  176. package/dist/react/utils/useFileInstance.js +30 -5
  177. package/dist/react/utils/useFileInstance.js.map +1 -1
  178. package/dist/renderers/DiffHunksRenderer.d.ts +28 -2
  179. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  180. package/dist/renderers/DiffHunksRenderer.js +244 -22
  181. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  182. package/dist/renderers/FileRenderer.d.ts +8 -1
  183. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  184. package/dist/renderers/FileRenderer.js +155 -45
  185. package/dist/renderers/FileRenderer.js.map +1 -1
  186. package/dist/ssr/index.d.ts +2 -2
  187. package/dist/ssr/preloadDiffs.d.ts +11 -10
  188. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  189. package/dist/ssr/preloadDiffs.js +15 -7
  190. package/dist/ssr/preloadDiffs.js.map +1 -1
  191. package/dist/style.js +1 -1
  192. package/dist/types.d.ts +282 -5
  193. package/dist/types.d.ts.map +1 -1
  194. package/dist/utils/applyLineTextWithNewline.d.ts +5 -0
  195. package/dist/utils/applyLineTextWithNewline.d.ts.map +1 -0
  196. package/dist/utils/applyLineTextWithNewline.js +11 -0
  197. package/dist/utils/applyLineTextWithNewline.js.map +1 -0
  198. package/dist/utils/areHunkDataEqual.js +1 -1
  199. package/dist/utils/areHunkDataEqual.js.map +1 -1
  200. package/dist/utils/areManagedSnapshotsEqual.d.ts +2 -2
  201. package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
  202. package/dist/utils/areManagedSnapshotsEqual.js +5 -0
  203. package/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
  204. package/dist/utils/awaitWithTimeout.d.ts +5 -0
  205. package/dist/utils/awaitWithTimeout.d.ts.map +1 -0
  206. package/dist/utils/awaitWithTimeout.js +15 -0
  207. package/dist/utils/awaitWithTimeout.js.map +1 -0
  208. package/dist/utils/cleanLastNewline.js +6 -1
  209. package/dist/utils/cleanLastNewline.js.map +1 -1
  210. package/dist/utils/cloneFileDiffMetadata.d.ts +7 -0
  211. package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -0
  212. package/dist/utils/cloneFileDiffMetadata.js +16 -0
  213. package/dist/utils/cloneFileDiffMetadata.js.map +1 -0
  214. package/dist/utils/computeEstimatedDiffHeights.d.ts +3 -1
  215. package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
  216. package/dist/utils/computeEstimatedDiffHeights.js +8 -1
  217. package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
  218. package/dist/utils/computeFileOffsets.d.ts +21 -0
  219. package/dist/utils/computeFileOffsets.d.ts.map +1 -0
  220. package/dist/utils/computeFileOffsets.js +51 -0
  221. package/dist/utils/computeFileOffsets.js.map +1 -0
  222. package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts +5 -0
  223. package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts.map +1 -0
  224. package/dist/utils/createCodeViewHeaderFooterHostElement.js +19 -0
  225. package/dist/utils/createCodeViewHeaderFooterHostElement.js.map +1 -0
  226. package/dist/utils/createFileHeaderElement.d.ts.map +1 -1
  227. package/dist/utils/createFileHeaderElement.js +5 -1
  228. package/dist/utils/createFileHeaderElement.js.map +1 -1
  229. package/dist/utils/createTransformerWithState.js +9 -0
  230. package/dist/utils/createTransformerWithState.js.map +1 -1
  231. package/dist/utils/editSessionHunks.d.ts +84 -0
  232. package/dist/utils/editSessionHunks.d.ts.map +1 -0
  233. package/dist/utils/editSessionHunks.js +366 -0
  234. package/dist/utils/editSessionHunks.js.map +1 -0
  235. package/dist/utils/getDiffFileInput.d.ts +14 -0
  236. package/dist/utils/getDiffFileInput.d.ts.map +1 -0
  237. package/dist/utils/getDiffFileInput.js +24 -0
  238. package/dist/utils/getDiffFileInput.js.map +1 -0
  239. package/dist/utils/getDiffHunksRendererOptions.js +1 -0
  240. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  241. package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
  242. package/dist/utils/getFiletypeFromFileName.js +2 -0
  243. package/dist/utils/getFiletypeFromFileName.js.map +1 -1
  244. package/dist/utils/hydratePartialDiff.d.ts +10 -0
  245. package/dist/utils/hydratePartialDiff.d.ts.map +1 -0
  246. package/dist/utils/hydratePartialDiff.js +140 -0
  247. package/dist/utils/hydratePartialDiff.js.map +1 -0
  248. package/dist/utils/iterateOverDiff.js +3 -3
  249. package/dist/utils/iterateOverDiff.js.map +1 -1
  250. package/dist/utils/parseDiffFromFile.d.ts +1 -1
  251. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  252. package/dist/utils/parseDiffFromFile.js +26 -5
  253. package/dist/utils/parseDiffFromFile.js.map +1 -1
  254. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  255. package/dist/utils/parsePatchFiles.js +2 -0
  256. package/dist/utils/parsePatchFiles.js.map +1 -1
  257. package/dist/utils/realignChangeContent.d.ts +28 -0
  258. package/dist/utils/realignChangeContent.d.ts.map +1 -0
  259. package/dist/utils/realignChangeContent.js +142 -0
  260. package/dist/utils/realignChangeContent.js.map +1 -0
  261. package/dist/utils/renderDiffWithHighlighter.js +1 -1
  262. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  263. package/dist/utils/renderFileWithHighlighter.js +5 -14
  264. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  265. package/dist/utils/updateDiffHunks.d.ts +24 -0
  266. package/dist/utils/updateDiffHunks.d.ts.map +1 -0
  267. package/dist/utils/updateDiffHunks.js +235 -0
  268. package/dist/utils/updateDiffHunks.js.map +1 -0
  269. package/dist/utils/virtualDiffLayout.d.ts +40 -1
  270. package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
  271. package/dist/utils/virtualDiffLayout.js +96 -1
  272. package/dist/utils/virtualDiffLayout.js.map +1 -1
  273. package/dist/worker/WorkerPoolManager.d.ts +7 -2
  274. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  275. package/dist/worker/WorkerPoolManager.js +83 -18
  276. package/dist/worker/WorkerPoolManager.js.map +1 -1
  277. package/dist/worker/index.d.ts +2 -2
  278. package/dist/worker/types.d.ts +11 -1
  279. package/dist/worker/types.d.ts.map +1 -1
  280. package/dist/worker/worker-portable.js +46 -66
  281. package/dist/worker/worker-portable.js.map +1 -1
  282. package/dist/worker/worker.js +46 -66
  283. package/dist/worker/worker.js.map +1 -1
  284. package/package.json +12 -5
  285. package/dist/utils/iterateOverFile.d.ts +0 -50
  286. package/dist/utils/iterateOverFile.d.ts.map +0 -1
  287. package/dist/utils/iterateOverFile.js +0 -49
  288. package/dist/utils/iterateOverFile.js.map +0 -1
@@ -0,0 +1,671 @@
1
+ import { computeLineOffsets } from "../utils/computeFileOffsets.js";
2
+ //#region src/editor/pieceTable.ts
3
+ const MAX_FIND_MATCHES = 1e5;
4
+ const LINE_FEED = 10;
5
+ const CARRIAGE_RETURN = 13;
6
+ const WORD_SEPARATORS = "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?";
7
+ var Piece = class {
8
+ source;
9
+ offset;
10
+ length;
11
+ lineOffsetStart;
12
+ lineOffsetEnd;
13
+ hasVirtualTrailingCRBreak;
14
+ firstCharCode;
15
+ lastCharCode;
16
+ static Original = 0;
17
+ static Added = 1;
18
+ constructor(source, offset, length, lineOffsetStart, lineOffsetEnd, hasVirtualTrailingCRBreak, firstCharCode, lastCharCode) {
19
+ this.source = source;
20
+ this.offset = offset;
21
+ this.length = length;
22
+ this.lineOffsetStart = lineOffsetStart;
23
+ this.lineOffsetEnd = lineOffsetEnd;
24
+ this.hasVirtualTrailingCRBreak = hasVirtualTrailingCRBreak;
25
+ this.firstCharCode = firstCharCode;
26
+ this.lastCharCode = lastCharCode;
27
+ }
28
+ get lineBreakCount() {
29
+ return this.lineOffsetEnd - this.lineOffsetStart + (this.hasVirtualTrailingCRBreak ? 1 : 0);
30
+ }
31
+ };
32
+ var TextBuffer = class {
33
+ text;
34
+ lineOffsets;
35
+ constructor(text) {
36
+ this.text = text;
37
+ this.lineOffsets = computeLineOffsets(text);
38
+ }
39
+ append(text) {
40
+ const offset = this.text.length;
41
+ const appendedLineOffsets = computeLineOffsets(text);
42
+ for (let i = 1; i < appendedLineOffsets.length; i++) this.lineOffsets.push(offset + appendedLineOffsets[i]);
43
+ this.text += text;
44
+ return offset;
45
+ }
46
+ };
47
+ var PieceNode = class {
48
+ piece;
49
+ subtreeLength;
50
+ subtreeLineBreakCount;
51
+ subtreeFirstCharCode;
52
+ subtreeLastCharCode;
53
+ left = null;
54
+ right = null;
55
+ parent = null;
56
+ priority = 0;
57
+ constructor(piece, subtreeLength = piece.length, subtreeLineBreakCount = piece.lineBreakCount, subtreeFirstCharCode = piece.firstCharCode, subtreeLastCharCode = piece.lastCharCode) {
58
+ this.piece = piece;
59
+ this.subtreeLength = subtreeLength;
60
+ this.subtreeLineBreakCount = subtreeLineBreakCount;
61
+ this.subtreeFirstCharCode = subtreeFirstCharCode;
62
+ this.subtreeLastCharCode = subtreeLastCharCode;
63
+ }
64
+ updateSubtreeLength() {
65
+ this.subtreeLength = (this.left?.subtreeLength ?? 0) + this.piece.length + (this.right?.subtreeLength ?? 0);
66
+ this.subtreeLineBreakCount = (this.left?.subtreeLineBreakCount ?? 0) + this.piece.lineBreakCount + (this.right?.subtreeLineBreakCount ?? 0) - (formsCRLF(this.left?.subtreeLastCharCode, this.piece.firstCharCode) ? 1 : 0) - (formsCRLF(this.piece.lastCharCode, this.right?.subtreeFirstCharCode) ? 1 : 0);
67
+ this.subtreeFirstCharCode = this.left?.subtreeFirstCharCode ?? this.piece.firstCharCode;
68
+ this.subtreeLastCharCode = this.right?.subtreeLastCharCode ?? this.piece.lastCharCode;
69
+ }
70
+ };
71
+ /**
72
+ * A piece table is a data structure that allows for efficient insertion and deletion of text.
73
+ * It is a tree of pieces, where each piece is a segment of text that is either original or added.
74
+ * The tree is a treap (a binary search tree that also keeps each node's random priority in heap
75
+ * order, which keeps the tree balanced without an explicit rebalancing pass). Each edit reshapes
76
+ * only the nodes along one root-to-leaf path via split and merge in O(log P), instead of
77
+ * rebuilding all P pieces.
78
+ * Inspired by https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation
79
+ */
80
+ var PieceTable = class {
81
+ #original;
82
+ #add = new TextBuffer("");
83
+ #root = null;
84
+ #length = 0;
85
+ #lineCount = 0;
86
+ #lastVisitedLine = null;
87
+ #lastVisitedLineLength = null;
88
+ #priorityState = 2654435769;
89
+ constructor(originalText) {
90
+ this.#original = new TextBuffer(originalText);
91
+ const piece = this.#createPiece(Piece.Original, 0, originalText.length);
92
+ this.#root = piece.length > 0 ? this.#createNode(piece) : null;
93
+ this.#length = this.#root?.subtreeLength ?? 0;
94
+ this.#lineCount = (this.#root?.subtreeLineBreakCount ?? 0) + 1;
95
+ }
96
+ get lineCount() {
97
+ return this.#lineCount;
98
+ }
99
+ getText(range) {
100
+ if (range === void 0) return this.#textFromPieces();
101
+ const start = this.offsetAt(range.start);
102
+ const end = this.offsetAt(range.end);
103
+ return this.getTextSlice(start, end);
104
+ }
105
+ getLineText(line, includeLineBreak = false) {
106
+ if (this.#lastVisitedLine !== null && this.#lastVisitedLine[0] === line && this.#lastVisitedLine[1] === includeLineBreak) return this.#lastVisitedLine[2];
107
+ const offset = this.#getLineOffset(line);
108
+ if (offset === void 0) throw new Error(`Line index out of range: ${line}`);
109
+ const text = this.getTextSlice(offset[0], offset[1], !includeLineBreak);
110
+ this.#lastVisitedLine = [
111
+ line,
112
+ includeLineBreak,
113
+ text
114
+ ];
115
+ this.#lastVisitedLineLength = [
116
+ line,
117
+ includeLineBreak,
118
+ text.length
119
+ ];
120
+ return text;
121
+ }
122
+ getLineLength(line, includeLineBreak = false) {
123
+ const lastVisitedLineLength = this.#lastVisitedLineLength;
124
+ const lastVisitedLine = this.#lastVisitedLine;
125
+ if (lastVisitedLineLength !== null && lastVisitedLineLength[0] === line && lastVisitedLineLength[1] === includeLineBreak) return lastVisitedLineLength[2];
126
+ if (lastVisitedLine !== null && lastVisitedLine[0] === line && lastVisitedLine[1] === includeLineBreak) {
127
+ const length = lastVisitedLine[2].length;
128
+ this.#lastVisitedLineLength = [
129
+ line,
130
+ includeLineBreak,
131
+ length
132
+ ];
133
+ return length;
134
+ }
135
+ const offset = this.#getLineOffset(line);
136
+ if (offset === void 0) throw new Error(`Line index out of range: ${line}`);
137
+ const [start, end] = offset;
138
+ let length = end - start;
139
+ if (!includeLineBreak) while (length > 0 && isEOL(this.charAt(start + length - 1).charCodeAt(0))) length--;
140
+ this.#lastVisitedLineLength = [
141
+ line,
142
+ includeLineBreak,
143
+ length
144
+ ];
145
+ return length;
146
+ }
147
+ getTextSlice(start, end, trimEOF = false) {
148
+ if (start >= end) return "";
149
+ const sliceStart = clamp(start, 0, this.#length);
150
+ const sliceEnd = clamp(end, sliceStart, this.#length);
151
+ if (sliceStart >= sliceEnd) return "";
152
+ const location = this.#findPieceAtOffset(sliceStart);
153
+ if (location === void 0) return "";
154
+ const chunks = [];
155
+ let [node, offsetInPiece] = location;
156
+ let remaining = sliceEnd - sliceStart;
157
+ while (node !== null && remaining > 0) {
158
+ const takeLength = Math.min(node.piece.length - offsetInPiece, remaining);
159
+ const buffer = this.#bufferFor(node.piece.source);
160
+ const start = node.piece.offset + offsetInPiece;
161
+ let end = start + takeLength;
162
+ if (trimEOF) while (end > start && isEOL(buffer.text.charCodeAt(end - 1))) end--;
163
+ chunks.push(buffer.text.slice(start, end));
164
+ remaining -= takeLength;
165
+ offsetInPiece = 0;
166
+ node = this.#nextNode(node);
167
+ }
168
+ return chunks.join("");
169
+ }
170
+ charAt(offset) {
171
+ const location = this.#findPieceAtOffset(offset);
172
+ if (location === void 0) return "";
173
+ const [node, offsetInPiece] = location;
174
+ return this.#bufferFor(node.piece.source).text.charAt(node.piece.offset + offsetInPiece);
175
+ }
176
+ includes(needle) {
177
+ if (needle.length === 0) return true;
178
+ const prefixTable = createPrefixTable(needle);
179
+ let matched = 0;
180
+ let found = false;
181
+ this.#forEachPieceSegment((segment) => {
182
+ for (let offset = segment.start; offset < segment.end; offset++) {
183
+ const charCode = segment.text.charCodeAt(offset);
184
+ while (matched > 0 && charCode !== needle.charCodeAt(matched)) matched = prefixTable[matched - 1];
185
+ if (charCode === needle.charCodeAt(matched)) matched++;
186
+ if (matched === needle.length) {
187
+ found = true;
188
+ return false;
189
+ }
190
+ }
191
+ return true;
192
+ });
193
+ return found;
194
+ }
195
+ findNextNonOverlappingSubstring(needle, occupied) {
196
+ if (needle.length === 0 || needle.length > this.#length) return;
197
+ const ranges = normalizeRanges(occupied, this.#length);
198
+ const pivot = ranges.reduce((max, [, end]) => Math.max(max, end), 0);
199
+ const prefixTable = createPrefixTable(needle);
200
+ let matched = 0;
201
+ let documentOffset = 0;
202
+ let wrappedOffset;
203
+ let foundOffset;
204
+ this.#forEachPieceSegment((segment) => {
205
+ for (let offset = segment.start; offset < segment.end; offset++) {
206
+ const charCode = segment.text.charCodeAt(offset);
207
+ while (matched > 0 && charCode !== needle.charCodeAt(matched)) matched = prefixTable[matched - 1];
208
+ if (charCode === needle.charCodeAt(matched)) matched++;
209
+ if (matched === needle.length) {
210
+ const start = documentOffset - needle.length + 1;
211
+ if (!rangeOverlaps(ranges, start, start + needle.length)) {
212
+ if (start >= pivot) {
213
+ foundOffset = start;
214
+ return false;
215
+ }
216
+ wrappedOffset ??= start;
217
+ }
218
+ matched = prefixTable[matched - 1];
219
+ }
220
+ documentOffset++;
221
+ }
222
+ return true;
223
+ });
224
+ return foundOffset ?? wrappedOffset;
225
+ }
226
+ search(searchParams) {
227
+ if (searchParams.text.length === 0 || this.#length === 0) return [];
228
+ if (searchParams.text.includes("\n") || searchParams.text.includes("\r") || searchParams.regex && (searchParams.text.includes("\\n") || searchParams.text.includes("\\r"))) return [];
229
+ let pattern;
230
+ try {
231
+ pattern = compileSearchRegExp(searchParams.text, searchParams.regex, searchParams.caseSensitive);
232
+ } catch {
233
+ return [];
234
+ }
235
+ return this.#collectSearchMatchesLineByLine(pattern, searchParams.wholeWord, MAX_FIND_MATCHES);
236
+ }
237
+ #collectSearchMatchesLineByLine(pattern, wholeWord, limit) {
238
+ const out = [];
239
+ const docLength = this.#length;
240
+ const charAt = (offset) => this.charAt(offset);
241
+ for (let line = 0; line < this.#lineCount; line++) {
242
+ const lineText = this.getLineText(line);
243
+ const lineStart = this.offsetAt({
244
+ line,
245
+ character: 0
246
+ });
247
+ pattern.lastIndex = 0;
248
+ let match;
249
+ while ((match = pattern.exec(lineText)) !== null) {
250
+ const rel = match.index;
251
+ const fragment = match[0];
252
+ if (fragment.length === 0) {
253
+ pattern.lastIndex = advancePastEmptyMatch(lineText, rel);
254
+ continue;
255
+ }
256
+ const docStart = lineStart + rel;
257
+ if (!wholeWord || isWholeWordAtDocOffsets(docStart, fragment.length, docLength, charAt)) {
258
+ out.push([docStart, docStart + fragment.length]);
259
+ if (out.length >= limit) return out;
260
+ }
261
+ if (rel === pattern.lastIndex) pattern.lastIndex = advancePastEmptyMatch(lineText, rel);
262
+ }
263
+ }
264
+ return out;
265
+ }
266
+ insert(text, offset) {
267
+ if (text.length === 0) return;
268
+ const start = clamp(offset, 0, this.#length);
269
+ this.#replaceRangeIncremental(start, start, text);
270
+ }
271
+ delete(offset, length) {
272
+ if (length <= 0 || this.#length === 0) return;
273
+ const start = clamp(offset, 0, this.#length);
274
+ const end = clamp(start + length, start, this.#length);
275
+ if (start === end) return;
276
+ this.#replaceRangeIncremental(start, end, "");
277
+ }
278
+ applyEdits(edits) {
279
+ if (edits.length === 0) return;
280
+ for (let i = edits.length - 1; i >= 0; i--) {
281
+ const edit = edits[i];
282
+ const start = clamp(edit.start, 0, this.#length);
283
+ const end = clamp(edit.end, start, this.#length);
284
+ this.#replaceRangeIncremental(start, end, edit.text);
285
+ }
286
+ }
287
+ positionAt(offset) {
288
+ const clampedOffset = clamp(offset, 0, this.#length);
289
+ if (this.#length === 0) return {
290
+ line: 0,
291
+ character: 0
292
+ };
293
+ const line = this.#lineAtOffset(clampedOffset);
294
+ return {
295
+ line,
296
+ character: clampedOffset - (line === 0 ? 0 : this.#lineBreakOffset(line - 1))
297
+ };
298
+ }
299
+ positionsAt(offsets) {
300
+ const positions = Array.from({ length: offsets.length });
301
+ if (offsets.length === 0) return positions;
302
+ if (this.#length === 0) return positions.fill({
303
+ line: 0,
304
+ character: 0
305
+ });
306
+ for (let i = 0; i < offsets.length; i++) positions[i] = this.positionAt(offsets[i]);
307
+ return positions;
308
+ }
309
+ offsetAt(position) {
310
+ if (position.line < 0 || this.#length === 0) return 0;
311
+ if (position.line >= this.#lineCount) throw new Error(`Line index out of range: ${position.line}`);
312
+ const offset = this.#getLineOffset(position.line);
313
+ if (offset === void 0) throw new Error(`Line index out of range: ${position.line}`);
314
+ const character = clamp(position.character, 0, offset[1] - offset[0]);
315
+ return offset[0] + character;
316
+ }
317
+ #findPieceAtOffset(offset) {
318
+ if (offset < 0 || offset >= this.#length) return;
319
+ let node = this.#root;
320
+ let remaining = offset;
321
+ while (node !== null) {
322
+ const leftLength = node.left?.subtreeLength ?? 0;
323
+ if (remaining < leftLength) {
324
+ node = node.left;
325
+ continue;
326
+ }
327
+ remaining -= leftLength;
328
+ if (remaining < node.piece.length) return [node, remaining];
329
+ remaining -= node.piece.length;
330
+ node = node.right;
331
+ }
332
+ }
333
+ #nextNode(node) {
334
+ if (node.right !== null) {
335
+ let next = node.right;
336
+ while (next.left !== null) next = next.left;
337
+ return next;
338
+ }
339
+ let current = node;
340
+ while (current.parent !== null && current === current.parent.right) current = current.parent;
341
+ return current.parent;
342
+ }
343
+ #getLineOffset(line) {
344
+ if (line < 0) throw new Error(`Line index out of range: ${line}`);
345
+ if (this.#length === 0) {
346
+ if (line === 0) return [0, 0];
347
+ throw new Error(`Line index out of range: ${line}`);
348
+ }
349
+ if (line >= this.#lineCount) throw new Error(`Line index out of range: ${line}`);
350
+ return [line === 0 ? 0 : this.#lineBreakOffset(line - 1), line < this.#lineCount - 1 ? this.#lineBreakOffset(line) : this.#length];
351
+ }
352
+ #lineAtOffset(offset) {
353
+ let node = this.#root;
354
+ let remaining = clamp(offset, 0, this.#length);
355
+ let line = 0;
356
+ while (node !== null) {
357
+ const leftLength = node.left?.subtreeLength ?? 0;
358
+ if (remaining < leftLength) {
359
+ node = node.left;
360
+ continue;
361
+ }
362
+ line += (node.left?.subtreeLineBreakCount ?? 0) - (formsCRLF(node.left?.subtreeLastCharCode, node.piece.firstCharCode) ? 1 : 0);
363
+ remaining -= leftLength;
364
+ if (remaining <= node.piece.length) {
365
+ const buffer = this.#bufferFor(node.piece.source);
366
+ const lineOffsetEnd = Math.min(upperBound(buffer.lineOffsets, node.piece.offset + remaining), node.piece.lineOffsetEnd);
367
+ line += lineOffsetEnd - node.piece.lineOffsetStart;
368
+ if (remaining === node.piece.length && node.piece.hasVirtualTrailingCRBreak) line++;
369
+ if (remaining === node.piece.length && formsCRLF(node.piece.lastCharCode, this.#nextNode(node)?.piece.firstCharCode)) line--;
370
+ return line;
371
+ }
372
+ line += node.piece.lineBreakCount - (formsCRLF(node.piece.lastCharCode, node.right?.subtreeFirstCharCode) ? 1 : 0);
373
+ remaining -= node.piece.length;
374
+ node = node.right;
375
+ }
376
+ return this.#lineCount - 1;
377
+ }
378
+ #lineBreakOffset(lineBreakIndex) {
379
+ let node = this.#root;
380
+ let remaining = lineBreakIndex;
381
+ let documentOffset = 0;
382
+ let followingCharCode;
383
+ while (node !== null) {
384
+ const leftLineBreakCount = (node.left?.subtreeLineBreakCount ?? 0) - (formsCRLF(node.left?.subtreeLastCharCode, node.piece.firstCharCode) ? 1 : 0);
385
+ if (remaining < leftLineBreakCount) {
386
+ followingCharCode = node.piece.firstCharCode;
387
+ node = node.left;
388
+ continue;
389
+ }
390
+ const leftLength = node.left?.subtreeLength ?? 0;
391
+ documentOffset += leftLength;
392
+ remaining -= leftLineBreakCount;
393
+ const nextCharCode = node.right?.subtreeFirstCharCode ?? followingCharCode;
394
+ const pieceLineBreakCount = node.piece.lineBreakCount - (formsCRLF(node.piece.lastCharCode, nextCharCode) ? 1 : 0);
395
+ if (remaining < pieceLineBreakCount) return documentOffset + this.#pieceLineBreakOffset(node.piece, remaining);
396
+ documentOffset += node.piece.length;
397
+ remaining -= pieceLineBreakCount;
398
+ node = node.right;
399
+ }
400
+ return this.#length;
401
+ }
402
+ #pieceLineBreakOffset(piece, lineBreakIndex) {
403
+ if (lineBreakIndex < piece.lineOffsetEnd - piece.lineOffsetStart) return this.#bufferFor(piece.source).lineOffsets[piece.lineOffsetStart + lineBreakIndex] - piece.offset;
404
+ return piece.length;
405
+ }
406
+ #textFromPieces() {
407
+ const chunks = [];
408
+ this.#forEachPieceSegment((segment) => {
409
+ chunks.push(segment.text.slice(segment.start, segment.end));
410
+ });
411
+ return chunks.join("");
412
+ }
413
+ #forEachPieceSegment(callback) {
414
+ this.#walk(this.#root, (node) => {
415
+ const buffer = this.#bufferFor(node.piece.source);
416
+ return callback({
417
+ text: buffer.text,
418
+ lineOffsets: buffer.lineOffsets,
419
+ lineOffsetStart: node.piece.lineOffsetStart,
420
+ lineOffsetEnd: node.piece.lineOffsetEnd,
421
+ start: node.piece.offset,
422
+ end: node.piece.offset + node.piece.length
423
+ });
424
+ });
425
+ }
426
+ #bufferFor(source) {
427
+ return source === Piece.Original ? this.#original : this.#add;
428
+ }
429
+ #createPiece(source, offset, length) {
430
+ const buffer = this.#bufferFor(source);
431
+ const end = offset + length;
432
+ const lineOffsetStart = upperBound(buffer.lineOffsets, offset);
433
+ const lineOffsetEnd = upperBound(buffer.lineOffsets, end);
434
+ const lastCharCode = buffer.text.charCodeAt(end - 1);
435
+ return new Piece(source, offset, length, lineOffsetStart, lineOffsetEnd, lastCharCode === CARRIAGE_RETURN && buffer.lineOffsets[lineOffsetEnd - 1] !== end, buffer.text.charCodeAt(offset), lastCharCode);
436
+ }
437
+ #replaceRangeIncremental(start, end, text) {
438
+ if (start === end && text.length === 0) return;
439
+ const [left, rest] = this.#split(this.#root, start);
440
+ const [, right] = this.#split(rest, end - start);
441
+ let root;
442
+ if (text.length > 0) {
443
+ const insertedPiece = this.#createPiece(Piece.Added, this.#add.append(text), text.length);
444
+ root = this.#mergeNodes(this.#appendCoalescing(left, insertedPiece), right);
445
+ } else {
446
+ const [seamPiece, restRight] = this.#popLeftmost(right);
447
+ root = seamPiece === void 0 ? left : this.#mergeNodes(this.#appendCoalescing(left, seamPiece), restRight);
448
+ }
449
+ if (root !== null) root.parent = null;
450
+ this.#root = root;
451
+ this.#length = root?.subtreeLength ?? 0;
452
+ this.#lineCount = (root?.subtreeLineBreakCount ?? 0) + 1;
453
+ this.#lastVisitedLine = null;
454
+ this.#lastVisitedLineLength = null;
455
+ }
456
+ #nextPriority() {
457
+ this.#priorityState = Math.imul(this.#priorityState, 1664525) + 1013904223 >>> 0;
458
+ return this.#priorityState;
459
+ }
460
+ #createNode(piece) {
461
+ const node = new PieceNode(piece);
462
+ node.priority = this.#nextPriority();
463
+ return node;
464
+ }
465
+ #setLeft(node, child) {
466
+ node.left = child;
467
+ if (child !== null) child.parent = node;
468
+ }
469
+ #setRight(node, child) {
470
+ node.right = child;
471
+ if (child !== null) child.parent = node;
472
+ }
473
+ #split(node, offset) {
474
+ if (node === null) return [null, null];
475
+ const leftLength = node.left?.subtreeLength ?? 0;
476
+ if (offset <= leftLength) {
477
+ const [left, right] = this.#split(node.left, offset);
478
+ this.#setLeft(node, right);
479
+ node.updateSubtreeLength();
480
+ return [left, node];
481
+ }
482
+ const pieceLength = node.piece.length;
483
+ if (offset >= leftLength + pieceLength) {
484
+ const [left, right] = this.#split(node.right, offset - leftLength - pieceLength);
485
+ this.#setRight(node, left);
486
+ node.updateSubtreeLength();
487
+ return [node, right];
488
+ }
489
+ const inPiece = offset - leftLength;
490
+ const leftNode = new PieceNode(this.#createPiece(node.piece.source, node.piece.offset, inPiece));
491
+ const rightNode = new PieceNode(this.#createPiece(node.piece.source, node.piece.offset + inPiece, pieceLength - inPiece));
492
+ leftNode.priority = node.priority;
493
+ rightNode.priority = node.priority;
494
+ this.#setLeft(leftNode, node.left);
495
+ this.#setRight(rightNode, node.right);
496
+ leftNode.updateSubtreeLength();
497
+ rightNode.updateSubtreeLength();
498
+ return [leftNode, rightNode];
499
+ }
500
+ #mergeNodes(left, right) {
501
+ if (left === null) return right;
502
+ if (right === null) return left;
503
+ if (left.priority >= right.priority) {
504
+ this.#setRight(left, this.#mergeNodes(left.right, right));
505
+ left.updateSubtreeLength();
506
+ return left;
507
+ }
508
+ this.#setLeft(right, this.#mergeNodes(left, right.left));
509
+ right.updateSubtreeLength();
510
+ return right;
511
+ }
512
+ #appendCoalescing(tree, piece) {
513
+ if (tree === null) return this.#createNode(piece);
514
+ let last = tree;
515
+ while (last.right !== null) last = last.right;
516
+ if (canCoalescePieces(last.piece, piece)) {
517
+ last.piece = coalesceTwoPieces(last.piece, piece);
518
+ for (let node = last; node !== null;) {
519
+ node.updateSubtreeLength();
520
+ if (node === tree) break;
521
+ node = node.parent;
522
+ }
523
+ return tree;
524
+ }
525
+ return this.#mergeNodes(tree, this.#createNode(piece));
526
+ }
527
+ #popLeftmost(tree) {
528
+ if (tree === null) return [void 0, null];
529
+ if (tree.left === null) return [tree.piece, tree.right];
530
+ const [piece, newLeft] = this.#popLeftmost(tree.left);
531
+ this.#setLeft(tree, newLeft);
532
+ tree.updateSubtreeLength();
533
+ return [piece, tree];
534
+ }
535
+ #walk(node, visit) {
536
+ if (node === null) return true;
537
+ if (!this.#walk(node.left, visit)) return false;
538
+ if (visit(node) === false) return false;
539
+ return this.#walk(node.right, visit);
540
+ }
541
+ };
542
+ function isEOL(charCode) {
543
+ return charCode === 10 || charCode === 13;
544
+ }
545
+ function clamp(value, min, max) {
546
+ return Math.min(Math.max(value, min), max);
547
+ }
548
+ function createPrefixTable(text) {
549
+ const table = Array.from({ length: text.length }).fill(0);
550
+ let matched = 0;
551
+ for (let i = 1; i < text.length; i++) {
552
+ const charCode = text.charCodeAt(i);
553
+ while (matched > 0 && charCode !== text.charCodeAt(matched)) matched = table[matched - 1];
554
+ if (charCode === text.charCodeAt(matched)) matched++;
555
+ table[i] = matched;
556
+ }
557
+ return table;
558
+ }
559
+ function normalizeRanges(ranges, length) {
560
+ const normalized = [];
561
+ for (const [rawStart, rawEnd] of ranges) {
562
+ const start = clamp(rawStart, 0, length);
563
+ const end = clamp(rawEnd, start, length);
564
+ if (start < end) normalized.push([start, end]);
565
+ }
566
+ normalized.sort((a, b) => a[0] - b[0]);
567
+ const merged = [];
568
+ for (const range of normalized) {
569
+ const previous = merged[merged.length - 1];
570
+ if (previous !== void 0 && range[0] <= previous[1]) {
571
+ previous[1] = Math.max(previous[1], range[1]);
572
+ continue;
573
+ }
574
+ merged.push(range);
575
+ }
576
+ return merged;
577
+ }
578
+ function rangeOverlaps(ranges, start, end) {
579
+ let low = 0;
580
+ let high = ranges.length;
581
+ while (low < high) {
582
+ const mid = low + Math.floor((high - low) / 2);
583
+ if (ranges[mid][1] <= start) low = mid + 1;
584
+ else high = mid;
585
+ }
586
+ const range = ranges[low];
587
+ return range !== void 0 && range[0] < end;
588
+ }
589
+ function canCoalescePieces(prev, next) {
590
+ return prev.source === next.source && prev.offset + prev.length === next.offset && !formsCRLF(prev.lastCharCode, next.firstCharCode);
591
+ }
592
+ function coalesceTwoPieces(prev, next) {
593
+ return new Piece(prev.source, prev.offset, prev.length + next.length, prev.lineOffsetStart, next.lineOffsetEnd, next.hasVirtualTrailingCRBreak, prev.firstCharCode, next.lastCharCode);
594
+ }
595
+ function formsCRLF(leftCharCode, rightCharCode) {
596
+ return leftCharCode === CARRIAGE_RETURN && rightCharCode === LINE_FEED;
597
+ }
598
+ function upperBound(values, target) {
599
+ let lo = 0;
600
+ let hi = values.length;
601
+ while (lo < hi) {
602
+ const mid = lo + Math.floor((hi - lo) / 2);
603
+ if (values[mid] <= target) lo = mid + 1;
604
+ else hi = mid;
605
+ }
606
+ return lo;
607
+ }
608
+ function escapeRegExp(text) {
609
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
610
+ }
611
+ function isWordSeparatorCharCode(charCode) {
612
+ if (charCode <= 32 || charCode === 127) return true;
613
+ const ch = String.fromCharCode(charCode);
614
+ return WORD_SEPARATORS.includes(ch);
615
+ }
616
+ function isWholeWordAtDocOffsets(docStart, length, docLength, charAt) {
617
+ const beforeOk = docStart <= 0 || isWordSeparatorCharCode(charCodeUnitAt(charAt, docStart - 1));
618
+ const afterOk = docStart + length >= docLength || isWordSeparatorCharCode(charCodeUnitAt(charAt, docStart + length));
619
+ return beforeOk && afterOk;
620
+ }
621
+ function charCodeUnitAt(charAt, offset) {
622
+ const unit = charAt(offset);
623
+ return unit.length === 0 ? 0 : unit.charCodeAt(0);
624
+ }
625
+ function compileSearchRegExp(source, isRegex, caseSensitive) {
626
+ const body = isRegex ? source : escapeRegExp(source);
627
+ return new RegExp(body, `g${caseSensitive ? "" : "i"}${isRegex ? "m" : ""}`);
628
+ }
629
+ /** Expands `$&`, `$1`, `$$`, etc. in a regex replace string using a match. */
630
+ function expandReplaceString(replacement, match) {
631
+ return replacement.replace(/\$([$&]|\d+)/g, (_token, group) => {
632
+ if (group === "$") return "$";
633
+ if (group === "&") return match[0] ?? "";
634
+ return match[Number(group)] ?? "";
635
+ });
636
+ }
637
+ /**
638
+ * Builds the text to insert for one search match, including regex capture
639
+ * substitution when regex mode is enabled.
640
+ */
641
+ function buildSearchReplacementText(positionAt, offsetAt, getLineText, searchParams, matchStart, matchEnd) {
642
+ if (!searchParams.regex) return searchParams.replaceText;
643
+ const position = positionAt(matchStart);
644
+ const lineText = getLineText(position.line);
645
+ const relStart = matchStart - offsetAt({
646
+ line: position.line,
647
+ character: 0
648
+ });
649
+ let pattern;
650
+ try {
651
+ pattern = compileSearchRegExp(searchParams.text, true, searchParams.caseSensitive);
652
+ } catch {
653
+ return searchParams.replaceText;
654
+ }
655
+ pattern.lastIndex = relStart;
656
+ const match = pattern.exec(lineText);
657
+ if (match === null || match.index !== relStart || match[0].length !== matchEnd - matchStart) return searchParams.replaceText;
658
+ return expandReplaceString(searchParams.replaceText, match);
659
+ }
660
+ function advancePastEmptyMatch(text, index) {
661
+ if (index + 1 < text.length) {
662
+ const first = text.charCodeAt(index);
663
+ const second = text.charCodeAt(index + 1);
664
+ if (first >= 55296 && first <= 56319 && second >= 56320 && second <= 57343) return index + 2;
665
+ }
666
+ return index + 1;
667
+ }
668
+ //#endregion
669
+ export { PieceTable, buildSearchReplacementText };
670
+
671
+ //# sourceMappingURL=pieceTable.js.map