@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,196 @@
1
+ /**
2
+ * Multi-cursor selection helpers extracted from CustomEditor.
3
+ * Pure functions that operate on EditorState.
4
+ */
5
+ import { findAllMatches, getSelectionStart, getSelectionEnd, isSelectionEmpty } from './core';
6
+ /**
7
+ * Test whether a character is a word character (\w). Used to enforce whole-word
8
+ * boundaries so that selecting `foo` does not also land cursors inside `foobar`.
9
+ */
10
+ function isWordChar(c) {
11
+ return c !== undefined && /\w/.test(c);
12
+ }
13
+ /**
14
+ * Find all matches of `searchText` across the document.
15
+ *
16
+ * - When `wholeWord` is true, matches are filtered so that the characters
17
+ * immediately before and after the match are NOT word characters. This is the
18
+ * "select word under cursor" behaviour where `foo` should not match `foobar`.
19
+ * - Multi-line search text (containing a newline) is the caller's responsibility
20
+ * to handle; this helper only ever sees single-line search text because the
21
+ * per-line search engine cannot span lines.
22
+ */
23
+ function findOccurrences(state, searchText, wholeWord) {
24
+ const matches = findAllMatches(state.lines, searchText, {
25
+ caseSensitive: true,
26
+ useRegex: false
27
+ });
28
+ if (!wholeWord)
29
+ return matches;
30
+ if (!isWordChar(searchText[0]) && !isWordChar(searchText[searchText.length - 1])) {
31
+ // The search text is not bounded by word characters at all (e.g. an
32
+ // operator or punctuation), so word-boundary filtering is meaningless.
33
+ return matches;
34
+ }
35
+ return matches.filter((m) => {
36
+ const lineText = state.getLine(m.start.line)?.text ?? '';
37
+ const before = m.start.column > 0 ? lineText[m.start.column - 1] : undefined;
38
+ const after = lineText[m.end.column];
39
+ return !isWordChar(before) && !isWordChar(after);
40
+ });
41
+ }
42
+ /**
43
+ * Get word at cursor position
44
+ */
45
+ export function getWordAtPosition(state, pos) {
46
+ const line = state.getLine(pos.line);
47
+ if (!line)
48
+ return null;
49
+ const text = line.text;
50
+ if (!text || pos.column >= text.length)
51
+ return null;
52
+ // Find word boundaries
53
+ let start = pos.column;
54
+ let end = pos.column;
55
+ const isWordChar = (c) => /\w/.test(c);
56
+ // Move start backwards
57
+ while (start > 0 && isWordChar(text[start - 1])) {
58
+ start--;
59
+ }
60
+ // Move end forwards
61
+ while (end < text.length && isWordChar(text[end])) {
62
+ end++;
63
+ }
64
+ if (start === end)
65
+ return null;
66
+ return {
67
+ text: text.slice(start, end),
68
+ start: { line: pos.line, column: start },
69
+ end: { line: pos.line, column: end }
70
+ };
71
+ }
72
+ /**
73
+ * Select next occurrence of current word/selection (Ctrl+D)
74
+ */
75
+ export function selectNextOccurrence(state) {
76
+ if (!state)
77
+ return;
78
+ const primary = state.primaryCursor;
79
+ let searchText;
80
+ // Whole-word matching only applies to the implicit "word under cursor" case;
81
+ // an explicit selection should match exactly as selected (substring).
82
+ let wholeWord = false;
83
+ // Get text to search for
84
+ if (!isSelectionEmpty(primary.selection)) {
85
+ // Use current selection
86
+ searchText = state.getTextInSelection(primary.selection);
87
+ }
88
+ else {
89
+ // Select word at cursor first
90
+ const word = getWordAtPosition(state, primary.selection.head);
91
+ if (!word)
92
+ return;
93
+ searchText = word.text;
94
+ wholeWord = true;
95
+ // Select the word under cursor for the primary cursor
96
+ state.cursorManager.setSelection(primary.id, word.start, word.end);
97
+ }
98
+ if (!searchText)
99
+ return;
100
+ // A multi-line selection cannot be matched by the per-line search engine, so
101
+ // bail out cleanly rather than silently searching for the (never-found) text.
102
+ if (searchText.includes('\n'))
103
+ return;
104
+ // Find all matches (whole-word filtered for the word-under-cursor case)
105
+ const matches = findOccurrences(state, searchText, wholeWord);
106
+ if (matches.length === 0)
107
+ return;
108
+ // Get all current cursor positions to find next unselected match
109
+ const currentCursors = state.allCursors;
110
+ // Find next match after the last cursor that isn't already selected
111
+ let lastCursorEnd = { line: 0, column: 0 };
112
+ for (const cursor of currentCursors) {
113
+ const end = getSelectionEnd(cursor.selection);
114
+ if (end.line > lastCursorEnd.line ||
115
+ (end.line === lastCursorEnd.line && end.column > lastCursorEnd.column)) {
116
+ lastCursorEnd = end;
117
+ }
118
+ }
119
+ // Find next match
120
+ let foundMatch = null;
121
+ for (const match of matches) {
122
+ const matchStart = match.start;
123
+ if (matchStart.line > lastCursorEnd.line ||
124
+ (matchStart.line === lastCursorEnd.line && matchStart.column >= lastCursorEnd.column)) {
125
+ // Check if this match is already covered by a cursor
126
+ const alreadySelected = currentCursors.some(cursor => {
127
+ const start = getSelectionStart(cursor.selection);
128
+ return start.line === matchStart.line && start.column === matchStart.column;
129
+ });
130
+ if (!alreadySelected) {
131
+ foundMatch = match;
132
+ break;
133
+ }
134
+ }
135
+ }
136
+ // If no match found after last cursor, wrap around
137
+ if (!foundMatch) {
138
+ for (const match of matches) {
139
+ const matchStart = match.start;
140
+ const alreadySelected = currentCursors.some(cursor => {
141
+ const start = getSelectionStart(cursor.selection);
142
+ return start.line === matchStart.line && start.column === matchStart.column;
143
+ });
144
+ if (!alreadySelected) {
145
+ foundMatch = match;
146
+ break;
147
+ }
148
+ }
149
+ }
150
+ if (foundMatch) {
151
+ state.addCursorWithSelection(foundMatch.start, foundMatch.end);
152
+ }
153
+ }
154
+ /**
155
+ * Select all occurrences of current word/selection (Ctrl+Shift+L)
156
+ */
157
+ export function selectAllOccurrences(state) {
158
+ if (!state)
159
+ return;
160
+ const primary = state.primaryCursor;
161
+ let searchText;
162
+ // Whole-word matching only applies to the implicit "word under cursor" case.
163
+ let wholeWord = false;
164
+ // Get text to search for
165
+ if (!isSelectionEmpty(primary.selection)) {
166
+ searchText = state.getTextInSelection(primary.selection);
167
+ }
168
+ else {
169
+ const word = getWordAtPosition(state, primary.selection.head);
170
+ if (!word)
171
+ return;
172
+ searchText = word.text;
173
+ wholeWord = true;
174
+ // Select the word under cursor for the primary cursor
175
+ state.cursorManager.setSelection(primary.id, word.start, word.end);
176
+ }
177
+ if (!searchText)
178
+ return;
179
+ // A multi-line selection cannot be matched by the per-line search engine.
180
+ if (searchText.includes('\n'))
181
+ return;
182
+ // Find all matches (whole-word filtered for the word-under-cursor case)
183
+ const matches = findOccurrences(state, searchText, wholeWord);
184
+ if (matches.length <= 1)
185
+ return;
186
+ // Add cursors at all other matches
187
+ for (const match of matches) {
188
+ const matchStart = match.start;
189
+ // Skip the primary cursor's position
190
+ const primaryStart = getSelectionStart(primary.selection);
191
+ if (matchStart.line === primaryStart.line && matchStart.column === primaryStart.column) {
192
+ continue;
193
+ }
194
+ state.addCursorWithSelection(match.start, match.end);
195
+ }
196
+ }
@@ -0,0 +1,14 @@
1
+ import type { Selection } from './core';
2
+ export interface ScrollConfig {
3
+ getEditorContent: () => HTMLDivElement | null;
4
+ getSelection: () => Selection;
5
+ getMeasurements: () => {
6
+ lineHeight: number;
7
+ charWidth: number;
8
+ gutterWidth: number;
9
+ contentPadding: number;
10
+ };
11
+ }
12
+ export declare function createEditorScroll(config: ScrollConfig): {
13
+ scrollCursorIntoView: () => Promise<void>;
14
+ };
@@ -0,0 +1,34 @@
1
+ import { tick } from 'svelte';
2
+ import { CONTENT_PADDING } from './constants';
3
+ export function createEditorScroll(config) {
4
+ async function scrollCursorIntoView() {
5
+ await tick();
6
+ const editorContent = config.getEditorContent();
7
+ if (!editorContent)
8
+ return;
9
+ const selection = config.getSelection();
10
+ const { lineHeight, charWidth, gutterWidth } = config.getMeasurements();
11
+ const cursorTop = selection.head.line * lineHeight;
12
+ const cursorLeft = gutterWidth + CONTENT_PADDING + selection.head.column * charWidth;
13
+ const viewportHeight = editorContent.clientHeight;
14
+ const viewportWidth = editorContent.clientWidth;
15
+ const scrollTop = editorContent.scrollTop;
16
+ const scrollLeft = editorContent.scrollLeft;
17
+ // Vertical scroll
18
+ if (cursorTop < scrollTop) {
19
+ editorContent.scrollTop = cursorTop;
20
+ }
21
+ else if (cursorTop + lineHeight > scrollTop + viewportHeight) {
22
+ editorContent.scrollTop = cursorTop + lineHeight - viewportHeight;
23
+ }
24
+ // Horizontal scroll
25
+ const contentStart = gutterWidth + CONTENT_PADDING;
26
+ if (cursorLeft < scrollLeft + contentStart) {
27
+ editorContent.scrollLeft = Math.max(0, cursorLeft - contentStart - 20);
28
+ }
29
+ else if (cursorLeft > scrollLeft + viewportWidth - 20) {
30
+ editorContent.scrollLeft = cursorLeft - viewportWidth + 40;
31
+ }
32
+ }
33
+ return { scrollCursorIntoView };
34
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Editor components and utilities
3
+ */
4
+ export { default as Editor } from './Editor.svelte';
5
+ export { default as CustomEditor } from './CustomEditor.svelte';
6
+ export { default as CollaborativeEditor } from './CollaborativeEditor.svelte';
7
+ export { default as EditorTabs } from './EditorTabs.svelte';
8
+ export { default as EditorPane } from './EditorPane.svelte';
9
+ export { default as FileIcon } from './FileIcon.svelte';
10
+ export { default as FileExplorer } from './FileExplorer.svelte';
11
+ export * from './core';
12
+ export * from './theme';
13
+ export { getLanguageExtension, getLanguageConfig, getLanguageFromExtension, getLanguageFromFilename, getLanguageFromMimeType, getAllLanguageConfigs, resolveLanguage, type LanguageConfig } from './languages';
14
+ export { getSupportedLanguages, isLanguageSupported } from './languages';
15
+ export { getTokenizer, tokenize, getTokenClass, tokensToHTML, PlaintextTokenizer, SimpleTokenizer, GrammarTokenizer, createToken, type Token, type TokenizedLine, type TokenizerState, type TokenType, type LanguageTokenizer, type TokenRule, type LanguageGrammar } from './tokenizer';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Editor components and utilities
3
+ */
4
+ // Components
5
+ export { default as Editor } from './Editor.svelte';
6
+ export { default as CustomEditor } from './CustomEditor.svelte';
7
+ export { default as CollaborativeEditor } from './CollaborativeEditor.svelte';
8
+ export { default as EditorTabs } from './EditorTabs.svelte';
9
+ export { default as EditorPane } from './EditorPane.svelte';
10
+ export { default as FileIcon } from './FileIcon.svelte';
11
+ export { default as FileExplorer } from './FileExplorer.svelte';
12
+ // Core utilities
13
+ export * from './core';
14
+ // Theme
15
+ export * from './theme';
16
+ // Languages (explicit exports to avoid conflicts with tokenizer)
17
+ export { getLanguageExtension, getLanguageConfig, getLanguageFromExtension, getLanguageFromFilename, getLanguageFromMimeType, getAllLanguageConfigs, resolveLanguage } from './languages';
18
+ // Re-export from languages (these exist in both but we prefer languages versions)
19
+ export { getSupportedLanguages, isLanguageSupported } from './languages';
20
+ // Tokenizer (explicit exports to avoid conflicts)
21
+ export { getTokenizer, tokenize, getTokenClass, tokensToHTML, PlaintextTokenizer, SimpleTokenizer, GrammarTokenizer, createToken } from './tokenizer';
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Language support for the custom editor
3
+ *
4
+ * This module provides language detection and configuration
5
+ * using the custom tokenizer system (no CodeMirror dependency).
6
+ */
7
+ /**
8
+ * Language configuration
9
+ */
10
+ export interface LanguageConfig {
11
+ /** Language identifier */
12
+ id: string;
13
+ /** Display name */
14
+ name: string;
15
+ /** File extensions (without dot) */
16
+ extensions: string[];
17
+ /** MIME types */
18
+ mimeTypes: string[];
19
+ /** Line comment prefix */
20
+ lineComment?: string;
21
+ /** Block comment delimiters */
22
+ blockComment?: [string, string];
23
+ /** Auto-closing pairs */
24
+ autoClosingPairs?: Array<[string, string]>;
25
+ /** Surrounding pairs */
26
+ surroundingPairs?: Array<[string, string]>;
27
+ /** Word pattern regex */
28
+ wordPattern?: RegExp;
29
+ }
30
+ /**
31
+ * Get language ID from file extension
32
+ */
33
+ export declare function getLanguageFromExtension(extension: string): string;
34
+ /**
35
+ * Get language ID from MIME type
36
+ */
37
+ export declare function getLanguageFromMimeType(mimeType: string): string;
38
+ /**
39
+ * Get language ID from filename
40
+ */
41
+ export declare function getLanguageFromFilename(filename: string): string;
42
+ /**
43
+ * Get language configuration
44
+ */
45
+ export declare function getLanguageConfig(language: string): LanguageConfig;
46
+ /**
47
+ * Check if a language is supported
48
+ */
49
+ export declare function isLanguageSupported(language: string): boolean;
50
+ /**
51
+ * Get list of supported languages
52
+ */
53
+ export declare function getSupportedLanguages(): string[];
54
+ /**
55
+ * Get all language configurations
56
+ */
57
+ export declare function getAllLanguageConfigs(): LanguageConfig[];
58
+ /**
59
+ * @deprecated Use getLanguageConfig instead
60
+ */
61
+ export declare function getLanguageExtension(language: string): Promise<string | null>;
62
+ export { resolveLanguage } from './tokenizer';
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Language support for the custom editor
3
+ *
4
+ * This module provides language detection and configuration
5
+ * using the custom tokenizer system (no CodeMirror dependency).
6
+ */
7
+ import { resolveLanguage, isLanguageSupported as tokenizerSupported, getSupportedLanguages as getTokenizerLanguages } from './tokenizer';
8
+ /**
9
+ * Language configurations
10
+ */
11
+ const languages = {
12
+ javascript: {
13
+ id: 'javascript',
14
+ name: 'JavaScript',
15
+ extensions: ['js', 'mjs', 'cjs'],
16
+ mimeTypes: ['text/javascript', 'application/javascript'],
17
+ lineComment: '//',
18
+ blockComment: ['/*', '*/'],
19
+ autoClosingPairs: [
20
+ ['{', '}'],
21
+ ['[', ']'],
22
+ ['(', ')'],
23
+ ['"', '"'],
24
+ ["'", "'"],
25
+ ['`', '`']
26
+ ],
27
+ surroundingPairs: [
28
+ ['{', '}'],
29
+ ['[', ']'],
30
+ ['(', ')'],
31
+ ['"', '"'],
32
+ ["'", "'"],
33
+ ['`', '`']
34
+ ],
35
+ wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g
36
+ },
37
+ typescript: {
38
+ id: 'typescript',
39
+ name: 'TypeScript',
40
+ extensions: ['ts', 'mts', 'cts'],
41
+ mimeTypes: ['text/typescript', 'application/typescript'],
42
+ lineComment: '//',
43
+ blockComment: ['/*', '*/'],
44
+ autoClosingPairs: [
45
+ ['{', '}'],
46
+ ['[', ']'],
47
+ ['(', ')'],
48
+ ['"', '"'],
49
+ ["'", "'"],
50
+ ['`', '`'],
51
+ ['<', '>']
52
+ ],
53
+ surroundingPairs: [
54
+ ['{', '}'],
55
+ ['[', ']'],
56
+ ['(', ')'],
57
+ ['"', '"'],
58
+ ["'", "'"],
59
+ ['`', '`'],
60
+ ['<', '>']
61
+ ]
62
+ },
63
+ jsx: {
64
+ id: 'jsx',
65
+ name: 'JavaScript React',
66
+ extensions: ['jsx'],
67
+ mimeTypes: ['text/jsx'],
68
+ lineComment: '//',
69
+ blockComment: ['/*', '*/'],
70
+ autoClosingPairs: [
71
+ ['{', '}'],
72
+ ['[', ']'],
73
+ ['(', ')'],
74
+ ['"', '"'],
75
+ ["'", "'"],
76
+ ['`', '`'],
77
+ ['<', '>']
78
+ ]
79
+ },
80
+ tsx: {
81
+ id: 'tsx',
82
+ name: 'TypeScript React',
83
+ extensions: ['tsx'],
84
+ mimeTypes: ['text/tsx'],
85
+ lineComment: '//',
86
+ blockComment: ['/*', '*/'],
87
+ autoClosingPairs: [
88
+ ['{', '}'],
89
+ ['[', ']'],
90
+ ['(', ')'],
91
+ ['"', '"'],
92
+ ["'", "'"],
93
+ ['`', '`'],
94
+ ['<', '>']
95
+ ]
96
+ },
97
+ html: {
98
+ id: 'html',
99
+ name: 'HTML',
100
+ extensions: ['html', 'htm', 'xhtml'],
101
+ mimeTypes: ['text/html'],
102
+ blockComment: ['<!--', '-->'],
103
+ autoClosingPairs: [
104
+ ['{', '}'],
105
+ ['[', ']'],
106
+ ['(', ')'],
107
+ ['"', '"'],
108
+ ["'", "'"],
109
+ ['<', '>']
110
+ ]
111
+ },
112
+ css: {
113
+ id: 'css',
114
+ name: 'CSS',
115
+ extensions: ['css'],
116
+ mimeTypes: ['text/css'],
117
+ blockComment: ['/*', '*/'],
118
+ autoClosingPairs: [
119
+ ['{', '}'],
120
+ ['[', ']'],
121
+ ['(', ')'],
122
+ ['"', '"'],
123
+ ["'", "'"]
124
+ ]
125
+ },
126
+ json: {
127
+ id: 'json',
128
+ name: 'JSON',
129
+ extensions: ['json', 'jsonc', 'json5'],
130
+ mimeTypes: ['application/json'],
131
+ autoClosingPairs: [
132
+ ['{', '}'],
133
+ ['[', ']'],
134
+ ['"', '"']
135
+ ]
136
+ },
137
+ python: {
138
+ id: 'python',
139
+ name: 'Python',
140
+ extensions: ['py', 'pyw', 'pyi'],
141
+ mimeTypes: ['text/x-python'],
142
+ lineComment: '#',
143
+ autoClosingPairs: [
144
+ ['{', '}'],
145
+ ['[', ']'],
146
+ ['(', ')'],
147
+ ['"', '"'],
148
+ ["'", "'"]
149
+ ]
150
+ },
151
+ go: {
152
+ id: 'go',
153
+ name: 'Go',
154
+ extensions: ['go'],
155
+ mimeTypes: ['text/x-go'],
156
+ lineComment: '//',
157
+ blockComment: ['/*', '*/'],
158
+ autoClosingPairs: [
159
+ ['{', '}'],
160
+ ['[', ']'],
161
+ ['(', ')'],
162
+ ['"', '"'],
163
+ ["'", "'"],
164
+ ['`', '`']
165
+ ]
166
+ },
167
+ markdown: {
168
+ id: 'markdown',
169
+ name: 'Markdown',
170
+ extensions: ['md', 'markdown', 'mdown', 'mkd'],
171
+ mimeTypes: ['text/markdown'],
172
+ autoClosingPairs: [
173
+ ['[', ']'],
174
+ ['(', ')'],
175
+ ['"', '"'],
176
+ ["'", "'"],
177
+ ['`', '`'],
178
+ ['*', '*'],
179
+ ['_', '_']
180
+ ]
181
+ },
182
+ xml: {
183
+ id: 'xml',
184
+ name: 'XML',
185
+ extensions: ['xml', 'xsl', 'xslt', 'svg', 'rss', 'atom'],
186
+ mimeTypes: ['text/xml', 'application/xml'],
187
+ blockComment: ['<!--', '-->'],
188
+ autoClosingPairs: [
189
+ ['"', '"'],
190
+ ["'", "'"],
191
+ ['<', '>']
192
+ ]
193
+ },
194
+ yaml: {
195
+ id: 'yaml',
196
+ name: 'YAML',
197
+ extensions: ['yaml', 'yml'],
198
+ mimeTypes: ['text/yaml'],
199
+ lineComment: '#',
200
+ autoClosingPairs: [
201
+ ['{', '}'],
202
+ ['[', ']'],
203
+ ['(', ')'],
204
+ ['"', '"'],
205
+ ["'", "'"]
206
+ ]
207
+ },
208
+ plaintext: {
209
+ id: 'plaintext',
210
+ name: 'Plain Text',
211
+ extensions: ['txt', 'text'],
212
+ mimeTypes: ['text/plain'],
213
+ autoClosingPairs: []
214
+ }
215
+ };
216
+ // Extension to language mapping
217
+ const extensionMap = new Map();
218
+ for (const [id, config] of Object.entries(languages)) {
219
+ for (const ext of config.extensions) {
220
+ extensionMap.set(ext.toLowerCase(), id);
221
+ }
222
+ }
223
+ // MIME type to language mapping
224
+ const mimeMap = new Map();
225
+ for (const [id, config] of Object.entries(languages)) {
226
+ for (const mime of config.mimeTypes) {
227
+ mimeMap.set(mime.toLowerCase(), id);
228
+ }
229
+ }
230
+ /**
231
+ * Get language ID from file extension
232
+ */
233
+ export function getLanguageFromExtension(extension) {
234
+ const ext = extension.toLowerCase().replace(/^\./, '');
235
+ return extensionMap.get(ext) ?? 'plaintext';
236
+ }
237
+ /**
238
+ * Get language ID from MIME type
239
+ */
240
+ export function getLanguageFromMimeType(mimeType) {
241
+ return mimeMap.get(mimeType.toLowerCase()) ?? 'plaintext';
242
+ }
243
+ /**
244
+ * Get language ID from filename
245
+ */
246
+ export function getLanguageFromFilename(filename) {
247
+ const ext = filename.split('.').pop() ?? '';
248
+ return getLanguageFromExtension(ext);
249
+ }
250
+ /**
251
+ * Get language configuration
252
+ */
253
+ export function getLanguageConfig(language) {
254
+ const resolved = resolveLanguage(language);
255
+ return languages[resolved] ?? languages['plaintext'];
256
+ }
257
+ /**
258
+ * Check if a language is supported
259
+ */
260
+ export function isLanguageSupported(language) {
261
+ return tokenizerSupported(language);
262
+ }
263
+ /**
264
+ * Get list of supported languages
265
+ */
266
+ export function getSupportedLanguages() {
267
+ return getTokenizerLanguages();
268
+ }
269
+ /**
270
+ * Get all language configurations
271
+ */
272
+ export function getAllLanguageConfigs() {
273
+ return Object.values(languages);
274
+ }
275
+ // For backwards compatibility - these functions previously loaded CodeMirror extensions
276
+ // Now they just return the language string since tokenization is handled internally
277
+ /**
278
+ * @deprecated Use getLanguageConfig instead
279
+ */
280
+ export async function getLanguageExtension(language) {
281
+ const resolved = resolveLanguage(language);
282
+ return isLanguageSupported(resolved) ? resolved : null;
283
+ }
284
+ // Re-export tokenizer functions for convenience
285
+ export { resolveLanguage } from './tokenizer';