@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,318 @@
1
+ import { isPrimaryModifier } from "./platform.js";
2
+ import { resolveFindAgainShortcut } from "./command.js";
3
+ import { h } from "./utils.js";
4
+ import { buildSearchReplacementText } from "./pieceTable.js";
5
+ import { getEditorIconSvg } from "./sprite.js";
6
+ //#region src/editor/searchPanel.ts
7
+ var SearchPanelWidget = class {
8
+ #container;
9
+ #inputElement;
10
+ #updateMatches;
11
+ #applyMode;
12
+ #navigate;
13
+ #close;
14
+ constructor(options) {
15
+ const { textDocument, containerElement, defaultQuery, mode = "find", initialMatch, scrollToMatch, applyReplace, onUpdate, onClose } = options;
16
+ const searchParams = {
17
+ text: defaultQuery,
18
+ replaceText: "",
19
+ caseSensitive: false,
20
+ wholeWord: false,
21
+ regex: false
22
+ };
23
+ const matches = {
24
+ all: [],
25
+ current: void 0
26
+ };
27
+ const matchResultElement = h("div", {
28
+ dataset: {
29
+ matches: "",
30
+ noMatches: ""
31
+ },
32
+ textContent: "No results"
33
+ });
34
+ const updateMatches = (options) => {
35
+ matches.all = searchParams.text !== "" ? textDocument.search(searchParams) : [];
36
+ const noMatches = matches.all.length === 0;
37
+ prevButton.disabled = noMatches;
38
+ nextButton.disabled = noMatches;
39
+ if (noMatches) {
40
+ matchResultElement.textContent = "No results";
41
+ matchResultElement.dataset.noMatches = "";
42
+ matches.current = void 0;
43
+ onUpdate([]);
44
+ return;
45
+ }
46
+ delete matchResultElement.dataset.noMatches;
47
+ if (options?.syncSelection === false) {
48
+ updateCurrentMatch(onUpdate(matches.all, { syncSelection: false }));
49
+ return;
50
+ }
51
+ updateCurrentMatch(onUpdate(matches.all));
52
+ };
53
+ this.#updateMatches = updateMatches;
54
+ const updateCurrentMatch = (currentMatch) => {
55
+ if (currentMatch === void 0) matchResultElement.textContent = `${matches.all.length} results`;
56
+ else {
57
+ const [start, end] = currentMatch;
58
+ matchResultElement.textContent = `${matches.all.findIndex((m) => m[0] === start && m[1] === end) + 1} of ${matches.all.length}`;
59
+ }
60
+ matches.current = currentMatch;
61
+ };
62
+ const updateSearchParam = (key, value) => {
63
+ searchParams[key] = value;
64
+ updateMatches();
65
+ };
66
+ const findNextMatch = (findPrevious = false, retainFocus = false) => {
67
+ const allMatches = matches.all;
68
+ let nextMatch = allMatches[0];
69
+ if (allMatches.length > 0) if (findPrevious) {
70
+ const searchOffset = matches.current?.[0] ?? 0;
71
+ nextMatch = allMatches.at(-1);
72
+ for (const m of allMatches) if (m[1] <= searchOffset) nextMatch = m;
73
+ else break;
74
+ } else {
75
+ const searchOffset = matches.current?.[1] ?? 0;
76
+ for (const m of allMatches) if (m[0] >= searchOffset) {
77
+ nextMatch = m;
78
+ break;
79
+ }
80
+ }
81
+ if (nextMatch !== void 0) {
82
+ updateCurrentMatch(nextMatch);
83
+ scrollToMatch(nextMatch, retainFocus);
84
+ }
85
+ matches.current = nextMatch;
86
+ };
87
+ this.#navigate = (findPrevious) => findNextMatch(findPrevious, true);
88
+ const buildReplacementEdit = (matchStart, matchEnd) => ({
89
+ start: matchStart,
90
+ end: matchEnd,
91
+ text: buildSearchReplacementText((offset) => textDocument.positionAt(offset), (position) => textDocument.offsetAt(position), (line) => textDocument.getLineText(line), searchParams, matchStart, matchEnd)
92
+ });
93
+ const replace = () => {
94
+ if (searchParams.text === "" || matches.all.length === 0) return;
95
+ let currentMatch = matches.current;
96
+ if (currentMatch === void 0) {
97
+ findNextMatch(false, true);
98
+ currentMatch = matches.current;
99
+ if (currentMatch === void 0) return;
100
+ }
101
+ const [start, end] = currentMatch;
102
+ const edit = buildReplacementEdit(start, end);
103
+ applyReplace([edit]);
104
+ scrollToMatch([start + edit.text.length, start + edit.text.length], true);
105
+ matches.current = void 0;
106
+ updateMatches();
107
+ };
108
+ const replaceAll = () => {
109
+ if (searchParams.text === "" || matches.all.length === 0) return;
110
+ applyReplace(matches.all.map(([start, end]) => buildReplacementEdit(start, end)));
111
+ matches.current = void 0;
112
+ updateMatches();
113
+ };
114
+ const close = () => {
115
+ this.cleanup();
116
+ onClose();
117
+ };
118
+ this.#close = close;
119
+ const iconButton = (opts) => h("button", {
120
+ type: "button",
121
+ title: opts.label,
122
+ ariaLabel: opts.label,
123
+ dataset: {
124
+ searchIcon: "",
125
+ ...opts.dataset
126
+ },
127
+ innerHTML: getEditorIconSvg(opts.icon, opts.size ?? 16),
128
+ onclick: opts.onClick
129
+ });
130
+ const makeToggle = (icon, title, key) => {
131
+ const button = iconButton({
132
+ icon,
133
+ label: title,
134
+ size: 14,
135
+ onClick: () => {
136
+ const next = !searchParams[key];
137
+ button.ariaPressed = String(next);
138
+ updateSearchParam(key, next);
139
+ }
140
+ });
141
+ button.ariaPressed = String(searchParams[key]);
142
+ return button;
143
+ };
144
+ const caseSensitiveToggle = makeToggle("case", "Match Case", "caseSensitive");
145
+ const wholeWordToggle = makeToggle("whole-word", "Whole Word", "wholeWord");
146
+ const regexToggle = makeToggle("regex", "Regexp", "regex");
147
+ const replaceInputElement = h("input", {
148
+ type: "text",
149
+ placeholder: "Replace",
150
+ dataset: "replace",
151
+ value: "",
152
+ oninput: (e) => {
153
+ searchParams.replaceText = e.target.value;
154
+ },
155
+ onkeydown: (e) => {
156
+ if (e.isComposing) return;
157
+ const findAgain = resolveFindAgainShortcut(e);
158
+ if (e.key === "Escape") {
159
+ e.preventDefault();
160
+ close();
161
+ } else if (e.key === "Enter") {
162
+ e.preventDefault();
163
+ replace();
164
+ } else if (findAgain !== void 0) {
165
+ e.preventDefault();
166
+ findNextMatch(findAgain === "previous", true);
167
+ }
168
+ }
169
+ });
170
+ this.#inputElement = h("input", {
171
+ type: "text",
172
+ placeholder: "Search",
173
+ dataset: "search",
174
+ value: defaultQuery,
175
+ oninput: (e) => {
176
+ searchParams.text = e.target.value;
177
+ matches.current = void 0;
178
+ updateMatches();
179
+ },
180
+ onkeydown: (e) => {
181
+ const findAgain = resolveFindAgainShortcut(e);
182
+ if (e.key === "Escape") {
183
+ e.preventDefault();
184
+ close();
185
+ } else if (e.key === "Enter") {
186
+ e.preventDefault();
187
+ findNextMatch(e.shiftKey, true);
188
+ } else if (findAgain !== void 0) {
189
+ e.preventDefault();
190
+ findNextMatch(findAgain === "previous", true);
191
+ } else if (isPrimaryModifier(e) && (e.key === "f" || e.code === "KeyF")) {
192
+ e.preventDefault();
193
+ applyMode(e.altKey ? "replace" : "find");
194
+ }
195
+ }
196
+ });
197
+ const searchTogglesElement = h("div", {
198
+ dataset: "searchToggles",
199
+ children: [
200
+ caseSensitiveToggle,
201
+ wholeWordToggle,
202
+ regexToggle
203
+ ]
204
+ });
205
+ const findInputBox = h("div", {
206
+ dataset: {
207
+ inputBox: "",
208
+ find: ""
209
+ },
210
+ children: [this.#inputElement, searchTogglesElement]
211
+ });
212
+ const replaceInputBox = h("div", {
213
+ dataset: {
214
+ inputBox: "",
215
+ replace: "",
216
+ replaceCell: ""
217
+ },
218
+ children: [replaceInputElement]
219
+ });
220
+ const replaceActionsElement = h("div", {
221
+ dataset: {
222
+ replaceActions: "",
223
+ replaceCell: ""
224
+ },
225
+ children: [iconButton({
226
+ icon: "replace",
227
+ label: "Replace",
228
+ onClick: replace
229
+ }), iconButton({
230
+ icon: "replace-all",
231
+ label: "Replace All",
232
+ onClick: replaceAll
233
+ })]
234
+ });
235
+ const prevButton = iconButton({
236
+ icon: "arrow-up",
237
+ label: "Previous",
238
+ onClick: () => {
239
+ findNextMatch(true);
240
+ }
241
+ });
242
+ const nextButton = iconButton({
243
+ icon: "arrow-down",
244
+ label: "Next",
245
+ onClick: () => {
246
+ findNextMatch();
247
+ }
248
+ });
249
+ prevButton.disabled = true;
250
+ nextButton.disabled = true;
251
+ const navElement = h("div", {
252
+ dataset: "searchNav",
253
+ children: [prevButton, nextButton]
254
+ });
255
+ const closeElement = iconButton({
256
+ icon: "close",
257
+ label: "Close",
258
+ onClick: close,
259
+ dataset: { searchClose: "" }
260
+ });
261
+ const gridElement = h("div", {
262
+ dataset: {
263
+ searchGrid: "",
264
+ mode
265
+ },
266
+ children: [
267
+ findInputBox,
268
+ replaceInputBox,
269
+ replaceActionsElement,
270
+ matchResultElement,
271
+ navElement,
272
+ closeElement
273
+ ]
274
+ });
275
+ const applyMode = (next) => {
276
+ gridElement.dataset.mode = next;
277
+ this.#inputElement.focus();
278
+ this.#inputElement.select();
279
+ };
280
+ this.#applyMode = applyMode;
281
+ this.#container = h("div", {
282
+ dataset: "searchPanel",
283
+ children: [h("div", {
284
+ dataset: "editorWidget",
285
+ children: [gridElement]
286
+ })]
287
+ });
288
+ matches.current = initialMatch;
289
+ containerElement.before(this.#container);
290
+ requestAnimationFrame(() => {
291
+ if (initialMatch !== void 0) updateMatches();
292
+ else onUpdate([]);
293
+ this.#inputElement.select();
294
+ });
295
+ }
296
+ focus() {
297
+ this.#inputElement.focus();
298
+ }
299
+ navigate(findPrevious) {
300
+ this.#navigate?.(findPrevious);
301
+ }
302
+ updateMatches(options) {
303
+ this.#updateMatches?.(options);
304
+ }
305
+ setMode(mode) {
306
+ this.#applyMode?.(mode);
307
+ }
308
+ close() {
309
+ this.#close?.();
310
+ }
311
+ cleanup() {
312
+ this.#container.remove();
313
+ }
314
+ };
315
+ //#endregion
316
+ export { SearchPanelWidget };
317
+
318
+ //# sourceMappingURL=searchPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchPanel.js","names":["#updateMatches","#navigate","#close","#inputElement","#applyMode","#container"],"sources":["../../src/editor/searchPanel.ts"],"sourcesContent":["import { resolveFindAgainShortcut } from './command';\nimport { buildSearchReplacementText } from './pieceTable';\nimport { isPrimaryModifier } from './platform';\nimport { getEditorIconSvg, type SVGSpriteNames } from './sprite';\nimport type { ResolvedTextEdit, TextDocument } from './textDocument';\nimport { h } from './utils';\n\nexport type MatchRange = [startOffset: number, endOffset: number];\n\nexport type SearchPanelMode = 'find' | 'replace';\n\nexport interface SearchParams {\n text: string;\n replaceText: string;\n caseSensitive: boolean;\n wholeWord: boolean;\n regex: boolean;\n}\n\nexport interface SearchPanelOptions {\n textDocument: TextDocument<unknown>;\n containerElement: HTMLElement;\n defaultQuery: string;\n mode?: SearchPanelMode;\n initialMatch?: MatchRange;\n scrollToMatch: (nextMatch: MatchRange, retainFocus: boolean) => void;\n applyReplace: (edits: ResolvedTextEdit[]) => void;\n onUpdate: (\n matches: MatchRange[],\n options?: { syncSelection?: boolean }\n ) => MatchRange | undefined;\n onClose: () => void;\n}\n\nexport class SearchPanelWidget {\n #container: HTMLDivElement;\n #inputElement: HTMLInputElement;\n #updateMatches?: (options?: { syncSelection?: boolean }) => void;\n #applyMode?: (mode: SearchPanelMode) => void;\n #navigate?: (findPrevious: boolean) => void;\n #close?: () => void;\n\n constructor(options: SearchPanelOptions) {\n const {\n textDocument,\n containerElement,\n defaultQuery,\n mode = 'find',\n initialMatch,\n scrollToMatch,\n applyReplace,\n onUpdate,\n onClose,\n } = options;\n\n const searchParams: SearchParams = {\n text: defaultQuery,\n replaceText: '',\n caseSensitive: false,\n wholeWord: false,\n regex: false,\n };\n\n const matches = {\n all: [] as MatchRange[],\n current: undefined as MatchRange | undefined,\n };\n\n // Default to the empty-query \"no results\" state so it shows on open before\n // any search runs.\n const matchResultElement = h('div', {\n dataset: { matches: '', noMatches: '' },\n textContent: 'No results',\n });\n const updateMatches = (options?: { syncSelection?: boolean }) => {\n matches.all =\n searchParams.text !== '' ? textDocument.search(searchParams) : [];\n const noMatches = matches.all.length === 0;\n prevButton.disabled = noMatches;\n nextButton.disabled = noMatches;\n\n // An empty query and a query with zero hits are the same \"no results\"\n // state. Both push an empty match set through onUpdate so the editor\n // drops #matches and clears the painted highlights.\n if (noMatches) {\n matchResultElement.textContent = 'No results';\n matchResultElement.dataset.noMatches = '';\n matches.current = undefined;\n onUpdate([]);\n return;\n }\n\n delete matchResultElement.dataset.noMatches;\n if (options?.syncSelection === false) {\n const currentMatch = onUpdate(matches.all, { syncSelection: false });\n updateCurrentMatch(currentMatch);\n return;\n }\n\n updateCurrentMatch(onUpdate(matches.all));\n };\n this.#updateMatches = updateMatches;\n\n const updateCurrentMatch = (currentMatch: MatchRange | undefined) => {\n if (currentMatch === undefined) {\n matchResultElement.textContent = `${matches.all.length} results`;\n } else {\n const [start, end] = currentMatch;\n const index = matches.all.findIndex(\n (m) => m[0] === start && m[1] === end\n );\n matchResultElement.textContent = `${index + 1} of ${matches.all.length}`;\n }\n matches.current = currentMatch;\n };\n\n const updateSearchParam = <K extends keyof SearchParams>(\n key: K,\n value: SearchParams[K]\n ) => {\n searchParams[key] = value;\n updateMatches();\n };\n\n const findNextMatch = (\n findPrevious: boolean = false,\n retainFocus: boolean = false\n ) => {\n const allMatches = matches.all;\n let nextMatch: MatchRange | undefined = allMatches[0];\n if (allMatches.length > 0) {\n if (findPrevious) {\n const searchOffset = matches.current?.[0] ?? 0;\n nextMatch = allMatches.at(-1);\n for (const m of allMatches) {\n if (m[1] <= searchOffset) {\n nextMatch = m;\n } else {\n break;\n }\n }\n } else {\n const searchOffset = matches.current?.[1] ?? 0;\n for (const m of allMatches) {\n if (m[0] >= searchOffset) {\n nextMatch = m;\n break;\n }\n }\n }\n }\n if (nextMatch !== undefined) {\n updateCurrentMatch(nextMatch);\n scrollToMatch(nextMatch, retainFocus);\n }\n matches.current = nextMatch;\n };\n // Keep focus in the panel when stepping through matches from the inputs.\n this.#navigate = (findPrevious: boolean) =>\n findNextMatch(findPrevious, true);\n\n const buildReplacementEdit = (\n matchStart: number,\n matchEnd: number\n ): ResolvedTextEdit => ({\n start: matchStart,\n end: matchEnd,\n text: buildSearchReplacementText(\n (offset) => textDocument.positionAt(offset),\n (position) => textDocument.offsetAt(position),\n (line) => textDocument.getLineText(line),\n searchParams,\n matchStart,\n matchEnd\n ),\n });\n\n const replace = () => {\n if (searchParams.text === '' || matches.all.length === 0) {\n return;\n }\n\n let currentMatch = matches.current;\n if (currentMatch === undefined) {\n findNextMatch(false, true);\n currentMatch = matches.current;\n if (currentMatch === undefined) {\n return;\n }\n }\n\n const [start, end] = currentMatch;\n const edit = buildReplacementEdit(start, end);\n applyReplace([edit]);\n\n // Collapse after the replacement so the next search pass advances.\n scrollToMatch([start + edit.text.length, start + edit.text.length], true);\n matches.current = undefined;\n updateMatches();\n };\n\n const replaceAll = () => {\n if (searchParams.text === '' || matches.all.length === 0) {\n return;\n }\n\n applyReplace(\n matches.all.map(([start, end]) => buildReplacementEdit(start, end))\n );\n matches.current = undefined;\n updateMatches();\n };\n\n const close = () => {\n this.cleanup();\n onClose();\n };\n this.#close = close;\n\n // Shared builder for the panel's icon controls. Every clickable control is a\n // real <button> so it gets focus, keyboard activation, and native disabled\n // handling for free; `getEditorIconSvg` marks the glyph aria-hidden, so the\n // accessible name comes from `label` (also used as the hover title).\n const iconButton = (opts: {\n icon: SVGSpriteNames;\n label: string;\n size?: number;\n dataset?: Record<string, string>;\n onClick: () => void;\n }) =>\n h('button', {\n type: 'button',\n title: opts.label,\n ariaLabel: opts.label,\n dataset: { searchIcon: '', ...opts.dataset },\n innerHTML: getEditorIconSvg(opts.icon, opts.size ?? 16),\n onclick: opts.onClick,\n });\n\n // Builds an always-visible icon button that toggles one boolean search\n // option (case/whole-word/regex). The button reflects its on/off state via\n // `aria-pressed` so the stylesheet can highlight it and assistive tech can\n // announce it.\n const makeToggle = (\n icon: SVGSpriteNames,\n title: string,\n key: 'caseSensitive' | 'wholeWord' | 'regex'\n ) => {\n const button = iconButton({\n icon,\n label: title,\n size: 14,\n onClick: () => {\n const next = !searchParams[key];\n button.ariaPressed = String(next);\n updateSearchParam(key, next);\n },\n });\n button.ariaPressed = String(searchParams[key]);\n return button;\n };\n\n const caseSensitiveToggle = makeToggle(\n 'case',\n 'Match Case',\n 'caseSensitive'\n );\n const wholeWordToggle = makeToggle('whole-word', 'Whole Word', 'wholeWord');\n const regexToggle = makeToggle('regex', 'Regexp', 'regex');\n\n const replaceInputElement = h('input', {\n type: 'text',\n placeholder: 'Replace',\n dataset: 'replace',\n value: '',\n oninput: (e: Event) => {\n searchParams.replaceText = (e.target as HTMLInputElement).value;\n },\n onkeydown: (e: KeyboardEvent) => {\n if (e.isComposing) {\n return;\n }\n const findAgain = resolveFindAgainShortcut(e);\n if (e.key === 'Escape') {\n e.preventDefault();\n close();\n } else if (e.key === 'Enter') {\n e.preventDefault();\n replace();\n } else if (findAgain !== undefined) {\n e.preventDefault();\n findNextMatch(findAgain === 'previous', true);\n }\n },\n });\n\n this.#inputElement = h('input', {\n type: 'text',\n placeholder: 'Search',\n dataset: 'search',\n value: defaultQuery,\n oninput: (e: Event) => {\n searchParams.text = (e.target as HTMLInputElement).value;\n matches.current = undefined;\n updateMatches();\n },\n onkeydown: (e: KeyboardEvent) => {\n const findAgain = resolveFindAgainShortcut(e);\n if (e.key === 'Escape') {\n e.preventDefault();\n close();\n } else if (e.key === 'Enter') {\n e.preventDefault();\n findNextMatch(e.shiftKey, true);\n } else if (findAgain !== undefined) {\n // Override the native browser find-again shortcut so cmd+g steps to\n // the next match and cmd+shift+g to the previous one.\n e.preventDefault();\n findNextMatch(findAgain === 'previous', true);\n } else if (\n isPrimaryModifier(e) &&\n (e.key === 'f' || e.code === 'KeyF')\n ) {\n // Prevent the default browser search panel and switch the panel mode\n // in place (cmd+f -> find, cmd+opt+f -> find/replace).\n e.preventDefault();\n applyMode(e.altKey ? 'replace' : 'find');\n }\n },\n });\n\n // The three search-option toggles are overlaid on the right edge of the\n // find input instead of sitting beside it.\n const searchTogglesElement = h('div', {\n dataset: 'searchToggles',\n children: [caseSensitiveToggle, wholeWordToggle, regexToggle],\n });\n\n const findInputBox = h('div', {\n dataset: { inputBox: '', find: '' },\n children: [this.#inputElement, searchTogglesElement],\n });\n\n // The replace input and its action buttons are tagged as replace cells so\n // they can be hidden together when the panel is in find-only mode.\n const replaceInputBox = h('div', {\n dataset: { inputBox: '', replace: '', replaceCell: '' },\n children: [replaceInputElement],\n });\n\n const replaceActionsElement = h('div', {\n dataset: { replaceActions: '', replaceCell: '' },\n children: [\n iconButton({ icon: 'replace', label: 'Replace', onClick: replace }),\n iconButton({\n icon: 'replace-all',\n label: 'Replace All',\n onClick: replaceAll,\n }),\n ],\n });\n\n // Held so the no-results state can toggle their native disabled flag.\n const prevButton = iconButton({\n icon: 'arrow-up',\n label: 'Previous',\n onClick: () => {\n findNextMatch(true);\n },\n });\n const nextButton = iconButton({\n icon: 'arrow-down',\n label: 'Next',\n onClick: () => {\n findNextMatch();\n },\n });\n prevButton.disabled = true;\n nextButton.disabled = true;\n\n const navElement = h('div', {\n dataset: 'searchNav',\n children: [prevButton, nextButton],\n });\n\n const closeElement = iconButton({\n icon: 'close',\n label: 'Close',\n onClick: close,\n dataset: { searchClose: '' },\n });\n\n // Cells are positioned by CSS grid-template-areas (see editor.css), so DOM\n // order here only drives tab/reading order, not layout. Keep the replace\n // input directly after the find input (and its toggles) so Tab walks\n // find -> replace before reaching the nav arrows and close button.\n const gridElement = h('div', {\n dataset: { searchGrid: '', mode },\n children: [\n findInputBox,\n replaceInputBox,\n replaceActionsElement,\n matchResultElement,\n navElement,\n closeElement,\n ],\n });\n\n // Toggles the panel between find and find/replace modes by showing or\n // hiding the replace cells, then returns focus to the find input.\n const applyMode = (next: SearchPanelMode) => {\n gridElement.dataset.mode = next;\n this.#inputElement.focus();\n this.#inputElement.select();\n };\n this.#applyMode = applyMode;\n\n this.#container = h('div', {\n dataset: 'searchPanel',\n children: [\n h('div', {\n dataset: 'editorWidget',\n children: [gridElement],\n }),\n ],\n });\n\n matches.current = initialMatch;\n containerElement.before(this.#container);\n\n requestAnimationFrame(() => {\n if (initialMatch !== undefined) {\n updateMatches();\n } else {\n onUpdate([]);\n }\n this.#inputElement.select();\n });\n }\n\n focus(): void {\n this.#inputElement.focus();\n }\n\n navigate(findPrevious: boolean): void {\n this.#navigate?.(findPrevious);\n }\n\n updateMatches(options?: { syncSelection?: boolean }): void {\n this.#updateMatches?.(options);\n }\n\n setMode(mode: SearchPanelMode): void {\n this.#applyMode?.(mode);\n }\n\n // Tears the panel down the way the close button and Escape-in-input do:\n // removes the DOM and runs onClose so the editor clears its match highlights.\n // Prefer this over cleanup() for any user-initiated dismissal.\n close(): void {\n this.#close?.();\n }\n\n // DOM-only teardown. Does NOT run onClose, so it leaves the editor's match\n // highlights in place; only use it when the caller clears that state itself\n // (e.g. a full editor reset). User-initiated dismissals should call close().\n cleanup(): void {\n this.#container.remove();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,211 @@
1
+ import { DiffLineAnnotation, EditorSelection, Position, Range, SelectionDirection, TextEdit } from "../types.js";
2
+ import { ResolvedTextEdit, TextDocument, TextDocumentChange } from "./textDocument.js";
3
+
4
+ //#region src/editor/selection.d.ts
5
+ declare const DirectionBackward = -1;
6
+ declare const DirectionNone = 0;
7
+ declare const DirectionForward = 1;
8
+ interface CursorMoveOptions {
9
+ getSoftLineOffsets?: (line: number) => ArrayLike<number> | undefined;
10
+ /**
11
+ * Fold-skip resolver for vertical motion crossing document lines: the
12
+ * nearest renderable line at or beyond the target in the move direction,
13
+ * or undefined when everything that way is hidden inside a collapsed
14
+ * region (the caret then stays put). Soft-line moves within one document
15
+ * line never consult it.
16
+ */
17
+ resolveRenderableLine?: ResolveRenderableLine;
18
+ }
19
+ /**
20
+ * Converts a selection from a web selection to an editor selection.
21
+ */
22
+ declare function convertSelection(range: StaticRange, direction?: SelectionDirection): EditorSelection | undefined;
23
+ /**
24
+ * Resolves the indent edits for a selection.
25
+ */
26
+ declare function resolveIndentEdits(textDocument: TextDocument<unknown>, selection: EditorSelection, tabSize: number, outdent: boolean): [edits: TextEdit[], nextSelection: EditorSelection];
27
+ /**
28
+ * The nearest zero-based document line at or beyond `line` in `direction`
29
+ * that has a rendered row, or undefined when everything that way is hidden
30
+ * inside a collapsed region. Vertical caret motion uses it to skip collapsed
31
+ * regions atomically, like code folds.
32
+ */
33
+ type ResolveRenderableLine = (line: number, direction: 'up' | 'down') => number | undefined;
34
+ /**
35
+ * Maps the cursor move to all selections.
36
+ */
37
+ declare function mapCursorMove(textDocument: TextDocument<unknown>, selections: EditorSelection[], shortcut: 'textStart' | 'start' | 'end' | 'up' | 'down' | 'left' | 'right', options?: CursorMoveOptions): EditorSelection[];
38
+ /**
39
+ * Same as mapCursorMove, but with shift key pressed.
40
+ */
41
+ declare function mapSelectionShift(textDocument: TextDocument<unknown>, selections: EditorSelection[], shortcut: 'textStart' | 'start' | 'end' | 'up' | 'down' | 'left' | 'right', options?: CursorMoveOptions): EditorSelection[];
42
+ /**
43
+ * Applies a text change to the given text document
44
+ */
45
+ declare function applyTextChangeToSelections<LAnnotation>(textDocument: TextDocument<LAnnotation>, selections: EditorSelection[], edit: ResolvedTextEdit, lineAnnotations?: DiffLineAnnotation<LAnnotation>[], tabSize?: number, undoBoundary?: boolean): {
46
+ nextSelections: EditorSelection[];
47
+ change?: TextDocumentChange;
48
+ };
49
+ /**
50
+ * Applies text replacements to multiple selections. Texts pair by selection
51
+ * index unless they are explicitly marked as document ordered.
52
+ */
53
+ declare function applyTextReplaceToSelections<LAnnotation>(textDocument: TextDocument<LAnnotation>, selections: EditorSelection[], texts: string[], lineAnnotations?: DiffLineAnnotation<LAnnotation>[], undoBoundary?: boolean, textOrder?: 'selection' | 'document'): {
54
+ nextSelections: EditorSelection[];
55
+ change?: TextDocumentChange;
56
+ };
57
+ type AutoSurround = 'default' | 'never' | 'brackets' | 'quotes' | 'languageDefined';
58
+ /**
59
+ * Returns per-selection replacement text when typing a surround character over
60
+ * non-collapsed selections, matching VS Code auto-surround behavior.
61
+ */
62
+ declare function getAutoSurroundReplacementTexts<LAnnotation>(textDocument: TextDocument<LAnnotation>, selections: EditorSelection[], char: string, autoSurround?: AutoSurround): string[] | undefined;
63
+ /**
64
+ * Swaps the two characters adjacent to a collapsed selection, matching browser
65
+ * insertTranspose (Ctrl+T) behavior.
66
+ */
67
+ declare function applyTransposeToSelections<LAnnotation>(textDocument: TextDocument<LAnnotation>, selections: EditorSelection[], lineAnnotations?: DiffLineAnnotation<LAnnotation>[]): {
68
+ nextSelections: EditorSelection[];
69
+ change?: TextDocumentChange;
70
+ };
71
+ /**
72
+ * Deletes from each selection to the end of its line, including the line break
73
+ * when the caret is already at the end of a non-final line. Non-collapsed
74
+ * selections delete their selected text instead.
75
+ */
76
+ declare function applyDeleteHardLineForwardToSelections<LAnnotation>(textDocument: TextDocument<LAnnotation>, selections: EditorSelection[], lineAnnotations?: DiffLineAnnotation<LAnnotation>[]): {
77
+ nextSelections: EditorSelection[];
78
+ change?: TextDocumentChange;
79
+ };
80
+ /**
81
+ * Deletes from each selection back to the start of its soft (visual) line.
82
+ * Non-collapsed selections delete their selected text instead.
83
+ */
84
+ declare function applyDeleteSoftLineBackwardToSelections<LAnnotation>(textDocument: TextDocument<LAnnotation>, selections: EditorSelection[], getSoftLineStart?: (line: number, character: number) => number, lineAnnotations?: DiffLineAnnotation<LAnnotation>[]): {
85
+ nextSelections: EditorSelection[];
86
+ change?: TextDocumentChange;
87
+ };
88
+ /**
89
+ * Deletes the word or separator group immediately before each selection.
90
+ * Non-collapsed selections delete their selected text instead.
91
+ */
92
+ declare function applyDeleteWordBackwardToSelections<LAnnotation>(textDocument: TextDocument<LAnnotation>, selections: EditorSelection[], lineAnnotations?: DiffLineAnnotation<LAnnotation>[]): {
93
+ nextSelections: EditorSelection[];
94
+ change?: TextDocumentChange;
95
+ };
96
+ /**
97
+ * Resolves the document range deleted by Backspace or Delete at a collapsed
98
+ * caret. Non-collapsed selections delete their selected text instead.
99
+ */
100
+ declare function resolveDeleteCharacterRange(textDocument: TextDocument<unknown>, selection: EditorSelection, forward: boolean): [start: Position, end: Position];
101
+ /**
102
+ * Deletes one grapheme (or selected text) at each selection.
103
+ */
104
+ declare function applyDeleteCharacterToSelections<LAnnotation>(textDocument: TextDocument<LAnnotation>, selections: EditorSelection[], forward: boolean, lineAnnotations?: DiffLineAnnotation<LAnnotation>[], tabSize?: number): {
105
+ nextSelections: EditorSelection[];
106
+ change?: TextDocumentChange;
107
+ };
108
+ /**
109
+ * Checks if a selection is collapsed.
110
+ */
111
+ declare function isCollapsedSelection(selection: EditorSelection | Range): boolean;
112
+ /**
113
+ * Returns the caret (focus) position for a selection.
114
+ */
115
+ declare function getCaretPosition(selection: EditorSelection): Position;
116
+ /**
117
+ * Checks if a line is editable.
118
+ */
119
+ declare function isLineEditable(lineType: string): boolean;
120
+ /**
121
+ * Checks whether selections `a` and `b` intersect.
122
+ */
123
+ declare function selectionIntersects(a: EditorSelection | Range, b: EditorSelection | Range): boolean;
124
+ /**
125
+ * Compares two positions.
126
+ */
127
+ declare function comparePosition(a: Position, b: Position): number;
128
+ /**
129
+ * Creates a selection from anchor and focus offsets.
130
+ */
131
+ declare function createSelectionFromAnchorAndFocusOffsets(textDocument: TextDocument<unknown>, anchorOffset: number, focusOffset: number): EditorSelection;
132
+ /**
133
+ * Re-anchors selections after a batch of text edits has been applied, so the
134
+ * caret keeps pointing at the same logical location in the changed buffer.
135
+ *
136
+ * `selectionOffsets` (one `[start, end]` pair per selection) and `edits` are
137
+ * measured in the PRE-edit document; the returned selections are built from
138
+ * `textDocument`, which must already reflect the applied edits. Selection
139
+ * direction is preserved by remapping each edge and re-deriving anchor/focus.
140
+ */
141
+ declare function remapSelectionsAfterEdits(textDocument: TextDocument<unknown>, selections: readonly EditorSelection[], selectionOffsets: ReadonlyArray<readonly [number, number]>, edits: readonly ResolvedTextEdit[]): EditorSelection[];
142
+ /**
143
+ * Creates a selection from a anchor and focus selection.
144
+ */
145
+ declare function createSelectionFrom(anchorSelection: EditorSelection, focusSelection: EditorSelection): EditorSelection;
146
+ /**
147
+ * Extends or shrinks the selection `original` using the endpoints of `target`, \
148
+ * matching contenteditable shift + click extend behavior.
149
+ */
150
+ declare function extendSelection(original: EditorSelection, target: EditorSelection): EditorSelection;
151
+ /**
152
+ * Extends multiple selections.
153
+ */
154
+ declare function extendSelections(selections: EditorSelection[], target: EditorSelection): EditorSelection[];
155
+ /**
156
+ * Merges overlapping selections.
157
+ */
158
+ declare function mergeOverlappingSelections(selections: EditorSelection[]): EditorSelection[];
159
+ /**
160
+ * Converts selections into merged line blocks for line-based commands.
161
+ */
162
+ declare function getSelectedLineBlocks(selections: EditorSelection[]): {
163
+ startLine: number;
164
+ endLine: number;
165
+ }[];
166
+ /**
167
+ * Moves a selection's line positions after its lines are shifted, clamping to
168
+ * the target document bounds.
169
+ */
170
+ declare function shiftSelectionLines(selection: EditorSelection, direction: -1 | 1, lineCount: number, getLineLength: (line: number) => number): EditorSelection;
171
+ /**
172
+ * Finds the next matching word and updates the selections.
173
+ */
174
+ declare function findNexMatch(textDocument: TextDocument<unknown>, selections: EditorSelection[]): EditorSelection[] | undefined;
175
+ /**
176
+ * Get the full selection of the document.
177
+ */
178
+ declare function getDocumentFullSelection(textDocument: TextDocument<unknown>): EditorSelection;
179
+ /**
180
+ * Get the boundary selection of the document.
181
+ */
182
+ declare function getDocumentBoundarySelection(textDocument: TextDocument<unknown>, atEnd: boolean, trimmedEndNewLine?: boolean): EditorSelection;
183
+ /**
184
+ * Gets the text contributed by each selection in document order, preserving
185
+ * the pairing needed to paste the values into another set of selections.
186
+ */
187
+ declare function getSelectionClipboardTexts(textDocument: TextDocument<unknown>, selections: EditorSelection[]): string[];
188
+ /**
189
+ * Get the clipboard text of the selections for the given text document. Used by
190
+ * both copy and cut so the two stay in sync. Overlapping regions (e.g. several
191
+ * carets on one line) are merged so the same text is never emitted twice, and a
192
+ * line-ending separator is inserted only between regions that aren't already
193
+ * contiguous in the document.
194
+ */
195
+ declare function getSelectionText(textDocument: TextDocument<unknown>, selections: EditorSelection[]): string;
196
+ declare function resolveSelectionCut(textDocument: TextDocument<unknown>, selections: EditorSelection[]): {
197
+ text: string;
198
+ edits: ResolvedTextEdit[];
199
+ nextSelectionOffsets: number[];
200
+ };
201
+ /**
202
+ * Get the anchor node and offset for a selection.
203
+ */
204
+ declare function getSelectionAnchor(lineElement: HTMLElement, character: number): [Node, number];
205
+ /**
206
+ * Expands a zero-width selection to the word-like segment that contains the caret.
207
+ */
208
+ declare function expandCollapsedSelectionToWord(textDocument: TextDocument<unknown>, selection: EditorSelection): EditorSelection;
209
+ //#endregion
210
+ export { AutoSurround, CursorMoveOptions, DirectionBackward, DirectionForward, DirectionNone, ResolveRenderableLine, applyDeleteCharacterToSelections, applyDeleteHardLineForwardToSelections, applyDeleteSoftLineBackwardToSelections, applyDeleteWordBackwardToSelections, applyTextChangeToSelections, applyTextReplaceToSelections, applyTransposeToSelections, comparePosition, convertSelection, createSelectionFrom, createSelectionFromAnchorAndFocusOffsets, expandCollapsedSelectionToWord, extendSelection, extendSelections, findNexMatch, getAutoSurroundReplacementTexts, getCaretPosition, getDocumentBoundarySelection, getDocumentFullSelection, getSelectedLineBlocks, getSelectionAnchor, getSelectionClipboardTexts, getSelectionText, isCollapsedSelection, isLineEditable, mapCursorMove, mapSelectionShift, mergeOverlappingSelections, remapSelectionsAfterEdits, resolveDeleteCharacterRange, resolveIndentEdits, resolveSelectionCut, selectionIntersects, shiftSelectionLines };
211
+ //# sourceMappingURL=selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.d.ts","names":[],"sources":["../../src/editor/selection.ts"],"mappings":"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"}