@pierre/diffs 1.3.0-beta.5 → 1.3.0-beta.6

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 (623) hide show
  1. package/README.md +9 -9
  2. package/dist/components/CodeView.d.ts +10 -11
  3. package/dist/components/CodeView.d.ts.map +1 -1
  4. package/dist/components/CodeView.js +8 -8
  5. package/dist/components/CodeView.js.map +1 -1
  6. package/dist/components/File.d.ts +4 -5
  7. package/dist/components/File.d.ts.map +1 -1
  8. package/dist/components/File.js +32 -17
  9. package/dist/components/File.js.map +1 -1
  10. package/dist/components/FileDiff.d.ts +19 -19
  11. package/dist/components/FileDiff.d.ts.map +1 -1
  12. package/dist/components/FileDiff.js +84 -54
  13. package/dist/components/FileDiff.js.map +1 -1
  14. package/dist/components/FileStream.d.ts +0 -1
  15. package/dist/components/FileStream.d.ts.map +1 -1
  16. package/dist/components/FileStream.js +4 -4
  17. package/dist/components/FileStream.js.map +1 -1
  18. package/dist/components/UnresolvedFile.d.ts +1 -2
  19. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  20. package/dist/components/UnresolvedFile.js +3 -3
  21. package/dist/components/UnresolvedFile.js.map +1 -1
  22. package/dist/components/VirtualizedFile.d.ts +0 -1
  23. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  24. package/dist/components/VirtualizedFile.js +19 -18
  25. package/dist/components/VirtualizedFile.js.map +1 -1
  26. package/dist/components/VirtualizedFileDiff.d.ts +2 -3
  27. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  28. package/dist/components/VirtualizedFileDiff.js +17 -18
  29. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  30. package/dist/components/Virtualizer.d.ts +1 -1
  31. package/dist/components/Virtualizer.d.ts.map +1 -1
  32. package/dist/components/Virtualizer.js +23 -24
  33. package/dist/components/Virtualizer.js.map +1 -1
  34. package/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
  35. package/dist/components/web-components.d.ts.map +1 -1
  36. package/dist/components/web-components.js +2 -3
  37. package/dist/components/web-components.js.map +1 -1
  38. package/dist/constants.d.ts +3 -2
  39. package/dist/constants.d.ts.map +1 -1
  40. package/dist/constants.js +3 -2
  41. package/dist/constants.js.map +1 -1
  42. package/dist/editor/command.d.ts +2 -1
  43. package/dist/editor/command.d.ts.map +1 -1
  44. package/dist/editor/command.js +7 -3
  45. package/dist/editor/command.js.map +1 -1
  46. package/dist/editor/editStack.d.ts +7 -1
  47. package/dist/editor/editStack.d.ts.map +1 -1
  48. package/dist/editor/editStack.js +3 -3
  49. package/dist/editor/editStack.js.map +1 -1
  50. package/dist/editor/editor.d.ts +26 -2
  51. package/dist/editor/editor.d.ts.map +1 -1
  52. package/dist/editor/editor.js +551 -252
  53. package/dist/editor/editor.js.map +1 -1
  54. package/dist/editor/editor2.js +3 -3
  55. package/dist/editor/editor2.js.map +1 -1
  56. package/dist/editor/index.js +1 -2
  57. package/dist/editor/lineAnnotations.d.ts.map +1 -1
  58. package/dist/editor/lineAnnotations.js +2 -3
  59. package/dist/editor/lineAnnotations.js.map +1 -1
  60. package/dist/editor/marker.d.ts +2 -1
  61. package/dist/editor/marker.d.ts.map +1 -1
  62. package/dist/editor/marker.js +28 -11
  63. package/dist/editor/marker.js.map +1 -1
  64. package/dist/editor/pieceTable.d.ts +4 -2
  65. package/dist/editor/pieceTable.d.ts.map +1 -1
  66. package/dist/editor/pieceTable.js +138 -128
  67. package/dist/editor/pieceTable.js.map +1 -1
  68. package/dist/editor/platform.d.ts +8 -1
  69. package/dist/editor/platform.d.ts.map +1 -1
  70. package/dist/editor/platform.js +16 -5
  71. package/dist/editor/platform.js.map +1 -1
  72. package/dist/editor/searchPanel.d.ts +1 -0
  73. package/dist/editor/searchPanel.d.ts.map +1 -1
  74. package/dist/editor/searchPanel.js +75 -62
  75. package/dist/editor/searchPanel.js.map +1 -1
  76. package/dist/editor/selection.d.ts +41 -4
  77. package/dist/editor/selection.d.ts.map +1 -1
  78. package/dist/editor/selection.js +423 -83
  79. package/dist/editor/selection.js.map +1 -1
  80. package/dist/editor/selectionAction.d.ts +4 -5
  81. package/dist/editor/selectionAction.d.ts.map +1 -1
  82. package/dist/editor/selectionAction.js +14 -64
  83. package/dist/editor/selectionAction.js.map +1 -1
  84. package/dist/editor/sprite.d.ts +2 -2
  85. package/dist/editor/sprite.d.ts.map +1 -1
  86. package/dist/editor/sprite.js +7 -14
  87. package/dist/editor/sprite.js.map +1 -1
  88. package/dist/editor/textDocument.d.ts +5 -4
  89. package/dist/editor/textDocument.d.ts.map +1 -1
  90. package/dist/editor/textDocument.js +26 -15
  91. package/dist/editor/textDocument.js.map +1 -1
  92. package/dist/editor/textMeasure.d.ts +36 -3
  93. package/dist/editor/textMeasure.d.ts.map +1 -1
  94. package/dist/editor/textMeasure.js +79 -10
  95. package/dist/editor/textMeasure.js.map +1 -1
  96. package/dist/editor/tokenzier.d.ts +1 -0
  97. package/dist/editor/tokenzier.d.ts.map +1 -1
  98. package/dist/editor/tokenzier.js +16 -13
  99. package/dist/editor/tokenzier.js.map +1 -1
  100. package/dist/editor/utils.d.ts +2 -1
  101. package/dist/editor/utils.d.ts.map +1 -1
  102. package/dist/editor/utils.js +6 -3
  103. package/dist/editor/utils.js.map +1 -1
  104. package/dist/highlighter/languages/areLanguagesAttached.d.ts.map +1 -1
  105. package/dist/highlighter/languages/areLanguagesAttached.js +1 -2
  106. package/dist/highlighter/languages/areLanguagesAttached.js.map +1 -1
  107. package/dist/highlighter/languages/attachResolvedLanguages.d.ts +0 -2
  108. package/dist/highlighter/languages/attachResolvedLanguages.d.ts.map +1 -1
  109. package/dist/highlighter/languages/attachResolvedLanguages.js +1 -2
  110. package/dist/highlighter/languages/attachResolvedLanguages.js.map +1 -1
  111. package/dist/highlighter/languages/cleanUpResolvedLanguages.d.ts.map +1 -1
  112. package/dist/highlighter/languages/cleanUpResolvedLanguages.js +1 -2
  113. package/dist/highlighter/languages/cleanUpResolvedLanguages.js.map +1 -1
  114. package/dist/highlighter/languages/constants.d.ts +0 -1
  115. package/dist/highlighter/languages/constants.d.ts.map +1 -1
  116. package/dist/highlighter/languages/constants.js +1 -1
  117. package/dist/highlighter/languages/constants.js.map +1 -1
  118. package/dist/highlighter/languages/getResolvedLanguages.d.ts +0 -2
  119. package/dist/highlighter/languages/getResolvedLanguages.d.ts.map +1 -1
  120. package/dist/highlighter/languages/getResolvedLanguages.js +1 -2
  121. package/dist/highlighter/languages/getResolvedLanguages.js.map +1 -1
  122. package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts +0 -2
  123. package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts.map +1 -1
  124. package/dist/highlighter/languages/getResolvedOrResolveLanguage.js +1 -2
  125. package/dist/highlighter/languages/getResolvedOrResolveLanguage.js.map +1 -1
  126. package/dist/highlighter/languages/hasResolvedLanguages.d.ts.map +1 -1
  127. package/dist/highlighter/languages/hasResolvedLanguages.js +1 -2
  128. package/dist/highlighter/languages/hasResolvedLanguages.js.map +1 -1
  129. package/dist/highlighter/languages/registerCustomLanguage.d.ts +0 -1
  130. package/dist/highlighter/languages/registerCustomLanguage.d.ts.map +1 -1
  131. package/dist/highlighter/languages/registerCustomLanguage.js +1 -2
  132. package/dist/highlighter/languages/registerCustomLanguage.js.map +1 -1
  133. package/dist/highlighter/languages/resolveLanguage.d.ts +0 -2
  134. package/dist/highlighter/languages/resolveLanguage.d.ts.map +1 -1
  135. package/dist/highlighter/languages/resolveLanguage.js +4 -5
  136. package/dist/highlighter/languages/resolveLanguage.js.map +1 -1
  137. package/dist/highlighter/languages/resolveLanguages.d.ts +0 -2
  138. package/dist/highlighter/languages/resolveLanguages.d.ts.map +1 -1
  139. package/dist/highlighter/languages/resolveLanguages.js +1 -2
  140. package/dist/highlighter/languages/resolveLanguages.js.map +1 -1
  141. package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
  142. package/dist/highlighter/shared_highlighter.js +3 -4
  143. package/dist/highlighter/shared_highlighter.js.map +1 -1
  144. package/dist/highlighter/themes/areThemesAttached.d.ts.map +1 -1
  145. package/dist/highlighter/themes/areThemesAttached.js +1 -2
  146. package/dist/highlighter/themes/areThemesAttached.js.map +1 -1
  147. package/dist/highlighter/themes/attachResolvedThemes.d.ts.map +1 -1
  148. package/dist/highlighter/themes/attachResolvedThemes.js +1 -2
  149. package/dist/highlighter/themes/attachResolvedThemes.js.map +1 -1
  150. package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts.map +1 -1
  151. package/dist/highlighter/themes/cleanUpResolvedThemes.js +1 -2
  152. package/dist/highlighter/themes/cleanUpResolvedThemes.js.map +1 -1
  153. package/dist/highlighter/themes/constants.d.ts.map +1 -1
  154. package/dist/highlighter/themes/constants.js +1 -1
  155. package/dist/highlighter/themes/constants.js.map +1 -1
  156. package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts.map +1 -1
  157. package/dist/highlighter/themes/getResolvedOrResolveTheme.js +1 -2
  158. package/dist/highlighter/themes/getResolvedOrResolveTheme.js.map +1 -1
  159. package/dist/highlighter/themes/getResolvedThemes.d.ts.map +1 -1
  160. package/dist/highlighter/themes/getResolvedThemes.js +1 -2
  161. package/dist/highlighter/themes/getResolvedThemes.js.map +1 -1
  162. package/dist/highlighter/themes/hasResolvedThemes.d.ts.map +1 -1
  163. package/dist/highlighter/themes/hasResolvedThemes.js +1 -2
  164. package/dist/highlighter/themes/hasResolvedThemes.js.map +1 -1
  165. package/dist/highlighter/themes/registerCustomCSSVariableTheme.d.ts.map +1 -1
  166. package/dist/highlighter/themes/registerCustomCSSVariableTheme.js +1 -2
  167. package/dist/highlighter/themes/registerCustomCSSVariableTheme.js.map +1 -1
  168. package/dist/highlighter/themes/registerCustomTheme.d.ts.map +1 -1
  169. package/dist/highlighter/themes/registerCustomTheme.js +1 -2
  170. package/dist/highlighter/themes/registerCustomTheme.js.map +1 -1
  171. package/dist/highlighter/themes/resolveTheme.d.ts.map +1 -1
  172. package/dist/highlighter/themes/resolveTheme.js +1 -2
  173. package/dist/highlighter/themes/resolveTheme.js.map +1 -1
  174. package/dist/highlighter/themes/resolveThemes.d.ts.map +1 -1
  175. package/dist/highlighter/themes/resolveThemes.js +1 -2
  176. package/dist/highlighter/themes/resolveThemes.js.map +1 -1
  177. package/dist/highlighter/themes/themeResolution.d.ts.map +1 -1
  178. package/dist/highlighter/themes/themeResolution.js +1 -2
  179. package/dist/highlighter/themes/themeResolution.js.map +1 -1
  180. package/dist/highlighter/themes/themeResolver.d.ts +2 -2
  181. package/dist/highlighter/themes/themeResolver.d.ts.map +1 -1
  182. package/dist/highlighter/themes/themeResolver.js +1 -2
  183. package/dist/highlighter/themes/themeResolver.js.map +1 -1
  184. package/dist/index.d.ts +10 -10
  185. package/dist/index.js +2 -3
  186. package/dist/managers/InteractionManager.d.ts +7 -0
  187. package/dist/managers/InteractionManager.d.ts.map +1 -1
  188. package/dist/managers/InteractionManager.js +25 -3
  189. package/dist/managers/InteractionManager.js.map +1 -1
  190. package/dist/managers/ResizeManager.d.ts.map +1 -1
  191. package/dist/managers/ResizeManager.js +1 -1
  192. package/dist/managers/ResizeManager.js.map +1 -1
  193. package/dist/managers/ScrollSyncManager.d.ts.map +1 -1
  194. package/dist/managers/ScrollSyncManager.js +1 -1
  195. package/dist/managers/ScrollSyncManager.js.map +1 -1
  196. package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
  197. package/dist/managers/UniversalRenderingManager.js +2 -2
  198. package/dist/managers/UniversalRenderingManager.js.map +1 -1
  199. package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts +228 -0
  200. package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts.map +1 -0
  201. package/dist/node_modules/.pnpm/@types_unist@3.0.3/node_modules/@types/unist/index.d.ts +84 -0
  202. package/dist/node_modules/.pnpm/@types_unist@3.0.3/node_modules/@types/unist/index.d.ts.map +1 -0
  203. package/dist/react/CodeView.d.ts +1 -1
  204. package/dist/react/CodeView.d.ts.map +1 -1
  205. package/dist/react/CodeView.js +17 -16
  206. package/dist/react/CodeView.js.map +1 -1
  207. package/dist/react/EditorContext.d.ts +0 -1
  208. package/dist/react/EditorContext.d.ts.map +1 -1
  209. package/dist/react/EditorContext.js +2 -5
  210. package/dist/react/EditorContext.js.map +1 -1
  211. package/dist/react/File.d.ts +1 -0
  212. package/dist/react/File.d.ts.map +1 -1
  213. package/dist/react/File.js +4 -6
  214. package/dist/react/File.js.map +1 -1
  215. package/dist/react/FileDiff.d.ts +1 -0
  216. package/dist/react/FileDiff.d.ts.map +1 -1
  217. package/dist/react/FileDiff.js +4 -6
  218. package/dist/react/FileDiff.js.map +1 -1
  219. package/dist/react/MultiFileDiff.d.ts +1 -0
  220. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  221. package/dist/react/MultiFileDiff.js +4 -6
  222. package/dist/react/MultiFileDiff.js.map +1 -1
  223. package/dist/react/PatchDiff.d.ts +1 -0
  224. package/dist/react/PatchDiff.d.ts.map +1 -1
  225. package/dist/react/PatchDiff.js +4 -6
  226. package/dist/react/PatchDiff.js.map +1 -1
  227. package/dist/react/UnresolvedFile.d.ts +2 -1
  228. package/dist/react/UnresolvedFile.d.ts.map +1 -1
  229. package/dist/react/UnresolvedFile.js +4 -6
  230. package/dist/react/UnresolvedFile.js.map +1 -1
  231. package/dist/react/Virtualizer.d.ts.map +1 -1
  232. package/dist/react/Virtualizer.js +2 -5
  233. package/dist/react/Virtualizer.js.map +1 -1
  234. package/dist/react/WorkerPoolContext.d.ts +0 -1
  235. package/dist/react/WorkerPoolContext.d.ts.map +1 -1
  236. package/dist/react/WorkerPoolContext.js +2 -5
  237. package/dist/react/WorkerPoolContext.js.map +1 -1
  238. package/dist/react/constants.d.ts.map +1 -1
  239. package/dist/react/constants.js +1 -1
  240. package/dist/react/constants.js.map +1 -1
  241. package/dist/react/index.d.ts +2 -2
  242. package/dist/react/index.js +1 -2
  243. package/dist/react/jsx.d.ts +0 -2
  244. package/dist/react/jsx.d.ts.map +1 -1
  245. package/dist/react/types.d.ts +2 -0
  246. package/dist/react/types.d.ts.map +1 -1
  247. package/dist/react/utils/renderDiffChildren.d.ts +2 -0
  248. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  249. package/dist/react/utils/renderDiffChildren.js +18 -11
  250. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  251. package/dist/react/utils/renderFileChildren.d.ts +2 -0
  252. package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
  253. package/dist/react/utils/renderFileChildren.js +18 -11
  254. package/dist/react/utils/renderFileChildren.js.map +1 -1
  255. package/dist/react/utils/templateRender.d.ts.map +1 -1
  256. package/dist/react/utils/templateRender.js +1 -2
  257. package/dist/react/utils/templateRender.js.map +1 -1
  258. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  259. package/dist/react/utils/useFileDiffInstance.js +1 -3
  260. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  261. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  262. package/dist/react/utils/useFileInstance.js +1 -2
  263. package/dist/react/utils/useFileInstance.js.map +1 -1
  264. package/dist/react/utils/useStableCallback.d.ts.map +1 -1
  265. package/dist/react/utils/useStableCallback.js +1 -2
  266. package/dist/react/utils/useStableCallback.js.map +1 -1
  267. package/dist/react/utils/useUnresolvedFileInstance.d.ts.map +1 -1
  268. package/dist/react/utils/useUnresolvedFileInstance.js +10 -11
  269. package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
  270. package/dist/renderers/DiffHunksRenderer.d.ts +2 -3
  271. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  272. package/dist/renderers/DiffHunksRenderer.js +30 -24
  273. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  274. package/dist/renderers/FileRenderer.d.ts +1 -3
  275. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  276. package/dist/renderers/FileRenderer.js +14 -11
  277. package/dist/renderers/FileRenderer.js.map +1 -1
  278. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts +1 -2
  279. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
  280. package/dist/renderers/UnresolvedFileHunksRenderer.js +1 -2
  281. package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
  282. package/dist/shiki-stream/index.js +1 -2
  283. package/dist/shiki-stream/stream.d.ts +0 -1
  284. package/dist/shiki-stream/stream.d.ts.map +1 -1
  285. package/dist/shiki-stream/stream.js +1 -2
  286. package/dist/shiki-stream/stream.js.map +1 -1
  287. package/dist/shiki-stream/tokenizer.d.ts.map +1 -1
  288. package/dist/shiki-stream/tokenizer.js +1 -1
  289. package/dist/shiki-stream/tokenizer.js.map +1 -1
  290. package/dist/shiki-stream/types.d.ts +0 -1
  291. package/dist/shiki-stream/types.d.ts.map +1 -1
  292. package/dist/sprite.d.ts.map +1 -1
  293. package/dist/sprite.js +1 -1
  294. package/dist/ssr/FileDiffReact.d.ts.map +1 -1
  295. package/dist/ssr/FileDiffReact.js +5 -8
  296. package/dist/ssr/FileDiffReact.js.map +1 -1
  297. package/dist/ssr/index.d.ts +2 -2
  298. package/dist/ssr/index.js +1 -2
  299. package/dist/ssr/preloadDiffs.d.ts +1 -1
  300. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  301. package/dist/ssr/preloadDiffs.js +1 -2
  302. package/dist/ssr/preloadDiffs.js.map +1 -1
  303. package/dist/ssr/preloadFile.d.ts.map +1 -1
  304. package/dist/ssr/preloadFile.js +1 -2
  305. package/dist/ssr/preloadFile.js.map +1 -1
  306. package/dist/ssr/preloadPatchFile.d.ts.map +1 -1
  307. package/dist/ssr/preloadPatchFile.js +2 -3
  308. package/dist/ssr/preloadPatchFile.js.map +1 -1
  309. package/dist/ssr/renderHTML.d.ts +1 -1
  310. package/dist/ssr/renderHTML.d.ts.map +1 -1
  311. package/dist/ssr/renderHTML.js +1 -2
  312. package/dist/ssr/renderHTML.js.map +1 -1
  313. package/dist/string-import.d.ts +4 -0
  314. package/dist/string-import.d.ts.map +1 -1
  315. package/dist/style.js +3 -3
  316. package/dist/style.js.map +1 -1
  317. package/dist/types.d.ts +11 -5
  318. package/dist/types.d.ts.map +1 -1
  319. package/dist/utils/areDiffLineAnnotationsEqual.d.ts.map +1 -1
  320. package/dist/utils/areDiffLineAnnotationsEqual.js +1 -1
  321. package/dist/utils/areDiffLineAnnotationsEqual.js.map +1 -1
  322. package/dist/utils/areDiffRenderOptionsEqual.d.ts.map +1 -1
  323. package/dist/utils/areDiffRenderOptionsEqual.js +1 -2
  324. package/dist/utils/areDiffRenderOptionsEqual.js.map +1 -1
  325. package/dist/utils/areDiffTargetsEqual.d.ts.map +1 -1
  326. package/dist/utils/areDiffTargetsEqual.js +1 -1
  327. package/dist/utils/areDiffTargetsEqual.js.map +1 -1
  328. package/dist/utils/areFileRenderOptionsEqual.d.ts.map +1 -1
  329. package/dist/utils/areFileRenderOptionsEqual.js +1 -2
  330. package/dist/utils/areFileRenderOptionsEqual.js.map +1 -1
  331. package/dist/utils/areFilesEqual.d.ts.map +1 -1
  332. package/dist/utils/areFilesEqual.js +1 -1
  333. package/dist/utils/areFilesEqual.js.map +1 -1
  334. package/dist/utils/areHunkDataEqual.d.ts.map +1 -1
  335. package/dist/utils/areHunkDataEqual.js +1 -1
  336. package/dist/utils/areHunkDataEqual.js.map +1 -1
  337. package/dist/utils/areLineAnnotationsEqual.d.ts.map +1 -1
  338. package/dist/utils/areLineAnnotationsEqual.js +1 -1
  339. package/dist/utils/areLineAnnotationsEqual.js.map +1 -1
  340. package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
  341. package/dist/utils/areManagedSnapshotsEqual.js +1 -1
  342. package/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
  343. package/dist/utils/areMergeConflictActionsEqual.d.ts.map +1 -1
  344. package/dist/utils/areMergeConflictActionsEqual.js +1 -1
  345. package/dist/utils/areMergeConflictActionsEqual.js.map +1 -1
  346. package/dist/utils/areObjectsEqual.d.ts.map +1 -1
  347. package/dist/utils/areObjectsEqual.js +1 -1
  348. package/dist/utils/areObjectsEqual.js.map +1 -1
  349. package/dist/utils/areOptionsEqual.d.ts +0 -2
  350. package/dist/utils/areOptionsEqual.d.ts.map +1 -1
  351. package/dist/utils/areOptionsEqual.js +1 -2
  352. package/dist/utils/areOptionsEqual.js.map +1 -1
  353. package/dist/utils/arePrePropertiesEqual.d.ts.map +1 -1
  354. package/dist/utils/arePrePropertiesEqual.js +1 -1
  355. package/dist/utils/arePrePropertiesEqual.js.map +1 -1
  356. package/dist/utils/areRenderRangesEqual.d.ts.map +1 -1
  357. package/dist/utils/areRenderRangesEqual.js +1 -1
  358. package/dist/utils/areRenderRangesEqual.js.map +1 -1
  359. package/dist/utils/areSelectionPointsEqual.d.ts.map +1 -1
  360. package/dist/utils/areSelectionPointsEqual.js +1 -1
  361. package/dist/utils/areSelectionPointsEqual.js.map +1 -1
  362. package/dist/utils/areSelectionsEqual.d.ts.map +1 -1
  363. package/dist/utils/areSelectionsEqual.js +1 -1
  364. package/dist/utils/areSelectionsEqual.js.map +1 -1
  365. package/dist/utils/areThemesEqual.d.ts.map +1 -1
  366. package/dist/utils/areThemesEqual.js +1 -1
  367. package/dist/utils/areThemesEqual.js.map +1 -1
  368. package/dist/utils/areVirtualWindowSpecsEqual.d.ts.map +1 -1
  369. package/dist/utils/areVirtualWindowSpecsEqual.js +1 -1
  370. package/dist/utils/areVirtualWindowSpecsEqual.js.map +1 -1
  371. package/dist/utils/areWorkerStatsEqual.d.ts +0 -2
  372. package/dist/utils/areWorkerStatsEqual.d.ts.map +1 -1
  373. package/dist/utils/areWorkerStatsEqual.js +1 -1
  374. package/dist/utils/areWorkerStatsEqual.js.map +1 -1
  375. package/dist/utils/cleanLastNewline.d.ts.map +1 -1
  376. package/dist/utils/cleanLastNewline.js +1 -1
  377. package/dist/utils/cleanLastNewline.js.map +1 -1
  378. package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
  379. package/dist/utils/computeEstimatedDiffHeights.js +1 -2
  380. package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
  381. package/dist/utils/computeFileOffsets.d.ts +9 -1
  382. package/dist/utils/computeFileOffsets.d.ts.map +1 -1
  383. package/dist/utils/computeFileOffsets.js +20 -2
  384. package/dist/utils/computeFileOffsets.js.map +1 -1
  385. package/dist/utils/computeVirtualFileMetrics.d.ts.map +1 -1
  386. package/dist/utils/computeVirtualFileMetrics.js +1 -2
  387. package/dist/utils/computeVirtualFileMetrics.js.map +1 -1
  388. package/dist/utils/createAnnotationElement.d.ts +1 -1
  389. package/dist/utils/createAnnotationElement.d.ts.map +1 -1
  390. package/dist/utils/createAnnotationElement.js +1 -2
  391. package/dist/utils/createAnnotationElement.js.map +1 -1
  392. package/dist/utils/createAnnotationWrapperNode.d.ts.map +1 -1
  393. package/dist/utils/createAnnotationWrapperNode.js +1 -1
  394. package/dist/utils/createAnnotationWrapperNode.js.map +1 -1
  395. package/dist/utils/createContentColumn.d.ts +1 -1
  396. package/dist/utils/createContentColumn.d.ts.map +1 -1
  397. package/dist/utils/createContentColumn.js +1 -2
  398. package/dist/utils/createContentColumn.js.map +1 -1
  399. package/dist/utils/createEmptyRowBuffer.d.ts +1 -1
  400. package/dist/utils/createEmptyRowBuffer.d.ts.map +1 -1
  401. package/dist/utils/createEmptyRowBuffer.js +1 -2
  402. package/dist/utils/createEmptyRowBuffer.js.map +1 -1
  403. package/dist/utils/createFileHeaderElement.d.ts +1 -1
  404. package/dist/utils/createFileHeaderElement.d.ts.map +1 -1
  405. package/dist/utils/createFileHeaderElement.js +6 -3
  406. package/dist/utils/createFileHeaderElement.js.map +1 -1
  407. package/dist/utils/createGutterUtilityContentNode.d.ts.map +1 -1
  408. package/dist/utils/createGutterUtilityContentNode.js +1 -1
  409. package/dist/utils/createGutterUtilityContentNode.js.map +1 -1
  410. package/dist/utils/createGutterUtilityElement.d.ts +1 -1
  411. package/dist/utils/createGutterUtilityElement.d.ts.map +1 -1
  412. package/dist/utils/createGutterUtilityElement.js +1 -2
  413. package/dist/utils/createGutterUtilityElement.js.map +1 -1
  414. package/dist/utils/createNoNewlineElement.d.ts +1 -1
  415. package/dist/utils/createNoNewlineElement.d.ts.map +1 -1
  416. package/dist/utils/createNoNewlineElement.js +1 -2
  417. package/dist/utils/createNoNewlineElement.js.map +1 -1
  418. package/dist/utils/createPreElement.d.ts +1 -1
  419. package/dist/utils/createPreElement.d.ts.map +1 -1
  420. package/dist/utils/createPreElement.js +1 -2
  421. package/dist/utils/createPreElement.js.map +1 -1
  422. package/dist/utils/createRowNodes.d.ts.map +1 -1
  423. package/dist/utils/createRowNodes.js +1 -1
  424. package/dist/utils/createRowNodes.js.map +1 -1
  425. package/dist/utils/createSeparator.d.ts +1 -1
  426. package/dist/utils/createSeparator.d.ts.map +1 -1
  427. package/dist/utils/createSeparator.js +1 -2
  428. package/dist/utils/createSeparator.js.map +1 -1
  429. package/dist/utils/createSpanNodeFromToken.d.ts.map +1 -1
  430. package/dist/utils/createSpanNodeFromToken.js +1 -2
  431. package/dist/utils/createSpanNodeFromToken.js.map +1 -1
  432. package/dist/utils/createStyleElement.d.ts +1 -1
  433. package/dist/utils/createStyleElement.d.ts.map +1 -1
  434. package/dist/utils/createStyleElement.js +1 -2
  435. package/dist/utils/createStyleElement.js.map +1 -1
  436. package/dist/utils/createTransformerWithState.d.ts.map +1 -1
  437. package/dist/utils/createTransformerWithState.js +1 -2
  438. package/dist/utils/createTransformerWithState.js.map +1 -1
  439. package/dist/utils/createUnsafeCSSStyleNode.d.ts.map +1 -1
  440. package/dist/utils/createUnsafeCSSStyleNode.js +1 -2
  441. package/dist/utils/createUnsafeCSSStyleNode.js.map +1 -1
  442. package/dist/utils/createWindowFromScrollPosition.d.ts.map +1 -1
  443. package/dist/utils/createWindowFromScrollPosition.js +5 -5
  444. package/dist/utils/createWindowFromScrollPosition.js.map +1 -1
  445. package/dist/utils/cssWrappers.d.ts.map +1 -1
  446. package/dist/utils/cssWrappers.js +2 -3
  447. package/dist/utils/cssWrappers.js.map +1 -1
  448. package/dist/utils/detachString.d.ts.map +1 -1
  449. package/dist/utils/detachString.js +1 -1
  450. package/dist/utils/detachString.js.map +1 -1
  451. package/dist/utils/diffAcceptRejectHunk.d.ts.map +1 -1
  452. package/dist/utils/diffAcceptRejectHunk.js +1 -2
  453. package/dist/utils/diffAcceptRejectHunk.js.map +1 -1
  454. package/dist/utils/formatCSSVariablePrefix.d.ts.map +1 -1
  455. package/dist/utils/formatCSSVariablePrefix.js +1 -1
  456. package/dist/utils/formatCSSVariablePrefix.js.map +1 -1
  457. package/dist/utils/getDiffHunksRendererOptions.d.ts.map +1 -1
  458. package/dist/utils/getDiffHunksRendererOptions.js +1 -1
  459. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  460. package/dist/utils/getFileRendererOptions.d.ts.map +1 -1
  461. package/dist/utils/getFileRendererOptions.js +1 -1
  462. package/dist/utils/getFileRendererOptions.js.map +1 -1
  463. package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
  464. package/dist/utils/getFiletypeFromFileName.js +1 -1
  465. package/dist/utils/getFiletypeFromFileName.js.map +1 -1
  466. package/dist/utils/getHighlighterOptions.d.ts.map +1 -1
  467. package/dist/utils/getHighlighterOptions.js +1 -2
  468. package/dist/utils/getHighlighterOptions.js.map +1 -1
  469. package/dist/utils/getHighlighterThemeStyles.d.ts.map +1 -1
  470. package/dist/utils/getHighlighterThemeStyles.js +1 -2
  471. package/dist/utils/getHighlighterThemeStyles.js.map +1 -1
  472. package/dist/utils/getHunkSeparatorSlotName.d.ts.map +1 -1
  473. package/dist/utils/getHunkSeparatorSlotName.js +1 -1
  474. package/dist/utils/getHunkSeparatorSlotName.js.map +1 -1
  475. package/dist/utils/getIconForType.d.ts.map +1 -1
  476. package/dist/utils/getIconForType.js +1 -1
  477. package/dist/utils/getIconForType.js.map +1 -1
  478. package/dist/utils/getLineAnnotationName.d.ts.map +1 -1
  479. package/dist/utils/getLineAnnotationName.js +1 -1
  480. package/dist/utils/getLineAnnotationName.js.map +1 -1
  481. package/dist/utils/getLineEndingType.d.ts.map +1 -1
  482. package/dist/utils/getLineEndingType.js +1 -1
  483. package/dist/utils/getLineEndingType.js.map +1 -1
  484. package/dist/utils/getLineNodes.d.ts +1 -1
  485. package/dist/utils/getLineNodes.d.ts.map +1 -1
  486. package/dist/utils/getLineNodes.js +1 -1
  487. package/dist/utils/getLineNodes.js.map +1 -1
  488. package/dist/utils/getMergeConflictActionSlotName.d.ts.map +1 -1
  489. package/dist/utils/getMergeConflictActionSlotName.js +1 -1
  490. package/dist/utils/getMergeConflictActionSlotName.js.map +1 -1
  491. package/dist/utils/getMergeConflictLineTypes.d.ts.map +1 -1
  492. package/dist/utils/getMergeConflictLineTypes.js +1 -2
  493. package/dist/utils/getMergeConflictLineTypes.js.map +1 -1
  494. package/dist/utils/getOrCreateCodeNode.d.ts.map +1 -1
  495. package/dist/utils/getOrCreateCodeNode.js +1 -1
  496. package/dist/utils/getOrCreateCodeNode.js.map +1 -1
  497. package/dist/utils/getSingularPatch.d.ts.map +1 -1
  498. package/dist/utils/getSingularPatch.js +1 -2
  499. package/dist/utils/getSingularPatch.js.map +1 -1
  500. package/dist/utils/getThemes.d.ts.map +1 -1
  501. package/dist/utils/getThemes.js +1 -2
  502. package/dist/utils/getThemes.js.map +1 -1
  503. package/dist/utils/getTotalLineCountFromHunks.d.ts.map +1 -1
  504. package/dist/utils/getTotalLineCountFromHunks.js +1 -1
  505. package/dist/utils/getTotalLineCountFromHunks.js.map +1 -1
  506. package/dist/utils/hast_utils.d.ts +1 -1
  507. package/dist/utils/hast_utils.d.ts.map +1 -1
  508. package/dist/utils/hast_utils.js +1 -1
  509. package/dist/utils/hast_utils.js.map +1 -1
  510. package/dist/utils/hostTheme.d.ts.map +1 -1
  511. package/dist/utils/hostTheme.js +1 -2
  512. package/dist/utils/hostTheme.js.map +1 -1
  513. package/dist/utils/includesFileAnnotations.d.ts.map +1 -1
  514. package/dist/utils/includesFileAnnotations.js +5 -5
  515. package/dist/utils/includesFileAnnotations.js.map +1 -1
  516. package/dist/utils/isDefaultRenderRange.d.ts.map +1 -1
  517. package/dist/utils/isDefaultRenderRange.js +1 -1
  518. package/dist/utils/isDefaultRenderRange.js.map +1 -1
  519. package/dist/utils/isDiffPlainText.d.ts.map +1 -1
  520. package/dist/utils/isDiffPlainText.js +1 -2
  521. package/dist/utils/isDiffPlainText.js.map +1 -1
  522. package/dist/utils/isFilePlainText.d.ts.map +1 -1
  523. package/dist/utils/isFilePlainText.js +1 -2
  524. package/dist/utils/isFilePlainText.js.map +1 -1
  525. package/dist/utils/isStyleNode.d.ts.map +1 -1
  526. package/dist/utils/isStyleNode.js +1 -1
  527. package/dist/utils/isStyleNode.js.map +1 -1
  528. package/dist/utils/isWorkerContext.d.ts.map +1 -1
  529. package/dist/utils/isWorkerContext.js +1 -1
  530. package/dist/utils/isWorkerContext.js.map +1 -1
  531. package/dist/utils/iterateOverDiff.d.ts.map +1 -1
  532. package/dist/utils/iterateOverDiff.js +44 -45
  533. package/dist/utils/iterateOverDiff.js.map +1 -1
  534. package/dist/utils/normalizeDiffResolution.d.ts.map +1 -1
  535. package/dist/utils/normalizeDiffResolution.js +1 -1
  536. package/dist/utils/normalizeDiffResolution.js.map +1 -1
  537. package/dist/utils/parseDiffDecorations.d.ts.map +1 -1
  538. package/dist/utils/parseDiffDecorations.js +1 -2
  539. package/dist/utils/parseDiffDecorations.js.map +1 -1
  540. package/dist/utils/parseDiffFromFile.d.ts +0 -1
  541. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  542. package/dist/utils/parseDiffFromFile.js +1 -2
  543. package/dist/utils/parseDiffFromFile.js.map +1 -1
  544. package/dist/utils/parseLineType.d.ts.map +1 -1
  545. package/dist/utils/parseLineType.js +1 -1
  546. package/dist/utils/parseLineType.js.map +1 -1
  547. package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
  548. package/dist/utils/parseMergeConflictDiffFromFile.js +5 -5
  549. package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
  550. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  551. package/dist/utils/parsePatchFiles.js +6 -7
  552. package/dist/utils/parsePatchFiles.js.map +1 -1
  553. package/dist/utils/prefersReducedMotion.d.ts.map +1 -1
  554. package/dist/utils/prefersReducedMotion.js +1 -1
  555. package/dist/utils/prefersReducedMotion.js.map +1 -1
  556. package/dist/utils/prerenderHTMLIfNecessary.d.ts.map +1 -1
  557. package/dist/utils/prerenderHTMLIfNecessary.js +1 -1
  558. package/dist/utils/prerenderHTMLIfNecessary.js.map +1 -1
  559. package/dist/utils/processLine.d.ts +1 -1
  560. package/dist/utils/processLine.d.ts.map +1 -1
  561. package/dist/utils/processLine.js +1 -2
  562. package/dist/utils/processLine.js.map +1 -1
  563. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  564. package/dist/utils/renderDiffWithHighlighter.js +4 -5
  565. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  566. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  567. package/dist/utils/renderFileWithHighlighter.js +1 -2
  568. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  569. package/dist/utils/resolveConflict.d.ts.map +1 -1
  570. package/dist/utils/resolveConflict.js +1 -2
  571. package/dist/utils/resolveConflict.js.map +1 -1
  572. package/dist/utils/resolveRegion.d.ts.map +1 -1
  573. package/dist/utils/resolveRegion.js +1 -1
  574. package/dist/utils/resolveRegion.js.map +1 -1
  575. package/dist/utils/roundToDevicePixel.d.ts.map +1 -1
  576. package/dist/utils/roundToDevicePixel.js +1 -1
  577. package/dist/utils/roundToDevicePixel.js.map +1 -1
  578. package/dist/utils/scrollbarGutter.d.ts.map +1 -1
  579. package/dist/utils/scrollbarGutter.js +1 -2
  580. package/dist/utils/scrollbarGutter.js.map +1 -1
  581. package/dist/utils/setLanguageOverride.d.ts.map +1 -1
  582. package/dist/utils/setLanguageOverride.js +1 -1
  583. package/dist/utils/setLanguageOverride.js.map +1 -1
  584. package/dist/utils/setWrapperNodeProps.d.ts.map +1 -1
  585. package/dist/utils/setWrapperNodeProps.js +1 -1
  586. package/dist/utils/setWrapperNodeProps.js.map +1 -1
  587. package/dist/utils/shouldUseTokenTransformer.d.ts.map +1 -1
  588. package/dist/utils/shouldUseTokenTransformer.js +1 -1
  589. package/dist/utils/shouldUseTokenTransformer.js.map +1 -1
  590. package/dist/utils/splitFileContents.d.ts.map +1 -1
  591. package/dist/utils/splitFileContents.js +1 -2
  592. package/dist/utils/splitFileContents.js.map +1 -1
  593. package/dist/utils/trimPatchContext.d.ts.map +1 -1
  594. package/dist/utils/trimPatchContext.js +1 -2
  595. package/dist/utils/trimPatchContext.js.map +1 -1
  596. package/dist/utils/updateDiffHunks.d.ts +2 -1
  597. package/dist/utils/updateDiffHunks.d.ts.map +1 -1
  598. package/dist/utils/updateDiffHunks.js +22 -3
  599. package/dist/utils/updateDiffHunks.js.map +1 -1
  600. package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
  601. package/dist/utils/virtualDiffLayout.js +1 -2
  602. package/dist/utils/virtualDiffLayout.js.map +1 -1
  603. package/dist/utils/wrapTokenFragments.d.ts +1 -1
  604. package/dist/utils/wrapTokenFragments.d.ts.map +1 -1
  605. package/dist/utils/wrapTokenFragments.js +1 -2
  606. package/dist/utils/wrapTokenFragments.js.map +1 -1
  607. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  608. package/dist/worker/WorkerPoolManager.js +5 -5
  609. package/dist/worker/WorkerPoolManager.js.map +1 -1
  610. package/dist/worker/getOrCreateWorkerPoolSingleton.d.ts.map +1 -1
  611. package/dist/worker/getOrCreateWorkerPoolSingleton.js +1 -2
  612. package/dist/worker/getOrCreateWorkerPoolSingleton.js.map +1 -1
  613. package/dist/worker/index.js +1 -2
  614. package/dist/worker/types.d.ts.map +1 -1
  615. package/dist/worker/wasm-B9ZqxnKj.js +8 -0
  616. package/dist/worker/wasm-B9ZqxnKj.js.map +1 -0
  617. package/dist/worker/worker-portable.js +2779 -6403
  618. package/dist/worker/worker-portable.js.map +1 -1
  619. package/dist/worker/worker.js +89 -123
  620. package/dist/worker/worker.js.map +1 -1
  621. package/package.json +13 -14
  622. package/dist/worker/wasm-qE0LgnY3.js +0 -10
  623. package/dist/worker/wasm-qE0LgnY3.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"editor.js","names":["#fileInstance","#renderRange","#textDocument","#getLineElement","#options","#initialize","#detach","#selections","#applyChange","#applyChangeToLineAnnotations","#getFileRef","#lineAnnotations","#resetCache","#resetState","#initSelections","#updateSelections","#scrollToPrimaryCaret","#markerRenderer","#metrics","#fileContainer","#getCharX","#getLineY","#isContentMouseDown","#isGutterMouseDown","#contentElement","#focus","#tokenizer","#globalEventDisposes","#editorEventDisposes","#selectEventDisposes","#gutterWidthCache","#contentWidthCache","#lineYCache","#wrapLineOffsetsCache","#lastAccessedLineElement","#lastAccessedCharX","#globalStyleElement","#editorStyleElement","#themeStyleElement","#spriteElement","#gutterElement","#overlayElement","#resizeObserver","codeElement: HTMLElement | undefined","gutterEl: HTMLElement | undefined","contentEl: HTMLElement | undefined","el","#fileContents","#onDeferTokenize","#listenContentElement","#wrap","#matches","#primaryCaretElement","#scrollingToLine","#scrollToLine","#scrollingToLineChar","#scrollingToLineNoFocus","#retainSearchPanelFocus","#searchPanel","#selectionAction","#isLineVisible","#shouldIgnoreSelectionChange","#overlayElements","#reservedSelections","editorCSS","#rangeBelongsToEditor","#shiftKeyPressed","#selectionStart","#setWindowSelection","#runCommand","#getSelectionText","#replaceSelectionText","#handleInput","selection: EditorSelection","textDocument","lineIndex","e","selection","#handleLayoutResize","#openSearchPanel","expanded: EditorSelection[]","edits: TextEdit[]","nextSelections: EditorSelection[]","#getGutterWidth","#getContentWidth","#deleteSelectionText","#deleteSoftLineBackward","#deleteHardLineForward","#deleteWordBackward","#insertTranspose","#getScrollMargin","#renderSelection","#renderCaret","#renderSelectionActionIcon","range: Range","#renderWrappedSelection","#renderSelectionBlock","#wrapLineText","segmentLeft: number","segmentWidth: number","line","wrapLine","css","left","cacheKey","#renderSearchPanel","initialMatch: [number, number] | undefined","primarySelection","nextMatch: MatchRange | undefined","edit: ResolvedTextEdit","#applyResolvedTextEdit","shouldUpdateBuffer: boolean | undefined","#rerender","lineElement: HTMLElement | null","starts: number[]"],"sources":["../../src/editor/editor.ts"],"sourcesContent":["import type {\n DiffLineAnnotation,\n DiffsEditableComponent,\n DiffsEditor,\n DiffsEditorSelection,\n DiffsHighlighter,\n FileContents,\n HighlightedToken,\n RenderRange,\n} from '../types';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport {\n type EditorCommand,\n resolveEditorCommandFromKeyboardEvent,\n} from './command';\nimport editorCSS from './editor.css';\nimport { EditStack } from './editStack';\nimport {\n applyDocumentChangeToLineAnnotations,\n renderLineAnnotations,\n} from './lineAnnotations';\nimport {\n type Marker,\n MarkerRenderer,\n markerSeverityDatasetKey,\n} from './marker';\nimport { isMoveCursorShortcut, isPrimaryModifier, isSafari } from './platform';\nimport {\n type MatchRange,\n type SearchPanelMode,\n SearchPanelWidget,\n} from './searchPanel';\nimport type { EditorSelection } from './selection';\nimport {\n applyDeleteHardLineForwardToSelections,\n applyDeleteSoftLineBackwardToSelections,\n applyDeleteWordBackwardToSelections,\n applyTextChangeToSelections,\n applyTextReplaceToSelections,\n applyTransposeToSelections,\n comparePosition,\n convertSelection,\n createSelectionFrom,\n createSelectionFromAnchorAndFocusOffsets,\n DirectionBackward,\n DirectionForward,\n DirectionNone,\n expandCollapsedSelectionToWord,\n extendSelection,\n extendSelections,\n findNexMatch,\n getCaretPosition,\n getDocumentBoundarySelection,\n getDocumentFullSelection,\n getSelectionAnchor,\n getSelectionText,\n isCollapsedSelection,\n isLineEditable,\n mapCursorMove,\n mapSelectionShift,\n mergeOverlappingSelections,\n resolveIndentEdits,\n selectionIntersects,\n} from './selection';\nimport {\n type SelectionActionContext,\n SelectionActionWidget,\n} from './selectionAction';\nimport { createSpriteElement } from './sprite';\nimport {\n type Position,\n type Range,\n type ResolvedTextEdit,\n TextDocument,\n type TextDocumentChange,\n type TextEdit,\n} from './textDocument';\nimport {\n getExpandedAsciiTextColumns,\n getUnicodeMeasurementOffsets,\n Metrics,\n snapTextOffsetToUnicodeBoundary,\n} from './textMeasure';\nimport { EditorTokenizer, renderLineTokens } from './tokenzier';\nimport {\n addEventListener,\n clampDomOffset,\n extend,\n getLineNumberAttr,\n h,\n round,\n} from './utils';\n\nexport interface EditorOptions<LAnnotation> {\n /** The maximum number of entries to keep in the undo stack. */\n historyMaxEntries?: number;\n /** Render rounded corners for selection ranges, default is true. */\n roundedSelection?: boolean;\n /** Show the clickable selection action icon, default is disabled. */\n enabledSelectionAction?: boolean;\n /** Render the selection action widget element. */\n renderSelectionAction?: (\n context: SelectionActionContext<LAnnotation>\n ) => HTMLElement;\n /** Callback when the editor is attached to a file. */\n onAttach?: (\n editor: Editor<LAnnotation>,\n fileInstance: DiffsEditableComponent<LAnnotation>\n ) => void;\n /** Callback when the editor document changes. */\n onChange?: (\n file: FileContents,\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[]\n ) => void;\n __debug?: boolean;\n}\n\nexport interface EditorState<LAnnotation> {\n file: FileContents;\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[];\n selections?: EditorSelection[];\n renderRange?: RenderRange;\n}\n\nexport class Editor<LAnnotation> implements DiffsEditor<LAnnotation> {\n #options: EditorOptions<LAnnotation>;\n #wrap = false;\n #metrics = new Metrics();\n #tokenizer?: EditorTokenizer;\n\n // event disposes\n #editorEventDisposes?: (() => void)[];\n #globalEventDisposes?: (() => void)[];\n #selectEventDisposes?: (() => void)[];\n #detach?: () => void;\n\n // cache\n #gutterWidthCache?: number;\n #contentWidthCache?: number;\n #lineYCache = new Map<number, number>();\n #wrapLineOffsetsCache = new Map<number, Uint32Array>();\n #lastAccessedLineElement?: [number, HTMLElement];\n #lastAccessedCharX?: [\n line: number,\n character: number,\n x: number,\n wrapLine: number,\n ];\n\n // dom\n #globalStyleElement?: HTMLStyleElement;\n #editorStyleElement?: HTMLStyleElement;\n #themeStyleElement?: HTMLStyleElement;\n #spriteElement?: SVGSVGElement;\n #fileContainer?: HTMLElement;\n #gutterElement?: HTMLElement;\n #contentElement?: HTMLElement;\n #overlayElement?: HTMLElement;\n #overlayElements?: Map<string, HTMLElement>;\n #primaryCaretElement?: HTMLElement;\n #resizeObserver?: ResizeObserver;\n\n // state\n #fileInstance?: DiffsEditableComponent<LAnnotation>;\n #fileContents?: FileContents;\n #lineAnnotations?: DiffLineAnnotation<LAnnotation>[];\n #textDocument?: TextDocument<LAnnotation>;\n #renderRange?: RenderRange;\n #markerRenderer?: MarkerRenderer;\n #searchPanel?: SearchPanelWidget;\n #selectionAction?: SelectionActionWidget;\n #shouldIgnoreSelectionChange = false;\n #isGutterMouseDown = false;\n #isContentMouseDown = false;\n #shiftKeyPressed = false;\n #selectionStart: EditorSelection | undefined;\n #reservedSelections?: EditorSelection[];\n #initSelections?: EditorSelection[];\n #selections?: EditorSelection[];\n #matches?: MatchRange[];\n #scrollingToLine?: number;\n #scrollingToLineChar?: number;\n #scrollingToLineNoFocus = false;\n #retainSearchPanelFocus = false;\n\n #onDeferTokenize = (\n lines: Map<number, Array<HighlightedToken>>,\n themeType: 'light' | 'dark'\n ) => {\n this.#fileInstance?.updateRenderCache(lines, themeType);\n // update the view if the render range is updated by scrolling\n // and the deferred tokenized lines inside the render range\n if (\n this.#renderRange !== undefined &&\n this.#renderRange.totalLines !== Infinity\n ) {\n const { startingLine, totalLines } = this.#renderRange;\n const endLine = Math.min(\n startingLine + totalLines,\n this.#textDocument?.lineCount ?? 0\n );\n for (const [line, tokens] of lines) {\n if (line >= startingLine && line < endLine) {\n const lineElement = this.#getLineElement(line);\n if (lineElement !== undefined) {\n lineElement.replaceChildren(...renderLineTokens(tokens, themeType));\n }\n }\n }\n }\n };\n\n constructor(options: EditorOptions<LAnnotation> = {}) {\n this.#options = options;\n }\n\n edit(component: DiffsEditableComponent<LAnnotation>): () => void {\n const {\n useTokenTransformer,\n enableGutterUtility,\n enableLineSelection,\n expandUnchanged,\n diffStyle,\n lineHoverHighlight,\n ...rest\n } = component.options;\n const isDiff = component.type === 'file-diff';\n if (\n useTokenTransformer !== true ||\n enableGutterUtility === true ||\n enableLineSelection === true ||\n lineHoverHighlight !== 'disabled' ||\n (expandUnchanged !== true && isDiff) ||\n (diffStyle === 'unified' && isDiff)\n ) {\n component.setOptions({\n ...rest,\n useTokenTransformer: true,\n enableGutterUtility: false,\n enableLineSelection: false,\n lineHoverHighlight: 'disabled',\n expandUnchanged: true,\n diffStyle: 'split',\n });\n component.rerender();\n }\n this.#fileInstance = component;\n this.#initialize();\n this.#detach = component.attachEditor(this);\n return () => this.cleanUp();\n }\n\n /**\n * Apply edits to current attached file.\n */\n applyEdits(edits: TextEdit[], updateHistory = false): void {\n const textDocument = this.#textDocument;\n if (textDocument == null) {\n throw new Error('Editor is not attached');\n }\n const change = textDocument.applyEdits(\n edits,\n updateHistory,\n this.#selections\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n undefined,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n getState(): EditorState<LAnnotation> {\n const fileRef = this.#getFileRef();\n if (fileRef === undefined) {\n throw new Error('Editor is not attached');\n }\n return {\n file: { ...fileRef, cacheKey: 'edited-at-' + Date.now() },\n selections: this.#selections,\n lineAnnotations: this.#lineAnnotations,\n renderRange: this.#renderRange,\n };\n }\n\n setState({\n file,\n lineAnnotations,\n renderRange,\n selections,\n }: EditorState<LAnnotation>): void {\n this.#resetCache();\n this.#resetState();\n this.#initSelections = selections;\n this.#fileInstance?.render({\n file: { ...file, cacheKey: 'edited-at-' + Date.now() },\n lineAnnotations,\n renderRange,\n });\n }\n\n setSelections(selections: DiffsEditorSelection[]): void {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n throw new Error('Text document is not initialized');\n }\n const resolvedSelections = selections.map<EditorSelection>((selection) => {\n const start = textDocument.normalizePosition(selection.start);\n const end = textDocument.normalizePosition(selection.end);\n const direction =\n selection.direction === 'none'\n ? DirectionNone\n : selection.direction === 'backward'\n ? DirectionBackward\n : DirectionForward;\n return { direction, start, end };\n });\n this.#updateSelections(resolvedSelections);\n this.#scrollToPrimaryCaret(false, 'center');\n }\n\n setMarkers(markers: Marker[]): void {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n throw new Error('Text document is not initialized');\n }\n\n if (markers.length === 0) {\n this.#markerRenderer?.cleanup();\n this.#markerRenderer = undefined;\n this.#updateSelections(this.#selections ?? []);\n return;\n }\n\n this.#markerRenderer ??= new MarkerRenderer({\n getLineHeight: () => this.#metrics.lineHeight,\n getFileContainer: () => this.#fileContainer,\n getCharX: (line, character) => this.#getCharX(line, character),\n getLineY: (line) => this.#getLineY(line),\n isMouseDown: () => this.#isContentMouseDown || this.#isGutterMouseDown,\n });\n this.#markerRenderer.setMarkers(markers, textDocument);\n if (this.#contentElement !== undefined) {\n this.#markerRenderer.listenHover(this.#contentElement);\n }\n this.#updateSelections(this.#selections ?? []);\n }\n\n focus(options?: FocusOptions): void {\n const preventScroll = options?.preventScroll ?? false;\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const pos =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n this.#focus(pos, preventScroll);\n } else {\n this.#focus(undefined, preventScroll);\n }\n }\n\n blur(): void {\n this.#contentElement?.blur();\n }\n\n cleanUp(): void {\n this.#tokenizer?.cleanUp();\n this.#tokenizer = undefined;\n\n // dispse event listeners\n this.#globalEventDisposes?.forEach((dispose) => dispose());\n this.#globalEventDisposes = undefined;\n this.#editorEventDisposes?.forEach((dispose) => dispose());\n this.#editorEventDisposes = undefined;\n this.#selectEventDisposes?.forEach((dispose) => dispose());\n this.#selectEventDisposes = undefined;\n this.#detach?.();\n this.#detach = undefined;\n\n // cache\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#lineYCache.clear();\n this.#wrapLineOffsetsCache.clear();\n this.#lastAccessedLineElement = undefined;\n this.#lastAccessedCharX = undefined;\n\n // clean up dom elements\n this.#globalStyleElement?.remove();\n this.#globalStyleElement = undefined;\n this.#editorStyleElement?.remove();\n this.#editorStyleElement = undefined;\n this.#themeStyleElement?.remove();\n this.#themeStyleElement = undefined;\n this.#spriteElement?.remove();\n this.#spriteElement = undefined;\n this.#fileContainer = undefined;\n this.#gutterElement = undefined;\n this.#contentElement?.removeAttribute('contentEditable');\n this.#contentElement = undefined;\n this.#overlayElement?.remove();\n this.#overlayElement = undefined;\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n\n this.#resetState();\n }\n\n /** @internal */\n __postponeBackgroundTokenizeToNextFrame(): void {\n const tokenizer = this.#tokenizer;\n if (tokenizer !== undefined) {\n tokenizer.pauseBackgroundTokenize();\n requestAnimationFrame(() => {\n tokenizer.resumeBackgroundTokenize();\n });\n }\n }\n\n /** @internal */\n __syncRenderView: DiffsEditor<LAnnotation>['__syncRenderView'] = (\n highlighter: DiffsHighlighter,\n fileContainer: HTMLElement,\n fileContents: FileContents,\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined,\n renderRange: RenderRange | undefined\n ) => {\n const shadowRoot = fileContainer.shadowRoot;\n if (shadowRoot == null) {\n console.error('[editor] Could not find the shadow root.');\n return;\n }\n\n let codeElement: HTMLElement | undefined;\n let gutterEl: HTMLElement | undefined;\n let contentEl: HTMLElement | undefined;\n for (const el of shadowRoot.querySelectorAll<HTMLElement>('[data-code]')) {\n if (el.dataset.deletions === undefined) {\n codeElement = el;\n for (const child of el.children) {\n const el = child as HTMLElement;\n const { gutter, content } = el.dataset;\n if (gutter !== undefined) {\n gutterEl = el;\n } else if (content !== undefined) {\n contentEl = el;\n }\n }\n break;\n }\n }\n if (codeElement === undefined || contentEl === undefined) {\n return;\n }\n\n // inject editor&theme style to the file container\n if (this.#fileContainer !== fileContainer) {\n this.#fileContainer = fileContainer;\n if (this.#globalStyleElement !== undefined) {\n fileContainer.appendChild(this.#globalStyleElement);\n }\n if (this.#editorStyleElement !== undefined) {\n shadowRoot.appendChild(this.#editorStyleElement);\n }\n if (this.#themeStyleElement !== undefined) {\n shadowRoot.appendChild(this.#themeStyleElement);\n }\n if (this.#spriteElement !== undefined) {\n shadowRoot.prepend(this.#spriteElement);\n }\n }\n\n if (\n this.#textDocument === undefined ||\n this.#fileContents === undefined ||\n this.#fileContents.name !== fileContents.name ||\n this.#fileContents.contents !== fileContents.contents ||\n this.#fileContents.lang !== fileContents.lang ||\n this.#fileContents.cacheKey !== fileContents.cacheKey\n ) {\n const editStack = new EditStack<LAnnotation>({\n maxEntries: this.#options.historyMaxEntries,\n });\n const textDocument = new TextDocument<LAnnotation>(\n fileContents.name,\n fileContents.contents,\n fileContents.lang ?? getFiletypeFromFileName(fileContents.name),\n 0,\n editStack\n );\n this.#fileContents = fileContents;\n this.#textDocument = textDocument;\n this.#tokenizer?.cleanUp();\n this.#tokenizer = new EditorTokenizer({\n highlighter,\n textDocument,\n codeOptions: this.#fileInstance?.options ?? {},\n onDeferTokenize: this.#onDeferTokenize,\n setStyle: (css) => {\n this.#themeStyleElement!.textContent = css;\n },\n __debug: this.#options.__debug,\n });\n this.#resetState();\n this.#selections = this.#initSelections;\n this.#options.onAttach?.(this, this.#fileInstance!);\n if (this.#textDocument !== undefined && this.#options.__debug === true) {\n console.log('[diffs/editor] text document changed !!!');\n }\n }\n\n if (this.#contentElement !== contentEl) {\n this.#gutterElement = gutterEl;\n this.#contentElement = extend(contentEl, {\n contentEditable: 'true',\n role: 'textbox',\n ariaMultiLine: 'true',\n autocapitalize: 'off',\n writingSuggestions: 'off',\n autocorrect: false,\n spellcheck: false,\n translate: false,\n });\n if (this.#overlayElement !== undefined) {\n contentEl.after(this.#overlayElement);\n }\n this.#metrics.init(contentEl);\n this.#listenContentElement(contentEl, gutterEl);\n if (\n this.#contentElement !== undefined &&\n this.#options.__debug === true\n ) {\n console.log('[diffs/editor] full re-render triggered !!!');\n }\n }\n\n this.#resetCache();\n\n this.#wrap = this.#fileInstance?.options.overflow === 'wrap';\n this.#lineAnnotations = lineAnnotations;\n this.#renderRange = renderRange;\n this.#tokenizer?.prebuildStateStack(renderRange);\n\n // re-render the existing selections, matches, and markers\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n }\n\n if (\n this.#initSelections !== undefined &&\n this.#primaryCaretElement !== undefined\n ) {\n this.#initSelections = undefined;\n this.#scrollToPrimaryCaret(false, 'center');\n } else if (this.#scrollingToLine !== undefined) {\n this.#scrollToLine(\n this.#scrollingToLine,\n this.#scrollingToLineChar,\n this.#scrollingToLineNoFocus\n );\n } else if (\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n !this.#retainSearchPanelFocus\n ) {\n this.focus({ preventScroll: true });\n }\n\n if (this.#retainSearchPanelFocus) {\n this.#searchPanel?.focus();\n }\n\n if (\n this.#selectionAction !== undefined &&\n this.#isLineVisible(this.#selectionAction.line) &&\n this.#contentElement !== undefined\n ) {\n this.#selectionAction.render(this.#contentElement);\n }\n\n if (this.#options.__debug === true && renderRange !== undefined) {\n const { startingLine, totalLines } = renderRange;\n console.log(\n '[diffs/editor] render file:',\n fileContents.name,\n 'RenderRange:',\n startingLine + '-' + (startingLine + totalLines),\n 'of',\n this.#textDocument.lineCount,\n 'lines'\n );\n }\n };\n\n #resetCache(): void {\n this.#lineYCache.clear();\n this.#wrapLineOffsetsCache.clear();\n this.#lastAccessedLineElement = undefined;\n this.#lastAccessedCharX = undefined;\n }\n\n #resetState(): void {\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#fileInstance?.setSelectedLines(null);\n this.#shouldIgnoreSelectionChange = false;\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements = undefined;\n this.#selections = undefined;\n this.#reservedSelections = undefined;\n this.#scrollingToLine = undefined;\n this.#markerRenderer?.cleanup();\n this.#markerRenderer = undefined;\n this.#searchPanel?.cleanup();\n this.#searchPanel = undefined;\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n }\n\n #initialize(): void {\n // Safari doesn't support `::selection` for slot elements in ShadowDOM,\n // Add a global style to disable selection for slot elements\n this.#globalStyleElement = h('style', {\n dataset: 'editorGlobalCss',\n textContent: `\n [data-annotation-slot] {\n user-select: none;\n -webkit-user-select: none;\n }\n `,\n });\n\n this.#editorStyleElement = h('style', {\n dataset: 'editorCss',\n textContent: editorCSS,\n });\n\n this.#themeStyleElement = h('style', {\n dataset: 'editorThemeCss',\n });\n\n this.#spriteElement = createSpriteElement();\n\n this.#overlayElement = h('div', {\n dataset: 'editorOverlay',\n });\n\n this.#globalEventDisposes = [\n addEventListener(\n document,\n 'selectionchange',\n () => {\n const shadowRoot = this.#fileContainer?.shadowRoot;\n if (this.#shouldIgnoreSelectionChange || shadowRoot == null) {\n return;\n }\n\n // Native selection only tracks one range. focus() and DOM updates while\n // typing mirror the primary caret there, so selectionchange must not\n // overwrite multi-cursor editor state outside an active pointer gesture.\n if (\n this.#selections !== undefined &&\n this.#selections.length > 1 &&\n !this.#isContentMouseDown\n ) {\n return;\n }\n\n const selectionRaw = document.getSelection();\n const composedRange = selectionRaw?.getComposedRanges({\n shadowRoots: [shadowRoot],\n })?.[0];\n if (\n composedRange === undefined ||\n !this.#rangeBelongsToEditor(composedRange)\n ) {\n return;\n }\n\n let selection = convertSelection(composedRange, DirectionNone);\n if (selection === undefined) {\n return;\n }\n\n // extend selection by shift + click\n if (\n this.#isContentMouseDown &&\n this.#shiftKeyPressed &&\n this.#selections !== undefined &&\n this.#selections.length > 0\n ) {\n const primarySelection = this.#selections.at(-1)!;\n this.#updateSelections([\n extendSelection(primarySelection, selection),\n ]);\n return;\n }\n\n if (this.#isContentMouseDown) {\n if (this.#selectionStart !== undefined) {\n selection = createSelectionFrom(this.#selectionStart, selection);\n } else {\n this.#selectionStart = selection;\n }\n } else if (this.#selectionStart !== undefined) {\n selection.direction = createSelectionFrom(\n this.#selectionStart,\n selection\n ).direction;\n }\n\n if (this.#reservedSelections !== undefined) {\n this.#updateSelections([\n ...this.#reservedSelections.filter(\n (reservedSelection) =>\n !selectionIntersects(reservedSelection, selection)\n ),\n selection,\n ]);\n } else {\n this.#updateSelections([selection]);\n }\n },\n { passive: true }\n ),\n\n addEventListener(\n document,\n 'pointerup',\n (e) => {\n if (e.pointerType !== 'mouse') {\n return;\n }\n\n this.#selectEventDisposes?.forEach((dispose) => dispose());\n this.#selectEventDisposes = undefined;\n\n if (this.#isGutterMouseDown) {\n this.#isGutterMouseDown = false;\n this.#focus();\n }\n this.#shouldIgnoreSelectionChange = false;\n this.#isContentMouseDown = false;\n this.#shiftKeyPressed = false;\n this.#selectionStart = undefined;\n this.#reservedSelections = undefined;\n this.#overlayElements?.forEach((el, key) => {\n if (key.startsWith('selectionActionIcon-')) {\n el.dataset.visible = 'true';\n }\n });\n },\n { passive: true }\n ),\n\n addEventListener(\n document,\n 'keydown',\n (e) => {\n if (e.key === 'Shift') {\n this.#selectionStart = this.#selections?.at(-1);\n }\n },\n { passive: true }\n ),\n\n addEventListener(\n document,\n 'keyup',\n (e) => {\n if (e.key === 'Shift') {\n this.#selectionStart = undefined;\n }\n },\n { passive: true }\n ),\n ];\n }\n\n #listenContentElement(contentEl: HTMLElement, gutterEl?: HTMLElement): void {\n const targetIsContentElement = (e: Event) => {\n const target = e.composedPath()[0] as HTMLElement | undefined;\n return (\n target !== undefined &&\n (target === contentEl || contentEl.contains(target))\n );\n };\n\n this.#editorEventDisposes?.forEach((dispose) => dispose());\n this.#editorEventDisposes = [\n addEventListener(\n contentEl,\n 'pointerdown',\n (e) => {\n if (e.pointerType !== 'mouse') {\n return;\n }\n\n this.#markerRenderer?.removePopup();\n\n // this is a workaround for the selection rendering glitch\n // happens when selecting content in shadow DOM on Safari\n if (\n isSafari() &&\n this.#lineAnnotations !== undefined &&\n this.#lineAnnotations.length > 0\n ) {\n this.#selectEventDisposes = [\n ...contentEl.querySelectorAll<HTMLElement>(\n '[data-line-annotation]'\n ),\n ]\n .map((el) => [\n addEventListener(el, 'mouseenter', () => {\n this.#shouldIgnoreSelectionChange = true;\n }),\n addEventListener(el, 'mouseleave', () => {\n this.#shouldIgnoreSelectionChange = false;\n }),\n ])\n .flat();\n }\n\n this.#isContentMouseDown = true;\n this.#selectionStart = undefined;\n if (e.button === 0 && isPrimaryModifier(e)) {\n this.#reservedSelections = this.#selections?.map((selection) => ({\n ...selection,\n }));\n }\n if (e.shiftKey) {\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const pos =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n // fix the window selection for shift mode\n this.#setWindowSelection({\n start: pos,\n end: pos,\n direction: DirectionNone,\n });\n }\n this.#shiftKeyPressed = true;\n }\n },\n { passive: true }\n ),\n\n addEventListener(contentEl, 'keydown', (e) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.#searchPanel?.cleanup();\n this.#searchPanel = undefined;\n this.#retainSearchPanelFocus = false;\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n if (this.#selections !== undefined && this.#selections.length > 0) {\n const primarySelection = this.#selections.at(-1)!;\n if (\n !isCollapsedSelection(primarySelection) ||\n this.#selections.length > 1\n ) {\n const pos = getCaretPosition(primarySelection);\n this.#updateSelections([\n {\n start: pos,\n end: pos,\n direction: DirectionNone,\n },\n ]);\n this.#focus(pos);\n }\n }\n return;\n }\n if (!targetIsContentElement(e)) {\n return;\n }\n\n // handle the cursor move events manually for multiple selections and virtual viewport\n const mvShortcut = isMoveCursorShortcut(e);\n const textDocument = this.#textDocument;\n if (\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n mvShortcut !== undefined &&\n textDocument !== undefined\n ) {\n if (e.shiftKey) {\n this.#updateSelections(\n mapSelectionShift(textDocument, this.#selections, mvShortcut)\n );\n } else {\n this.#updateSelections(\n mapCursorMove(textDocument, this.#selections, mvShortcut)\n );\n }\n this.#scrollToPrimaryCaret();\n e.preventDefault();\n return;\n }\n\n const command = resolveEditorCommandFromKeyboardEvent(e);\n if (command !== undefined) {\n e.preventDefault();\n this.#runCommand(command);\n }\n }),\n\n addEventListener(contentEl, 'copy', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n e.clipboardData?.setData('text', this.#getSelectionText());\n }),\n\n addEventListener(contentEl, 'cut', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n e.clipboardData?.setData('text', this.#getSelectionText());\n this.#replaceSelectionText('');\n }),\n\n addEventListener(contentEl, 'paste', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n const text = e.clipboardData?.getData('text');\n if (text !== undefined) {\n // TODO(@ije): Add support of multiple selections copy&paste\n // TODO(@ije): normalize the pasted text with textDocument.EOF\n this.#replaceSelectionText(text);\n }\n }),\n\n addEventListener(contentEl, 'beforeinput', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n this.#handleInput(e.inputType, e.data);\n }),\n\n addEventListener(contentEl, 'drop', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // TODO(@ije): Add support of drag move selection\n }),\n\n addEventListener(\n contentEl,\n 'compositionstart',\n (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#shouldIgnoreSelectionChange = true;\n },\n { passive: true }\n ),\n\n addEventListener(\n contentEl,\n 'compositionend',\n (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#shouldIgnoreSelectionChange = false;\n this.#handleInput('insertText', e.data);\n },\n { passive: true }\n ),\n ];\n if (gutterEl !== undefined) {\n const resolveGutterTarget = (\n eventTarget: HTMLElement | undefined,\n includeContentLine = false\n ) => {\n let target = eventTarget;\n if (target?.dataset.lineNumberContent !== undefined) {\n target = target.parentElement ?? undefined;\n } else if (includeContentLine && target?.tagName === 'SPAN') {\n target = target.closest('[data-line]') as HTMLElement | undefined;\n }\n return target;\n };\n\n const resolveEditableLine = (target: HTMLElement | undefined) => {\n if (target === undefined) {\n return;\n }\n const lineType = target.dataset.lineType;\n const lineNumber =\n getLineNumberAttr(target) ??\n getLineNumberAttr(target, 'columnNumber');\n if (\n lineNumber === undefined ||\n lineType === undefined ||\n !isLineEditable(lineType)\n ) {\n return;\n }\n return lineNumber - 1;\n };\n\n this.#editorEventDisposes.push(\n addEventListener(\n gutterEl,\n 'pointerdown',\n (e) => {\n const textDocument = this.#textDocument;\n const lineIndex = resolveEditableLine(\n resolveGutterTarget(\n e.composedPath()[0] as HTMLElement | undefined\n )\n );\n if (lineIndex === undefined || textDocument === undefined) {\n return;\n }\n\n this.#markerRenderer?.removePopup();\n const selection: EditorSelection = {\n start: { line: lineIndex, character: 0 },\n end: {\n line: lineIndex,\n character: textDocument.getLineText(lineIndex).length,\n },\n direction: DirectionForward,\n };\n this.#isGutterMouseDown = true;\n this.#selectionStart = selection;\n this.#updateSelections([selection]);\n this.#focus(selection.end);\n this.#selectEventDisposes = [\n addEventListener(\n document,\n 'mousemove',\n (e) => {\n if (!this.#isGutterMouseDown) {\n return;\n }\n const textDocument = this.#textDocument;\n const lineIndex = resolveEditableLine(\n resolveGutterTarget(\n e.composedPath()[0] as HTMLElement | undefined,\n true\n )\n );\n if (lineIndex === undefined || textDocument === undefined) {\n return;\n }\n\n let selection: EditorSelection = {\n start: { line: lineIndex, character: 0 },\n end: {\n line: lineIndex,\n character: textDocument.getLineText(lineIndex).length,\n },\n direction: DirectionForward,\n };\n if (this.#selectionStart !== undefined) {\n selection = createSelectionFrom(\n this.#selectionStart,\n selection\n );\n } else {\n this.#selectionStart = selection;\n }\n this.#updateSelections([selection]);\n this.#focus(selection.end);\n },\n { passive: true }\n ),\n ];\n },\n { passive: true }\n )\n );\n }\n\n this.#markerRenderer?.listenHover(contentEl);\n\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = new ResizeObserver(() => {\n this.#handleLayoutResize();\n });\n this.#resizeObserver.observe(contentEl);\n this.#resizeObserver.observe(contentEl.parentElement!);\n }\n\n // TODO(@ije): add command registry\n #runCommand(command: EditorCommand) {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n return;\n }\n\n switch (command) {\n case 'openSearchPanel':\n this.#openSearchPanel('find');\n break;\n\n case 'openSearchReplacePanel':\n this.#openSearchPanel('replace');\n break;\n\n case 'findNextMatch': {\n const selections = this.#selections;\n if (selections === undefined) {\n break;\n }\n const hasCollapsed = selections.some(isCollapsedSelection);\n if (hasCollapsed) {\n const expanded: EditorSelection[] = selections.map((sel) => {\n if (isCollapsedSelection(sel)) {\n return expandCollapsedSelectionToWord(textDocument, sel);\n }\n return sel;\n });\n this.#updateSelections(expanded);\n this.focus();\n } else {\n const nextMatch = findNexMatch(textDocument, selections);\n if (nextMatch !== undefined) {\n this.#updateSelections(nextMatch);\n this.#scrollToPrimaryCaret();\n }\n }\n break;\n }\n\n case 'indent':\n case 'outdent':\n if (this.#selections !== undefined) {\n const edits: TextEdit[] = [];\n const nextSelections: EditorSelection[] = [];\n for (const selection of this.#selections) {\n const startLine = selection.start.line;\n const outdent = command === 'outdent';\n if (startLine !== selection.end.line || outdent) {\n const ret = resolveIndentEdits(\n textDocument,\n selection,\n this.#metrics.tabSize,\n outdent\n );\n edits.push(...ret[0]);\n nextSelections.push(ret[1]);\n } else {\n const lineChar0 = textDocument.charAt({\n line: startLine,\n character: 0,\n });\n this.#replaceSelectionText(\n lineChar0 === '\\t' ? '\\t' : ' '.repeat(this.#metrics.tabSize)\n );\n }\n }\n const change = textDocument.applyEdits(\n edits,\n true,\n this.#selections,\n nextSelections\n );\n if (change !== undefined) {\n this.#applyChange(change, nextSelections);\n }\n }\n break;\n\n case 'selectAll':\n this.#updateSelections([getDocumentFullSelection(textDocument)]);\n this.focus();\n break;\n\n case 'moveCursorToDocStart':\n case 'moveCursorToDocEnd':\n {\n const atEnd = command === 'moveCursorToDocEnd';\n this.#updateSelections([\n getDocumentBoundarySelection(textDocument, atEnd),\n ]);\n this.#scrollToPrimaryCaret();\n }\n break;\n\n case 'expandSelectionDocStart':\n case 'expandSelectionDocEnd':\n {\n const atEnd = command === 'expandSelectionDocEnd';\n const selections = this.#selections;\n if (selections !== undefined) {\n this.#updateSelections(\n extendSelections(\n selections,\n getDocumentBoundarySelection(textDocument, atEnd)\n )\n );\n this.#scrollToPrimaryCaret();\n }\n }\n break;\n\n case 'undo':\n if (this.#textDocument?.canUndo === true) {\n const undoResult = this.#textDocument.undo();\n if (undoResult !== undefined) {\n this.#applyChange(...undoResult);\n }\n }\n break;\n\n case 'redo':\n if (this.#textDocument?.canRedo === true) {\n const redoResult = this.#textDocument.redo();\n if (redoResult !== undefined) {\n this.#applyChange(...redoResult);\n }\n }\n break;\n }\n }\n\n #handleLayoutResize() {\n const lineAnnotations = this.#lineAnnotations?.length ?? 0;\n const prevGutterWidth = this.#gutterWidthCache;\n const prevContentWidth = this.#contentWidthCache;\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n const gutterWidthChanged = this.#getGutterWidth() !== prevGutterWidth;\n const contentWidthChanged = this.#getContentWidth() !== prevContentWidth;\n if (!gutterWidthChanged && !contentWidthChanged) {\n return;\n }\n\n this.#lastAccessedLineElement = undefined;\n this.#lastAccessedCharX = undefined;\n if (contentWidthChanged && (this.#wrap || lineAnnotations > 0)) {\n this.#lineYCache.clear();\n this.#wrapLineOffsetsCache.clear();\n }\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n if (this.#selections !== undefined) {\n this.focus();\n }\n }\n this.#markerRenderer?.removePopup();\n }\n\n #rerender(\n change: TextDocumentChange,\n newLineAnnotations?: DiffLineAnnotation<LAnnotation>[],\n renderRange = this.#renderRange,\n shouldUpdateBuffer?: boolean\n ) {\n const tokenizer = this.#tokenizer;\n const fileInstance = this.#fileInstance;\n const fileContents = this.#fileContents;\n const textDocument = this.#textDocument;\n const gutterEl = this.#gutterElement;\n const contentEl = this.#contentElement;\n if (\n tokenizer === undefined ||\n fileInstance === undefined ||\n fileContents === undefined ||\n textDocument === undefined ||\n contentEl === undefined\n ) {\n return;\n }\n\n // cancel existing background tokenzier task\n tokenizer.stopBackgroundTokenize();\n\n const t = performance.now();\n const dirtyLines = tokenizer.tokenize(change, renderRange);\n const t2 = performance.now();\n\n if (dirtyLines.size > 0) {\n const children = contentEl.children;\n const dirtyLineIndexes = new Set<number>(dirtyLines.keys());\n\n // update line elements that have been changed in the document\n const startingLine = renderRange?.startingLine ?? 0;\n for (let i = change.startLine - startingLine; i < children.length; i++) {\n const child = children[i] as HTMLElement | undefined;\n if (child !== undefined) {\n const lineNumber = getLineNumberAttr(child);\n if (lineNumber !== undefined) {\n const lineIndex = lineNumber - 1;\n if (dirtyLines.has(lineIndex)) {\n const tokens = dirtyLines.get(lineIndex)!;\n child.replaceChildren(\n ...renderLineTokens(tokens, tokenizer.themeType)\n );\n dirtyLineIndexes.delete(lineIndex);\n if (dirtyLineIndexes.size === 0) {\n break;\n }\n }\n }\n }\n }\n\n // create new line elements for the new lines\n if (dirtyLineIndexes.size > 0) {\n for (const lineIndex of dirtyLineIndexes) {\n const tokens = dirtyLines.get(lineIndex)!;\n const lineNumber = String(lineIndex + 1);\n h(\n 'div',\n {\n dataset: {\n line: lineNumber,\n lineType: 'context',\n lineIndex: lineIndex.toString(),\n },\n // oxlint-disable-next-line react/no-children-prop\n children: renderLineTokens(tokens, tokenizer.themeType),\n },\n contentEl\n );\n if (gutterEl !== undefined) {\n h(\n 'div',\n {\n dataset: {\n lineType: 'context',\n columnNumber: lineNumber,\n lineIndex: lineIndex.toString(),\n },\n // oxlint-disable-next-line react/no-children-prop\n children: [\n h('span', {\n dataset: {\n lineNumberContent: '',\n },\n textContent: lineNumber,\n }),\n ],\n },\n gutterEl\n );\n }\n }\n }\n }\n\n // remove line elements that have been deleted in the document\n if (change.lineDelta < 0) {\n for (const children of [contentEl.children, gutterEl?.children ?? []]) {\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i] as HTMLElement;\n const lineNumber =\n getLineNumberAttr(child) ??\n getLineNumberAttr(child, 'columnNumber');\n if (lineNumber === undefined) {\n continue;\n }\n if (lineNumber - 1 < change.lineCount) {\n break;\n }\n child.remove();\n }\n }\n }\n\n const isDiff = Object.hasOwn(fileInstance, 'fileDiff');\n const didLineCountChange = change.lineDelta !== 0;\n\n // fix grid layout\n if (didLineCountChange) {\n let gridRow = contentEl.children.length;\n for (const child of contentEl.children) {\n const { bufferSize } = (child as HTMLElement).dataset;\n if (bufferSize !== undefined) {\n gridRow += parseInt(bufferSize) - 1;\n }\n }\n contentEl.style.gridRow = 'span ' + gridRow;\n if (gutterEl !== undefined) {\n gutterEl.style.gridRow = 'span ' + gridRow;\n }\n }\n\n fileInstance.updateRenderCache(\n dirtyLines,\n tokenizer.themeType,\n isDiff ? !didLineCountChange : undefined\n );\n if (didLineCountChange) {\n fileInstance.applyDocumentChange(\n textDocument,\n newLineAnnotations,\n shouldUpdateBuffer\n );\n }\n\n if (newLineAnnotations !== undefined) {\n this.#lineAnnotations = newLineAnnotations;\n renderLineAnnotations(newLineAnnotations, contentEl, gutterEl);\n }\n\n if (this.#options.__debug === true) {\n console.log(\n `[diffs/editor] re-render in: ${round(performance.now() - t2)}ms,`,\n `tokenize in: ${round(t2 - t)}ms (${dirtyLines.size} dirty lines)`\n );\n }\n }\n\n // input type doc: https://developer.mozilla.org/en-US/docs/Web/API/InputEvent/inputType\n #handleInput(inputType: string, data: string | null) {\n switch (inputType) {\n case 'insertText':\n this.#replaceSelectionText(data ?? '');\n break;\n case 'insertParagraph':\n // TODO(@ije): use document.EOF instead of '\\n'\n this.#replaceSelectionText('\\n');\n break;\n case 'deleteContentBackward':\n this.#deleteSelectionText();\n break;\n case 'deleteContentForward':\n this.#deleteSelectionText(true);\n break;\n case 'deleteSoftLineBackward':\n this.#deleteSoftLineBackward();\n break;\n case 'deleteHardLineForward':\n // TODO(@ije): Safari and Firefox does not support this input type\n // use command instead\n this.#deleteHardLineForward();\n break;\n case 'deleteWordBackward':\n this.#deleteWordBackward();\n break;\n case 'insertTranspose':\n this.#insertTranspose();\n break;\n default:\n console.warn(`[diffs] Unknown input type: ${inputType}`, data);\n break;\n }\n }\n\n #focus(position?: Position, preventScroll = true) {\n if (position !== undefined) {\n this.#shouldIgnoreSelectionChange = true;\n this.#setWindowSelection({\n start: position,\n end: position,\n direction: DirectionNone,\n });\n // call focus in a request animation frame to prevent conflict with\n // the `setBaseAndExtent` method\n requestAnimationFrame(() => {\n this.#contentElement?.focus({ preventScroll });\n // another request animation frame since the `focus` call\n // may trigger a selectionchange event, which we want to ignore\n requestAnimationFrame(() => {\n this.#shouldIgnoreSelectionChange = false;\n });\n });\n } else {\n this.#contentElement?.focus({ preventScroll });\n }\n }\n\n // set window native selection to match the selection\n #setWindowSelection(selection: EditorSelection) {\n const winSelection = window.getSelection();\n if (winSelection === null) {\n return;\n }\n let { start, end, direction } = selection;\n if (comparePosition(start, end) > 0) {\n [start, end] = [end, start];\n }\n const startLineElement = this.#getLineElement(start.line);\n const endLineElement = this.#getLineElement(end.line);\n if (startLineElement === undefined || endLineElement === undefined) {\n return;\n }\n let [anchorNode, anchorOffset] = getSelectionAnchor(\n startLineElement,\n start.character\n );\n let [focusNode, focusOffset] = getSelectionAnchor(\n endLineElement,\n end.character\n );\n if (direction === DirectionBackward) {\n [anchorNode, anchorOffset, focusNode, focusOffset] = [\n focusNode,\n focusOffset,\n anchorNode,\n anchorOffset,\n ];\n }\n try {\n winSelection.setBaseAndExtent(\n anchorNode,\n clampDomOffset(anchorNode, anchorOffset),\n focusNode,\n clampDomOffset(focusNode, focusOffset)\n );\n } catch (err) {\n console.error('[diffs/editor] failed to update window selection:', err);\n }\n }\n\n #scrollToPrimaryCaret(\n noFocus = false,\n scrollPosition: ScrollLogicalPosition = 'nearest'\n ) {\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection === undefined) {\n return;\n }\n const primaryCaretElement = this.#primaryCaretElement;\n if (primaryCaretElement !== undefined) {\n primaryCaretElement.scrollIntoView({\n block: scrollPosition,\n inline: 'nearest',\n });\n if (!noFocus) {\n this.#focus(\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start\n );\n }\n } else {\n const pos = getCaretPosition(primarySelection);\n this.#scrollToLine(pos.line, pos.character, noFocus);\n }\n }\n\n // add scroll margin to the primary caret element to prevent\n // the caret from being hidden by the gutter\n #getScrollMargin() {\n const componentTop = this.#fileInstance?.top ?? 0;\n const top = this.#searchPanel !== undefined ? 48 : 0;\n const start = this.#getGutterWidth() + this.#metrics.ch;\n const end = this.#metrics.ch;\n return `${componentTop + top}px ${end}px 0 ${start}px`;\n }\n\n #scrollToLine(line: number, char = 0, noFocus = false) {\n this.__postponeBackgroundTokenizeToNextFrame();\n\n const virtualCaret = h('div', {\n style: {\n position: 'absolute',\n left: '0',\n width: '2px',\n height: this.#metrics.lineHeight + 'px',\n scrollMargin: this.#getScrollMargin(),\n },\n });\n if (this.#getLineElement(line) !== undefined) {\n const [left, wrapLine] = this.#getCharX(line, char);\n const lineY = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight;\n virtualCaret.style.top = lineY + 'px';\n virtualCaret.style.left = left + 'px';\n this.#overlayElement?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n if (!noFocus) {\n this.#focus({ line, character: char });\n }\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineNoFocus = false;\n }\n // if the line is not rendered yet(virtualized), scroll to the approximate\n // line position to trigger the line to be rendered, then recall this function\n // to ensure the line is scrolled into view\n else {\n let yFix = 0;\n if (\n this.#scrollingToLine === line &&\n this.#contentElement !== undefined\n ) {\n for (let i = this.#contentElement.childElementCount - 1; i >= 0; i--) {\n const child = this.#contentElement.children[i] as HTMLElement;\n const lineType = child.dataset.lineType;\n const lineNumber = getLineNumberAttr(child);\n if (\n lineType !== undefined &&\n isLineEditable(lineType) &&\n lineNumber !== undefined\n ) {\n yFix = (line - lineNumber) * this.#metrics.lineHeight;\n break;\n }\n }\n }\n const lineAnnotations = (this.#lineAnnotations ?? []).filter(\n (annotation) => annotation.lineNumber < line\n ).length;\n const approximateLineY =\n (lineAnnotations + line) * this.#metrics.lineHeight + yFix;\n virtualCaret.style.top = approximateLineY + 'px';\n this.#fileContainer?.shadowRoot?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n if (this.#scrollingToLine === line && yFix === 0) {\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineNoFocus = false;\n } else {\n this.#scrollingToLine = line;\n this.#scrollingToLineChar = char;\n this.#scrollingToLineNoFocus = noFocus;\n }\n }\n virtualCaret.remove();\n }\n\n #updateSelections(selections: EditorSelection[]) {\n this.__postponeBackgroundTokenizeToNextFrame();\n\n this.#primaryCaretElement = undefined;\n this.#fileInstance?.setSelectedLines(null);\n this.#gutterElement\n ?.querySelectorAll('[data-active]')\n .forEach((el) => el.removeAttribute('data-active'));\n\n if (\n selections.length === 0 &&\n this.#matches === undefined &&\n this.#markerRenderer === undefined\n ) {\n this.#selections = undefined;\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements?.clear();\n return;\n }\n\n const fragment = document.createDocumentFragment();\n const renderCtx = {\n fragment,\n elements: new Map<string, HTMLElement>(),\n };\n\n if (selections.length > 0) {\n const normalizedSelections = mergeOverlappingSelections(selections);\n const primarySelection = normalizedSelections.at(-1)!;\n this.#selections = normalizedSelections;\n if (isCollapsedSelection(primarySelection)) {\n const line = primarySelection.start.line + 1;\n this.#fileInstance?.setSelectedLines({\n start: line,\n end: line,\n });\n } else {\n if (this.#gutterElement !== undefined) {\n const pos = getCaretPosition(primarySelection);\n this.#gutterElement\n .querySelector(`[data-column-number=\"${pos.line + 1}\"]`)\n ?.setAttribute('data-active', '');\n }\n }\n\n for (const selection of normalizedSelections) {\n if (!isCollapsedSelection(selection)) {\n this.#renderSelection(renderCtx, 'selection', selection);\n }\n this.#renderCaret(renderCtx, selection, selection === primarySelection);\n }\n if (\n this.#options.enabledSelectionAction === true &&\n !isCollapsedSelection(primarySelection)\n ) {\n this.#renderSelectionActionIcon(renderCtx, primarySelection);\n }\n }\n\n const textDocument = this.#textDocument;\n if (this.#matches !== undefined && textDocument !== undefined) {\n const primarySelection = this.#selections?.at(-1);\n const primaryStartOffset =\n primarySelection !== undefined\n ? textDocument.offsetAt(primarySelection.start)\n : -1;\n const primaryEndOffset =\n primarySelection !== undefined\n ? textDocument.offsetAt(primarySelection.end)\n : -1;\n for (const [startOffset, endOffset] of this.#matches) {\n const range: Range = {\n start: textDocument.positionAt(startOffset),\n end: textDocument.positionAt(endOffset),\n };\n const isFocused =\n primaryStartOffset === startOffset && primaryEndOffset === endOffset;\n this.#renderSelection(\n renderCtx,\n 'match',\n range,\n isFocused ? 'focus' : undefined\n );\n }\n }\n\n if (this.#markerRenderer !== undefined && textDocument !== undefined) {\n for (const marker of this.#markerRenderer.markers) {\n this.#renderSelection(\n renderCtx,\n 'marker',\n marker,\n markerSeverityDatasetKey(marker.severity)\n );\n }\n }\n\n this.#overlayElement?.appendChild(fragment);\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements?.clear();\n this.#overlayElements = renderCtx.elements;\n }\n\n #renderSelection(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n type: 'selection' | 'match' | 'marker',\n range: Range,\n extraDataset?: string\n ) {\n if (this.#textDocument === undefined) {\n return;\n }\n\n const { start, end } = range;\n for (let line = start.line; line <= end.line; line++) {\n if (!this.#isLineVisible(line)) {\n continue;\n }\n\n const isLastLine = line === end.line;\n const lineText = this.#textDocument.getLineText(line);\n const startChar = line === start.line ? start.character : 0;\n const endChar = isLastLine ? end.character : lineText.length;\n\n if (this.#wrap) {\n const contentWidth = this.#getContentWidth();\n const textWidth =\n 2 * this.#metrics.ch + this.#metrics.measureTextWidth(lineText);\n if (textWidth > contentWidth) {\n this.#renderWrappedSelection(\n renderCtx,\n line,\n lineText,\n startChar,\n endChar,\n isLastLine,\n type,\n extraDataset\n );\n continue;\n }\n }\n\n let left = 0;\n let width = 0;\n let paddingEnd = 0;\n if (startChar === 0) {\n left = this.#getGutterWidth() + this.#metrics.ch; // gutter width + inline padding (1ch)\n } else {\n left = this.#getCharX(line, startChar)[0];\n }\n if (!isLastLine && type === 'selection') {\n paddingEnd = this.#metrics.ch;\n }\n if (startChar === endChar) {\n width = paddingEnd;\n } else {\n width = this.#getCharX(line, endChar)[0] - left + paddingEnd;\n }\n this.#renderSelectionBlock(\n renderCtx,\n type,\n line,\n 0,\n left,\n width,\n extraDataset\n );\n }\n }\n\n // Render the selection on a wrapped logical line by splitting it into one\n // selection-range div per visual sub-line. For each wrap segment, we compute\n // the intersection with the line's selection range and render the slice in\n // segment-local coordinates so left/width line up with the visually wrapped\n // text. Zero-width slices that fall on intermediate segment boundaries are\n // skipped to avoid duplicate markers across consecutive visual lines.\n #renderWrappedSelection(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n line: number,\n lineText: string,\n startChar: number,\n endChar: number,\n isLastLine: boolean,\n type: 'selection' | 'match' | 'marker',\n extraDataset?: string\n ) {\n const wrapOffsets = this.#wrapLineText(line);\n const segmentCount = wrapOffsets.length - 1;\n const offsetLeft = this.#getGutterWidth() + this.#metrics.ch;\n\n for (let wrapLine = 0; wrapLine < segmentCount; wrapLine++) {\n const segmentStart = wrapOffsets[wrapLine];\n const segmentEnd = wrapOffsets[wrapLine + 1];\n const wrapStartChar = Math.max(startChar, segmentStart);\n const wrapEndChar = Math.min(endChar, segmentEnd);\n\n // Selection range doesn't reach this visual segment.\n if (wrapStartChar > wrapEndChar) {\n continue;\n }\n\n let segmentLeft: number;\n let segmentWidth: number;\n let paddingEnd = 0;\n if (wrapStartChar === 0) {\n segmentLeft = offsetLeft;\n } else {\n const prefixInSegment = lineText.slice(segmentStart, wrapStartChar);\n const prefixAsciiColumns = getExpandedAsciiTextColumns(\n prefixInSegment,\n this.#metrics.tabSize\n );\n segmentLeft =\n offsetLeft +\n (prefixAsciiColumns !== -1\n ? prefixAsciiColumns * this.#metrics.ch\n : this.#metrics.measureTextWidth(prefixInSegment));\n }\n if (\n !isLastLine &&\n wrapLine === segmentCount - 1 &&\n type === 'selection'\n ) {\n paddingEnd = this.#metrics.ch;\n }\n if (wrapStartChar === wrapEndChar) {\n segmentWidth = paddingEnd;\n } else {\n const selectionInSegment = lineText.slice(wrapStartChar, wrapEndChar);\n const selectionAsciiWidth = getExpandedAsciiTextColumns(\n selectionInSegment,\n this.#metrics.tabSize\n );\n segmentWidth =\n selectionAsciiWidth !== -1\n ? selectionAsciiWidth * this.#metrics.ch\n : this.#metrics.measureTextWidth(selectionInSegment);\n segmentWidth += paddingEnd;\n }\n\n this.#renderSelectionBlock(\n renderCtx,\n type,\n line,\n wrapLine,\n segmentLeft,\n segmentWidth,\n extraDataset\n );\n }\n }\n\n // Render one selection block for a single visual line.\n #renderSelectionBlock(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n previousSelectionRange?: {\n element: HTMLElement;\n line: number;\n wrapLine: number;\n left: number;\n width: number;\n };\n },\n type: 'selection' | 'match' | 'marker',\n line: number,\n wrapLine: number,\n left: number,\n width: number,\n extraDataset?: string\n ) {\n if (width === 0) {\n return;\n }\n\n const { ch, lineHeight } = this.#metrics;\n const y = this.#getLineY(line) + wrapLine * lineHeight;\n const css = `width:${width}px;transform:translateX(${left}px) translateY(${y}px);`;\n const cacheKey = `${type}-${left}-${y}-${width}${extraDataset ?? ''}`;\n const overlayEls = this.#overlayElements;\n\n const rounded =\n (this.#options.roundedSelection ?? true) && type === 'selection';\n const addRoundedCorner = (\n line: number,\n wrapLine: number,\n left: number,\n radius: 'rtl' | 'rbl' | 'rbr'\n ) => {\n const top = this.#getLineY(line) + wrapLine * lineHeight;\n const css = `width:${ch}px;transform:translateX(${left}px) translateY(${top}px);`;\n const dataset = {\n selectionCorner: '',\n [radius]: '',\n };\n const cacheKeyPrefix = `${type}-block-${left}-${top}-1ch`;\n let cacheKey = cacheKeyPrefix + '-' + radius;\n if (radius === 'rbl') {\n const prevCornerKey = cacheKeyPrefix + '-rtl';\n const prevCorner = renderCtx.elements.get(prevCornerKey);\n if (prevCorner !== undefined) {\n prevCorner.remove();\n renderCtx.elements.delete(prevCornerKey);\n cacheKey += '-rtl';\n dataset.rtl = '';\n }\n }\n let cornerEl = renderCtx.elements.get(cacheKey);\n if (cornerEl !== undefined) {\n return;\n }\n if (overlayEls?.has(cacheKey) === true) {\n cornerEl = overlayEls.get(cacheKey)!;\n overlayEls.delete(cacheKey);\n } else {\n cornerEl = h(\n 'div',\n {\n dataset: 'selectionRange',\n style: { cssText: css },\n children: [\n h('div', {\n dataset: dataset,\n }),\n ],\n },\n renderCtx.fragment\n );\n }\n renderCtx.elements.set(cacheKey, cornerEl);\n };\n const addRadiusStyle = (element: HTMLElement) => {\n const end = left + width;\n const dataset = element.dataset;\n const previousSelectionRange = renderCtx.previousSelectionRange;\n if (\n previousSelectionRange === undefined ||\n previousSelectionRange.line !== line ||\n previousSelectionRange.wrapLine !== wrapLine\n ) {\n renderCtx.previousSelectionRange = {\n element,\n line,\n wrapLine,\n left,\n width,\n };\n }\n if (\n previousSelectionRange === undefined ||\n end <= previousSelectionRange.left\n ) {\n ['rtl', 'rtr', 'rbl', 'rbr'].forEach((key) => {\n dataset[key] = '';\n });\n } else {\n const prevLine = previousSelectionRange.line;\n const prevWrapLine = previousSelectionRange.wrapLine;\n const prevLeft = previousSelectionRange.left;\n const prevDataset = previousSelectionRange.element.dataset;\n const prevEnd = prevLeft + previousSelectionRange.width;\n if (prevLeft > left) {\n addRoundedCorner(prevLine, prevWrapLine, prevLeft - ch, 'rbr');\n }\n delete prevDataset.rbl;\n delete dataset.rtl;\n delete dataset.rtr;\n if (end >= prevEnd) {\n delete prevDataset.rbr;\n }\n if (end > prevEnd) {\n addRoundedCorner(prevLine, prevWrapLine, prevEnd, 'rbl');\n dataset.rtr = '';\n }\n if (end < prevEnd) {\n addRoundedCorner(line, wrapLine, end, 'rtl');\n }\n if (left < prevLeft) {\n dataset.rtl = '';\n }\n dataset.rbl = '';\n dataset.rbr = '';\n }\n };\n\n let rangeEl = renderCtx.elements.get(cacheKey);\n if (rangeEl !== undefined) {\n if (rounded) {\n addRadiusStyle(rangeEl);\n }\n return;\n }\n\n if (overlayEls?.has(cacheKey) === true) {\n rangeEl = overlayEls.get(cacheKey)!;\n overlayEls.delete(cacheKey);\n } else {\n rangeEl = h(\n 'div',\n {\n dataset: extraDataset\n ? [type + 'Range', extraDataset]\n : type + 'Range',\n style: { cssText: css },\n },\n renderCtx.fragment\n );\n }\n\n if (rounded) {\n addRadiusStyle(rangeEl);\n }\n renderCtx.elements.set(cacheKey, rangeEl);\n }\n\n #renderCaret(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n selection: EditorSelection,\n isPrimary: boolean\n ) {\n const { line, character } = getCaretPosition(selection);\n if (!this.#isLineVisible(line)) {\n return;\n }\n const [left, wrapLine] = this.#getCharX(line, character);\n const cacheKey = 'caret-' + line + '/' + wrapLine + ':' + character;\n if (renderCtx.elements.has(cacheKey)) {\n return;\n }\n const x = left - 1;\n const y = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight;\n const caretEl = h(\n 'div',\n {\n dataset: 'caret',\n style: {\n transform: `translateX(${x}px) translateY(${y}px)`,\n },\n },\n renderCtx.fragment\n );\n renderCtx.elements.set(cacheKey, caretEl);\n if (isPrimary) {\n caretEl.style.scrollMargin = this.#getScrollMargin();\n this.#primaryCaretElement = caretEl;\n }\n }\n\n #renderSelectionActionIcon(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n selection: EditorSelection\n ) {\n const line = getCaretPosition(selection).line;\n if (!this.#isLineVisible(line)) {\n return;\n }\n\n const [left, wrapLine] = this.#getCharX(line, 0);\n const cacheKey = 'selectionActionIcon-' + line + '(' + wrapLine + ')';\n if (renderCtx.elements.has(cacheKey)) {\n return;\n }\n\n const selectionActionIcon = SelectionActionWidget.renderIcon(\n left,\n this.#getLineY(line) + wrapLine * this.#metrics.lineHeight,\n renderCtx.fragment,\n () => {\n const cleanUp = () => {\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n };\n\n const handleWidgetDomResize = () => {\n // the line y cache is invalidated by the DOM change,\n // clear the line y cache and re-render the selection\n this.#lineYCache.clear();\n if (this.#selections !== undefined) {\n this.#updateSelections(this.#selections);\n }\n };\n\n // remove the existing selection action element\n cleanUp();\n\n const textDocument = this.#textDocument;\n const renderSelectionAction = this.#options.renderSelectionAction;\n const fileContainer = this.#fileContainer;\n if (\n textDocument === undefined ||\n renderSelectionAction === undefined ||\n fileContainer == null\n ) {\n return;\n }\n\n const line = selection.end.line;\n const lineText = textDocument.getLineText(line);\n const selectionActionElement = renderSelectionAction({\n textDocument,\n selection,\n applyEdits: (edits: TextEdit[]) => this.applyEdits(edits, true),\n getSelectionText: () => {\n return this.#textDocument?.getText(selection) ?? '';\n },\n replaceSelectionText: (text: string) => {\n this.#replaceSelectionText(text, [selection]);\n },\n close: () => {\n cleanUp();\n handleWidgetDomResize();\n this.#scrollToPrimaryCaret();\n },\n });\n let leadingWhitespaces = 0;\n for (let i = 0; i < lineText.length; i++) {\n const charCode = lineText.charCodeAt(i);\n if (charCode === /* space */ 32) {\n leadingWhitespaces++;\n } else if (charCode === /* tab */ 9) {\n leadingWhitespaces += this.#metrics.tabSize;\n } else {\n break;\n }\n }\n this.#selectionAction = new SelectionActionWidget(\n line,\n selectionActionElement,\n fileContainer,\n leadingWhitespaces,\n handleWidgetDomResize\n );\n this.#updateSelections([selection]);\n if (this.#isLineVisible(line) && this.#contentElement !== undefined) {\n this.#selectionAction.render(this.#contentElement);\n }\n }\n );\n renderCtx.elements.set(cacheKey, selectionActionIcon);\n }\n\n // Opens the search panel in the requested mode. If a panel is already open,\n // it switches that panel's mode in place (preserving the current query)\n // rather than recreating it.\n #openSearchPanel(mode: SearchPanelMode) {\n if (this.#searchPanel !== undefined) {\n this.#searchPanel.setMode(mode);\n return;\n }\n this.#renderSearchPanel(mode);\n }\n\n // TODO(@ije): render search highlight\n #renderSearchPanel(mode: SearchPanelMode) {\n // cleanup the existing search panel\n this.#searchPanel?.cleanup();\n\n const textDocument = this.#textDocument;\n const preElement =\n this.#fileContainer?.shadowRoot?.querySelector<HTMLElement>('pre');\n const selections = this.#selections;\n if (textDocument === undefined || preElement == null) {\n return;\n }\n\n let defaultQuery = '';\n let initialMatch: [number, number] | undefined = undefined;\n\n if (selections !== undefined && selections.length > 0) {\n let primarySelection = selections.at(-1)!;\n if (isCollapsedSelection(primarySelection)) {\n primarySelection = expandCollapsedSelectionToWord(\n textDocument,\n primarySelection\n );\n this.#updateSelections([...selections.slice(0, -1), primarySelection]);\n const selectionText = textDocument.getText(primarySelection);\n if (selectionText !== '' && !selectionText.includes('\\n')) {\n defaultQuery = selectionText;\n initialMatch = [\n textDocument.offsetAt(primarySelection.start),\n textDocument.offsetAt(primarySelection.end),\n ];\n }\n }\n }\n\n const scrollToMatch = (\n [startOffset, endOffset]: MatchRange,\n retainFocus: boolean\n ) => {\n const nextSelection = createSelectionFromAnchorAndFocusOffsets(\n textDocument,\n startOffset,\n endOffset\n );\n this.#updateSelections([nextSelection]);\n this.#scrollToPrimaryCaret(true); // scroll to the primary caret and don't focus\n this.#retainSearchPanelFocus = retainFocus;\n };\n\n const searchPanel = new SearchPanelWidget({\n textDocument,\n containerElement: preElement,\n defaultQuery,\n mode,\n initialMatch,\n scrollToMatch,\n applyReplace: (edits: ResolvedTextEdit[]) => {\n if (edits.length === 0) {\n return;\n }\n const change = textDocument.applyEdits(\n edits.map((edit) => ({\n range: {\n start: textDocument.positionAt(edit.start),\n end: textDocument.positionAt(edit.end),\n },\n newText: edit.text,\n })),\n true,\n this.#selections\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n undefined,\n this.#applyChangeToLineAnnotations(change),\n { skipSearchRefresh: true }\n );\n }\n },\n onUpdate: (\n allMatches: MatchRange[],\n options?: { syncSelection?: boolean }\n ): MatchRange | undefined => {\n if (allMatches.length === 0) {\n this.#matches = undefined;\n this.#updateSelections(this.#selections ?? []);\n return;\n }\n\n this.#matches = allMatches;\n if (options?.syncSelection === false) {\n this.#updateSelections(this.#selections ?? []);\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const startOffset = textDocument.offsetAt(primarySelection.start);\n const endOffset = textDocument.offsetAt(primarySelection.end);\n for (const match of allMatches) {\n if (match[0] === startOffset && match[1] === endOffset) {\n return match;\n }\n }\n }\n return undefined;\n }\n\n const primarySelection = this.#selections?.at(-1);\n let searchOffset = 0;\n let nextMatch: MatchRange | undefined;\n if (primarySelection !== undefined) {\n searchOffset = textDocument.offsetAt(primarySelection.start);\n }\n for (const m of allMatches) {\n if (m[0] >= searchOffset) {\n nextMatch = m;\n break;\n }\n }\n if (nextMatch !== undefined) {\n scrollToMatch(nextMatch, true);\n } else {\n this.#updateSelections(this.#selections ?? []);\n }\n return nextMatch;\n },\n onClose: () => {\n this.#searchPanel = undefined;\n this.#retainSearchPanelFocus = false;\n this.#matches = undefined;\n this.#updateSelections(this.#selections ?? []);\n },\n });\n\n this.#searchPanel = searchPanel;\n this.#retainSearchPanelFocus = false;\n }\n\n #getSelectionText() {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return '';\n }\n return getSelectionText(textDocument, selections);\n }\n\n // replace the selection text\n #replaceSelectionText(\n text: string | string[],\n selections = this.#selections\n ) {\n if (selections === undefined) {\n return;\n }\n const textDocument = this.#textDocument;\n const primarySelection = selections.at(-1);\n if (textDocument === undefined || primarySelection === undefined) {\n return;\n }\n const { nextSelections, change } =\n Array.isArray(text) && text.length === selections.length\n ? applyTextReplaceToSelections<LAnnotation>(\n textDocument,\n selections,\n text,\n this.#lineAnnotations\n )\n : applyTextChangeToSelections<LAnnotation>(\n textDocument,\n selections,\n {\n start: textDocument.offsetAt(primarySelection.start),\n end: textDocument.offsetAt(primarySelection.end),\n text: Array.isArray(text) ? text.join('\\n') : text,\n },\n this.#lineAnnotations\n );\n\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteSelectionText(forward: boolean = false) {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n\n const primarySelection = selections.at(-1);\n if (primarySelection === undefined) {\n return;\n }\n\n let edit: ResolvedTextEdit;\n if (isCollapsedSelection(primarySelection)) {\n const offset = textDocument.offsetAt(primarySelection.start);\n const nextOffset = forward\n ? Math.min(textDocument.getText().length, offset + 1)\n : Math.max(0, offset - 1);\n edit = {\n start: Math.min(offset, nextOffset),\n end: Math.max(offset, nextOffset),\n text: '',\n };\n } else {\n edit = {\n start: textDocument.offsetAt(primarySelection.start),\n end: textDocument.offsetAt(primarySelection.end),\n text: '',\n };\n }\n\n this.#applyResolvedTextEdit(edit);\n }\n\n #deleteSoftLineBackward() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const getSoftLineStart = this.#wrap\n ? (line: number, character: number) => {\n const wrapOffsets = this.#wrapLineText(line);\n for (let w = 0; w + 1 < wrapOffsets.length; w++) {\n const segmentStart = wrapOffsets[w];\n const segmentEnd = wrapOffsets[w + 1];\n if (character >= segmentStart && character <= segmentEnd) {\n return segmentStart;\n }\n }\n return 0;\n }\n : undefined;\n const { nextSelections, change } =\n applyDeleteSoftLineBackwardToSelections<LAnnotation>(\n textDocument,\n selections,\n getSoftLineStart,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteWordBackward() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } =\n applyDeleteWordBackwardToSelections<LAnnotation>(\n textDocument,\n selections,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteHardLineForward() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } =\n applyDeleteHardLineForwardToSelections<LAnnotation>(\n textDocument,\n selections,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #insertTranspose() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } = applyTransposeToSelections<LAnnotation>(\n textDocument,\n selections,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #applyResolvedTextEdit(edit: ResolvedTextEdit) {\n if (this.#selections === undefined || this.#textDocument === undefined) {\n return;\n }\n const { nextSelections, change } = applyTextChangeToSelections<LAnnotation>(\n this.#textDocument,\n this.#selections,\n edit,\n this.#lineAnnotations,\n this.#metrics.tabSize\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #getFileRef(): FileContents | undefined {\n const fileContents = this.#fileContents;\n const textDocument = this.#textDocument;\n if (fileContents === undefined || textDocument === undefined) {\n return undefined;\n }\n const { contents: _, ...file } = fileContents;\n Object.defineProperty(file, 'contents', {\n enumerable: true,\n get: () => textDocument.getText(),\n });\n return file as FileContents;\n }\n\n #applyChange(\n change: TextDocumentChange,\n selections?: EditorSelection[],\n newLineAnnotations?: DiffLineAnnotation<LAnnotation>[],\n options?: { skipSearchRefresh?: boolean }\n ) {\n const fileRef = this.#getFileRef();\n const onChange = this.#options.onChange;\n if (fileRef !== undefined && onChange !== undefined) {\n onChange(fileRef, newLineAnnotations ?? this.#lineAnnotations);\n }\n\n // Invalidate layout caches touched by the edit.\n // - line inserts/deletes shift line numbers, so clear from startLine onward\n // - wrapped edits can change visual height, which shifts downstream line Y\n if (change.lineDelta !== 0) {\n for (const line of this.#lineYCache.keys()) {\n if (line >= change.startLine) {\n this.#lineYCache.delete(line);\n }\n }\n }\n if (this.#wrap) {\n for (const line of this.#wrapLineOffsetsCache.keys()) {\n if (line >= change.startLine) {\n this.#wrapLineOffsetsCache.delete(line);\n }\n }\n }\n this.#lastAccessedCharX = undefined;\n\n let renderRange = this.#renderRange;\n let shouldUpdateBuffer: boolean | undefined;\n if (\n renderRange !== undefined &&\n selections !== undefined &&\n selections.length > 0\n ) {\n const primarySelection = selections.at(-1)!;\n const renderRangeEndLine =\n renderRange.startingLine + renderRange.totalLines;\n // when typing new line at the end of the file,\n // extend the render range +1 to trigger the re-render of the new line\n if (primarySelection.end.line === renderRangeEndLine) {\n renderRange = {\n ...renderRange,\n totalLines: renderRange.totalLines + 1,\n };\n } else if (primarySelection.end.line > renderRangeEndLine) {\n shouldUpdateBuffer = true;\n }\n }\n this.#rerender(change, newLineAnnotations, renderRange, shouldUpdateBuffer);\n\n if (\n options?.skipSearchRefresh !== true &&\n this.#searchPanel !== undefined &&\n this.#matches !== undefined\n ) {\n this.#searchPanel.updateMatches({ syncSelection: false });\n }\n\n if (selections !== undefined) {\n // re-render selection range and caret, focus to the editor to update the window selection,\n // and scroll to the crate to mock the 'contenteditable' behavior\n this.#updateSelections(selections);\n if (this.#primaryCaretElement !== undefined) {\n this.#primaryCaretElement.scrollIntoView({\n block: 'nearest',\n inline: 'nearest',\n });\n } else if (selections.length > 0) {\n const pos = getCaretPosition(selections.at(-1)!);\n this.#scrollToLine(pos.line, pos.character);\n }\n this.focus({ preventScroll: true });\n }\n }\n\n #applyChangeToLineAnnotations(\n change: TextDocumentChange\n ): DiffLineAnnotation<LAnnotation>[] | undefined {\n if (this.#lineAnnotations !== undefined) {\n const nextLineAnnotations =\n applyDocumentChangeToLineAnnotations<LAnnotation>(\n change,\n this.#lineAnnotations\n );\n if (nextLineAnnotations !== undefined) {\n this.#textDocument?.setLastUndoLineAnnotations(\n this.#lineAnnotations,\n nextLineAnnotations\n );\n return nextLineAnnotations;\n }\n }\n return undefined;\n }\n\n #getLineElement(line: number): HTMLElement | undefined {\n const lastAccessed = this.#lastAccessedLineElement;\n if (lastAccessed !== undefined && lastAccessed[0] === line) {\n return lastAccessed[1];\n }\n\n const contentElement = this.#contentElement;\n if (contentElement === undefined) {\n return undefined;\n }\n\n let lineElement: HTMLElement | null = null;\n\n // check if the line is within the render range (fast)\n if (this.#renderRange !== undefined) {\n const { startingLine } = this.#renderRange;\n const { children } = contentElement;\n for (let i = line - startingLine; i <= children.length; i++) {\n const child = children[i] as HTMLElement | undefined;\n if (child === undefined) {\n break;\n }\n const lineNumber = getLineNumberAttr(child);\n const lineType = child.dataset.lineType;\n if (\n lineNumber !== undefined &&\n lineNumber === line + 1 &&\n lineType !== undefined &&\n isLineEditable(lineType)\n ) {\n lineElement = child;\n break;\n }\n }\n }\n\n // fallback to query selector\n lineElement ??= contentElement.querySelector<HTMLElement>(\n `[data-line=\"${line + 1}\"]`\n );\n\n if (lineElement !== null) {\n if (lastAccessed !== undefined) {\n lastAccessed[0] = line;\n lastAccessed[1] = lineElement;\n } else {\n this.#lastAccessedLineElement = [line, lineElement];\n }\n return lineElement;\n }\n return undefined;\n }\n\n #getGutterWidth(): number {\n if (this.#gutterElement === undefined) {\n return 0;\n }\n\n if (this.#gutterWidthCache === undefined) {\n const diffsColumnNumberWidth =\n this.#contentElement?.parentElement?.style.getPropertyValue(\n '--diffs-column-number-width'\n );\n if (\n diffsColumnNumberWidth !== undefined &&\n diffsColumnNumberWidth.length > 2 &&\n diffsColumnNumberWidth.endsWith('px')\n ) {\n this.#gutterWidthCache = parseInt(\n diffsColumnNumberWidth.slice(0, -2),\n 10\n );\n } else {\n this.#gutterWidthCache = this.#gutterElement.offsetWidth;\n }\n }\n\n return this.#gutterWidthCache;\n }\n\n #getContentWidth(): number {\n if (this.#contentElement === undefined) {\n return 0;\n }\n\n if (this.#contentWidthCache === undefined) {\n const diffsColumnContentWidth =\n this.#contentElement.parentElement?.style.getPropertyValue(\n '--diffs-column-content-width'\n );\n if (\n diffsColumnContentWidth !== undefined &&\n diffsColumnContentWidth.length > 2 &&\n diffsColumnContentWidth.endsWith('px')\n ) {\n this.#contentWidthCache = parseFloat(\n diffsColumnContentWidth.slice(0, -2)\n );\n } else {\n this.#contentWidthCache = this.#contentElement.offsetWidth;\n }\n }\n return this.#contentWidthCache;\n }\n\n // get line top(y-coordinate) position\n #getLineY(line: number) {\n const cachedY = this.#lineYCache.get(line);\n if (cachedY !== undefined) {\n return cachedY;\n }\n\n const lineElement = this.#getLineElement(line);\n if (lineElement === undefined) {\n return -1;\n }\n\n // cold(slow) path: measure line top position from DOM (will cause reflow)\n const y = lineElement.offsetTop + this.#metrics.paddingTop;\n this.#lineYCache.set(line, y);\n return y;\n }\n\n // Return the visual position for a character. Wrapped lines include the\n // visual line index so carets can be placed on the correct row.\n #getCharX(line: number, char: number): [x: number, wrapLine: number] {\n if (\n this.#lastAccessedCharX !== undefined &&\n this.#lastAccessedCharX[0] === line &&\n this.#lastAccessedCharX[1] === char\n ) {\n return [this.#lastAccessedCharX[2], this.#lastAccessedCharX[3]];\n }\n\n const lineText = this.#textDocument?.getLineText(line);\n const offsetLeft = this.#getGutterWidth() + this.#metrics.ch; // gutter width + inline padding (1ch)\n if (lineText === undefined || lineText.length === 0 || char <= 0) {\n return [offsetLeft, 0];\n }\n\n const boundedCharacter = snapTextOffsetToUnicodeBoundary(\n lineText,\n Math.min(char, lineText.length)\n );\n const textBeforeCharacter = lineText.slice(0, boundedCharacter);\n const asciiColumns = getExpandedAsciiTextColumns(\n textBeforeCharacter,\n this.#metrics.tabSize\n );\n\n let left = 0;\n let wrapLine = 0;\n if (asciiColumns !== -1) {\n left = offsetLeft + asciiColumns * this.#metrics.ch;\n } else {\n left = offsetLeft + this.#metrics.measureTextWidth(textBeforeCharacter);\n }\n\n if (this.#wrap) {\n const contentWidth = this.#getContentWidth();\n const textWidth =\n 2 * this.#metrics.ch + this.#metrics.measureTextWidth(lineText);\n if (textWidth > contentWidth) {\n const wrapOffsets = this.#wrapLineText(line);\n for (let w = 0; w + 1 < wrapOffsets.length; w++) {\n const segmentStart = wrapOffsets[w];\n const segmentEnd = wrapOffsets[w + 1];\n if (boundedCharacter <= segmentEnd) {\n wrapLine = w;\n const prefixInSegment = lineText.slice(\n segmentStart,\n boundedCharacter\n );\n const segmentAsciiColumns = getExpandedAsciiTextColumns(\n prefixInSegment,\n this.#metrics.tabSize\n );\n if (segmentAsciiColumns !== -1) {\n left = offsetLeft + segmentAsciiColumns * this.#metrics.ch;\n } else {\n left =\n offsetLeft + this.#metrics.measureTextWidth(prefixInSegment);\n }\n break;\n }\n }\n }\n }\n\n if (this.#lastAccessedCharX !== undefined) {\n this.#lastAccessedCharX[0] = line;\n this.#lastAccessedCharX[1] = char;\n this.#lastAccessedCharX[2] = left;\n this.#lastAccessedCharX[3] = wrapLine;\n } else {\n this.#lastAccessedCharX = [line, char, left, wrapLine];\n }\n\n return [left, wrapLine];\n }\n\n // Compute how a logical line of text is broken into visual lines when line\n // wrapping is enabled.\n #wrapLineText(line: number): Uint32Array {\n const cachedOffsets = this.#wrapLineOffsetsCache.get(line);\n if (cachedOffsets !== undefined) {\n return cachedOffsets;\n }\n\n const lineText = this.#textDocument?.getLineText(line);\n if (lineText === undefined || lineText.length === 0) {\n const offsets = new Uint32Array([0]);\n this.#wrapLineOffsetsCache.set(line, offsets);\n return offsets;\n }\n\n const div = h(\n 'div',\n {\n style: {\n position: 'absolute',\n top: '0',\n left: '0',\n width: '100%',\n boxSizing: 'border-box',\n visibility: 'hidden',\n pointerEvents: 'none',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n font: 'inherit',\n paddingInline: '1ch',\n tabSize: this.#metrics.tabSize.toString(),\n },\n textContent: lineText,\n },\n this.#contentElement\n );\n const textNode = div.firstChild as Text;\n const range = document.createRange();\n const starts: number[] = [];\n\n try {\n const unicodeOffsets = getUnicodeMeasurementOffsets(lineText);\n const wrapLineStartLeft =\n div.getBoundingClientRect().left + this.#metrics.ch;\n\n let previousOffset = 0;\n let lastTop = Number.NEGATIVE_INFINITY;\n\n for (let i = 0, offsetIndex = 0; i < lineText.length; ) {\n const nextOffset =\n unicodeOffsets === undefined\n ? i + 1\n : unicodeOffsets[offsetIndex + 1];\n range.setStart(textNode, i);\n range.setEnd(textNode, nextOffset);\n\n // A new visual line starts whenever the character's top edge moves\n // below the previous character's top edge.\n const { left, top } = range.getBoundingClientRect();\n if (top > lastTop) {\n // Safari can report the first range on a wrapped visual line as\n // starting one character past the visual line start. Use the previous\n // offset so segment-local caret math begins at the actual wrap point.\n const startsPastLineStart =\n isSafari() &&\n starts.length > 0 &&\n left - wrapLineStartLeft > this.#metrics.ch / 2;\n starts.push(startsPastLineStart ? previousOffset : i);\n lastTop = top;\n }\n previousOffset = i;\n i = nextOffset;\n offsetIndex++;\n }\n\n const offsets = new Uint32Array(starts.length + 1);\n for (let i = 0; i < starts.length; i++) {\n offsets[i] = starts[i]!;\n }\n offsets[starts.length] = lineText.length;\n this.#wrapLineOffsetsCache.set(line, offsets);\n return offsets;\n } finally {\n div.remove();\n }\n }\n\n // check if the web selection belongs to editor\n #rangeBelongsToEditor({ startContainer, endContainer }: StaticRange) {\n const contentEl = this.#contentElement;\n if (contentEl === undefined) {\n return false;\n }\n return (\n contentEl.contains(startContainer) && contentEl.contains(endContainer)\n );\n }\n\n // Check whether a line is visible in the currently rendered line window.\n #isLineVisible(line: number): boolean {\n const lineCount = this.#textDocument?.lineCount ?? 0;\n if (line < 0 || line >= lineCount) {\n return false;\n }\n if (this.#renderRange === undefined) {\n return true;\n }\n const { startingLine, totalLines } = this.#renderRange;\n if (line < startingLine) {\n return false;\n }\n if (totalLines === Infinity) {\n return true;\n }\n return line < startingLine + totalLines;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"editor.js","names":["#fileInstance","#renderRange","#textDocument","#getLineElement","#options","#initialize","#detach","#contentHasFocus","#selections","#applyChange","#applyChangeToLineAnnotations","#runCommand","#getFileRef","#lineAnnotations","#resetCache","#resetState","#initSelections","#updateSelections","#scrollToPrimaryCaret","#markerRenderer","#metrics","#overlayElement","#getGutterWidth","#getCharX","#getLineY","#isContentMouseDown","#isGutterMouseDown","#contentElement","#focus","#tokenizer","#globalEventDisposes","#editorEventDisposes","#selectEventDisposes","#gutterWidthCache","#contentWidthCache","#lineYCache","#wrapLineOffsetsCache","#lastAccessedLineElement","#lastAccessedCharX","#globalStyleElement","#editorStyleElement","#themeStyleElement","#spriteElement","#fileContainer","#gutterElement","#resizeObserver","#fontRemeasureScheduled","#fileInfo","#onDeferTokenize","#remeasureMetricsOnFontLoad","#listenContentElement","#isDiff","#diffSyle","#viewportWindowLines","#shouldRenderDivergeFromDocument","#matches","#primaryCaretElement","#scrollingToLine","#scrollToLine","#scrollingToLineChar","#scrollingToLineNoFocus","#retainSearchPanelFocus","#searchPanel","#isWrap","#setSelectedLinesSafe","#shouldIgnoreSelectionChange","#overlayElements","#reservedSelections","#selectionAction","editorCSS","#rangeBelongsToEditor","#shiftKeyPressed","#selectionStart","#setWindowSelection","#isDeletedLineTarget","#setDeletedTextSelectionActive","#replaceSelectEventListeners","#handleCustomPasteEvent","#isDeletedTextSelectionActive","#deletedTextForClipboard","#getSelectionText","#cutSelectionText","#replaceSelectionText","#handleInput","#isComposing","#beginDeletionGutterSelection","#spanLineSelection","#handleLayoutResize","#computeContentOffset","#contentOffset","#activeContentOffset","#openSearchPanel","#getContentWidth","#deleteSelectionText","#deleteSoftLineBackward","#deleteHardLineForward","#deleteWordBackward","#insertTranspose","#getScrollMargin","#deletedSelectionText","#contentRowForGutterRow","#selectDeletedLines","#renderSelection","#renderCaret","#updateSelectionActionPopover","#isLineVisible","#renderWrappedSelection","#renderSelectionBlock","#wrapLineText","#segmentTextWidth","#renderSearchPanel","#applySelectionCutEdits","#rerender"],"sources":["../../src/editor/editor.ts"],"sourcesContent":["import { queueRender } from '../managers/UniversalRenderingManager';\nimport type {\n DiffLineAnnotation,\n DiffsEditableComponent,\n DiffsEditor,\n DiffsEditorSelection,\n DiffsHighlighter,\n FileContents,\n FileDiffMetadata,\n HighlightedToken,\n RenderRange,\n} from '../types';\nimport { getFiletypeFromFileName } from '../utils/getFiletypeFromFileName';\nimport {\n type EditorCommand,\n resolveEditorCommandFromKeyboardEvent,\n resolveFindAgainShortcut,\n} from './command';\nimport editorCSS from './editor.css?inline';\nimport { EditStack } from './editStack';\nimport {\n applyDocumentChangeToLineAnnotations,\n renderLineAnnotations,\n} from './lineAnnotations';\nimport {\n type Marker,\n MarkerRenderer,\n markerSeverityDatasetKey,\n} from './marker';\nimport { isMoveCursorShortcut, isPrimaryModifier, isSafari } from './platform';\nimport {\n type MatchRange,\n type SearchPanelMode,\n SearchPanelWidget,\n} from './searchPanel';\nimport type { AutoSurround, EditorSelection } from './selection';\nimport {\n applyDeleteCharacterToSelections,\n applyDeleteHardLineForwardToSelections,\n applyDeleteSoftLineBackwardToSelections,\n applyDeleteWordBackwardToSelections,\n applyTextChangeToSelections,\n applyTextReplaceToSelections,\n applyTransposeToSelections,\n comparePosition,\n convertSelection,\n createSelectionFrom,\n createSelectionFromAnchorAndFocusOffsets,\n DirectionBackward,\n DirectionForward,\n DirectionNone,\n expandCollapsedSelectionToWord,\n extendSelection,\n extendSelections,\n findNexMatch,\n getAutoSurroundReplacementTexts,\n getCaretPosition,\n getDocumentBoundarySelection,\n getDocumentFullSelection,\n getSelectionAnchor,\n getSelectionText,\n isCollapsedSelection,\n isLineEditable,\n mapCursorMove,\n mapSelectionShift,\n mergeOverlappingSelections,\n remapSelectionsAfterEdits,\n resolveIndentEdits,\n resolveSelectionCut,\n selectionIntersects,\n} from './selection';\nimport {\n type SelectionActionContext,\n SelectionActionWidget,\n} from './selectionAction';\nimport { createSpriteElement } from './sprite';\nimport {\n type Position,\n type Range,\n type ResolvedTextEdit,\n TextDocument,\n type TextDocumentChange,\n type TextEdit,\n} from './textDocument';\nimport {\n getExpandedAsciiTextColumns,\n getUnicodeMeasurementOffsets,\n Metrics,\n snapTextOffsetToUnicodeBoundary,\n} from './textMeasure';\nimport { EditorTokenizer, renderLineTokens } from './tokenzier';\nimport {\n addEventListener,\n clampDomOffset,\n extend,\n getLineNumberAttr,\n h,\n round,\n} from './utils';\n\nexport interface EditorOptions<LAnnotation> {\n /** The maximum number of entries to keep in the undo stack. */\n historyMaxEntries?: number;\n /** Render rounded corners for selection ranges, default is true. */\n roundedSelection?: boolean;\n /**\n * Controls auto-surround when typing quotes or brackets over a selection.\n * Default is `\"default\"` (both quotes and brackets).\n */\n autoSurround?: AutoSurround;\n /**\n * Show a floating selection action popover anchored to the active selection,\n * default is disabled.\n */\n enabledSelectionAction?: boolean;\n /**\n * Custom clipboard provider.\n * Highly recommended to use native clipboard API if you are building an electron app.\n * see https://www.electronjs.org/docs/latest/api/clipboard\n */\n clipboard?: {\n readText: () => Promise<string> | string;\n };\n /** Render the selection action widget element. */\n renderSelectionAction?: (\n context: SelectionActionContext<LAnnotation>\n ) => HTMLElement;\n /** Callback when the editor is attached to a file. */\n onAttach?: (\n editor: Editor<LAnnotation>,\n fileInstance: DiffsEditableComponent<LAnnotation>\n ) => void;\n /** Callback when the editor document changes. */\n onChange?: (\n file: FileContents,\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[]\n ) => void;\n __debug?: boolean;\n}\n\nexport interface EditorState<LAnnotation> {\n file: FileContents;\n lineAnnotations?: DiffLineAnnotation<LAnnotation>[];\n selections?: EditorSelection[];\n renderRange?: RenderRange;\n}\n\n// Cap on how far an edit may widen the virtualized render window, as a multiple\n// of the bounded window the virtualizer last synced (~viewport + 2*hunkLineCount).\n// Edits within this many lines of the window bottom widen so their caret renders;\n// larger inserts fall back to the bounded buffer-only path instead of building a\n// row per inserted line. A safety bound, not a correctness-critical value.\nconst MAX_EDIT_WIDEN_WINDOW_MULTIPLE = 2;\n\nexport class Editor<LAnnotation> implements DiffsEditor<LAnnotation> {\n #options: EditorOptions<LAnnotation>;\n #metrics = new Metrics();\n #tokenizer?: EditorTokenizer;\n\n // event disposes\n #editorEventDisposes?: (() => void)[];\n #globalEventDisposes?: (() => void)[];\n #selectEventDisposes?: (() => void)[];\n #detach?: () => void;\n\n // cache\n #contentOffset?: { left: number; top: number };\n #gutterWidthCache?: number;\n #contentWidthCache?: number;\n #lineYCache = new Map<number, number>();\n #wrapLineOffsetsCache = new Map<number, Uint32Array>();\n #lastAccessedLineElement?: [number, HTMLElement];\n #lastAccessedCharX?: [\n line: number,\n character: number,\n x: number,\n wrapLine: number,\n ];\n\n // dom\n #globalStyleElement?: HTMLStyleElement;\n #editorStyleElement?: HTMLStyleElement;\n #themeStyleElement?: HTMLStyleElement;\n #spriteElement?: SVGSVGElement;\n #fileContainer?: HTMLElement;\n #gutterElement?: HTMLElement;\n #contentElement?: HTMLElement;\n #overlayElement?: HTMLElement;\n #overlayElements?: Map<string, HTMLElement>;\n #primaryCaretElement?: HTMLElement;\n #resizeObserver?: ResizeObserver;\n\n // state\n #fileInstance?: DiffsEditableComponent<LAnnotation>;\n #fileInfo?: Omit<FileContents, 'contents'>;\n #lineAnnotations?: DiffLineAnnotation<LAnnotation>[];\n #textDocument?: TextDocument<LAnnotation>;\n #renderRange?: RenderRange;\n // Bounded render-window size (~viewport + 2*hunkLineCount) from the last view\n // sync. Used to cap how far #applyChange widens the window for an edit, so a\n // large insert can't materialize an unbounded number of rows. Captured at sync\n // time so consecutive edits that grow #renderRange can't ratchet the cap up.\n // undefined until the first sync; Infinity for non-virtualized (whole-file)\n // windows, where no cap is needed.\n #viewportWindowLines?: number;\n #markerRenderer?: MarkerRenderer;\n #searchPanel?: SearchPanelWidget;\n #selectionAction?: SelectionActionWidget;\n #shouldIgnoreSelectionChange = false;\n // Whether the contenteditable holds (or is claiming) focus. Synced by\n // focus/blur listeners and set eagerly by #focus(), whose real focus() call is\n // deferred to a rAF. Lets applyEdits skip focus/scroll only on unfocused\n // editors, without regressing a same-tick setSelections-then-applyEdits flow.\n #contentHasFocus = false;\n #isComposing = false;\n #isGutterMouseDown = false;\n #isContentMouseDown = false;\n #shiftKeyPressed = false;\n #selectionStart: EditorSelection | undefined;\n // The full text of a read-only deleted-line selection built from the gutter,\n // captured when the selection is made. Deleted lines are separate read-only\n // hosts, so window.getSelection() only spans the first line; the copy/cut\n // handlers prefer this. Empty for a direct content drag (no gutter range).\n #deletedSelectionText = '';\n #reservedSelections?: EditorSelection[];\n #initSelections?: EditorSelection[];\n #selections?: EditorSelection[];\n #matches?: MatchRange[];\n #scrollingToLine?: number;\n #scrollingToLineChar?: number;\n #scrollingToLineNoFocus = false;\n #retainSearchPanelFocus = false;\n #fontRemeasureScheduled = false;\n\n #onDeferTokenize = (\n lines: Map<number, Array<HighlightedToken>>,\n themeType: 'light' | 'dark'\n ) => {\n this.#fileInstance?.updateRenderCache(lines, themeType);\n // update the view if the render range is updated by scrolling\n // and the deferred tokenized lines inside the render range\n if (\n this.#renderRange !== undefined &&\n this.#renderRange.totalLines !== Infinity\n ) {\n const { startingLine, totalLines } = this.#renderRange;\n const endLine = Math.min(\n startingLine + totalLines,\n this.#textDocument?.lineCount ?? 0\n );\n for (const [line, tokens] of lines) {\n if (line >= startingLine && line < endLine) {\n const lineElement = this.#getLineElement(line);\n if (lineElement !== undefined) {\n lineElement.replaceChildren(...renderLineTokens(tokens, themeType));\n }\n }\n }\n }\n };\n\n constructor(options: EditorOptions<LAnnotation> = {}) {\n this.#options = options;\n }\n\n edit(component: DiffsEditableComponent<LAnnotation>): () => void {\n const {\n useTokenTransformer,\n enableGutterUtility,\n enableLineSelection,\n expandUnchanged,\n lineHoverHighlight,\n ...rest\n } = component.options;\n const isDiff = component.type === 'file-diff';\n if (\n useTokenTransformer !== true ||\n enableGutterUtility === true ||\n enableLineSelection === true ||\n (expandUnchanged !== true && isDiff) ||\n lineHoverHighlight !== 'disabled'\n ) {\n component.setOptions({\n ...rest,\n useTokenTransformer: true,\n enableGutterUtility: false,\n enableLineSelection: false,\n expandUnchanged: true,\n lineHoverHighlight: 'disabled',\n });\n component.rerender();\n }\n this.#fileInstance = component;\n this.#initialize();\n this.#detach = component.attachEditor(this);\n return () => this.cleanUp();\n }\n\n /**\n * Apply edits to current attached file.\n */\n applyEdits(edits: TextEdit[], updateHistory = false): void {\n const textDocument = this.#textDocument;\n if (textDocument == null) {\n throw new Error('Editor is not attached');\n }\n // Only reposition focus and scroll when the editor already holds focus. A\n // programmatic edit must not pull focus from another input the user is\n // typing in; the selection state below is re-anchored either way.\n const wasFocused = this.#contentHasFocus;\n // Capture the current selection edges and the edit ranges as pre-edit\n // offsets so the caret can be re-anchored once the buffer changes. Reading\n // them after applyEdits would resolve against the new buffer and desync.\n const selectionsBefore = this.#selections;\n const selectionOffsetsBefore = selectionsBefore?.map(\n (selection) =>\n [\n textDocument.offsetAt(selection.start),\n textDocument.offsetAt(selection.end),\n ] as [number, number]\n );\n // Resolve edits to pre-edit offsets, mirroring TextDocument's own\n // resolution (swap reversed ranges, sort ascending), so the remap matches\n // the edits TextDocument actually applies below.\n const resolvedEditOffsets =\n selectionsBefore === undefined\n ? undefined\n : edits\n .map((edit) => {\n const a = textDocument.offsetAt(edit.range.start);\n const b = textDocument.offsetAt(edit.range.end);\n return {\n start: Math.min(a, b),\n end: Math.max(a, b),\n text: edit.newText,\n };\n })\n .sort((a, b) => a.start - b.start);\n\n const change = textDocument.applyEdits(\n edits,\n updateHistory,\n selectionsBefore\n );\n if (change === undefined) {\n return;\n }\n\n // Re-anchor selections against the applied edits so the editor #selections,\n // the native window selection, and the on-screen caret stay in sync with\n // the new buffer. Skipping this leaves a programmatic edit (e.g. an AI or\n // codemod insertion) with a stale caret and corrupts the next keystroke.\n let nextSelections: EditorSelection[] | undefined;\n if (\n selectionsBefore !== undefined &&\n selectionOffsetsBefore !== undefined &&\n resolvedEditOffsets !== undefined\n ) {\n nextSelections = remapSelectionsAfterEdits(\n textDocument,\n selectionsBefore,\n selectionOffsetsBefore,\n resolvedEditOffsets\n );\n if (updateHistory) {\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n }\n }\n\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change),\n { skipFocus: !wasFocused }\n );\n }\n\n /** Whether there is an edit to undo. */\n get canUndo(): boolean {\n return this.#textDocument?.canUndo ?? false;\n }\n\n /** Whether there is an undone edit to redo. */\n get canRedo(): boolean {\n return this.#textDocument?.canRedo ?? false;\n }\n\n /** Undo the last edit. Does nothing when there is nothing to undo. */\n undo(): void {\n this.#runCommand('undo');\n }\n\n /** Redo the last undone edit. Does nothing when there is nothing to redo. */\n redo(): void {\n this.#runCommand('redo');\n }\n\n getState(): EditorState<LAnnotation> {\n const fileRef = this.#getFileRef();\n if (fileRef === undefined) {\n throw new Error('Editor is not attached');\n }\n return {\n file: { ...fileRef, cacheKey: 'edited-at-' + Date.now() },\n selections: this.#selections,\n lineAnnotations: this.#lineAnnotations,\n renderRange: this.#renderRange,\n };\n }\n\n setState({\n file,\n lineAnnotations,\n renderRange,\n selections,\n }: EditorState<LAnnotation>): void {\n this.#resetCache();\n this.#resetState();\n this.#initSelections = selections;\n this.#fileInstance?.render({\n file: { ...file, cacheKey: 'edited-at-' + Date.now() },\n lineAnnotations,\n renderRange,\n });\n }\n\n setSelections(selections: DiffsEditorSelection[]): void {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n throw new Error('Text document is not initialized');\n }\n const resolvedSelections = selections.map<EditorSelection>((selection) => {\n const start = textDocument.normalizePosition(selection.start);\n const end = textDocument.normalizePosition(selection.end);\n const direction =\n selection.direction === 'none'\n ? DirectionNone\n : selection.direction === 'backward'\n ? DirectionBackward\n : DirectionForward;\n return { direction, start, end };\n });\n this.#updateSelections(resolvedSelections);\n this.#scrollToPrimaryCaret(false, 'center');\n }\n\n setMarkers(markers: Marker[]): void {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n throw new Error('Text document is not initialized');\n }\n\n if (markers.length === 0) {\n this.#markerRenderer?.cleanup();\n this.#markerRenderer = undefined;\n this.#updateSelections(this.#selections ?? []);\n return;\n }\n\n this.#markerRenderer ??= new MarkerRenderer({\n getLineHeight: () => this.#metrics.lineHeight,\n getOverlayElement: () => this.#overlayElement,\n getGutterWidth: () => this.#getGutterWidth(),\n getCharX: (line, character) => this.#getCharX(line, character),\n getLineY: (line) => this.#getLineY(line),\n isMouseDown: () => this.#isContentMouseDown || this.#isGutterMouseDown,\n });\n this.#markerRenderer.setMarkers(markers, textDocument);\n if (this.#contentElement !== undefined) {\n this.#markerRenderer.listenHover(this.#contentElement);\n }\n this.#updateSelections(this.#selections ?? []);\n }\n\n focus(options?: FocusOptions): void {\n const preventScroll = options?.preventScroll ?? false;\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const pos =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n this.#focus(pos, preventScroll);\n } else {\n this.#focus(undefined, preventScroll);\n }\n }\n\n blur(): void {\n this.#contentElement?.blur();\n }\n\n cleanUp(): void {\n this.#tokenizer?.cleanUp();\n this.#tokenizer = undefined;\n\n // dispse event listeners\n this.#globalEventDisposes?.forEach((dispose) => dispose());\n this.#globalEventDisposes = undefined;\n this.#editorEventDisposes?.forEach((dispose) => dispose());\n this.#editorEventDisposes = undefined;\n this.#selectEventDisposes?.forEach((dispose) => dispose());\n this.#selectEventDisposes = undefined;\n this.#detach?.();\n this.#detach = undefined;\n\n // cache\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#lineYCache.clear();\n this.#wrapLineOffsetsCache.clear();\n this.#lastAccessedLineElement = undefined;\n this.#lastAccessedCharX = undefined;\n\n // clean up dom elements\n this.#globalStyleElement?.remove();\n this.#globalStyleElement = undefined;\n this.#editorStyleElement?.remove();\n this.#editorStyleElement = undefined;\n this.#themeStyleElement?.remove();\n this.#themeStyleElement = undefined;\n this.#spriteElement?.remove();\n this.#spriteElement = undefined;\n this.#fileContainer = undefined;\n this.#gutterElement = undefined;\n this.#contentElement?.removeAttribute('contentEditable');\n this.#contentElement = undefined;\n this.#contentHasFocus = false;\n this.#overlayElement?.remove();\n this.#overlayElement = undefined;\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n // Let a reused instance schedule the font re-measure again on its next\n // mount, where a different font-family string may not be loaded yet.\n this.#fontRemeasureScheduled = false;\n\n this.#resetState();\n }\n\n /** @internal */\n __postponeBackgroundTokenizeToNextFrame(): void {\n const tokenizer = this.#tokenizer;\n if (tokenizer !== undefined) {\n tokenizer.pauseBackgroundTokenize();\n requestAnimationFrame(() => {\n tokenizer.resumeBackgroundTokenize();\n });\n }\n }\n\n /** @internal */\n __syncRenderView: DiffsEditor<LAnnotation>['__syncRenderView'] = (\n highlighter: DiffsHighlighter,\n fileContainer: HTMLElement,\n fileOrDiff: FileContents | FileDiffMetadata,\n lineAnnotations: DiffLineAnnotation<LAnnotation>[] | undefined,\n renderRange: RenderRange | undefined\n ) => {\n const shadowRoot = fileContainer.shadowRoot;\n if (shadowRoot == null) {\n console.error('[editor] Could not find the shadow root.');\n return;\n }\n\n let codeElement: HTMLElement | undefined;\n let gutterEl: HTMLElement | undefined;\n let contentEl: HTMLElement | undefined;\n for (const el of shadowRoot.querySelectorAll<HTMLElement>('[data-code]')) {\n if (el.dataset.deletions === undefined) {\n codeElement = el;\n for (const child of el.children) {\n const el = child as HTMLElement;\n const { gutter, content } = el.dataset;\n if (gutter !== undefined) {\n gutterEl = el;\n } else if (content !== undefined) {\n contentEl = el;\n }\n }\n break;\n }\n }\n if (codeElement === undefined || contentEl === undefined) {\n return;\n }\n\n // inject editor&theme style to the file container\n if (this.#fileContainer !== fileContainer) {\n this.#fileContainer = fileContainer;\n if (this.#globalStyleElement !== undefined) {\n fileContainer.appendChild(this.#globalStyleElement);\n }\n if (this.#editorStyleElement !== undefined) {\n shadowRoot.appendChild(this.#editorStyleElement);\n }\n if (this.#themeStyleElement !== undefined) {\n shadowRoot.appendChild(this.#themeStyleElement);\n }\n if (this.#spriteElement !== undefined) {\n shadowRoot.prepend(this.#spriteElement);\n }\n }\n\n // Whether this sync replaces the document with a freshly parsed one (a new\n // file, language, or cache key) versus reusing the existing one. A reused\n // document keeps any edits the host's file contents do not have, which the\n // rebuilt line DOM below must be reconciled against.\n const documentReplaced =\n this.#textDocument === undefined ||\n this.#fileInfo === undefined ||\n this.#fileInfo.name !== fileOrDiff.name ||\n this.#fileInfo.lang !== fileOrDiff.lang ||\n this.#fileInfo.cacheKey !== fileOrDiff.cacheKey;\n if (documentReplaced) {\n let contents = '';\n if ('contents' in fileOrDiff) {\n contents = fileOrDiff.contents;\n } else {\n contents = fileOrDiff.additionLines.join('');\n }\n const editStack = new EditStack<LAnnotation>({\n maxEntries: this.#options.historyMaxEntries,\n });\n const textDocument = new TextDocument<LAnnotation>(\n fileOrDiff.name,\n contents,\n fileOrDiff.lang ?? getFiletypeFromFileName(fileOrDiff.name),\n 0,\n editStack\n );\n const { name, lang, cacheKey } = fileOrDiff;\n this.#fileInfo = { name, lang, cacheKey };\n this.#textDocument = textDocument;\n this.#tokenizer?.cleanUp();\n this.#tokenizer = new EditorTokenizer({\n highlighter,\n textDocument,\n codeOptions: this.#fileInstance?.options ?? {},\n onDeferTokenize: this.#onDeferTokenize,\n setStyle: (css) => {\n this.#themeStyleElement!.textContent = css;\n },\n __debug: this.#options.__debug,\n });\n this.#resetState();\n this.#selections = this.#initSelections;\n requestAnimationFrame(() => {\n this.#options.onAttach?.(this, this.#fileInstance!);\n });\n if (this.#textDocument !== undefined && this.#options.__debug === true) {\n console.log('[diffs/editor] text document changed !!!');\n }\n }\n\n // A full re-render swaps in a new content element, so comparing identity\n // detects one. This is reliable for FileDiff, which rebuilds the column\n // (a new node) on a full render and reuses it on a partial one (scrolling).\n // File reuses its content element in place, so this would not fire for a\n // File full render - but File has no rerenderFromDocument path, so the\n // re-render gate below never applies to it. If File ever gains one, this\n // detection must be revisited.\n let fullRerender = false;\n if (this.#contentElement !== contentEl) {\n fullRerender = true;\n this.#gutterElement = gutterEl;\n this.#contentElement = extend(contentEl, {\n contentEditable: 'true',\n role: 'textbox',\n ariaMultiLine: 'true',\n autocapitalize: 'off',\n writingSuggestions: 'off',\n autocorrect: false,\n spellcheck: false,\n translate: false,\n });\n if (this.#overlayElement !== undefined) {\n contentEl.after(this.#overlayElement);\n }\n this.#metrics.init(contentEl);\n this.#remeasureMetricsOnFontLoad();\n this.#listenContentElement(contentEl, gutterEl);\n if (\n this.#contentElement !== undefined &&\n this.#options.__debug === true\n ) {\n console.log('[diffs/editor] full re-render triggered !!!');\n }\n }\n\n // The contenteditable host advertises role=\"textbox\", so without an\n // accessible name screen readers announce an unlabeled text field. Label it\n // with the file name. The same content element is reused across file\n // switches (see File#applyFullRender), so refresh the label on every sync\n // rather than only when the element is first initialized above.\n if (contentEl.ariaLabel !== fileOrDiff.name) {\n contentEl.ariaLabel = fileOrDiff.name;\n }\n\n if (\n (lineAnnotations !== undefined && lineAnnotations.length > 0) ||\n (this.#isDiff && this.#diffSyle === 'unified')\n ) {\n for (const child of this.#contentElement.children) {\n const el = child as HTMLElement;\n const { lineAnnotation, lineType } = el.dataset;\n if (lineAnnotation !== undefined || lineType === 'change-deletion') {\n el.setAttribute('contenteditable', 'false');\n }\n }\n }\n\n this.#resetCache();\n\n // The tokenizer is created once per attached document and reused across\n // re-renders, so a host-driven theme swap (theme picker, light/dark toggle)\n // wouldn't otherwise reach it. Re-apply the surface's current theme on every\n // sync so the editor's line-highlight/token colors track the active theme.\n this.#tokenizer?.syncTheme(this.#fileInstance?.options ?? {});\n\n this.#lineAnnotations = lineAnnotations;\n this.#renderRange = renderRange;\n // Remember the bounded window the virtualizer just synced so #applyChange\n // can clamp any edit-time widening against it. Refreshed on every scroll;\n // undefined/Infinity windows leave the clamp disabled.\n this.#viewportWindowLines = renderRange?.totalLines;\n this.#tokenizer?.prebuildStateStack(renderRange);\n\n // A host-driven full re-render (theme, diff style, wrap, or line-number\n // toggle) rebuilds the diff rows from the file contents the host passes in.\n // When the editor's document survived that re-render it stays the source of\n // truth and may hold edits the host's contents do not, so the rebuilt rows\n // show the pre-edit content. Re-render the diff from the editor's document\n // instead, so the rows match it - text, syntax colors, and line count - in\n // one pass, rather than reconciling the rebuilt rows after the fact.\n //\n // Gated three ways:\n // - documentReplaced: a new file/lang/cacheKey already rebuilt the document\n // from the host's contents, so there is nothing to restore.\n // - contentRebuilt: a partial render (scrolling a virtualized file) reuses\n // the existing edited rows, so it needs no re-render.\n // - divergence: when the rebuilt content already matches the document there\n // is nothing to do. This also stops the recursion, since the re-render\n // below comes back through here with content that now matches.\n // Only components with a document-backed re-render (FileDiff) implement\n // rerenderFromDocument; the plain File has no such path yet and is skipped.\n const fileInstance = this.#fileInstance;\n const textDocument = this.#textDocument;\n if (\n !documentReplaced &&\n fullRerender &&\n fileInstance?.rerenderFromDocument !== undefined &&\n textDocument !== undefined &&\n this.#shouldRenderDivergeFromDocument(textDocument)\n ) {\n fileInstance.rerenderFromDocument(textDocument);\n return;\n }\n\n this.#markerRenderer?.removePopup();\n\n // re-render the existing selections, matches, and markers\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n }\n\n if (\n this.#initSelections !== undefined &&\n this.#primaryCaretElement !== undefined\n ) {\n this.#initSelections = undefined;\n this.#scrollToPrimaryCaret(false, 'center');\n } else if (this.#scrollingToLine !== undefined) {\n this.#scrollToLine(\n this.#scrollingToLine,\n this.#scrollingToLineChar,\n this.#scrollingToLineNoFocus\n );\n } else if (\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n !this.#retainSearchPanelFocus\n ) {\n this.focus({ preventScroll: true });\n }\n\n if (this.#retainSearchPanelFocus) {\n this.#searchPanel?.focus();\n }\n\n if (this.#options.__debug === true && renderRange !== undefined) {\n const { startingLine, totalLines } = renderRange;\n console.log(\n '[diffs/editor] render file:',\n fileOrDiff.name,\n 'RenderRange:',\n startingLine + '-' + (startingLine + totalLines),\n 'of',\n this.#textDocument?.lineCount,\n 'lines'\n );\n }\n };\n\n get #diffSyle(): 'unified' | 'split' {\n return this.#fileInstance?.options.diffStyle ?? 'split';\n }\n\n get #isDiff(): boolean {\n return this.#fileInstance?.type === 'file-diff';\n }\n\n get #isWrap(): boolean {\n return this.#fileInstance?.options.overflow === 'wrap';\n }\n\n #resetCache(): void {\n this.#lineYCache.clear();\n this.#wrapLineOffsetsCache.clear();\n this.#lastAccessedLineElement = undefined;\n this.#lastAccessedCharX = undefined;\n }\n\n #resetState(): void {\n this.#setSelectedLinesSafe(null);\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#shouldIgnoreSelectionChange = false;\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements = undefined;\n this.#selections = undefined;\n this.#reservedSelections = undefined;\n this.#scrollingToLine = undefined;\n this.#markerRenderer?.cleanup();\n this.#markerRenderer = undefined;\n this.#searchPanel?.cleanup();\n this.#searchPanel = undefined;\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n }\n\n #initialize(): void {\n // Safari doesn't support `::selection` for slot elements in ShadowDOM,\n // Add a global style to disable selection for slot elements\n this.#globalStyleElement = h('style', {\n dataset: 'editorGlobalCss',\n textContent: `\n [data-annotation-slot] {\n user-select: none;\n -webkit-user-select: none;\n }\n `,\n });\n\n this.#editorStyleElement = h('style', {\n dataset: 'editorCss',\n textContent: editorCSS,\n });\n\n this.#themeStyleElement = h('style', {\n dataset: 'editorThemeCss',\n });\n\n this.#spriteElement = createSpriteElement();\n\n this.#overlayElement = h('div', {\n dataset: 'editorOverlay',\n });\n\n this.#globalEventDisposes = [\n addEventListener(\n document,\n 'selectionchange',\n () => {\n const shadowRoot = this.#fileContainer?.shadowRoot;\n // Ignore selection changes while the contenteditable is unfocused. A\n // programmatic applyEdits (skipFocus) re-anchors #selections without\n // syncing the native Selection, so a DOM-driven or refocus\n // selectionchange whose range still belongs to the editor must not\n // overwrite the remapped #selections before the user returns to type.\n if (\n this.#shouldIgnoreSelectionChange ||\n shadowRoot == null ||\n !this.#contentHasFocus\n ) {\n return;\n }\n\n // Native selection only tracks one range. focus() and DOM updates while\n // typing mirror the primary caret there, so selectionchange must not\n // overwrite multi-cursor editor state outside an active pointer gesture.\n if (\n this.#selections !== undefined &&\n this.#selections.length > 1 &&\n !this.#isContentMouseDown\n ) {\n return;\n }\n\n const selectionRaw = document.getSelection();\n // getComposedRanges is the only selection API that reads through the\n // editor's shadow root, but it is newly available and missing on\n // older browsers and embedded WebViews. Bail out instead of throwing\n // out of this listener on every selectionchange when it is absent.\n if (\n selectionRaw == null ||\n typeof selectionRaw.getComposedRanges !== 'function'\n ) {\n return;\n }\n const composedRange = selectionRaw.getComposedRanges({\n shadowRoots: [shadowRoot],\n })?.[0];\n if (\n composedRange === undefined ||\n !this.#rangeBelongsToEditor(composedRange)\n ) {\n return;\n }\n\n let selection = convertSelection(composedRange, DirectionNone);\n if (selection === undefined) {\n return;\n }\n\n // extend selection by shift + click\n if (\n this.#isContentMouseDown &&\n this.#shiftKeyPressed &&\n this.#selections !== undefined &&\n this.#selections.length > 0\n ) {\n const primarySelection = this.#selections.at(-1)!;\n this.#updateSelections([\n extendSelection(primarySelection, selection),\n ]);\n return;\n }\n\n if (this.#isContentMouseDown) {\n if (this.#selectionStart !== undefined) {\n selection = createSelectionFrom(this.#selectionStart, selection);\n } else {\n this.#selectionStart = selection;\n }\n } else if (this.#selectionStart !== undefined) {\n selection.direction = createSelectionFrom(\n this.#selectionStart,\n selection\n ).direction;\n }\n\n if (this.#reservedSelections !== undefined) {\n this.#updateSelections([\n ...this.#reservedSelections.filter(\n (reservedSelection) =>\n !selectionIntersects(reservedSelection, selection)\n ),\n selection,\n ]);\n } else {\n this.#updateSelections([selection]);\n }\n },\n { passive: true }\n ),\n\n addEventListener(\n document,\n 'pointerup',\n (e) => {\n if (e.pointerType !== 'mouse') {\n return;\n }\n\n this.#selectEventDisposes?.forEach((dispose) => dispose());\n this.#selectEventDisposes = undefined;\n\n if (this.#isGutterMouseDown) {\n this.#isGutterMouseDown = false;\n this.#focus();\n }\n this.#shouldIgnoreSelectionChange = false;\n this.#isContentMouseDown = false;\n this.#shiftKeyPressed = false;\n this.#selectionStart = undefined;\n this.#reservedSelections = undefined;\n // The popover is suppressed while the mouse is down so it doesn't\n // flicker under the cursor mid-drag. Now that the drag has ended,\n // re-run the overlay pass so a settled ranged selection reveals it.\n if (\n this.#options.enabledSelectionAction === true &&\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n !isCollapsedSelection(this.#selections.at(-1)!)\n ) {\n this.#updateSelections(this.#selections);\n }\n },\n { passive: true }\n ),\n\n addEventListener(\n document,\n 'keydown',\n (e) => {\n if (e.key === 'Shift') {\n this.#selectionStart = this.#selections?.at(-1);\n }\n },\n { passive: true }\n ),\n\n addEventListener(\n document,\n 'keyup',\n (e) => {\n if (e.key === 'Shift') {\n this.#selectionStart = undefined;\n }\n },\n { passive: true }\n ),\n ];\n }\n\n // Swaps in a new batch of transient \"select\" listeners — gutter drag\n // tracking or the Safari annotation-hover workaround — disposing the\n // previous batch first. Routing every reassignment through here keeps the\n // dispose-before-replace invariant in one place: a stale set (e.g. from a\n // pointerup that never fired after a canceled gesture, or a fresh\n // pointerdown before the previous interaction tore down) can never be\n // overwritten while its listeners are still attached to the document.\n #replaceSelectEventListeners(disposes: (() => void)[]): void {\n this.#selectEventDisposes?.forEach((dispose) => dispose());\n this.#selectEventDisposes = disposes;\n }\n\n #listenContentElement(contentEl: HTMLElement, gutterEl?: HTMLElement): void {\n const targetIsContentElement = (e: Event) => {\n const target = e.composedPath()[0] as HTMLElement | undefined;\n return (\n target !== undefined &&\n (target === contentEl || contentEl.contains(target))\n );\n };\n\n this.#editorEventDisposes?.forEach((dispose) => dispose());\n this.#editorEventDisposes = [\n addEventListener(\n contentEl,\n 'focus',\n () => {\n this.#contentHasFocus = true;\n // A keyboard or direct programmatic refocus restores a stale native\n // Selection that the selectionchange handler would apply over the\n // remapped #selections (after an applyEdits inserted a line above the\n // unfocused caret). Re-assert the editor's selection so the caret\n // stays anchored. A pointer focus is left to the click, and #focus()\n // already syncs the selection during an editor-driven focus.\n if (\n !this.#isContentMouseDown &&\n !this.#shouldIgnoreSelectionChange &&\n this.#selections !== undefined &&\n this.#selections.length > 0\n ) {\n this.#setWindowSelection(this.#selections.at(-1)!);\n }\n },\n { passive: true }\n ),\n addEventListener(\n contentEl,\n 'blur',\n () => {\n this.#contentHasFocus = false;\n },\n { passive: true }\n ),\n addEventListener(\n contentEl,\n 'pointerdown',\n (e) => {\n if (e.pointerType !== 'mouse') {\n return;\n }\n\n // A click on a read-only deleted line (unified view) selects it\n // natively. Hand the selection to the deleted text and drop the\n // editor's own selection, so only one region is highlighted at a\n // time and the deleted line is not swept into an editable selection.\n if (this.#isDeletedLineTarget(e)) {\n this.#setDeletedTextSelectionActive(true);\n if (this.#selections !== undefined) {\n this.#updateSelections([]);\n }\n return;\n }\n this.#setDeletedTextSelectionActive(false);\n\n this.#markerRenderer?.removePopup();\n\n // this is a workaround for the selection rendering glitch\n // happens when selecting content in shadow DOM on Safari\n if (\n isSafari() &&\n this.#lineAnnotations !== undefined &&\n this.#lineAnnotations.length > 0\n ) {\n const annotationDisposes = [\n ...contentEl.querySelectorAll<HTMLElement>(\n '[data-line-annotation]'\n ),\n ]\n .map((el) => [\n addEventListener(el, 'mouseenter', () => {\n this.#shouldIgnoreSelectionChange = true;\n }),\n addEventListener(el, 'mouseleave', () => {\n this.#shouldIgnoreSelectionChange = false;\n }),\n ])\n .flat();\n this.#replaceSelectEventListeners(annotationDisposes);\n }\n\n this.#isContentMouseDown = true;\n this.#selectionStart = undefined;\n if (e.button === 0 && isPrimaryModifier(e)) {\n this.#reservedSelections = this.#selections?.map((selection) => ({\n ...selection,\n }));\n }\n if (e.shiftKey) {\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const pos =\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start;\n // fix the window selection for shift mode\n this.#setWindowSelection({\n start: pos,\n end: pos,\n direction: DirectionNone,\n });\n }\n this.#shiftKeyPressed = true;\n }\n },\n { passive: true }\n ),\n\n addEventListener(contentEl, 'keydown', (e) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.#searchPanel?.cleanup();\n this.#searchPanel = undefined;\n this.#retainSearchPanelFocus = false;\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n if (this.#selections !== undefined && this.#selections.length > 0) {\n const primarySelection = this.#selections.at(-1)!;\n if (\n !isCollapsedSelection(primarySelection) ||\n this.#selections.length > 1\n ) {\n const pos = getCaretPosition(primarySelection);\n this.#updateSelections([\n {\n start: pos,\n end: pos,\n direction: DirectionNone,\n },\n ]);\n this.#focus(pos);\n }\n }\n return;\n }\n if (!targetIsContentElement(e)) {\n return;\n }\n\n // handle the cursor move events manually for multiple selections and virtual viewport\n const mvShortcut = isMoveCursorShortcut(e);\n const textDocument = this.#textDocument;\n if (\n this.#selections !== undefined &&\n this.#selections.length > 0 &&\n mvShortcut !== undefined &&\n textDocument !== undefined\n ) {\n if (e.shiftKey) {\n this.#updateSelections(\n mapSelectionShift(textDocument, this.#selections, mvShortcut)\n );\n } else {\n this.#updateSelections(\n mapCursorMove(textDocument, this.#selections, mvShortcut)\n );\n }\n this.#scrollToPrimaryCaret();\n e.preventDefault();\n return;\n }\n\n // Handle the 'paste' event manually with the custom clipboard API.\n if (\n e.key === 'v' &&\n isPrimaryModifier(e) &&\n this.#options.clipboard !== undefined\n ) {\n e.preventDefault();\n queueRender(this.#handleCustomPasteEvent);\n return;\n }\n\n // Only hijack the native find-again shortcut while the panel is open\n // so cmd+g/cmd+shift+g step through matches; otherwise leave it alone.\n if (this.#searchPanel !== undefined) {\n const findAgain = resolveFindAgainShortcut(e);\n if (findAgain !== undefined) {\n e.preventDefault();\n this.#searchPanel.navigate(findAgain === 'previous');\n return;\n }\n }\n\n const command = resolveEditorCommandFromKeyboardEvent(e);\n if (command !== undefined) {\n e.preventDefault();\n this.#runCommand(command);\n }\n }),\n\n addEventListener(contentEl, 'copy', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // A read-only deleted-text selection lives outside the editor's\n // document, so #getSelectionText() would be empty. Copy the selected\n // deleted text instead.\n e.clipboardData?.setData(\n 'text',\n this.#isDeletedTextSelectionActive()\n ? this.#deletedTextForClipboard()\n : this.#getSelectionText()\n );\n }),\n\n addEventListener(contentEl, 'cut', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // Deleted text is read-only and can't be removed, so a cut there copies\n // the selected deleted text (like the copy handler) without editing.\n e.clipboardData?.setData(\n 'text',\n this.#isDeletedTextSelectionActive()\n ? this.#deletedTextForClipboard()\n : this.#cutSelectionText()\n );\n }),\n\n addEventListener(contentEl, 'paste', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n const text = e.clipboardData?.getData('text');\n const textDocument = this.#textDocument;\n if (text !== undefined && textDocument !== undefined) {\n // Rewrite clipboard line breaks to the document's EOL so a Windows\n // clipboard (\\r\\n or \\r) doesn't leave mixed line endings behind.\n // TODO(@ije): Add support of multiple selections copy&paste\n this.#replaceSelectionText(\n textDocument.normalizeEol(text),\n undefined,\n true\n );\n }\n }),\n\n addEventListener(contentEl, 'beforeinput', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n if (e.inputType === 'insertCompositionText') {\n return;\n }\n e.preventDefault();\n this.#handleInput(e.inputType, e.data);\n }),\n\n addEventListener(contentEl, 'drop', (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n e.preventDefault();\n // TODO(@ije): Add support of drag move selection\n }),\n\n addEventListener(\n contentEl,\n 'compositionstart',\n (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#isComposing = true;\n this.#shouldIgnoreSelectionChange = true;\n },\n { passive: true }\n ),\n\n addEventListener(\n contentEl,\n 'compositionend',\n (e) => {\n if (!targetIsContentElement(e)) {\n return;\n }\n this.#shouldIgnoreSelectionChange = false;\n const wasComposing = this.#isComposing;\n this.#isComposing = false;\n // An empty compositionend during a tracked composition means the\n // candidate was canceled (e.g. Esc), so there is nothing to commit.\n if (e.data !== '' || !wasComposing) {\n this.#handleInput('insertText', e.data);\n }\n },\n { passive: true }\n ),\n ];\n\n // A selection in the read-only deletions column is painted natively (see\n // the gated ::selection rule). Starting one there reveals that selection\n // and clears the editor's own selection on the additions side, so only one\n // column shows a selection at a time. Non-diff files have no deletions\n // column.\n const deletionsCode =\n this.#fileContainer?.shadowRoot?.querySelector<HTMLElement>(\n '[data-deletions]'\n );\n if (deletionsCode != null) {\n this.#editorEventDisposes.push(\n addEventListener(\n deletionsCode,\n 'pointerdown',\n (e) => {\n // Clicking a deletion line's number selects the whole line's text\n // and dragging extends the selection across deletion lines (like a\n // click/drag on an addition line number); clicking its text lets\n // the browser place/extend the selection directly. Either way the\n // deleted-text marker reveals it and the editor drops its own\n // selection.\n const target = e.composedPath()[0];\n const gutterRow =\n target instanceof HTMLElement\n ? target.closest('[data-column-number]')\n : null;\n if (\n gutterRow instanceof HTMLElement &&\n this.#beginDeletionGutterSelection(\n gutterRow,\n deletionsCode,\n e.pointerType === 'mouse'\n )\n ) {\n return;\n }\n this.#setDeletedTextSelectionActive(true);\n if (this.#selections !== undefined) {\n this.#updateSelections([]);\n }\n },\n { passive: true }\n )\n );\n }\n\n if (gutterEl !== undefined) {\n const resolveGutterTarget = (\n eventTarget: HTMLElement | undefined,\n includeContentLine = false\n ) => {\n let target = eventTarget;\n if (target?.dataset.lineNumberContent !== undefined) {\n target = target.parentElement ?? undefined;\n } else if (includeContentLine && target?.tagName === 'SPAN') {\n target = target.closest('[data-line]') as HTMLElement | undefined;\n }\n return target;\n };\n\n const resolveEditableLine = (target: HTMLElement | undefined) => {\n if (target === undefined) {\n return;\n }\n const lineType = target.dataset.lineType;\n const lineNumber =\n getLineNumberAttr(target) ??\n getLineNumberAttr(target, 'columnNumber');\n if (\n lineNumber === undefined ||\n lineType === undefined ||\n !isLineEditable(lineType)\n ) {\n return;\n }\n return lineNumber - 1;\n };\n\n this.#editorEventDisposes.push(\n addEventListener(\n gutterEl,\n 'pointerdown',\n (e) => {\n const gutterRow = resolveGutterTarget(\n e.composedPath()[0] as HTMLElement | undefined\n );\n // Clicking a read-only deleted line's number (unified view) selects\n // that line's text natively, since the line is not in the editor's\n // document. This runs before the mouse-only gate below: a deletion\n // tap registers no drag state to strand, so it works on touch too,\n // matching the split deletions column.\n if (gutterRow?.dataset.lineType === 'change-deletion') {\n const code = gutterRow.closest('[data-code]');\n if (code != null) {\n this.#beginDeletionGutterSelection(\n gutterRow,\n code,\n e.pointerType === 'mouse'\n );\n }\n return;\n }\n\n // Editable gutter drag-selection is mouse-only: the global pointerup\n // that clears #isGutterMouseDown and disposes the mousemove listener\n // bails for non-mouse pointers, so reacting to a touch/pen tap here\n // would strand that state and leak the listener. Mirror the content\n // pointerdown guard.\n if (e.pointerType !== 'mouse') {\n return;\n }\n\n const textDocument = this.#textDocument;\n const lineIndex = resolveEditableLine(gutterRow);\n if (lineIndex === undefined || textDocument === undefined) {\n return;\n }\n\n this.#markerRenderer?.removePopup();\n const selection = this.#spanLineSelection(\n lineIndex,\n lineIndex,\n textDocument\n );\n this.#isGutterMouseDown = true;\n this.#selectionStart = selection;\n this.#updateSelections([selection]);\n // Span the native selection across the clicked line and focus\n // without collapsing it. #focus(position) would drop a collapsed\n // caret at the line end, which a later selectionchange then turns\n // into a bare caret — so a single click on a line number would\n // place a cursor instead of selecting the whole line's text.\n this.#setWindowSelection(selection);\n this.#focus();\n this.#replaceSelectEventListeners([\n addEventListener(\n document,\n 'mousemove',\n (e) => {\n if (!this.#isGutterMouseDown) {\n return;\n }\n const textDocument = this.#textDocument;\n const lineIndex = resolveEditableLine(\n resolveGutterTarget(\n e.composedPath()[0] as HTMLElement | undefined,\n true\n )\n );\n if (lineIndex === undefined || textDocument === undefined) {\n return;\n }\n\n // A gutter drag keeps both the clicked line (the anchor) and\n // the line under the pointer fully selected. Until a drag\n // outruns its pointerdown the anchor is set; if it somehow is\n // not, the line under the pointer becomes the anchor.\n const anchorLine =\n this.#selectionStart?.start.line ?? lineIndex;\n const selection = this.#spanLineSelection(\n anchorLine,\n lineIndex,\n textDocument\n );\n this.#selectionStart ??= selection;\n this.#updateSelections([selection]);\n this.#focus(\n selection.direction === DirectionBackward\n ? selection.start\n : selection.end\n );\n },\n { passive: true }\n ),\n ]);\n },\n { passive: true }\n )\n );\n }\n\n this.#markerRenderer?.listenHover(contentEl);\n\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = new ResizeObserver(this.#handleLayoutResize);\n this.#resizeObserver.observe(contentEl);\n this.#resizeObserver.observe(contentEl.parentElement!);\n this.#computeContentOffset(contentEl);\n }\n\n #handleCustomPasteEvent = async () => {\n const clipboard = this.#options.clipboard;\n if (clipboard !== undefined) {\n const text = await clipboard.readText();\n this.#replaceSelectionText(text, undefined, true);\n }\n };\n\n // diff(split) treat the content element as grid item,\n // that breaks the overlay element positioning.\n // this function computes the content offset to fix\n // the overlay element position.\n #computeContentOffset(contentEl: HTMLElement) {\n if (this.#isDiff && this.#diffSyle === 'split' && this.#isWrap) {\n this.#contentOffset = {\n top: contentEl.offsetTop,\n left: contentEl.offsetLeft - this.#getGutterWidth(),\n };\n if (this.#options.__debug === true) {\n console.log('[diffs/editor] content offset:', this.#contentOffset);\n }\n }\n }\n\n // #computeContentOffset only assigns #contentOffset in a split + wrap diff and\n // never clears it, so after toggling wrap off (or switching to unified) the\n // same editor keeps a stale offset. Read it through this getter, which returns\n // the offset only while the live layout is the one that produced it, so a\n // stale value is never applied to caret, selection, or line-Y positions.\n get #activeContentOffset(): { left: number; top: number } | undefined {\n if (this.#isDiff && this.#diffSyle === 'split' && this.#isWrap) {\n return this.#contentOffset;\n }\n return undefined;\n }\n\n // TODO(@ije): add command registry\n #runCommand(command: EditorCommand) {\n const textDocument = this.#textDocument;\n if (textDocument === undefined) {\n return;\n }\n\n switch (command) {\n case 'openSearchPanel':\n this.#openSearchPanel('find');\n break;\n\n case 'openSearchReplacePanel':\n this.#openSearchPanel('replace');\n break;\n\n case 'findNextMatch': {\n const selections = this.#selections;\n if (selections === undefined) {\n break;\n }\n const hasCollapsed = selections.some(isCollapsedSelection);\n if (hasCollapsed) {\n const expanded: EditorSelection[] = selections.map((sel) => {\n if (isCollapsedSelection(sel)) {\n return expandCollapsedSelectionToWord(textDocument, sel);\n }\n return sel;\n });\n this.#updateSelections(expanded);\n this.focus();\n } else {\n const nextMatch = findNexMatch(textDocument, selections);\n if (nextMatch !== undefined) {\n this.#updateSelections(nextMatch);\n this.#scrollToPrimaryCaret();\n }\n }\n break;\n }\n\n case 'indent':\n case 'outdent':\n if (this.#selections !== undefined) {\n const edits: TextEdit[] = [];\n const nextSelections: EditorSelection[] = [];\n // Single-line indent inserts text at each caret. When several carets\n // share a line, indentation inserted by carets to their left shifts\n // them right, so record each one here and offset its resulting\n // position once every edit on the line is known. Without this, later\n // same-line carets land before their own inserted indent.\n const sameLineIndents: Array<{\n line: number;\n startCharacter: number;\n addedLength: number;\n selectionIndex: number;\n }> = [];\n for (const selection of this.#selections) {\n const startLine = selection.start.line;\n const outdent = command === 'outdent';\n if (startLine !== selection.end.line || outdent) {\n const ret = resolveIndentEdits(\n textDocument,\n selection,\n this.#metrics.tabSize,\n outdent\n );\n edits.push(...ret[0]);\n nextSelections.push(ret[1]);\n } else {\n const lineChar0 = textDocument.charAt({\n line: startLine,\n character: 0,\n });\n const text =\n lineChar0 === '\\t' ? '\\t' : ' '.repeat(this.#metrics.tabSize);\n edits.push({\n range: selection,\n newText: text,\n });\n sameLineIndents.push({\n line: startLine,\n startCharacter: selection.start.character,\n addedLength:\n text.length -\n (selection.end.character - selection.start.character),\n selectionIndex: nextSelections.length,\n });\n const nextPosition = {\n line: selection.start.line,\n character: selection.start.character + text.length,\n };\n nextSelections.push({\n start: nextPosition,\n end: nextPosition,\n direction: DirectionNone,\n });\n }\n }\n for (const indent of sameLineIndents) {\n let shift = 0;\n for (const other of sameLineIndents) {\n if (\n other.line === indent.line &&\n other.startCharacter < indent.startCharacter\n ) {\n shift += other.addedLength;\n }\n }\n if (shift !== 0) {\n const current = nextSelections[indent.selectionIndex];\n const position = {\n line: indent.line,\n character: current.start.character + shift,\n };\n nextSelections[indent.selectionIndex] = {\n start: position,\n end: position,\n direction: DirectionNone,\n };\n }\n }\n const change = textDocument.applyEdits(\n edits,\n true,\n this.#selections,\n nextSelections\n );\n if (change !== undefined) {\n this.#applyChange(change, nextSelections);\n }\n }\n break;\n\n case 'selectAll':\n this.#updateSelections([getDocumentFullSelection(textDocument)]);\n this.focus();\n break;\n\n case 'moveCursorToDocStart':\n case 'moveCursorToDocEnd':\n {\n const atEnd = command === 'moveCursorToDocEnd';\n this.#updateSelections([\n getDocumentBoundarySelection(textDocument, atEnd),\n ]);\n this.#scrollToPrimaryCaret();\n }\n break;\n\n case 'expandSelectionDocStart':\n case 'expandSelectionDocEnd':\n {\n const atEnd = command === 'expandSelectionDocEnd';\n const selections = this.#selections;\n if (selections !== undefined) {\n this.#updateSelections(\n extendSelections(\n selections,\n getDocumentBoundarySelection(textDocument, atEnd)\n )\n );\n this.#scrollToPrimaryCaret();\n }\n }\n break;\n\n case 'undo':\n if (this.#textDocument?.canUndo === true) {\n const undoResult = this.#textDocument.undo();\n if (undoResult !== undefined) {\n this.#applyChange(...undoResult);\n }\n }\n break;\n\n case 'redo':\n if (this.#textDocument?.canRedo === true) {\n const redoResult = this.#textDocument.redo();\n if (redoResult !== undefined) {\n this.#applyChange(...redoResult);\n }\n }\n break;\n }\n }\n\n #handleLayoutResize = () => {\n const lineAnnotations = this.#lineAnnotations?.length ?? 0;\n const prevGutterWidth = this.#gutterWidthCache;\n const prevContentWidth = this.#contentWidthCache;\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n const gutterWidthChanged = this.#getGutterWidth() !== prevGutterWidth;\n const contentWidthChanged = this.#getContentWidth() !== prevContentWidth;\n if (!gutterWidthChanged && !contentWidthChanged) {\n return;\n }\n\n this.#lastAccessedLineElement = undefined;\n this.#lastAccessedCharX = undefined;\n // A width change means the inherited font/metrics may have changed (e.g. a\n // web font finished loading) while this same content element survived, so\n // discard memoized non-ASCII text widths and let them re-measure.\n this.#metrics.clearTextWidthCache();\n if (contentWidthChanged && (this.#isWrap || lineAnnotations > 0)) {\n this.#lineYCache.clear();\n this.#wrapLineOffsetsCache.clear();\n }\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n if (this.#selections !== undefined) {\n this.focus();\n }\n }\n this.#markerRenderer?.removePopup();\n this.#computeContentOffset(this.#contentElement!);\n };\n\n // A custom monospace web font can finish loading after the editor first\n // renders. Until then Metrics measured the '0' width against the fallback\n // font, so the gutter width and every caret/selection x-position (each\n // offset by a whole number of `ch` units) are wrong. Re-measure once fonts\n // settle and, when the width actually changed, drop the cached widths and\n // offsets and repaint the overlays so they line up with the loaded glyphs.\n // FontFaceSet is unavailable in non-browser hosts (e.g. jsdom in tests).\n #remeasureMetricsOnFontLoad(): void {\n if (this.#fontRemeasureScheduled) {\n return;\n }\n const fonts = document.fonts as FontFaceSet | undefined;\n if (fonts === undefined) {\n return;\n }\n this.#fontRemeasureScheduled = true;\n void fonts.ready.then(() => {\n if (\n this.#contentElement === undefined ||\n !this.#metrics.remeasureCharacterWidth()\n ) {\n return;\n }\n this.#gutterWidthCache = undefined;\n this.#contentWidthCache = undefined;\n this.#resetCache();\n if (\n this.#selections !== undefined ||\n this.#matches !== undefined ||\n this.#markerRenderer !== undefined\n ) {\n this.#updateSelections(this.#selections ?? []);\n }\n this.#markerRenderer?.removePopup();\n });\n }\n\n #rerender(\n change: TextDocumentChange,\n newLineAnnotations?: DiffLineAnnotation<LAnnotation>[],\n renderRange = this.#renderRange,\n shouldUpdateBuffer?: boolean\n ) {\n const tokenizer = this.#tokenizer;\n const fileInstance = this.#fileInstance;\n const textDocument = this.#textDocument;\n const gutterEl = this.#gutterElement;\n const contentEl = this.#contentElement;\n if (\n tokenizer === undefined ||\n fileInstance === undefined ||\n textDocument === undefined ||\n contentEl === undefined\n ) {\n return;\n }\n\n // cancel existing background tokenzier task\n tokenizer.stopBackgroundTokenize();\n\n const t = performance.now();\n const dirtyLines = tokenizer.tokenize(change, renderRange);\n const t2 = performance.now();\n\n if (dirtyLines.size > 0) {\n const children = contentEl.children;\n const dirtyLineIndexes = new Set<number>(dirtyLines.keys());\n\n // update line elements that have been changed in the document\n const startingLine = renderRange?.startingLine ?? 0;\n for (let i = change.startLine - startingLine; i < children.length; i++) {\n const child = children[i] as HTMLElement | undefined;\n if (child !== undefined) {\n const lineNumber = getLineNumberAttr(child);\n const lineType = child.dataset.lineType;\n if (lineNumber === undefined || lineType === 'change-deletion') {\n continue;\n }\n const lineIndex = lineNumber - 1;\n if (dirtyLines.has(lineIndex)) {\n const tokens = dirtyLines.get(lineIndex)!;\n child.replaceChildren(\n ...renderLineTokens(tokens, tokenizer.themeType)\n );\n dirtyLineIndexes.delete(lineIndex);\n if (dirtyLineIndexes.size === 0) {\n break;\n }\n }\n }\n }\n\n // create new line elements for the new lines\n if (dirtyLineIndexes.size > 0) {\n for (const lineIndex of dirtyLineIndexes) {\n const tokens = dirtyLines.get(lineIndex)!;\n const lineNumber = String(lineIndex + 1);\n h(\n 'div',\n {\n dataset: {\n line: lineNumber,\n lineType: 'context',\n lineIndex: lineIndex.toString(),\n },\n // oxlint-disable-next-line react/no-children-prop\n children: renderLineTokens(tokens, tokenizer.themeType),\n },\n contentEl\n );\n if (gutterEl !== undefined) {\n h(\n 'div',\n {\n dataset: {\n lineType: 'context',\n columnNumber: lineNumber,\n lineIndex: lineIndex.toString(),\n },\n // oxlint-disable-next-line react/no-children-prop\n children: [\n h('span', {\n dataset: {\n lineNumberContent: '',\n },\n textContent: lineNumber,\n }),\n ],\n },\n gutterEl\n );\n }\n }\n }\n }\n\n // remove line elements that have been deleted in the document\n if (change.lineDelta < 0) {\n for (const children of [contentEl.children, gutterEl?.children ?? []]) {\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i] as HTMLElement;\n const lineNumber =\n getLineNumberAttr(child) ??\n getLineNumberAttr(child, 'columnNumber');\n const lineType = child.dataset.lineType;\n if (lineNumber === undefined || lineType === 'change-deletion') {\n continue;\n }\n if (lineNumber - 1 < change.lineCount) {\n break;\n }\n child.remove();\n }\n }\n }\n\n const didLineCountChange = change.lineDelta !== 0;\n\n // fix grid layout\n if (didLineCountChange) {\n let gridRow = contentEl.children.length;\n for (const child of contentEl.children) {\n const { bufferSize } = (child as HTMLElement).dataset;\n if (bufferSize !== undefined) {\n gridRow += parseInt(bufferSize) - 1;\n }\n }\n contentEl.style.gridRow = 'span ' + gridRow;\n if (gutterEl !== undefined) {\n gutterEl.style.gridRow = 'span ' + gridRow;\n }\n }\n\n fileInstance.updateRenderCache(\n dirtyLines,\n tokenizer.themeType,\n this.#isDiff && !didLineCountChange,\n // On a line-count change we recompute hunk metadata authoritatively in\n // `applyDocumentChange` below, so skip the redundant recompute here.\n didLineCountChange\n );\n if (didLineCountChange) {\n fileInstance.applyDocumentChange(\n textDocument,\n newLineAnnotations,\n shouldUpdateBuffer\n );\n }\n\n if (newLineAnnotations !== undefined) {\n this.#lineAnnotations = newLineAnnotations;\n renderLineAnnotations(newLineAnnotations, contentEl, gutterEl);\n }\n\n if (this.#options.__debug === true) {\n console.log(\n `[diffs/editor] re-render in: ${round(performance.now() - t2)}ms,`,\n `tokenize in: ${round(t2 - t)}ms (${dirtyLines.size} dirty lines)`\n );\n }\n }\n\n // Whether the rendered editable rows no longer match the editor's document -\n // a row's text drifted, a row's line number is past the document (a stale row\n // left after a deletion), or a row that should exist is missing/shifted (an\n // insertion shows the following line's text). Reads the DOM rather than the\n // diff metadata so it catches rows whose cached highlight is stale even after\n // the underlying text was updated, and it only inspects the rendered rows so\n // it stays correct under virtualization.\n #shouldRenderDivergeFromDocument(\n textDocument: TextDocument<LAnnotation>\n ): boolean {\n const contentEl = this.#contentElement;\n if (contentEl === undefined) {\n return false;\n }\n for (const child of contentEl.children) {\n const el = child as HTMLElement;\n const lineType = el.dataset.lineType;\n const lineNumber = getLineNumberAttr(el);\n if (\n lineNumber === undefined ||\n lineType === undefined ||\n !isLineEditable(lineType)\n ) {\n continue;\n }\n const lineIndex = lineNumber - 1;\n if (\n lineIndex >= textDocument.lineCount ||\n el.textContent !== textDocument.getLineText(lineIndex)\n ) {\n return true;\n }\n }\n return false;\n }\n\n // input type doc: https://developer.mozilla.org/en-US/docs/Web/API/InputEvent/inputType\n #handleInput(inputType: string, data: string | null) {\n switch (inputType) {\n case 'insertText': {\n const text = data ?? '';\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n const autoSurroundTexts =\n textDocument !== undefined && selections !== undefined\n ? getAutoSurroundReplacementTexts(\n textDocument,\n selections,\n text,\n this.#options.autoSurround\n )\n : undefined;\n this.#replaceSelectionText(autoSurroundTexts ?? text);\n break;\n }\n case 'insertCompositionText':\n break;\n case 'insertLineBreak':\n case 'insertParagraph':\n // TODO(@ije): use document.EOF instead of '\\n'\n this.#replaceSelectionText('\\n');\n break;\n case 'deleteContentBackward':\n this.#deleteSelectionText();\n break;\n case 'deleteContentForward':\n this.#deleteSelectionText(true);\n break;\n case 'deleteSoftLineBackward':\n this.#deleteSoftLineBackward();\n break;\n case 'deleteHardLineForward':\n // TODO(@ije): Safari and Firefox does not support this input type\n // use command instead\n this.#deleteHardLineForward();\n break;\n case 'deleteWordBackward':\n this.#deleteWordBackward();\n break;\n case 'insertTranspose':\n this.#insertTranspose();\n break;\n default:\n console.warn(`[diffs] Unknown input type: ${inputType}`, data);\n break;\n }\n }\n\n #focus(position?: Position, preventScroll = true) {\n // Mark focus eagerly: the positional branch defers the real focus() to a\n // rAF, so a same-tick applyEdits would otherwise see the editor as\n // unfocused and skip repositioning while this focus still lands afterward.\n this.#contentHasFocus = true;\n if (position !== undefined) {\n this.#shouldIgnoreSelectionChange = true;\n this.#setWindowSelection({\n start: position,\n end: position,\n direction: DirectionNone,\n });\n // call focus in a request animation frame to prevent conflict with\n // the `setBaseAndExtent` method\n requestAnimationFrame(() => {\n this.#contentElement?.focus({ preventScroll });\n // another request animation frame since the `focus` call\n // may trigger a selectionchange event, which we want to ignore\n requestAnimationFrame(() => {\n this.#shouldIgnoreSelectionChange = false;\n });\n });\n } else {\n this.#contentElement?.focus({ preventScroll });\n }\n }\n\n // set window native selection to match the selection\n #setWindowSelection(selection: EditorSelection) {\n const winSelection = window.getSelection();\n if (winSelection === null) {\n return;\n }\n let { start, end, direction } = selection;\n if (comparePosition(start, end) > 0) {\n [start, end] = [end, start];\n }\n const startLineElement = this.#getLineElement(start.line);\n const endLineElement = this.#getLineElement(end.line);\n if (startLineElement === undefined || endLineElement === undefined) {\n return;\n }\n let [anchorNode, anchorOffset] = getSelectionAnchor(\n startLineElement,\n start.character\n );\n let [focusNode, focusOffset] = getSelectionAnchor(\n endLineElement,\n end.character\n );\n if (direction === DirectionBackward) {\n [anchorNode, anchorOffset, focusNode, focusOffset] = [\n focusNode,\n focusOffset,\n anchorNode,\n anchorOffset,\n ];\n }\n try {\n winSelection.setBaseAndExtent(\n anchorNode,\n clampDomOffset(anchorNode, anchorOffset),\n focusNode,\n clampDomOffset(focusNode, focusOffset)\n );\n } catch (err) {\n console.error('[diffs/editor] failed to update window selection:', err);\n }\n }\n\n #scrollToPrimaryCaret(\n noFocus = false,\n scrollPosition: ScrollLogicalPosition = 'nearest'\n ) {\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection === undefined) {\n return;\n }\n const primaryCaretElement = this.#primaryCaretElement;\n if (primaryCaretElement !== undefined) {\n primaryCaretElement.scrollIntoView({\n block: scrollPosition,\n inline: 'nearest',\n });\n if (!noFocus) {\n this.#focus(\n primarySelection.direction === DirectionBackward\n ? primarySelection.end\n : primarySelection.start\n );\n }\n } else {\n const pos = getCaretPosition(primarySelection);\n this.#scrollToLine(pos.line, pos.character, noFocus);\n }\n }\n\n // add scroll margin to the primary caret element to prevent\n // the caret from being hidden by the gutter\n #getScrollMargin() {\n const componentTop = this.#fileInstance?.top ?? 0;\n const top = this.#searchPanel !== undefined ? 48 : 0;\n const start = this.#getGutterWidth() + this.#metrics.ch;\n const end = this.#metrics.ch;\n return `${componentTop + top}px ${end}px 0 ${start}px`;\n }\n\n #scrollToLine(line: number, char = 0, noFocus = false) {\n this.__postponeBackgroundTokenizeToNextFrame();\n\n const virtualCaret = h('div', {\n style: {\n position: 'absolute',\n left: '0',\n width: '2px',\n height: this.#metrics.lineHeight + 'px',\n scrollMargin: this.#getScrollMargin(),\n },\n });\n if (this.#getLineElement(line) !== undefined) {\n const [left, wrapLine] = this.#getCharX(line, char);\n const lineY = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight;\n virtualCaret.style.top = lineY + 'px';\n virtualCaret.style.left = left + 'px';\n this.#overlayElement?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n if (!noFocus) {\n this.#focus({ line, character: char });\n }\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineNoFocus = false;\n }\n // if the line is not rendered yet(virtualized), scroll to the approximate\n // line position to trigger the line to be rendered, then recall this function\n // to ensure the line is scrolled into view\n else {\n let yFix = 0;\n if (\n this.#scrollingToLine === line &&\n this.#contentElement !== undefined\n ) {\n for (let i = this.#contentElement.childElementCount - 1; i >= 0; i--) {\n const child = this.#contentElement.children[i] as HTMLElement;\n const lineType = child.dataset.lineType;\n const lineNumber = getLineNumberAttr(child);\n if (\n lineType !== undefined &&\n isLineEditable(lineType) &&\n lineNumber !== undefined\n ) {\n yFix = (line - lineNumber) * this.#metrics.lineHeight;\n break;\n }\n }\n }\n const lineAnnotations = (this.#lineAnnotations ?? []).filter(\n (annotation) => annotation.lineNumber < line\n ).length;\n const approximateLineY =\n (lineAnnotations + line) * this.#metrics.lineHeight + yFix;\n virtualCaret.style.top = approximateLineY + 'px';\n this.#fileContainer?.shadowRoot?.appendChild(virtualCaret);\n virtualCaret.scrollIntoView({ block: 'center', inline: 'nearest' });\n if (this.#scrollingToLine === line && yFix === 0) {\n this.#scrollingToLine = undefined;\n this.#scrollingToLineChar = undefined;\n this.#scrollingToLineNoFocus = false;\n } else {\n this.#scrollingToLine = line;\n this.#scrollingToLineChar = char;\n this.#scrollingToLineNoFocus = noFocus;\n }\n }\n virtualCaret.remove();\n }\n\n // Build a selection that fully covers every line from the anchor line to the\n // focus line — from the topmost line's start to the bottommost line's end.\n // Dragging above the anchor yields a backward selection so the anchor line\n // stays selected and #focus lands on the line the gesture ended on. A single\n // line (anchor === focus) is a forward whole-line selection.\n #spanLineSelection(\n anchorLine: number,\n focusLine: number,\n textDocument: TextDocument<LAnnotation>\n ): EditorSelection {\n const lineStart = (line: number): Position => ({ line, character: 0 });\n const lineEnd = (line: number): Position => ({\n line,\n character: textDocument.getLineText(line).length,\n });\n if (focusLine < anchorLine) {\n return {\n start: lineStart(focusLine),\n end: lineEnd(anchorLine),\n direction: DirectionBackward,\n };\n }\n return {\n start: lineStart(anchorLine),\n end: lineEnd(focusLine),\n direction: DirectionForward,\n };\n }\n\n // A pointer gesture targets read-only deleted text when its closest row is a\n // change-deletion. Used to route a click in unified view's deleted text to a\n // native selection instead of the editor's own.\n #isDeletedLineTarget(event: Event): boolean {\n const target = event.composedPath()[0];\n return (\n target instanceof HTMLElement &&\n target.closest('[data-line]')?.getAttribute('data-line-type') ===\n 'change-deletion'\n );\n }\n\n // Select read-only deleted text with the native selection, spanning from the\n // anchor row to the focus row (the same row for a click). Deleted lines are\n // not part of the editor's document, so they cannot be selected as editor\n // text; instead select their DOM text, reveal it via the deleted-text marker,\n // drop the editor's own selection, and highlight the deleted gutter numbers so\n // the result matches a click/drag on an addition line.\n #selectDeletedLines(\n anchorContent: HTMLElement,\n focusContent: HTMLElement,\n deletionsCode: Element\n ): void {\n const rows = [\n ...deletionsCode.querySelectorAll('[data-content] > [data-line]'),\n ];\n const anchorIndex = rows.indexOf(anchorContent);\n const focusIndex = rows.indexOf(focusContent);\n const [topContent, bottomContent] =\n focusIndex < anchorIndex\n ? [focusContent, anchorContent]\n : [anchorContent, focusContent];\n\n const winSelection = window.getSelection();\n if (winSelection !== null) {\n const range = document.createRange();\n range.setStart(topContent, 0);\n range.setEnd(bottomContent, bottomContent.childNodes.length);\n winSelection.removeAllRanges();\n winSelection.addRange(range);\n }\n\n this.#setDeletedTextSelectionActive(true);\n this.#updateSelections([]);\n\n // Highlight only the focus line's gutter number — the line where the click\n // landed or the drag ended. An addition selection highlights just its caret\n // line (getCaretPosition is the focus end), so matching that keeps the two\n // sides consistent. #setDeletedTextSelectionActive cleared the previous\n // selection's number above, so set this one's directly on the gutter row\n // that lines up with the focus content row.\n const gutterRows = [\n ...deletionsCode.querySelectorAll('[data-gutter] > [data-column-number]'),\n ];\n gutterRows[focusIndex]?.setAttribute('data-selected-line', 'single');\n\n // Record the selected deleted lines' text for the clipboard. Each deleted\n // line is its own read-only host, so window.getSelection().toString() only\n // captures the first line; the copy/cut handlers prefer this value.\n const lo = Math.min(anchorIndex, focusIndex);\n const hi = Math.max(anchorIndex, focusIndex);\n this.#deletedSelectionText =\n lo < 0\n ? ''\n : rows\n .slice(lo, hi + 1)\n .filter(\n (row) => row.getAttribute('data-line-type') === 'change-deletion'\n )\n .map((row) => row.textContent ?? '')\n .join('\\n');\n }\n\n // The content row that lines up with a gutter row: the two columns are\n // parallel, so the gutter row's index is the content row's index.\n #contentRowForGutterRow(\n gutterRow: HTMLElement,\n contentColumn: Element | null | undefined\n ): HTMLElement | undefined {\n const gutterColumn = gutterRow.parentElement;\n if (gutterColumn == null || contentColumn == null) {\n return undefined;\n }\n const index = [...gutterColumn.children].indexOf(gutterRow);\n const row = contentColumn.children[index];\n return row instanceof HTMLElement ? row : undefined;\n }\n\n // Begin a native selection of read-only deleted lines from a pointerdown on a\n // deletion line number. Selects the clicked line and, for a mouse pointer,\n // tracks a drag across the deletion gutter that extends the selection — the\n // same gesture as a click/drag on an addition line number. `code` is the\n // [data-code] holding the deletion column: the separate deletions column in\n // split view, or the shared column in unified view. Returns false when the\n // gutter row has no matching content row, letting the caller fall back to a\n // plain deleted-text selection.\n #beginDeletionGutterSelection(\n gutterRow: HTMLElement,\n code: Element,\n isMouse: boolean\n ): boolean {\n const contentColumn = code.querySelector('[data-content]');\n const anchorContent = this.#contentRowForGutterRow(\n gutterRow,\n contentColumn\n );\n if (anchorContent === undefined) {\n return false;\n }\n this.#selectDeletedLines(anchorContent, anchorContent, code);\n // The document pointerup disposes this listener; it must not set\n // #isGutterMouseDown, whose pointerup focuses the editor and would collapse\n // the native deletion selection.\n if (isMouse) {\n this.#replaceSelectEventListeners([\n addEventListener(\n document,\n 'mousemove',\n (moveEvent) => {\n const moveTarget = moveEvent.composedPath()[0];\n const moveGutter =\n moveTarget instanceof HTMLElement\n ? moveTarget.closest('[data-column-number]')\n : null;\n if (\n moveGutter instanceof HTMLElement &&\n code.contains(moveGutter)\n ) {\n const focusContent = this.#contentRowForGutterRow(\n moveGutter,\n contentColumn\n );\n if (focusContent !== undefined) {\n this.#selectDeletedLines(anchorContent, focusContent, code);\n }\n }\n },\n { passive: true }\n ),\n ]);\n }\n return true;\n }\n\n // Whether a read-only deleted-text selection is currently active (the marker\n // #setDeletedTextSelectionActive sets). The copy/cut handlers read this to\n // copy the native selection instead of the editor's empty document selection.\n #isDeletedTextSelectionActive(): boolean {\n return (\n this.#fileContainer?.shadowRoot\n ?.querySelector('pre')\n ?.hasAttribute('data-deleted-text-selection') ?? false\n );\n }\n\n // The clipboard text for a read-only deleted-text selection. A gutter\n // selection records the full multi-line text in #deletedSelectionText; a\n // direct content drag leaves it empty, so fall back to the browser's native\n // selection (which spans only the first deleted line — its separate host).\n #deletedTextForClipboard(): string {\n return this.#deletedSelectionText !== ''\n ? this.#deletedSelectionText\n : (window.getSelection()?.toString() ?? '');\n }\n\n // Toggle the marker that reveals the native selection inside read-only\n // deleted text (see the gated ::selection rule). It stays on only while the\n // user is actively selecting within deleted lines, so a normal selection of\n // editable code that sweeps across an interleaved deleted line does not\n // highlight it.\n #setDeletedTextSelectionActive(active: boolean): void {\n const pre = this.#fileContainer?.shadowRoot?.querySelector('pre');\n if (pre == null) {\n return;\n }\n if (active) {\n pre.setAttribute('data-deleted-text-selection', '');\n // Drop any line-number highlight left over from a previous selection.\n // #selectDeletedLines marks the deleted gutter numbers directly, and the\n // editor only clears them when its own selection range changes — but\n // deletion selections leave that range null, so a second deletion click\n // would otherwise keep the first selection's numbers highlighted.\n for (const highlighted of pre.querySelectorAll('[data-selected-line]')) {\n highlighted.removeAttribute('data-selected-line');\n }\n // Reset the captured selection text. #selectDeletedLines refills it for a\n // gutter selection; a content drag leaves it empty so the copy/cut\n // handlers fall back to the native selection.\n this.#deletedSelectionText = '';\n } else {\n pre.removeAttribute('data-deleted-text-selection');\n this.#deletedSelectionText = '';\n }\n }\n\n #setSelectedLinesSafe(\n range: { start: number; end: number } | null,\n lineNumberOnly = false\n ): void {\n try {\n // notify: false renders the active-line highlight without firing the\n // host's onLineSelected callback. A caret or text selection in the editor\n // is not a gutter line selection, so it must not publish one.\n //\n // activeLineSide keeps the highlight on the additions pane, the side the\n // editor edits. Without it a split diff also highlights the matching\n // read-only deletions row on the left.\n //\n // lineNumberOnly marks just the caret line's gutter number while text is\n // selected, so the line keeps its highlighted number but drops the\n // full-line background in favor of the text selection.\n this.#fileInstance?.setSelectedLines(range, {\n notify: false,\n activeLineSide: 'additions',\n lineNumberOnly,\n });\n } catch {\n // InteractionManager.renderSelection can throw while editor DOM is updating.\n }\n }\n\n #updateSelections(selections: EditorSelection[]) {\n this.__postponeBackgroundTokenizeToNextFrame();\n\n this.#primaryCaretElement = undefined;\n this.#setSelectedLinesSafe(null);\n\n if (\n selections.length === 0 &&\n this.#matches === undefined &&\n this.#markerRenderer === undefined\n ) {\n this.#selections = undefined;\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements?.clear();\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n return;\n }\n\n const fragment = document.createDocumentFragment();\n const renderCtx = {\n fragment,\n elements: new Map<string, HTMLElement>(),\n };\n\n if (selections.length > 0) {\n const normalizedSelections = mergeOverlappingSelections(selections);\n const primarySelection = normalizedSelections.at(-1)!;\n this.#selections = normalizedSelections;\n // The caret line always keeps its highlighted gutter number. With a bare\n // caret it also gets the full-line background; once any selection spans\n // text, the background is dropped (lineNumberOnly) so the text selection\n // is the only line-level highlight.\n const hasNonEmptySelection = normalizedSelections.some(\n (selection) => !isCollapsedSelection(selection)\n );\n const caretLine = getCaretPosition(primarySelection).line + 1;\n this.#setSelectedLinesSafe(\n { start: caretLine, end: caretLine },\n hasNonEmptySelection\n );\n\n for (const selection of normalizedSelections) {\n if (!isCollapsedSelection(selection)) {\n this.#renderSelection(renderCtx, 'selection', selection);\n }\n this.#renderCaret(renderCtx, selection, selection === primarySelection);\n }\n }\n\n const textDocument = this.#textDocument;\n if (this.#matches !== undefined && textDocument !== undefined) {\n const primarySelection = this.#selections?.at(-1);\n const primaryStartOffset =\n primarySelection !== undefined\n ? textDocument.offsetAt(primarySelection.start)\n : -1;\n const primaryEndOffset =\n primarySelection !== undefined\n ? textDocument.offsetAt(primarySelection.end)\n : -1;\n for (const [startOffset, endOffset] of this.#matches) {\n const range: Range = {\n start: textDocument.positionAt(startOffset),\n end: textDocument.positionAt(endOffset),\n };\n const isFocused =\n primaryStartOffset === startOffset && primaryEndOffset === endOffset;\n this.#renderSelection(\n renderCtx,\n 'match',\n range,\n isFocused ? 'focus' : undefined\n );\n }\n }\n\n if (this.#markerRenderer !== undefined && textDocument !== undefined) {\n for (const marker of this.#markerRenderer.markers) {\n this.#renderSelection(\n renderCtx,\n 'marker',\n marker,\n markerSeverityDatasetKey(marker.severity)\n );\n }\n }\n\n this.#overlayElement?.appendChild(fragment);\n this.#overlayElements?.forEach((el) => el.remove());\n this.#overlayElements?.clear();\n this.#overlayElements = renderCtx.elements;\n\n this.#updateSelectionActionPopover();\n }\n\n #renderSelection(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n type: 'selection' | 'match' | 'marker',\n range: Range,\n extraDataset?: string\n ) {\n if (this.#textDocument === undefined) {\n return;\n }\n\n const { start, end } = range;\n for (let line = start.line; line <= end.line; line++) {\n if (!this.#isLineVisible(line)) {\n continue;\n }\n\n const isLastLine = line === end.line;\n const lineText = this.#textDocument.getLineText(line);\n const startChar = line === start.line ? start.character : 0;\n const endChar = isLastLine ? end.character : lineText.length;\n\n if (this.#isWrap) {\n const contentWidth = this.#getContentWidth();\n const textWidth =\n 2 * this.#metrics.ch + this.#metrics.measureTextWidth(lineText);\n if (textWidth > contentWidth) {\n this.#renderWrappedSelection(\n renderCtx,\n line,\n lineText,\n startChar,\n endChar,\n isLastLine,\n type,\n extraDataset\n );\n continue;\n }\n }\n\n let left = 0;\n let width = 0;\n let paddingEnd = 0;\n if (startChar === 0) {\n // gutter width + inline padding (1ch), plus the split-diff content\n // offset so a column-0 selection lines up with the content panel the\n // same way #getCharX (used for startChar > 0 and the caret) does.\n left =\n this.#getGutterWidth() +\n this.#metrics.ch +\n (this.#activeContentOffset?.left ?? 0);\n } else {\n left = this.#getCharX(line, startChar)[0];\n }\n if (!isLastLine && type === 'selection') {\n paddingEnd = this.#metrics.ch;\n }\n if (startChar === endChar) {\n width = paddingEnd;\n } else {\n width = this.#getCharX(line, endChar)[0] - left + paddingEnd;\n }\n this.#renderSelectionBlock(\n renderCtx,\n type,\n line,\n 0,\n left,\n width,\n extraDataset\n );\n }\n }\n\n // Render the selection on a wrapped logical line by splitting it into one\n // selection-range div per visual sub-line. For each wrap segment, we compute\n // the intersection with the line's selection range and render the slice in\n // segment-local coordinates so left/width line up with the visually wrapped\n // text. Zero-width slices that fall on intermediate segment boundaries are\n // skipped to avoid duplicate markers across consecutive visual lines.\n #renderWrappedSelection(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n line: number,\n lineText: string,\n startChar: number,\n endChar: number,\n isLastLine: boolean,\n type: 'selection' | 'match' | 'marker',\n extraDataset?: string\n ) {\n const wrapOffsets = this.#wrapLineText(line);\n const segmentCount = wrapOffsets.length - 1;\n // offsetLeft is the x of the content's left edge in overlay coordinates.\n // In a split diff with wrapping the content element is a grid item shifted\n // right of the deletion panel, so the same content offset that #getCharX\n // adds for the caret must be included here too; otherwise every wrapped\n // selection block is pulled left by the panel offset.\n const offsetLeft =\n this.#getGutterWidth() +\n this.#metrics.ch +\n (this.#activeContentOffset?.left ?? 0);\n\n for (let wrapLine = 0; wrapLine < segmentCount; wrapLine++) {\n const segmentStart = wrapOffsets[wrapLine];\n const segmentEnd = wrapOffsets[wrapLine + 1];\n const wrapStartChar = Math.max(startChar, segmentStart);\n const wrapEndChar = Math.min(endChar, segmentEnd);\n\n // Selection range doesn't reach this visual segment.\n if (wrapStartChar > wrapEndChar) {\n continue;\n }\n\n const segmentStartWidth = this.#segmentTextWidth(\n lineText,\n segmentStart,\n wrapStartChar\n );\n const segmentLeft = offsetLeft + segmentStartWidth;\n let paddingEnd = 0;\n if (\n !isLastLine &&\n wrapLine === segmentCount - 1 &&\n type === 'selection'\n ) {\n paddingEnd = this.#metrics.ch;\n }\n // Measure the selection width as the gap between two segment-relative\n // offsets so a tab inside the selection advances from its real column,\n // not from the start of the sliced selection text.\n const segmentWidth =\n wrapStartChar === wrapEndChar\n ? paddingEnd\n : this.#segmentTextWidth(lineText, segmentStart, wrapEndChar) -\n segmentStartWidth +\n paddingEnd;\n\n this.#renderSelectionBlock(\n renderCtx,\n type,\n line,\n wrapLine,\n segmentLeft,\n segmentWidth,\n extraDataset\n );\n }\n }\n\n // Pixel width of the text from a wrapped segment's start up to a character,\n // relative to the segment's left edge. Tabs advance from the segment start,\n // which sits on a tab stop, so tab stops line up with the rendered text.\n #segmentTextWidth(\n lineText: string,\n segmentStart: number,\n character: number\n ): number {\n if (character <= segmentStart) {\n return 0;\n }\n const segmentText = lineText.slice(segmentStart, character);\n const asciiColumns = getExpandedAsciiTextColumns(\n segmentText,\n this.#metrics.tabSize\n );\n return asciiColumns !== -1\n ? asciiColumns * this.#metrics.ch\n : this.#metrics.measureTextWidth(segmentText);\n }\n\n // Render one selection block for a single visual line.\n #renderSelectionBlock(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n previousSelectionRange?: {\n element: HTMLElement;\n line: number;\n wrapLine: number;\n left: number;\n width: number;\n };\n },\n type: 'selection' | 'match' | 'marker',\n line: number,\n wrapLine: number,\n left: number,\n width: number,\n extraDataset?: string\n ) {\n if (width === 0) {\n return;\n }\n\n const { ch, lineHeight } = this.#metrics;\n const y = this.#getLineY(line) + wrapLine * lineHeight;\n const cacheKey = `${type}-${line}/${wrapLine}-${left}-${width} ${extraDataset ?? ''}`;\n const overlayEls = this.#overlayElements;\n const rounded =\n (this.#options.roundedSelection ?? true) && type === 'selection';\n\n const addRoundedCorner = (\n line: number,\n wrapLine: number,\n left: number,\n radius: 'rtl' | 'rbl' | 'rbr'\n ) => {\n const top = this.#getLineY(line) + wrapLine * lineHeight;\n const css = `width:${ch}px;transform:translateX(${left}px) translateY(${top}px);`;\n const dataset = {\n selectionCorner: '',\n [radius]: '',\n };\n const cacheKeyPrefix = `${type}-block-${line}/${wrapLine}-${left}-1ch`;\n let cacheKey = cacheKeyPrefix + '-' + radius;\n if (radius === 'rbl') {\n const prevCornerKey = cacheKeyPrefix + '-rtl';\n const prevCorner = renderCtx.elements.get(prevCornerKey);\n if (prevCorner !== undefined) {\n prevCorner.remove();\n renderCtx.elements.delete(prevCornerKey);\n cacheKey += '-rtl';\n dataset.rtl = '';\n }\n }\n let cornerEl = renderCtx.elements.get(cacheKey);\n if (cornerEl !== undefined) {\n return;\n }\n if (overlayEls?.has(cacheKey) === true) {\n cornerEl = overlayEls.get(cacheKey)!;\n cornerEl.style.cssText = css;\n overlayEls.delete(cacheKey);\n } else {\n cornerEl = h(\n 'div',\n {\n dataset: 'selectionRange',\n style: { cssText: css },\n children: [\n h('div', {\n dataset: dataset,\n }),\n ],\n },\n renderCtx.fragment\n );\n }\n renderCtx.elements.set(cacheKey, cornerEl);\n };\n const addRadiusStyle = (element: HTMLElement) => {\n const end = left + width;\n const dataset = element.dataset;\n const previousSelectionRange = renderCtx.previousSelectionRange;\n if (\n previousSelectionRange === undefined ||\n previousSelectionRange.line !== line ||\n previousSelectionRange.wrapLine !== wrapLine\n ) {\n renderCtx.previousSelectionRange = {\n element,\n line,\n wrapLine,\n left,\n width,\n };\n }\n if (\n previousSelectionRange === undefined ||\n end <= previousSelectionRange.left\n ) {\n ['rtl', 'rtr', 'rbl', 'rbr'].forEach((key) => {\n dataset[key] = '';\n });\n } else {\n const prevLine = previousSelectionRange.line;\n const prevWrapLine = previousSelectionRange.wrapLine;\n const prevLeft = previousSelectionRange.left;\n const prevDataset = previousSelectionRange.element.dataset;\n const prevEnd = prevLeft + previousSelectionRange.width;\n if (prevLeft > left) {\n addRoundedCorner(prevLine, prevWrapLine, prevLeft - ch, 'rbr');\n }\n delete prevDataset.rbl;\n delete dataset.rtl;\n delete dataset.rtr;\n if (end >= prevEnd) {\n delete prevDataset.rbr;\n }\n if (end > prevEnd) {\n addRoundedCorner(prevLine, prevWrapLine, prevEnd, 'rbl');\n dataset.rtr = '';\n }\n if (end < prevEnd) {\n addRoundedCorner(line, wrapLine, end, 'rtl');\n }\n if (left < prevLeft) {\n dataset.rtl = '';\n }\n dataset.rbl = '';\n dataset.rbr = '';\n }\n };\n\n let rangeEl = renderCtx.elements.get(cacheKey);\n if (rangeEl !== undefined) {\n if (rounded) {\n addRadiusStyle(rangeEl);\n }\n return;\n }\n\n if (overlayEls?.has(cacheKey) === true) {\n rangeEl = overlayEls.get(cacheKey)!;\n overlayEls.delete(cacheKey);\n } else {\n rangeEl = h(\n 'div',\n {\n dataset: extraDataset\n ? [type + 'Range', extraDataset]\n : type + 'Range',\n },\n renderCtx.fragment\n );\n }\n\n rangeEl.style.width = `${width}px`;\n rangeEl.style.transform = `translateX(${left}px) translateY(${y}px)`;\n if (rounded) {\n addRadiusStyle(rangeEl);\n }\n renderCtx.elements.set(cacheKey, rangeEl);\n }\n\n #renderCaret(\n renderCtx: {\n fragment: DocumentFragment;\n elements: Map<string, HTMLElement>;\n },\n selection: EditorSelection,\n isPrimary: boolean\n ) {\n const { line, character } = getCaretPosition(selection);\n if (!this.#isLineVisible(line)) {\n return;\n }\n const [left, wrapLine] = this.#getCharX(line, character);\n const cacheKey = 'caret-' + line + '/' + wrapLine + ':' + character;\n if (renderCtx.elements.has(cacheKey)) {\n return;\n }\n\n const x = left - 1;\n const y = this.#getLineY(line) + wrapLine * this.#metrics.lineHeight;\n\n let caretEl: HTMLElement;\n if (this.#overlayElements?.has(cacheKey) === true) {\n caretEl = this.#overlayElements.get(cacheKey)!;\n this.#overlayElements.delete(cacheKey);\n } else {\n caretEl = h(\n 'div',\n {\n dataset: 'caret',\n },\n renderCtx.fragment\n );\n }\n caretEl.style.transform = `translateX(${x}px) translateY(${y}px)`;\n renderCtx.elements.set(cacheKey, caretEl);\n if (isPrimary) {\n caretEl.style.scrollMargin = this.#getScrollMargin();\n this.#primaryCaretElement = caretEl;\n }\n }\n\n // Keeps the floating selection-action popover in sync with the current\n // selection. Called at the end of every overlay render so the popover appears\n // as soon as a ranged selection settles, follows it while it stays open, and\n // tears down when the selection collapses, the option is off, or the anchor\n // line scrolls out of view. Creation is suppressed while the mouse is down so\n // the popover doesn't flicker under the cursor mid-drag; the pointerup handler\n // re-runs this once the drag ends.\n #updateSelectionActionPopover(): void {\n const primarySelection = this.#selections?.at(-1);\n const overlayElement = this.#overlayElement;\n const textDocument = this.#textDocument;\n const renderSelectionAction = this.#options.renderSelectionAction;\n if (\n this.#options.enabledSelectionAction !== true ||\n renderSelectionAction === undefined ||\n primarySelection === undefined ||\n isCollapsedSelection(primarySelection) ||\n this.#isContentMouseDown ||\n overlayElement === undefined ||\n textDocument === undefined\n ) {\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n return;\n }\n\n const head = getCaretPosition(primarySelection);\n if (!this.#isLineVisible(head.line)) {\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n return;\n }\n\n if (this.#selectionAction === undefined) {\n // The popover element is reused while a selection stays open, so its\n // action handlers read the live primary selection rather than the\n // snapshot taken at creation time (extending the selection by keyboard\n // would otherwise leave them acting on the original range). A fresh drag\n // tears the popover down (see #isContentMouseDown above) and pointerup\n // recreates it, so the reuse only spans keyboard-driven selection changes.\n const getActiveSelection = (): EditorSelection =>\n this.#selections?.at(-1) ?? primarySelection;\n const selectionActionElement = renderSelectionAction({\n textDocument,\n // Live getter so consumers reading `selection` always see the current\n // range, matching getSelectionText/replaceSelectionText below.\n get selection(): EditorSelection {\n return getActiveSelection();\n },\n applyEdits: (edits: TextEdit[]) => this.applyEdits(edits, true),\n getSelectionText: () =>\n this.#textDocument?.getText(getActiveSelection()) ?? '',\n replaceSelectionText: (text: string) => {\n this.#replaceSelectionText(text, [getActiveSelection()]);\n },\n close: () => {\n this.#selectionAction?.cleanup();\n this.#selectionAction = undefined;\n this.#scrollToPrimaryCaret();\n },\n });\n this.#selectionAction = new SelectionActionWidget(\n head.line,\n selectionActionElement,\n overlayElement\n );\n }\n\n // Anchor just below the selection's head line, mirroring the marker hover\n // popover's geometry.\n const [left, wrapLine] = this.#getCharX(head.line, head.character);\n const lineHeight = this.#metrics.lineHeight;\n const top = this.#getLineY(head.line) + wrapLine * lineHeight + lineHeight;\n this.#selectionAction.line = head.line;\n this.#selectionAction.reposition(left, top, this.#getGutterWidth());\n }\n\n // Opens the search panel in the requested mode. If a panel is already open,\n // it switches that panel's mode in place (preserving the current query)\n // rather than recreating it.\n #openSearchPanel(mode: SearchPanelMode) {\n if (this.#searchPanel !== undefined) {\n this.#searchPanel.setMode(mode);\n return;\n }\n this.#renderSearchPanel(mode);\n }\n\n // TODO(@ije): render search highlight\n #renderSearchPanel(mode: SearchPanelMode) {\n // cleanup the existing search panel\n this.#searchPanel?.cleanup();\n\n const textDocument = this.#textDocument;\n const preElement =\n this.#fileContainer?.shadowRoot?.querySelector<HTMLElement>('pre');\n const selections = this.#selections;\n if (textDocument === undefined || preElement == null) {\n return;\n }\n\n let defaultQuery = '';\n let initialMatch: [number, number] | undefined = undefined;\n\n if (selections !== undefined && selections.length > 0) {\n let primarySelection = selections.at(-1)!;\n if (isCollapsedSelection(primarySelection)) {\n primarySelection = expandCollapsedSelectionToWord(\n textDocument,\n primarySelection\n );\n this.#updateSelections([...selections.slice(0, -1), primarySelection]);\n const selectionText = textDocument.getText(primarySelection);\n if (selectionText !== '' && !selectionText.includes('\\n')) {\n defaultQuery = selectionText;\n initialMatch = [\n textDocument.offsetAt(primarySelection.start),\n textDocument.offsetAt(primarySelection.end),\n ];\n }\n }\n }\n\n const scrollToMatch = (\n [startOffset, endOffset]: MatchRange,\n retainFocus: boolean\n ) => {\n const nextSelection = createSelectionFromAnchorAndFocusOffsets(\n textDocument,\n startOffset,\n endOffset\n );\n this.#updateSelections([nextSelection]);\n this.#scrollToPrimaryCaret(true); // scroll to the primary caret and don't focus\n this.#retainSearchPanelFocus = retainFocus;\n };\n\n const searchPanel = new SearchPanelWidget({\n textDocument,\n containerElement: preElement,\n defaultQuery,\n mode,\n initialMatch,\n scrollToMatch,\n applyReplace: (edits: ResolvedTextEdit[]) => {\n if (edits.length === 0) {\n return;\n }\n const change = textDocument.applyEdits(\n edits.map((edit) => ({\n range: {\n start: textDocument.positionAt(edit.start),\n end: textDocument.positionAt(edit.end),\n },\n newText: edit.text,\n })),\n true,\n this.#selections\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n undefined,\n this.#applyChangeToLineAnnotations(change),\n { skipSearchRefresh: true }\n );\n }\n },\n onUpdate: (\n allMatches: MatchRange[],\n options?: { syncSelection?: boolean }\n ): MatchRange | undefined => {\n if (allMatches.length === 0) {\n this.#matches = undefined;\n this.#updateSelections(this.#selections ?? []);\n return;\n }\n\n this.#matches = allMatches;\n if (options?.syncSelection === false) {\n this.#updateSelections(this.#selections ?? []);\n const primarySelection = this.#selections?.at(-1);\n if (primarySelection !== undefined) {\n const startOffset = textDocument.offsetAt(primarySelection.start);\n const endOffset = textDocument.offsetAt(primarySelection.end);\n for (const match of allMatches) {\n if (match[0] === startOffset && match[1] === endOffset) {\n return match;\n }\n }\n }\n return undefined;\n }\n\n const primarySelection = this.#selections?.at(-1);\n let searchOffset = 0;\n let nextMatch: MatchRange | undefined;\n if (primarySelection !== undefined) {\n searchOffset = textDocument.offsetAt(primarySelection.start);\n }\n for (const m of allMatches) {\n if (m[0] >= searchOffset) {\n nextMatch = m;\n break;\n }\n }\n if (nextMatch !== undefined) {\n scrollToMatch(nextMatch, true);\n } else {\n this.#updateSelections(this.#selections ?? []);\n }\n return nextMatch;\n },\n onClose: () => {\n this.#searchPanel = undefined;\n this.#retainSearchPanelFocus = false;\n this.#matches = undefined;\n this.#updateSelections(this.#selections ?? []);\n },\n });\n\n this.#searchPanel = searchPanel;\n this.#retainSearchPanelFocus = false;\n }\n\n #getSelectionText() {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (textDocument === undefined || selections === undefined) {\n return '';\n }\n return getSelectionText(textDocument, selections);\n }\n\n #cutSelectionText(): string {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (\n textDocument === undefined ||\n selections === undefined ||\n selections.length === 0\n ) {\n return '';\n }\n\n if (selections.some((selection) => isCollapsedSelection(selection))) {\n const cut = resolveSelectionCut(textDocument, selections);\n this.#applySelectionCutEdits(cut.edits, cut.nextSelectionOffsets);\n return cut.text;\n }\n\n const text = getSelectionText(textDocument, selections);\n this.#replaceSelectionText('', undefined, true);\n return text;\n }\n\n #applySelectionCutEdits(\n edits: ResolvedTextEdit[],\n nextSelectionOffsets: number[]\n ): void {\n const textDocument = this.#textDocument;\n const selections = this.#selections;\n if (\n textDocument === undefined ||\n selections === undefined ||\n edits.length === 0\n ) {\n return;\n }\n\n const change = textDocument.applyResolvedEdits(\n edits,\n true,\n selections,\n undefined,\n true\n );\n if (change === undefined) {\n return;\n }\n\n const nextSelections = nextSelectionOffsets.map<EditorSelection>(\n (offset) => {\n const caret = textDocument.positionAt(offset);\n return {\n start: caret,\n end: caret,\n direction: DirectionNone,\n };\n }\n );\n textDocument.setLastUndoSelectionsAfter(nextSelections);\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n\n // replace the selection text\n #replaceSelectionText(\n text: string | string[],\n selections = this.#selections,\n undoBoundary = false\n ) {\n if (selections === undefined) {\n return;\n }\n const textDocument = this.#textDocument;\n const primarySelection = selections.at(-1);\n if (textDocument === undefined || primarySelection === undefined) {\n return;\n }\n const { nextSelections, change } =\n Array.isArray(text) && text.length === selections.length\n ? applyTextReplaceToSelections<LAnnotation>(\n textDocument,\n selections,\n text,\n this.#lineAnnotations,\n undoBoundary\n )\n : applyTextChangeToSelections<LAnnotation>(\n textDocument,\n selections,\n {\n start: textDocument.offsetAt(primarySelection.start),\n end: textDocument.offsetAt(primarySelection.end),\n text: Array.isArray(text) ? text.join('\\n') : text,\n },\n this.#lineAnnotations,\n undefined,\n undoBoundary\n );\n\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteSelectionText(forward: boolean = false) {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n\n const { nextSelections, change } =\n applyDeleteCharacterToSelections<LAnnotation>(\n textDocument,\n selections,\n forward,\n this.#lineAnnotations,\n this.#metrics.tabSize\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteSoftLineBackward() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const getSoftLineStart = this.#isWrap\n ? (line: number, character: number) => {\n const wrapOffsets = this.#wrapLineText(line);\n for (let w = 0; w + 1 < wrapOffsets.length; w++) {\n const segmentStart = wrapOffsets[w];\n const segmentEnd = wrapOffsets[w + 1];\n if (character >= segmentStart && character <= segmentEnd) {\n return segmentStart;\n }\n }\n return 0;\n }\n : undefined;\n const { nextSelections, change } =\n applyDeleteSoftLineBackwardToSelections<LAnnotation>(\n textDocument,\n selections,\n getSoftLineStart,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteWordBackward() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } =\n applyDeleteWordBackwardToSelections<LAnnotation>(\n textDocument,\n selections,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #deleteHardLineForward() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } =\n applyDeleteHardLineForwardToSelections<LAnnotation>(\n textDocument,\n selections,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #insertTranspose() {\n const selections = this.#selections;\n const textDocument = this.#textDocument;\n if (selections === undefined || textDocument === undefined) {\n return;\n }\n const { nextSelections, change } = applyTransposeToSelections<LAnnotation>(\n textDocument,\n selections,\n this.#lineAnnotations\n );\n if (change !== undefined) {\n this.#applyChange(\n change,\n nextSelections,\n this.#applyChangeToLineAnnotations(change)\n );\n }\n }\n\n #getFileRef(): FileContents | undefined {\n const fileInfo = this.#fileInfo;\n const textDocument = this.#textDocument;\n if (fileInfo === undefined || textDocument === undefined) {\n return undefined;\n }\n const file = { ...fileInfo }; // copy\n Object.defineProperty(file, 'contents', {\n enumerable: true,\n get: () => textDocument.getText(),\n });\n return file as FileContents;\n }\n\n #applyChange(\n change: TextDocumentChange,\n selections?: EditorSelection[],\n newLineAnnotations?: DiffLineAnnotation<LAnnotation>[],\n options?: { skipSearchRefresh?: boolean; skipFocus?: boolean }\n ) {\n const fileRef = this.#getFileRef();\n const onChange = this.#options.onChange;\n if (fileRef !== undefined && onChange !== undefined) {\n onChange(fileRef, newLineAnnotations ?? this.#lineAnnotations);\n }\n\n // Invalidate layout caches touched by the edit. Clear cached line Y\n // positions from startLine onward when either:\n // - the line count changed (inserts/deletes renumber every later line), or\n // - wrap is on, where editing a line can add or remove a wrapped row and\n // shift the Y of every line after it even though the line count is the\n // same.\n if (change.lineDelta !== 0 || this.#isWrap) {\n for (const line of this.#lineYCache.keys()) {\n if (line >= change.startLine) {\n this.#lineYCache.delete(line);\n }\n }\n }\n if (this.#isWrap) {\n for (const line of this.#wrapLineOffsetsCache.keys()) {\n if (line >= change.startLine) {\n this.#wrapLineOffsetsCache.delete(line);\n }\n }\n }\n this.#lastAccessedCharX = undefined;\n\n let renderRange = this.#renderRange;\n let shouldUpdateBuffer: boolean | undefined;\n if (\n renderRange !== undefined &&\n selections !== undefined &&\n selections.length > 0\n ) {\n const primarySelection = selections.at(-1)!;\n const renderRangeEndLine =\n renderRange.startingLine + renderRange.totalLines;\n // When an edit moves the caret to or past the last rendered line — typing\n // Enter at the window's bottom edge, or pasting a few lines there — widen\n // the render range so every new line up to the caret gets a row when\n // #rerender runs below. The widened range is also written back to\n // #renderRange: the next edit reads renderRangeEndLine from it, and\n // #renderCaret/#isLineVisible read it to decide whether to draw the caret.\n // Without persisting, the end line stays stale, a following edit is\n // misclassified as \"past the window\", and its just-typed line is left\n // unrendered until the next scroll re-syncs the range. Only edits that\n // carry a caret reach here (the block is guarded on `selections` above), so\n // a bare programmatic applyEdits with no active selection does not widen.\n //\n // Cap the widening at a multiple of the bounded window the virtualizer\n // last synced. A large insert at the caret — most often a big multi-line\n // paste, or a scripted set-selection-then-edit at scale — can drop the\n // caret far below the window; widening to reach it would make #rerender\n // build a row per inserted line synchronously, defeating virtualization.\n // Past the cap, keep the bounded window and only recompute the buffer\n // spacer — the scroll that follows a focused edit (or the next user scroll\n // when unfocused) renders the far region with a bounded window.\n if (primarySelection.end.line >= renderRangeEndLine) {\n const widenedTotalLines =\n primarySelection.end.line - renderRange.startingLine + 1;\n const maxWidenLines =\n this.#viewportWindowLines === undefined ||\n this.#viewportWindowLines === Infinity\n ? Infinity\n : this.#viewportWindowLines * MAX_EDIT_WIDEN_WINDOW_MULTIPLE;\n // Only widen when the edit actually reaches the rendered window — its\n // dirty lines start at or before the window end. #rerender materializes\n // rows from change.startLine onward, so widening for an edit that starts\n // entirely below the window (e.g. setSelections to an offscreen line\n // then applyEdits before the virtualizer re-syncs) would leave the\n // rows between the window and the edit unbuilt while #isLineVisible\n // reports them visible, mispositioning the new rows and caret until the\n // next scroll.\n if (\n change.startLine <= renderRangeEndLine &&\n widenedTotalLines <= maxWidenLines\n ) {\n if (primarySelection.end.line > renderRangeEndLine) {\n // The line count grew below the window, so the buffer spacer must be\n // recomputed (preserves the prior behavior for this case).\n shouldUpdateBuffer = true;\n }\n renderRange = { ...renderRange, totalLines: widenedTotalLines };\n this.#renderRange = renderRange;\n } else {\n // The edit is past the cap, or starts below the rendered window: keep\n // the bounded window and only recompute the buffer; the scroll that\n // follows a focused edit (or the next user scroll) renders the far\n // region.\n shouldUpdateBuffer = true;\n }\n }\n }\n this.#rerender(change, newLineAnnotations, renderRange, shouldUpdateBuffer);\n\n if (\n options?.skipSearchRefresh !== true &&\n this.#searchPanel !== undefined &&\n this.#matches !== undefined\n ) {\n this.#searchPanel.updateMatches({ syncSelection: false });\n }\n\n if (selections !== undefined) {\n // Always re-render the selection range and caret overlay so editor state\n // stays in sync. When skipFocus is set (a programmatic edit on an editor\n // that is not focused) we stop here: focusing or scrolling would pull the\n // caret and viewport toward an editor the user is not interacting with.\n this.#updateSelections(selections);\n if (options?.skipFocus !== true) {\n // focus to update the native window selection, and scroll to the caret\n // to mock the 'contenteditable' behavior\n if (this.#primaryCaretElement !== undefined) {\n this.#primaryCaretElement.scrollIntoView({\n block: 'nearest',\n inline: 'nearest',\n });\n } else if (selections.length > 0) {\n const pos = getCaretPosition(selections.at(-1)!);\n this.#scrollToLine(pos.line, pos.character);\n }\n this.focus({ preventScroll: true });\n }\n }\n }\n\n #applyChangeToLineAnnotations(\n change: TextDocumentChange\n ): DiffLineAnnotation<LAnnotation>[] | undefined {\n if (this.#lineAnnotations !== undefined) {\n const nextLineAnnotations =\n applyDocumentChangeToLineAnnotations<LAnnotation>(\n change,\n this.#lineAnnotations\n );\n if (nextLineAnnotations !== undefined) {\n this.#textDocument?.setLastUndoLineAnnotations(\n this.#lineAnnotations,\n nextLineAnnotations\n );\n return nextLineAnnotations;\n }\n }\n return undefined;\n }\n\n #getLineElement(line: number): HTMLElement | undefined {\n const lastAccessed = this.#lastAccessedLineElement;\n if (lastAccessed !== undefined && lastAccessed[0] === line) {\n return lastAccessed[1];\n }\n\n const contentElement = this.#contentElement;\n if (contentElement === undefined) {\n return undefined;\n }\n\n let lineElement: HTMLElement | null = null;\n\n // check if the line is within the render range (fast)\n if (this.#renderRange !== undefined) {\n const { startingLine } = this.#renderRange;\n const { children } = contentElement;\n for (let i = line - startingLine; i <= children.length; i++) {\n const child = children[i] as HTMLElement | undefined;\n if (child === undefined) {\n break;\n }\n const lineNumber = getLineNumberAttr(child);\n const lineType = child.dataset.lineType;\n if (\n lineNumber !== undefined &&\n lineNumber === line + 1 &&\n lineType !== undefined &&\n isLineEditable(lineType)\n ) {\n lineElement = child;\n break;\n }\n }\n }\n\n // fallback to query selector\n lineElement ??= contentElement.querySelector<HTMLElement>(\n `[data-line=\"${line + 1}\"]` +\n (this.#diffSyle === 'unified'\n ? ':not([data-line-type=\"change-deletion\"])'\n : '')\n );\n\n if (lineElement !== null) {\n if (lastAccessed !== undefined) {\n lastAccessed[0] = line;\n lastAccessed[1] = lineElement;\n } else {\n this.#lastAccessedLineElement = [line, lineElement];\n }\n return lineElement;\n }\n return undefined;\n }\n\n #getGutterWidth(): number {\n if (this.#gutterElement === undefined) {\n return 0;\n }\n\n if (this.#gutterWidthCache === undefined) {\n const diffsColumnNumberWidth =\n this.#contentElement?.parentElement?.style.getPropertyValue(\n '--diffs-column-number-width'\n );\n if (\n diffsColumnNumberWidth !== undefined &&\n diffsColumnNumberWidth.length > 2 &&\n diffsColumnNumberWidth.endsWith('px')\n ) {\n this.#gutterWidthCache = parseInt(\n diffsColumnNumberWidth.slice(0, -2),\n 10\n );\n } else {\n this.#gutterWidthCache = this.#gutterElement.offsetWidth;\n }\n }\n\n return this.#gutterWidthCache;\n }\n\n #getContentWidth(): number {\n if (this.#contentElement === undefined) {\n return 0;\n }\n\n if (this.#contentWidthCache === undefined) {\n const diffsColumnContentWidth =\n this.#contentElement.parentElement?.style.getPropertyValue(\n '--diffs-column-content-width'\n );\n if (\n diffsColumnContentWidth !== undefined &&\n diffsColumnContentWidth.length > 2 &&\n diffsColumnContentWidth.endsWith('px')\n ) {\n this.#contentWidthCache = parseFloat(\n diffsColumnContentWidth.slice(0, -2)\n );\n } else {\n this.#contentWidthCache = this.#contentElement.offsetWidth;\n }\n }\n return this.#contentWidthCache;\n }\n\n // get line top(y-coordinate) position\n #getLineY(line: number) {\n const cachedY = this.#lineYCache.get(line);\n if (cachedY !== undefined) {\n return cachedY;\n }\n\n const lineElement = this.#getLineElement(line);\n if (lineElement === undefined) {\n return -1;\n }\n\n // cold(slow) path: measure line top position from DOM (will cause reflow)\n let y = lineElement.offsetTop + this.#metrics.paddingTop;\n y += this.#activeContentOffset?.top ?? 0;\n this.#lineYCache.set(line, y);\n return y;\n }\n\n // Return the visual position for a character. Wrapped lines include the\n // visual line index so carets can be placed on the correct row.\n #getCharX(line: number, char: number): [x: number, wrapLine: number] {\n if (\n this.#lastAccessedCharX !== undefined &&\n this.#lastAccessedCharX[0] === line &&\n this.#lastAccessedCharX[1] === char\n ) {\n return [this.#lastAccessedCharX[2], this.#lastAccessedCharX[3]];\n }\n\n const lineText = this.#textDocument?.getLineText(line);\n const offsetLeft = this.#getGutterWidth() + this.#metrics.ch; // gutter width + inline padding (1ch)\n if (lineText === undefined || lineText.length === 0 || char <= 0) {\n return [offsetLeft + (this.#activeContentOffset?.left ?? 0), 0];\n }\n\n const boundedCharacter = snapTextOffsetToUnicodeBoundary(\n lineText,\n Math.min(char, lineText.length)\n );\n const textBeforeCharacter = lineText.slice(0, boundedCharacter);\n const asciiColumns = getExpandedAsciiTextColumns(\n textBeforeCharacter,\n this.#metrics.tabSize\n );\n\n let left = 0;\n let wrapLine = 0;\n if (asciiColumns !== -1) {\n left = offsetLeft + asciiColumns * this.#metrics.ch;\n } else {\n left = offsetLeft + this.#metrics.measureTextWidth(textBeforeCharacter);\n }\n\n if (this.#isWrap) {\n const contentWidth = this.#getContentWidth();\n const textWidth =\n 2 * this.#metrics.ch + this.#metrics.measureTextWidth(lineText);\n if (textWidth > contentWidth) {\n const wrapOffsets = this.#wrapLineText(line);\n for (let w = 0; w + 1 < wrapOffsets.length; w++) {\n const segmentStart = wrapOffsets[w];\n const segmentEnd = wrapOffsets[w + 1];\n if (boundedCharacter <= segmentEnd) {\n wrapLine = w;\n const prefixInSegment = lineText.slice(\n segmentStart,\n boundedCharacter\n );\n const segmentAsciiColumns = getExpandedAsciiTextColumns(\n prefixInSegment,\n this.#metrics.tabSize\n );\n if (segmentAsciiColumns !== -1) {\n left = offsetLeft + segmentAsciiColumns * this.#metrics.ch;\n } else {\n left =\n offsetLeft + this.#metrics.measureTextWidth(prefixInSegment);\n }\n break;\n }\n }\n }\n left += this.#activeContentOffset?.left ?? 0;\n }\n\n if (this.#lastAccessedCharX !== undefined) {\n this.#lastAccessedCharX[0] = line;\n this.#lastAccessedCharX[1] = char;\n this.#lastAccessedCharX[2] = left;\n this.#lastAccessedCharX[3] = wrapLine;\n } else {\n this.#lastAccessedCharX = [line, char, left, wrapLine];\n }\n\n return [left, wrapLine];\n }\n\n // Compute how a logical line of text is broken into visual lines when line\n // wrapping is enabled.\n #wrapLineText(line: number): Uint32Array {\n const cachedOffsets = this.#wrapLineOffsetsCache.get(line);\n if (cachedOffsets !== undefined) {\n return cachedOffsets;\n }\n\n const lineText = this.#textDocument?.getLineText(line);\n if (lineText === undefined || lineText.length === 0) {\n const offsets = new Uint32Array([0]);\n this.#wrapLineOffsetsCache.set(line, offsets);\n return offsets;\n }\n\n const div = h(\n 'div',\n {\n style: {\n position: 'absolute',\n top: '0',\n left: '0',\n width: '100%',\n boxSizing: 'border-box',\n visibility: 'hidden',\n pointerEvents: 'none',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n font: 'inherit',\n paddingInline: '1ch',\n tabSize: this.#metrics.tabSize.toString(),\n },\n textContent: lineText,\n },\n this.#contentElement\n );\n const textNode = div.firstChild as Text;\n const range = document.createRange();\n const starts: number[] = [];\n\n try {\n const unicodeOffsets = getUnicodeMeasurementOffsets(lineText);\n const wrapLineStartLeft =\n div.getBoundingClientRect().left + this.#metrics.ch;\n\n let previousOffset = 0;\n let lastTop = Number.NEGATIVE_INFINITY;\n\n for (let i = 0, offsetIndex = 0; i < lineText.length; ) {\n const nextOffset =\n unicodeOffsets === undefined\n ? i + 1\n : unicodeOffsets[offsetIndex + 1];\n range.setStart(textNode, i);\n range.setEnd(textNode, nextOffset);\n\n // A new visual line starts whenever the character's top edge moves\n // below the previous character's top edge.\n const { left, top } = range.getBoundingClientRect();\n if (top > lastTop) {\n // Safari can report the first range on a wrapped visual line as\n // starting one character past the visual line start. Use the previous\n // offset so segment-local caret math begins at the actual wrap point.\n const startsPastLineStart =\n isSafari() &&\n starts.length > 0 &&\n left - wrapLineStartLeft > this.#metrics.ch / 2;\n starts.push(startsPastLineStart ? previousOffset : i);\n lastTop = top;\n }\n previousOffset = i;\n i = nextOffset;\n offsetIndex++;\n }\n\n const offsets = new Uint32Array(starts.length + 1);\n for (let i = 0; i < starts.length; i++) {\n offsets[i] = starts[i]!;\n }\n offsets[starts.length] = lineText.length;\n this.#wrapLineOffsetsCache.set(line, offsets);\n return offsets;\n } finally {\n div.remove();\n }\n }\n\n // check if the web selection belongs to editor\n #rangeBelongsToEditor({ startContainer, endContainer }: StaticRange) {\n const contentEl = this.#contentElement;\n if (contentEl === undefined) {\n return false;\n }\n return (\n contentEl.contains(startContainer) && contentEl.contains(endContainer)\n );\n }\n\n // Check whether a line is visible in the currently rendered line window.\n #isLineVisible(line: number): boolean {\n const lineCount = this.#textDocument?.lineCount ?? 0;\n if (line < 0 || line >= lineCount) {\n return false;\n }\n if (this.#renderRange === undefined) {\n return true;\n }\n const { startingLine, totalLines } = this.#renderRange;\n if (line < startingLine) {\n return false;\n }\n if (totalLines === Infinity) {\n return true;\n }\n return line < startingLine + totalLines;\n }\n}\n"],"mappings":"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"}