@nocturnium/svelte-ide 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -0
  3. package/dist/components/agents/AgentActivityPanel.svelte +565 -0
  4. package/dist/components/agents/AgentActivityPanel.svelte.d.ts +24 -0
  5. package/dist/components/agents/AgentAvatar.svelte +417 -0
  6. package/dist/components/agents/AgentAvatar.svelte.d.ts +23 -0
  7. package/dist/components/agents/AgentCursor.svelte +224 -0
  8. package/dist/components/agents/AgentCursor.svelte.d.ts +35 -0
  9. package/dist/components/agents/AgentPresenceBar.svelte +261 -0
  10. package/dist/components/agents/AgentPresenceBar.svelte.d.ts +20 -0
  11. package/dist/components/agents/index.d.ts +4 -0
  12. package/dist/components/agents/index.js +5 -0
  13. package/dist/components/ai/AIConversationList.svelte +524 -0
  14. package/dist/components/ai/AIConversationList.svelte.d.ts +17 -0
  15. package/dist/components/ai/AIEditPreview.svelte +132 -0
  16. package/dist/components/ai/AIEditPreview.svelte.d.ts +8 -0
  17. package/dist/components/ai/AIInlineEdit.svelte +155 -0
  18. package/dist/components/ai/AIInlineEdit.svelte.d.ts +10 -0
  19. package/dist/components/ai/AIMessage.svelte +239 -0
  20. package/dist/components/ai/AIMessage.svelte.d.ts +13 -0
  21. package/dist/components/ai/AIMessageActions.svelte +176 -0
  22. package/dist/components/ai/AIMessageActions.svelte.d.ts +12 -0
  23. package/dist/components/ai/AIMessageContent.svelte +355 -0
  24. package/dist/components/ai/AIMessageContent.svelte.d.ts +7 -0
  25. package/dist/components/ai/AIPanel.svelte +561 -0
  26. package/dist/components/ai/AIPanel.svelte.d.ts +7 -0
  27. package/dist/components/ai/AISuggestionWidget.svelte +132 -0
  28. package/dist/components/ai/AISuggestionWidget.svelte.d.ts +10 -0
  29. package/dist/components/ai/AIToolCallDisplay.svelte +317 -0
  30. package/dist/components/ai/AIToolCallDisplay.svelte.d.ts +12 -0
  31. package/dist/components/ai/index.d.ts +9 -0
  32. package/dist/components/ai/index.js +10 -0
  33. package/dist/components/core/Avatar.svelte +110 -0
  34. package/dist/components/core/Avatar.svelte.d.ts +12 -0
  35. package/dist/components/core/Badge.svelte +98 -0
  36. package/dist/components/core/Badge.svelte.d.ts +11 -0
  37. package/dist/components/core/Button.svelte +175 -0
  38. package/dist/components/core/Button.svelte.d.ts +18 -0
  39. package/dist/components/core/ConnectionStatus.svelte +294 -0
  40. package/dist/components/core/ConnectionStatus.svelte.d.ts +20 -0
  41. package/dist/components/core/ContextMenu.svelte +176 -0
  42. package/dist/components/core/ContextMenu.svelte.d.ts +19 -0
  43. package/dist/components/core/ErrorBoundary.svelte +277 -0
  44. package/dist/components/core/ErrorBoundary.svelte.d.ts +23 -0
  45. package/dist/components/core/Icon.svelte +107 -0
  46. package/dist/components/core/Icon.svelte.d.ts +8 -0
  47. package/dist/components/core/Input.svelte +138 -0
  48. package/dist/components/core/Input.svelte.d.ts +20 -0
  49. package/dist/components/core/Kbd.svelte +34 -0
  50. package/dist/components/core/Kbd.svelte.d.ts +7 -0
  51. package/dist/components/core/ResizeHandle.svelte +200 -0
  52. package/dist/components/core/ResizeHandle.svelte.d.ts +23 -0
  53. package/dist/components/core/Spinner.svelte +35 -0
  54. package/dist/components/core/Spinner.svelte.d.ts +7 -0
  55. package/dist/components/core/Textarea.svelte +112 -0
  56. package/dist/components/core/Textarea.svelte.d.ts +18 -0
  57. package/dist/components/core/Tooltip.svelte +103 -0
  58. package/dist/components/core/Tooltip.svelte.d.ts +11 -0
  59. package/dist/components/core/index.d.ts +13 -0
  60. package/dist/components/core/index.js +14 -0
  61. package/dist/components/editor/AIFocusLayer.svelte +430 -0
  62. package/dist/components/editor/AIFocusLayer.svelte.d.ts +32 -0
  63. package/dist/components/editor/Breadcrumbs.svelte +435 -0
  64. package/dist/components/editor/Breadcrumbs.svelte.d.ts +33 -0
  65. package/dist/components/editor/BreakpointLayer.svelte +642 -0
  66. package/dist/components/editor/BreakpointLayer.svelte.d.ts +20 -0
  67. package/dist/components/editor/CognitiveLoadMeter.svelte +324 -0
  68. package/dist/components/editor/CognitiveLoadMeter.svelte.d.ts +18 -0
  69. package/dist/components/editor/CollaborativeEditor.svelte +218 -0
  70. package/dist/components/editor/CollaborativeEditor.svelte.d.ts +32 -0
  71. package/dist/components/editor/CommandPalette.svelte +434 -0
  72. package/dist/components/editor/CommandPalette.svelte.d.ts +11 -0
  73. package/dist/components/editor/ComplexityLayer.svelte +293 -0
  74. package/dist/components/editor/ComplexityLayer.svelte.d.ts +23 -0
  75. package/dist/components/editor/ConflictZoneLayer.svelte +441 -0
  76. package/dist/components/editor/ConflictZoneLayer.svelte.d.ts +25 -0
  77. package/dist/components/editor/ContextLens.svelte +262 -0
  78. package/dist/components/editor/ContextLens.svelte.d.ts +27 -0
  79. package/dist/components/editor/CustomEditor.svelte +1242 -0
  80. package/dist/components/editor/CustomEditor.svelte.d.ts +37 -0
  81. package/dist/components/editor/DebugConsole.svelte +646 -0
  82. package/dist/components/editor/DebugConsole.svelte.d.ts +41 -0
  83. package/dist/components/editor/EchoCursorLayer.svelte +363 -0
  84. package/dist/components/editor/EchoCursorLayer.svelte.d.ts +24 -0
  85. package/dist/components/editor/Editor.svelte +61 -0
  86. package/dist/components/editor/Editor.svelte.d.ts +22 -0
  87. package/dist/components/editor/EditorGutter.svelte +119 -0
  88. package/dist/components/editor/EditorGutter.svelte.d.ts +19 -0
  89. package/dist/components/editor/EditorLines.svelte +182 -0
  90. package/dist/components/editor/EditorLines.svelte.d.ts +43 -0
  91. package/dist/components/editor/EditorPane.svelte +134 -0
  92. package/dist/components/editor/EditorPane.svelte.d.ts +9 -0
  93. package/dist/components/editor/EditorSelections.svelte +186 -0
  94. package/dist/components/editor/EditorSelections.svelte.d.ts +25 -0
  95. package/dist/components/editor/EditorTabs.svelte +170 -0
  96. package/dist/components/editor/EditorTabs.svelte.d.ts +12 -0
  97. package/dist/components/editor/FileExplorer.svelte +811 -0
  98. package/dist/components/editor/FileExplorer.svelte.d.ts +67 -0
  99. package/dist/components/editor/FileIcon.svelte +110 -0
  100. package/dist/components/editor/FileIcon.svelte.d.ts +10 -0
  101. package/dist/components/editor/FindReplace.svelte +448 -0
  102. package/dist/components/editor/FindReplace.svelte.d.ts +40 -0
  103. package/dist/components/editor/GhostBracketLayer.svelte +391 -0
  104. package/dist/components/editor/GhostBracketLayer.svelte.d.ts +24 -0
  105. package/dist/components/editor/GitBlameLayer.svelte +436 -0
  106. package/dist/components/editor/GitBlameLayer.svelte.d.ts +18 -0
  107. package/dist/components/editor/InlineDiagnosticsLayer.svelte +540 -0
  108. package/dist/components/editor/InlineDiagnosticsLayer.svelte.d.ts +35 -0
  109. package/dist/components/editor/InlineDiffLayer.svelte +337 -0
  110. package/dist/components/editor/InlineDiffLayer.svelte.d.ts +31 -0
  111. package/dist/components/editor/MinimalEditor.svelte +75 -0
  112. package/dist/components/editor/MinimalEditor.svelte.d.ts +6 -0
  113. package/dist/components/editor/MinimalEditor2.svelte +84 -0
  114. package/dist/components/editor/MinimalEditor2.svelte.d.ts +6 -0
  115. package/dist/components/editor/Minimap.svelte +327 -0
  116. package/dist/components/editor/Minimap.svelte.d.ts +34 -0
  117. package/dist/components/editor/PluginPreviewSandbox.svelte +793 -0
  118. package/dist/components/editor/PluginPreviewSandbox.svelte.d.ts +49 -0
  119. package/dist/components/editor/ProblemsPanel.svelte +628 -0
  120. package/dist/components/editor/ProblemsPanel.svelte.d.ts +25 -0
  121. package/dist/components/editor/QuickActionsMenu.svelte +403 -0
  122. package/dist/components/editor/QuickActionsMenu.svelte.d.ts +18 -0
  123. package/dist/components/editor/SnippetPalette.svelte +530 -0
  124. package/dist/components/editor/SnippetPalette.svelte.d.ts +16 -0
  125. package/dist/components/editor/StructureMap.svelte +431 -0
  126. package/dist/components/editor/StructureMap.svelte.d.ts +37 -0
  127. package/dist/components/editor/SymbolOutline.svelte +722 -0
  128. package/dist/components/editor/SymbolOutline.svelte.d.ts +44 -0
  129. package/dist/components/editor/TimelineScrubber.svelte +470 -0
  130. package/dist/components/editor/TimelineScrubber.svelte.d.ts +40 -0
  131. package/dist/components/editor/TokenRenderer.svelte +69 -0
  132. package/dist/components/editor/TokenRenderer.svelte.d.ts +15 -0
  133. package/dist/components/editor/constants.d.ts +32 -0
  134. package/dist/components/editor/constants.js +36 -0
  135. package/dist/components/editor/core/ai-awareness.d.ts +176 -0
  136. package/dist/components/editor/core/ai-awareness.js +210 -0
  137. package/dist/components/editor/core/bracket-healer.d.ts +189 -0
  138. package/dist/components/editor/core/bracket-healer.js +406 -0
  139. package/dist/components/editor/core/breakpoints.d.ts +203 -0
  140. package/dist/components/editor/core/breakpoints.js +414 -0
  141. package/dist/components/editor/core/commands.d.ts +108 -0
  142. package/dist/components/editor/core/commands.js +246 -0
  143. package/dist/components/editor/core/complexity-analyzer.d.ts +123 -0
  144. package/dist/components/editor/core/complexity-analyzer.js +376 -0
  145. package/dist/components/editor/core/conflict-predictor.d.ts +135 -0
  146. package/dist/components/editor/core/conflict-predictor.js +316 -0
  147. package/dist/components/editor/core/crdt-binding.d.ts +118 -0
  148. package/dist/components/editor/core/crdt-binding.js +286 -0
  149. package/dist/components/editor/core/diagnostics.d.ts +210 -0
  150. package/dist/components/editor/core/diagnostics.js +335 -0
  151. package/dist/components/editor/core/echo-cursor.d.ts +201 -0
  152. package/dist/components/editor/core/echo-cursor.js +267 -0
  153. package/dist/components/editor/core/folding.d.ts +124 -0
  154. package/dist/components/editor/core/folding.js +672 -0
  155. package/dist/components/editor/core/ghost-pair.d.ts +122 -0
  156. package/dist/components/editor/core/ghost-pair.js +221 -0
  157. package/dist/components/editor/core/git-blame.d.ts +170 -0
  158. package/dist/components/editor/core/git-blame.js +324 -0
  159. package/dist/components/editor/core/index.d.ts +26 -0
  160. package/dist/components/editor/core/index.js +24 -0
  161. package/dist/components/editor/core/keybindings.d.ts +79 -0
  162. package/dist/components/editor/core/keybindings.js +357 -0
  163. package/dist/components/editor/core/multi-cursor.d.ts +196 -0
  164. package/dist/components/editor/core/multi-cursor.js +521 -0
  165. package/dist/components/editor/core/navigation.d.ts +107 -0
  166. package/dist/components/editor/core/navigation.js +408 -0
  167. package/dist/components/editor/core/quick-actions.d.ts +189 -0
  168. package/dist/components/editor/core/quick-actions.js +427 -0
  169. package/dist/components/editor/core/search.d.ts +88 -0
  170. package/dist/components/editor/core/search.js +192 -0
  171. package/dist/components/editor/core/semantic-analyzer.d.ts +77 -0
  172. package/dist/components/editor/core/semantic-analyzer.js +424 -0
  173. package/dist/components/editor/core/snippet-manager.d.ts +202 -0
  174. package/dist/components/editor/core/snippet-manager.js +565 -0
  175. package/dist/components/editor/core/state.d.ts +367 -0
  176. package/dist/components/editor/core/state.js +900 -0
  177. package/dist/components/editor/core/timeline.d.ts +204 -0
  178. package/dist/components/editor/core/timeline.js +349 -0
  179. package/dist/components/editor/editor-find.d.ts +56 -0
  180. package/dist/components/editor/editor-find.js +148 -0
  181. package/dist/components/editor/editor-input.d.ts +77 -0
  182. package/dist/components/editor/editor-input.js +445 -0
  183. package/dist/components/editor/editor-multicursor.d.ts +21 -0
  184. package/dist/components/editor/editor-multicursor.js +196 -0
  185. package/dist/components/editor/editor-scroll.d.ts +14 -0
  186. package/dist/components/editor/editor-scroll.js +34 -0
  187. package/dist/components/editor/index.d.ts +15 -0
  188. package/dist/components/editor/index.js +21 -0
  189. package/dist/components/editor/languages.d.ts +62 -0
  190. package/dist/components/editor/languages.js +285 -0
  191. package/dist/components/editor/theme.d.ts +88 -0
  192. package/dist/components/editor/theme.js +139 -0
  193. package/dist/components/editor/tokenizer/base.d.ts +40 -0
  194. package/dist/components/editor/tokenizer/base.js +203 -0
  195. package/dist/components/editor/tokenizer/index.d.ts +56 -0
  196. package/dist/components/editor/tokenizer/index.js +215 -0
  197. package/dist/components/editor/tokenizer/languages/css.d.ts +17 -0
  198. package/dist/components/editor/tokenizer/languages/css.js +194 -0
  199. package/dist/components/editor/tokenizer/languages/go.d.ts +17 -0
  200. package/dist/components/editor/tokenizer/languages/go.js +220 -0
  201. package/dist/components/editor/tokenizer/languages/html.d.ts +24 -0
  202. package/dist/components/editor/tokenizer/languages/html.js +145 -0
  203. package/dist/components/editor/tokenizer/languages/javascript.d.ts +56 -0
  204. package/dist/components/editor/tokenizer/languages/javascript.js +452 -0
  205. package/dist/components/editor/tokenizer/languages/json.d.ts +12 -0
  206. package/dist/components/editor/tokenizer/languages/json.js +91 -0
  207. package/dist/components/editor/tokenizer/languages/markdown.d.ts +16 -0
  208. package/dist/components/editor/tokenizer/languages/markdown.js +156 -0
  209. package/dist/components/editor/tokenizer/languages/python.d.ts +20 -0
  210. package/dist/components/editor/tokenizer/languages/python.js +227 -0
  211. package/dist/components/editor/tokenizer/languages/svelte.d.ts +40 -0
  212. package/dist/components/editor/tokenizer/languages/svelte.js +326 -0
  213. package/dist/components/editor/tokenizer/types.d.ts +86 -0
  214. package/dist/components/editor/tokenizer/types.js +4 -0
  215. package/dist/components/layout/IDELayout.svelte +274 -0
  216. package/dist/components/layout/IDELayout.svelte.d.ts +29 -0
  217. package/dist/components/layout/StatusBar.svelte +511 -0
  218. package/dist/components/layout/StatusBar.svelte.d.ts +47 -0
  219. package/dist/components/layout/index.d.ts +2 -0
  220. package/dist/components/layout/index.js +3 -0
  221. package/dist/components/lsp/AutocompleteWidget.svelte +364 -0
  222. package/dist/components/lsp/AutocompleteWidget.svelte.d.ts +33 -0
  223. package/dist/components/lsp/DiagnosticMarker.svelte +166 -0
  224. package/dist/components/lsp/DiagnosticMarker.svelte.d.ts +19 -0
  225. package/dist/components/lsp/DiagnosticsPanel.svelte +388 -0
  226. package/dist/components/lsp/DiagnosticsPanel.svelte.d.ts +21 -0
  227. package/dist/components/lsp/HoverTooltip.svelte +274 -0
  228. package/dist/components/lsp/HoverTooltip.svelte.d.ts +24 -0
  229. package/dist/components/lsp/LSPEditor.svelte +486 -0
  230. package/dist/components/lsp/LSPEditor.svelte.d.ts +39 -0
  231. package/dist/components/lsp/SignatureHelpWidget.svelte +216 -0
  232. package/dist/components/lsp/SignatureHelpWidget.svelte.d.ts +22 -0
  233. package/dist/components/lsp/index.d.ts +6 -0
  234. package/dist/components/lsp/index.js +7 -0
  235. package/dist/components/plugins/PluginCard.svelte +153 -0
  236. package/dist/components/plugins/PluginCard.svelte.d.ts +19 -0
  237. package/dist/components/plugins/PluginPanel.svelte +280 -0
  238. package/dist/components/plugins/PluginPanel.svelte.d.ts +8 -0
  239. package/dist/components/plugins/PluginProposalForm.svelte +250 -0
  240. package/dist/components/plugins/PluginProposalForm.svelte.d.ts +6 -0
  241. package/dist/components/plugins/PluginStatusBadge.svelte +14 -0
  242. package/dist/components/plugins/PluginStatusBadge.svelte.d.ts +8 -0
  243. package/dist/components/plugins/index.d.ts +4 -0
  244. package/dist/components/plugins/index.js +5 -0
  245. package/dist/components/vfs/LockConflictDialog.svelte +705 -0
  246. package/dist/components/vfs/LockConflictDialog.svelte.d.ts +21 -0
  247. package/dist/components/vfs/LockIndicator.svelte +194 -0
  248. package/dist/components/vfs/LockIndicator.svelte.d.ts +29 -0
  249. package/dist/components/vfs/LockOverlay.svelte +344 -0
  250. package/dist/components/vfs/LockOverlay.svelte.d.ts +17 -0
  251. package/dist/components/vfs/VersionConflictDialog.svelte +549 -0
  252. package/dist/components/vfs/VersionConflictDialog.svelte.d.ts +24 -0
  253. package/dist/components/vfs/index.d.ts +4 -0
  254. package/dist/components/vfs/index.js +5 -0
  255. package/dist/crdt/awareness.d.ts +42 -0
  256. package/dist/crdt/awareness.js +109 -0
  257. package/dist/crdt/document.d.ts +101 -0
  258. package/dist/crdt/document.js +187 -0
  259. package/dist/crdt/index.d.ts +9 -0
  260. package/dist/crdt/index.js +8 -0
  261. package/dist/crdt/provider.d.ts +85 -0
  262. package/dist/crdt/provider.js +150 -0
  263. package/dist/crdt/types.d.ts +61 -0
  264. package/dist/crdt/types.js +4 -0
  265. package/dist/crdt/undo.d.ts +34 -0
  266. package/dist/crdt/undo.js +70 -0
  267. package/dist/index.d.ts +277 -0
  268. package/dist/index.js +280 -0
  269. package/dist/plugins/index.d.ts +103 -0
  270. package/dist/plugins/index.js +153 -0
  271. package/dist/services/error-handling.d.ts +95 -0
  272. package/dist/services/error-handling.js +413 -0
  273. package/dist/services/ide-integration.d.ts +83 -0
  274. package/dist/services/ide-integration.js +367 -0
  275. package/dist/services/lsp-client.d.ts +69 -0
  276. package/dist/services/lsp-client.js +667 -0
  277. package/dist/services/mock-ai.d.ts +37 -0
  278. package/dist/services/mock-ai.js +318 -0
  279. package/dist/services/optimistic.d.ts +141 -0
  280. package/dist/services/optimistic.js +367 -0
  281. package/dist/services/vfs-client.d.ts +81 -0
  282. package/dist/services/vfs-client.js +348 -0
  283. package/dist/stores/agents.svelte.d.ts +85 -0
  284. package/dist/stores/agents.svelte.js +459 -0
  285. package/dist/stores/ai-persistence.svelte.d.ts +76 -0
  286. package/dist/stores/ai-persistence.svelte.js +334 -0
  287. package/dist/stores/ai.svelte.d.ts +140 -0
  288. package/dist/stores/ai.svelte.js +383 -0
  289. package/dist/stores/collaboration.svelte.d.ts +164 -0
  290. package/dist/stores/collaboration.svelte.js +334 -0
  291. package/dist/stores/editor.svelte.d.ts +131 -0
  292. package/dist/stores/editor.svelte.js +250 -0
  293. package/dist/stores/index.d.ts +10 -0
  294. package/dist/stores/index.js +29 -0
  295. package/dist/stores/layout.svelte.d.ts +171 -0
  296. package/dist/stores/layout.svelte.js +351 -0
  297. package/dist/stores/plugin.svelte.d.ts +121 -0
  298. package/dist/stores/plugin.svelte.js +410 -0
  299. package/dist/stores/vfs.svelte.d.ts +123 -0
  300. package/dist/stores/vfs.svelte.js +680 -0
  301. package/dist/styles/theme.css +623 -0
  302. package/dist/types/agents.d.ts +127 -0
  303. package/dist/types/agents.js +5 -0
  304. package/dist/types/ai.d.ts +137 -0
  305. package/dist/types/ai.js +4 -0
  306. package/dist/types/crdt.d.ts +222 -0
  307. package/dist/types/crdt.js +5 -0
  308. package/dist/types/editor.d.ts +52 -0
  309. package/dist/types/editor.js +18 -0
  310. package/dist/types/events.d.ts +133 -0
  311. package/dist/types/events.js +4 -0
  312. package/dist/types/filesystem.d.ts +77 -0
  313. package/dist/types/filesystem.js +4 -0
  314. package/dist/types/index.d.ts +9 -0
  315. package/dist/types/index.js +12 -0
  316. package/dist/types/lsp.d.ts +691 -0
  317. package/dist/types/lsp.js +108 -0
  318. package/dist/types/plugin.d.ts +239 -0
  319. package/dist/types/plugin.js +5 -0
  320. package/dist/types/vfs.d.ts +191 -0
  321. package/dist/types/vfs.js +18 -0
  322. package/dist/utils/format.d.ts +55 -0
  323. package/dist/utils/format.js +152 -0
  324. package/dist/utils/index.d.ts +3 -0
  325. package/dist/utils/index.js +4 -0
  326. package/dist/utils/keybindings.d.ts +33 -0
  327. package/dist/utils/keybindings.js +171 -0
  328. package/dist/utils/language.d.ts +27 -0
  329. package/dist/utils/language.js +222 -0
  330. package/package.json +178 -0
@@ -0,0 +1,357 @@
1
+ /**
2
+ * Keyboard handling for the custom editor
3
+ *
4
+ * This module provides keybinding management and keyboard event handling.
5
+ */
6
+ /**
7
+ * Normalize key event to consistent format
8
+ */
9
+ function normalizeKey(e) {
10
+ return e.key;
11
+ }
12
+ /**
13
+ * Check if modifiers match
14
+ */
15
+ function modifiersMatch(e, modifiers) {
16
+ const ctrl = modifiers?.ctrl ?? false;
17
+ const shift = modifiers?.shift ?? false;
18
+ const alt = modifiers?.alt ?? false;
19
+ const meta = modifiers?.meta ?? false;
20
+ // Handle Cmd on Mac as Ctrl
21
+ const ctrlOrMeta = e.ctrlKey || e.metaKey;
22
+ return ((ctrl ? ctrlOrMeta : !ctrlOrMeta) &&
23
+ (shift ? e.shiftKey : !e.shiftKey) &&
24
+ (alt ? e.altKey : !e.altKey) &&
25
+ (meta === e.metaKey || ctrl) // Allow meta to match either on its own or as part of ctrl
26
+ );
27
+ }
28
+ /**
29
+ * Platform detection
30
+ */
31
+ const isMac = typeof navigator !== 'undefined' && /Mac/.test(navigator.platform);
32
+ /**
33
+ * Create default keybindings for the editor
34
+ */
35
+ export function createDefaultKeybindings(state, nav, options = {}) {
36
+ const pageSize = options.pageSize ?? 20;
37
+ const keybindings = [];
38
+ // ============================================
39
+ // Navigation
40
+ // ============================================
41
+ // Arrow keys
42
+ keybindings.push({
43
+ key: 'ArrowLeft',
44
+ handler: () => nav.moveLeft(),
45
+ description: 'Move cursor left',
46
+ readonly: true
47
+ }, {
48
+ key: 'ArrowLeft',
49
+ modifiers: { shift: true },
50
+ handler: () => nav.moveLeft(true),
51
+ description: 'Extend selection left',
52
+ readonly: true
53
+ }, {
54
+ key: 'ArrowRight',
55
+ handler: () => nav.moveRight(),
56
+ description: 'Move cursor right',
57
+ readonly: true
58
+ }, {
59
+ key: 'ArrowRight',
60
+ modifiers: { shift: true },
61
+ handler: () => nav.moveRight(true),
62
+ description: 'Extend selection right',
63
+ readonly: true
64
+ }, {
65
+ key: 'ArrowUp',
66
+ handler: () => nav.moveUp(),
67
+ description: 'Move cursor up',
68
+ readonly: true
69
+ }, {
70
+ key: 'ArrowUp',
71
+ modifiers: { shift: true },
72
+ handler: () => nav.moveUp(true),
73
+ description: 'Extend selection up',
74
+ readonly: true
75
+ }, {
76
+ key: 'ArrowDown',
77
+ handler: () => nav.moveDown(),
78
+ description: 'Move cursor down',
79
+ readonly: true
80
+ }, {
81
+ key: 'ArrowDown',
82
+ modifiers: { shift: true },
83
+ handler: () => nav.moveDown(true),
84
+ description: 'Extend selection down',
85
+ readonly: true
86
+ });
87
+ // Word navigation
88
+ keybindings.push({
89
+ key: 'ArrowLeft',
90
+ modifiers: { ctrl: true },
91
+ handler: () => nav.moveWordLeft(),
92
+ description: 'Move to previous word',
93
+ readonly: true
94
+ }, {
95
+ key: 'ArrowLeft',
96
+ modifiers: { ctrl: true, shift: true },
97
+ handler: () => nav.moveWordLeft(true),
98
+ description: 'Extend selection to previous word',
99
+ readonly: true
100
+ }, {
101
+ key: 'ArrowRight',
102
+ modifiers: { ctrl: true },
103
+ handler: () => nav.moveWordRight(),
104
+ description: 'Move to next word',
105
+ readonly: true
106
+ }, {
107
+ key: 'ArrowRight',
108
+ modifiers: { ctrl: true, shift: true },
109
+ handler: () => nav.moveWordRight(true),
110
+ description: 'Extend selection to next word',
111
+ readonly: true
112
+ });
113
+ // Line navigation
114
+ keybindings.push({
115
+ key: 'Home',
116
+ handler: () => nav.moveToLineStart(),
117
+ description: 'Move to line start',
118
+ readonly: true
119
+ }, {
120
+ key: 'Home',
121
+ modifiers: { shift: true },
122
+ handler: () => nav.moveToLineStart(true),
123
+ description: 'Extend selection to line start',
124
+ readonly: true
125
+ }, {
126
+ key: 'End',
127
+ handler: () => nav.moveToLineEnd(),
128
+ description: 'Move to line end',
129
+ readonly: true
130
+ }, {
131
+ key: 'End',
132
+ modifiers: { shift: true },
133
+ handler: () => nav.moveToLineEnd(true),
134
+ description: 'Extend selection to line end',
135
+ readonly: true
136
+ });
137
+ // Document navigation
138
+ keybindings.push({
139
+ key: 'Home',
140
+ modifiers: { ctrl: true },
141
+ handler: () => nav.moveToDocumentStart(),
142
+ description: 'Move to document start',
143
+ readonly: true
144
+ }, {
145
+ key: 'Home',
146
+ modifiers: { ctrl: true, shift: true },
147
+ handler: () => nav.moveToDocumentStart(true),
148
+ description: 'Extend selection to document start',
149
+ readonly: true
150
+ }, {
151
+ key: 'End',
152
+ modifiers: { ctrl: true },
153
+ handler: () => nav.moveToDocumentEnd(),
154
+ description: 'Move to document end',
155
+ readonly: true
156
+ }, {
157
+ key: 'End',
158
+ modifiers: { ctrl: true, shift: true },
159
+ handler: () => nav.moveToDocumentEnd(true),
160
+ description: 'Extend selection to document end',
161
+ readonly: true
162
+ });
163
+ // Page navigation
164
+ keybindings.push({
165
+ key: 'PageUp',
166
+ handler: () => nav.movePageUp(pageSize),
167
+ description: 'Move up one page',
168
+ readonly: true
169
+ }, {
170
+ key: 'PageUp',
171
+ modifiers: { shift: true },
172
+ handler: () => nav.movePageUp(pageSize, true),
173
+ description: 'Extend selection up one page',
174
+ readonly: true
175
+ }, {
176
+ key: 'PageDown',
177
+ handler: () => nav.movePageDown(pageSize),
178
+ description: 'Move down one page',
179
+ readonly: true
180
+ }, {
181
+ key: 'PageDown',
182
+ modifiers: { shift: true },
183
+ handler: () => nav.movePageDown(pageSize, true),
184
+ description: 'Extend selection down one page',
185
+ readonly: true
186
+ });
187
+ // ============================================
188
+ // Selection
189
+ // ============================================
190
+ keybindings.push({
191
+ key: 'a',
192
+ modifiers: { ctrl: true },
193
+ handler: () => state.selectAll(),
194
+ description: 'Select all',
195
+ readonly: true
196
+ });
197
+ // ============================================
198
+ // Editing (only when not readonly)
199
+ // ============================================
200
+ if (!options.readonly) {
201
+ keybindings.push(
202
+ // Basic input is handled by onInput, not keybindings
203
+ // Backspace
204
+ {
205
+ key: 'Backspace',
206
+ handler: () => state.deleteBackward(),
207
+ description: 'Delete character before cursor'
208
+ }, {
209
+ key: 'Backspace',
210
+ modifiers: { ctrl: true },
211
+ handler: () => {
212
+ // Delete word before cursor
213
+ nav.moveWordLeft(true);
214
+ state.deleteSelection();
215
+ },
216
+ description: 'Delete word before cursor'
217
+ },
218
+ // Delete
219
+ {
220
+ key: 'Delete',
221
+ handler: () => state.deleteForward(),
222
+ description: 'Delete character after cursor'
223
+ }, {
224
+ key: 'Delete',
225
+ modifiers: { ctrl: true },
226
+ handler: () => {
227
+ // Delete word after cursor
228
+ nav.moveWordRight(true);
229
+ state.deleteSelection();
230
+ },
231
+ description: 'Delete word after cursor'
232
+ },
233
+ // Enter
234
+ {
235
+ key: 'Enter',
236
+ handler: () => state.insertNewline(),
237
+ description: 'Insert new line'
238
+ },
239
+ // Tab
240
+ {
241
+ key: 'Tab',
242
+ handler: () => state.insertTab(),
243
+ description: 'Insert tab'
244
+ },
245
+ // Undo/Redo
246
+ {
247
+ key: 'z',
248
+ modifiers: { ctrl: true },
249
+ handler: () => state.undo(),
250
+ description: 'Undo'
251
+ }, {
252
+ key: 'z',
253
+ modifiers: { ctrl: true, shift: true },
254
+ handler: () => state.redo(),
255
+ description: 'Redo'
256
+ }, {
257
+ key: 'y',
258
+ modifiers: { ctrl: true },
259
+ handler: () => state.redo(),
260
+ description: 'Redo'
261
+ });
262
+ }
263
+ // ============================================
264
+ // Custom commands
265
+ // ============================================
266
+ if (options.onSave) {
267
+ keybindings.push({
268
+ key: 's',
269
+ modifiers: { ctrl: true },
270
+ handler: () => {
271
+ options.onSave();
272
+ return true;
273
+ },
274
+ description: 'Save',
275
+ readonly: true
276
+ });
277
+ }
278
+ return keybindings;
279
+ }
280
+ /**
281
+ * Keyboard handler class
282
+ */
283
+ export class KeyboardHandler {
284
+ keybindings = [];
285
+ enabled = true;
286
+ /**
287
+ * Set keybindings
288
+ */
289
+ setKeybindings(keybindings) {
290
+ this.keybindings = keybindings;
291
+ }
292
+ /**
293
+ * Add a keybinding
294
+ */
295
+ addKeybinding(keybinding) {
296
+ this.keybindings.push(keybinding);
297
+ }
298
+ /**
299
+ * Remove a keybinding
300
+ */
301
+ removeKeybinding(key, modifiers) {
302
+ this.keybindings = this.keybindings.filter((kb) => !(kb.key === key && this.modifiersEqual(kb.modifiers, modifiers)));
303
+ }
304
+ /**
305
+ * Enable/disable keyboard handling
306
+ */
307
+ setEnabled(enabled) {
308
+ this.enabled = enabled;
309
+ }
310
+ /**
311
+ * Handle a keyboard event
312
+ * Returns true if the event was handled
313
+ */
314
+ handleKeyDown(e, readonly = false) {
315
+ if (!this.enabled) {
316
+ return false;
317
+ }
318
+ const key = normalizeKey(e);
319
+ // Find matching keybinding
320
+ for (const binding of this.keybindings) {
321
+ if (binding.key === key && modifiersMatch(e, binding.modifiers)) {
322
+ // Skip non-readonly bindings in readonly mode
323
+ if (readonly && !binding.readonly) {
324
+ continue;
325
+ }
326
+ const result = binding.handler();
327
+ if (result !== false) {
328
+ e.preventDefault();
329
+ e.stopPropagation();
330
+ return true;
331
+ }
332
+ }
333
+ }
334
+ return false;
335
+ }
336
+ /**
337
+ * Check if modifiers are equal
338
+ */
339
+ modifiersEqual(a, b) {
340
+ return ((a?.ctrl ?? false) === (b?.ctrl ?? false) &&
341
+ (a?.shift ?? false) === (b?.shift ?? false) &&
342
+ (a?.alt ?? false) === (b?.alt ?? false) &&
343
+ (a?.meta ?? false) === (b?.meta ?? false));
344
+ }
345
+ /**
346
+ * Get all keybindings for documentation
347
+ */
348
+ getKeybindings() {
349
+ return [...this.keybindings];
350
+ }
351
+ }
352
+ /**
353
+ * Create keyboard handler
354
+ */
355
+ export function createKeyboardHandler() {
356
+ return new KeyboardHandler();
357
+ }
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Multi-cursor management for the custom editor
3
+ *
4
+ * Provides support for creating, managing, and editing with multiple cursors.
5
+ * Cursors can have selections and are automatically merged when they touch or overlap.
6
+ */
7
+ import type { Position, Selection } from './state';
8
+ /**
9
+ * A single cursor with optional selection
10
+ */
11
+ export interface Cursor {
12
+ /** Unique identifier */
13
+ id: string;
14
+ /** Selection range (anchor = head for no selection) */
15
+ selection: Selection;
16
+ /** Whether this is the primary cursor */
17
+ isPrimary: boolean;
18
+ }
19
+ /**
20
+ * Configuration for CursorManager
21
+ */
22
+ export interface CursorManagerConfig {
23
+ /** Maximum number of cursors allowed (default: 100) */
24
+ maxCursors?: number;
25
+ }
26
+ /**
27
+ * Compare two positions
28
+ * Returns negative if a < b, positive if a > b, 0 if equal
29
+ */
30
+ export declare function comparePositions(a: Position, b: Position): number;
31
+ /**
32
+ * Check if position a is before position b
33
+ */
34
+ export declare function isPositionBefore(a: Position, b: Position): boolean;
35
+ /**
36
+ * Check if position a is before or equal to position b
37
+ */
38
+ export declare function isPositionBeforeOrEqual(a: Position, b: Position): boolean;
39
+ /**
40
+ * Check if two positions are equal
41
+ */
42
+ export declare function positionsEqual(a: Position, b: Position): boolean;
43
+ /**
44
+ * Get the start position of a selection (min of anchor and head)
45
+ */
46
+ export declare function getSelectionStart(selection: Selection): Position;
47
+ /**
48
+ * Get the end position of a selection (max of anchor and head)
49
+ */
50
+ export declare function getSelectionEnd(selection: Selection): Position;
51
+ /**
52
+ * Check if a selection is empty (anchor equals head)
53
+ */
54
+ export declare function isSelectionEmpty(selection: Selection): boolean;
55
+ /**
56
+ * Check if two selections overlap or touch
57
+ */
58
+ export declare function selectionsOverlap(a: Selection, b: Selection): boolean;
59
+ /**
60
+ * Merge two selections into one (union)
61
+ */
62
+ export declare function mergeSelections(a: Selection, b: Selection): Selection;
63
+ export declare class CursorManager {
64
+ private cursors;
65
+ private primaryId;
66
+ private nextId;
67
+ private maxCursors;
68
+ private listeners;
69
+ constructor(config?: CursorManagerConfig);
70
+ /**
71
+ * Get all cursors
72
+ */
73
+ getCursors(): readonly Cursor[];
74
+ /**
75
+ * Get all cursors sorted by position (top to bottom, left to right)
76
+ */
77
+ getSortedCursors(): Cursor[];
78
+ /**
79
+ * Get cursors sorted in reverse order (bottom to top)
80
+ * Useful for editing operations to maintain position validity
81
+ */
82
+ getSortedCursorsReverse(): Cursor[];
83
+ /**
84
+ * Get the primary cursor
85
+ */
86
+ getPrimary(): Cursor;
87
+ /**
88
+ * Get cursor count
89
+ */
90
+ get count(): number;
91
+ /**
92
+ * Check if there are multiple cursors
93
+ */
94
+ get hasMultiple(): boolean;
95
+ /**
96
+ * Add a new cursor at a position
97
+ * @param position - Position for the new cursor
98
+ * @param makePrimary - Make this the primary cursor
99
+ * @returns The new cursor, or null if at max capacity
100
+ */
101
+ addCursor(position: Position, makePrimary?: boolean): Cursor;
102
+ /**
103
+ * Add a cursor with a selection
104
+ */
105
+ addCursorWithSelection(anchor: Position, head: Position, makePrimary?: boolean): Cursor;
106
+ /**
107
+ * Remove a cursor by ID
108
+ * @returns true if removed, false if it was the last cursor
109
+ */
110
+ removeCursor(id: string): boolean;
111
+ /**
112
+ * Remove the last added secondary cursor (for Ctrl+U)
113
+ * @returns true if a cursor was removed
114
+ */
115
+ removeLastSecondary(): boolean;
116
+ /**
117
+ * Clear all secondary cursors, keeping only the primary
118
+ */
119
+ clearSecondary(): void;
120
+ /**
121
+ * Set the primary cursor
122
+ */
123
+ setPrimary(id: string): void;
124
+ /**
125
+ * Set cursor position (clears selection)
126
+ */
127
+ setCursor(id: string, position: Position): void;
128
+ /**
129
+ * Batch update cursor positions without triggering merge/emit on each update
130
+ * More efficient for updating multiple cursors at once
131
+ */
132
+ batchUpdateCursors(updates: Array<{
133
+ id: string;
134
+ position: Position;
135
+ }>): void;
136
+ /**
137
+ * Set cursor selection
138
+ */
139
+ setSelection(id: string, anchor: Position, head: Position): void;
140
+ /**
141
+ * Extend cursor selection (move head, keep anchor)
142
+ */
143
+ extendSelection(id: string, head: Position): void;
144
+ /**
145
+ * Set all cursors to new positions (for single cursor operations)
146
+ */
147
+ setSingleCursor(position: Position): void;
148
+ /**
149
+ * Set single cursor with selection
150
+ */
151
+ setSingleSelection(anchor: Position, head: Position): void;
152
+ /**
153
+ * Check if any cursor contains a position
154
+ */
155
+ isPositionInAnyCursor(position: Position): boolean;
156
+ /**
157
+ * Get the closest cursor to a position
158
+ */
159
+ private getClosestCursor;
160
+ /**
161
+ * Merge overlapping or touching cursors
162
+ */
163
+ private mergeTouchingCursors;
164
+ /**
165
+ * Add cursor above the current primary cursor
166
+ * @param lineCount - Number of lines in the document
167
+ */
168
+ addCursorAbove(lineCount: number): boolean;
169
+ /**
170
+ * Add cursor below the current primary cursor
171
+ * @param lineCount - Number of lines in the document
172
+ */
173
+ addCursorBelow(lineCount: number): boolean;
174
+ /**
175
+ * Subscribe to cursor changes
176
+ * In development mode, throws an error to catch memory leaks early.
177
+ * In production, warns and evicts the oldest listener.
178
+ */
179
+ onChange(callback: () => void): () => void;
180
+ private emit;
181
+ /**
182
+ * Restore cursors from a saved state (for undo/redo)
183
+ */
184
+ restore(cursors: Cursor[], primaryId: string): void;
185
+ /**
186
+ * Clone the current state (for undo/redo)
187
+ */
188
+ clone(): {
189
+ cursors: Cursor[];
190
+ primaryId: string;
191
+ };
192
+ }
193
+ /**
194
+ * Create a new CursorManager
195
+ */
196
+ export declare function createCursorManager(config?: CursorManagerConfig): CursorManager;