@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,182 @@
1
+ <script lang="ts">
2
+ /**
3
+ * EditorLines - Renders the main line loop with gutter, tokens, and fold placeholders.
4
+ *
5
+ * Internal sub-component extracted from CustomEditor.svelte.
6
+ * Not exported from the library — used only by CustomEditor.
7
+ */
8
+ import type { TokenizedLine } from './tokenizer';
9
+ import TokenRenderer from './TokenRenderer.svelte';
10
+ import EditorGutter from './EditorGutter.svelte';
11
+
12
+ interface LineData {
13
+ tokens?: TokenizedLine;
14
+ text?: string;
15
+ }
16
+
17
+ interface Props {
18
+ /**
19
+ * Virtualized slice of the (folded) visible line sequence. Only the rows
20
+ * intersecting the viewport (+ overscan) are passed in. Each entry carries:
21
+ * - `line`: the line data to render
22
+ * - `index`: the raw 0-based line index (for gutter numbers, folds)
23
+ * - `visualRow`: the absolute visual-row position, used to position the
24
+ * rendered line at its true offset (visualRow * lineHeight)
25
+ */
26
+ windowedLines: Array<{ line: LineData | undefined; index: number; visualRow: number }>;
27
+ /** Full scrollable content height in px (spacer keeps the scrollbar correct). */
28
+ totalHeight: number;
29
+ lineHeight: number;
30
+ activeLine: number;
31
+ highlightActiveLine: boolean;
32
+ lineNumbers: string; // 'on' | 'off'
33
+ gutterWidth: number;
34
+ tabSize: number;
35
+ folding: boolean;
36
+ hasFoldIndicator: (line: number) => boolean;
37
+ isFoldCollapsed: (line: number) => boolean;
38
+ getHiddenLineCount: (line: number) => number;
39
+ onFoldIndicatorClick: (line: number, e: MouseEvent) => void;
40
+ onExpandFold: (line: number) => void;
41
+ }
42
+
43
+ let {
44
+ windowedLines,
45
+ totalHeight,
46
+ lineHeight,
47
+ activeLine,
48
+ highlightActiveLine,
49
+ lineNumbers,
50
+ gutterWidth,
51
+ tabSize,
52
+ folding,
53
+ hasFoldIndicator,
54
+ isFoldCollapsed,
55
+ getHiddenLineCount,
56
+ onFoldIndicatorClick,
57
+ onExpandFold
58
+ }: Props = $props();
59
+ </script>
60
+
61
+ <div class="custom-editor__lines" style="height: {totalHeight}px;">
62
+ {#each windowedLines as { line, index, visualRow } (index)}
63
+ <div
64
+ class="custom-editor__line"
65
+ class:custom-editor__line--active={highlightActiveLine && activeLine === index}
66
+ style="top: {visualRow * lineHeight}px;"
67
+ data-line-index={index}
68
+ >
69
+ <EditorGutter
70
+ lineIndex={index}
71
+ {lineNumbers}
72
+ {gutterWidth}
73
+ {folding}
74
+ hasFoldIndicator={hasFoldIndicator(index)}
75
+ isFoldCollapsed={isFoldCollapsed(index)}
76
+ hiddenLineCount={getHiddenLineCount(index)}
77
+ {onFoldIndicatorClick}
78
+ />
79
+
80
+ <!-- Line content -->
81
+ <div class="custom-editor__line-content">
82
+ <TokenRenderer tokens={line?.tokens} {tabSize} />
83
+ {#if folding && isFoldCollapsed(index)}
84
+ <button
85
+ class="custom-editor__fold-placeholder"
86
+ title="{getHiddenLineCount(index)} lines hidden"
87
+ onclick={(e) => { e.stopPropagation(); onExpandFold(index); }}
88
+ aria-label="Expand {getHiddenLineCount(index)} hidden lines"
89
+ >...</button>
90
+ {/if}
91
+ </div>
92
+ </div>
93
+ {/each}
94
+ </div>
95
+
96
+ <style>
97
+ .custom-editor__lines {
98
+ position: relative;
99
+ min-height: 100%;
100
+ z-index: 2;
101
+ }
102
+
103
+ /*
104
+ * Each line is absolutely positioned at its true vertical offset
105
+ * (top = visualRow * lineHeight, set inline). This lets us render only the
106
+ * windowed slice of rows while keeping every line at the correct position;
107
+ * the parent .custom-editor__lines reserves the full document height so the
108
+ * scrollbar range stays correct.
109
+ */
110
+ .custom-editor__line {
111
+ position: absolute;
112
+ left: 0;
113
+ display: flex;
114
+ /* At least full width (so active-line highlight spans the viewport) but free
115
+ to grow with long, non-wrapping content for horizontal scrolling. */
116
+ min-width: 100%;
117
+ width: max-content;
118
+ height: var(--editor-line-height);
119
+ line-height: var(--editor-line-height);
120
+ min-height: var(--editor-line-height);
121
+ cursor: default;
122
+ }
123
+
124
+ .custom-editor__line--active {
125
+ background: var(--ide-bg-elevated);
126
+ box-shadow: inset 2px 0 0 0 var(--ide-interactive);
127
+ }
128
+
129
+ /* Gutter overrides for active line (cross-component into EditorGutter) */
130
+ .custom-editor__line--active :global(.custom-editor__gutter) {
131
+ background: var(--ide-bg-elevated);
132
+ }
133
+
134
+ .custom-editor__line--active :global(.custom-editor__line-number) {
135
+ color: var(--ide-text-secondary);
136
+ }
137
+
138
+ /* Show fold indicator on line hover (cross-component into EditorGutter) */
139
+ .custom-editor__line:hover :global(.custom-editor__fold-indicator) {
140
+ opacity: 1;
141
+ }
142
+
143
+ .custom-editor__line-content {
144
+ flex: 1;
145
+ white-space: pre;
146
+ padding-left: 8px;
147
+ cursor: text;
148
+ }
149
+
150
+ /* Ensure line-content cursor doesn't affect siblings */
151
+ .custom-editor__line-content,
152
+ .custom-editor__line-content * {
153
+ cursor: text;
154
+ }
155
+
156
+ /* Fold placeholder (ellipsis) - styled as inline button */
157
+ .custom-editor__fold-placeholder {
158
+ display: inline-block;
159
+ margin-left: 4px;
160
+ padding: 0 6px;
161
+ background: var(--ide-bg-tertiary);
162
+ border: 1px solid var(--ide-border);
163
+ border-radius: 3px;
164
+ color: var(--ide-text-muted);
165
+ font: inherit;
166
+ font-size: 0.85em;
167
+ cursor: pointer;
168
+ vertical-align: middle;
169
+ line-height: 1.2;
170
+ }
171
+
172
+ .custom-editor__fold-placeholder:hover {
173
+ background: var(--ide-bg-elevated);
174
+ color: var(--ide-text-secondary);
175
+ border-color: var(--ide-interactive);
176
+ }
177
+
178
+ .custom-editor__fold-placeholder:focus {
179
+ outline: 2px solid var(--ide-interactive);
180
+ outline-offset: 1px;
181
+ }
182
+ </style>
@@ -0,0 +1,43 @@
1
+ /**
2
+ * EditorLines - Renders the main line loop with gutter, tokens, and fold placeholders.
3
+ *
4
+ * Internal sub-component extracted from CustomEditor.svelte.
5
+ * Not exported from the library — used only by CustomEditor.
6
+ */
7
+ import type { TokenizedLine } from './tokenizer';
8
+ interface LineData {
9
+ tokens?: TokenizedLine;
10
+ text?: string;
11
+ }
12
+ interface Props {
13
+ /**
14
+ * Virtualized slice of the (folded) visible line sequence. Only the rows
15
+ * intersecting the viewport (+ overscan) are passed in. Each entry carries:
16
+ * - `line`: the line data to render
17
+ * - `index`: the raw 0-based line index (for gutter numbers, folds)
18
+ * - `visualRow`: the absolute visual-row position, used to position the
19
+ * rendered line at its true offset (visualRow * lineHeight)
20
+ */
21
+ windowedLines: Array<{
22
+ line: LineData | undefined;
23
+ index: number;
24
+ visualRow: number;
25
+ }>;
26
+ /** Full scrollable content height in px (spacer keeps the scrollbar correct). */
27
+ totalHeight: number;
28
+ lineHeight: number;
29
+ activeLine: number;
30
+ highlightActiveLine: boolean;
31
+ lineNumbers: string;
32
+ gutterWidth: number;
33
+ tabSize: number;
34
+ folding: boolean;
35
+ hasFoldIndicator: (line: number) => boolean;
36
+ isFoldCollapsed: (line: number) => boolean;
37
+ getHiddenLineCount: (line: number) => number;
38
+ onFoldIndicatorClick: (line: number, e: MouseEvent) => void;
39
+ onExpandFold: (line: number) => void;
40
+ }
41
+ declare const EditorLines: import("svelte").Component<Props, {}, "">;
42
+ type EditorLines = ReturnType<typeof EditorLines>;
43
+ export default EditorLines;
@@ -0,0 +1,134 @@
1
+ <script lang="ts">
2
+ import Editor from './Editor.svelte';
3
+ import EditorTabs from './EditorTabs.svelte';
4
+ import type { EditorTab, EditorPreferences } from '../../types';
5
+ import {
6
+ getTabs,
7
+ getActiveTab,
8
+ getActiveTabId,
9
+ setActiveTab,
10
+ closeTab,
11
+ updateContent,
12
+ markSaved,
13
+ updateCursor
14
+ } from '../../stores/editor.svelte';
15
+
16
+ interface Props {
17
+ preferences?: Partial<EditorPreferences>;
18
+ onSave?: (path: string, content: string) => Promise<void>;
19
+ class?: string;
20
+ }
21
+
22
+ let { preferences = {}, onSave, class: className = '' }: Props = $props();
23
+
24
+ // Use getter functions for reactive access
25
+ let tabs = $derived(getTabs());
26
+ let activeTab = $derived(getActiveTab());
27
+ let activeTabId = $derived(getActiveTabId());
28
+
29
+ async function handleSave() {
30
+ if (!activeTab) return;
31
+
32
+ if (onSave) {
33
+ await onSave(activeTab.path, activeTab.content);
34
+ }
35
+ markSaved(activeTab.id);
36
+ }
37
+
38
+ function handleChange(content: string) {
39
+ if (activeTab) {
40
+ updateContent(activeTab.id, content);
41
+ }
42
+ }
43
+
44
+ function handleCursorChange(line: number, column: number) {
45
+ if (activeTab) {
46
+ updateCursor(activeTab.id, { line, column });
47
+ }
48
+ }
49
+
50
+ function handleCloseTab(tabId: string) {
51
+ const tab = tabs.find((t) => t.id === tabId);
52
+ if (tab?.isDirty) {
53
+ // Could show confirmation dialog
54
+ if (!confirm(`"${tab.name}" has unsaved changes. Close anyway?`)) {
55
+ return;
56
+ }
57
+ }
58
+ closeTab(tabId);
59
+ }
60
+ </script>
61
+
62
+ <div class="editor-pane {className}">
63
+ {#if tabs.length > 0}
64
+ <EditorTabs
65
+ {tabs}
66
+ {activeTabId}
67
+ onSelect={setActiveTab}
68
+ onClose={handleCloseTab}
69
+ />
70
+
71
+ {#if activeTab}
72
+ <div class="editor-pane__content">
73
+ <Editor
74
+ content={activeTab.content}
75
+ language={activeTab.language}
76
+ readonly={activeTab.aiEditing}
77
+ {preferences}
78
+ onChange={handleChange}
79
+ onCursorChange={handleCursorChange}
80
+ onSave={handleSave}
81
+ />
82
+ </div>
83
+ {/if}
84
+ {:else}
85
+ <div class="editor-pane__empty">
86
+ <p>No files open</p>
87
+ <p class="editor-pane__hint">
88
+ Open a file from the explorer or use <kbd>Cmd/Ctrl+P</kbd> to quick open
89
+ </p>
90
+ </div>
91
+ {/if}
92
+ </div>
93
+
94
+ <style>
95
+ .editor-pane {
96
+ display: flex;
97
+ flex-direction: column;
98
+ height: 100%;
99
+ background: var(--ide-bg-primary);
100
+ }
101
+
102
+ .editor-pane__content {
103
+ flex: 1;
104
+ min-height: 0;
105
+ }
106
+
107
+ .editor-pane__empty {
108
+ display: flex;
109
+ flex-direction: column;
110
+ align-items: center;
111
+ justify-content: center;
112
+ height: 100%;
113
+ text-align: center;
114
+ color: var(--ide-text-muted);
115
+ }
116
+
117
+ .editor-pane__empty p {
118
+ margin: 0;
119
+ }
120
+
121
+ .editor-pane__hint {
122
+ margin-top: var(--ide-spacing-sm) !important;
123
+ font-size: var(--ide-font-size-xs);
124
+ }
125
+
126
+ .editor-pane__hint kbd {
127
+ padding: 2px 6px;
128
+ font-family: var(--ide-font-mono);
129
+ font-size: 10px;
130
+ background: var(--ide-bg-secondary);
131
+ border: 1px solid var(--ide-border);
132
+ border-radius: var(--ide-radius-sm);
133
+ }
134
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { EditorPreferences } from '../../types';
2
+ interface Props {
3
+ preferences?: Partial<EditorPreferences>;
4
+ onSave?: (path: string, content: string) => Promise<void>;
5
+ class?: string;
6
+ }
7
+ declare const EditorPane: import("svelte").Component<Props, {}, "">;
8
+ type EditorPane = ReturnType<typeof EditorPane>;
9
+ export default EditorPane;
@@ -0,0 +1,186 @@
1
+ <script lang="ts">
2
+ /**
3
+ * EditorSelections - Renders selection rectangles and cursors for all cursors.
4
+ *
5
+ * Internal sub-component extracted from CustomEditor.svelte.
6
+ * Not exported from the library — used only by CustomEditor.
7
+ */
8
+ import {
9
+ type Cursor,
10
+ type Position,
11
+ getSelectionStart,
12
+ getSelectionEnd,
13
+ isSelectionEmpty
14
+ } from './core';
15
+ import { CONTENT_PADDING, FALLBACK_VIEWPORT_HEIGHT } from './constants';
16
+
17
+ interface Props {
18
+ cursors: readonly Cursor[];
19
+ cursorVisible: boolean;
20
+ readonly: boolean;
21
+ lineHeight: number;
22
+ charWidth: number;
23
+ gutterWidth: number;
24
+ contentPadding: number;
25
+ scrollTop: number;
26
+ viewportHeight: number;
27
+ getLine: (n: number) => { text: string } | undefined;
28
+ lineCount: number;
29
+ }
30
+
31
+ let {
32
+ cursors,
33
+ cursorVisible,
34
+ readonly: isReadonly,
35
+ lineHeight,
36
+ charWidth,
37
+ gutterWidth,
38
+ contentPadding,
39
+ scrollTop,
40
+ viewportHeight,
41
+ getLine,
42
+ lineCount
43
+ }: Props = $props();
44
+
45
+ // Selection rects memoization
46
+ let cachedSelectionRects: Array<{ top: number; left: number; width: number; height: number; isPrimary: boolean }> = [];
47
+ let cachedSelectionKey = '';
48
+
49
+ // Get selection rectangles for all cursors (memoized and virtualized to viewport)
50
+ function getSelectionRects(): Array<{ top: number; left: number; width: number; height: number; isPrimary: boolean }> {
51
+ // Check if any cursor has a selection
52
+ const anySelection = cursors.some(c => !isSelectionEmpty(c.selection));
53
+ if (!anySelection) {
54
+ cachedSelectionRects = [];
55
+ cachedSelectionKey = '';
56
+ return [];
57
+ }
58
+
59
+ // Calculate visible line range (with 1-line buffer for smooth scrolling)
60
+ const vh = viewportHeight || FALLBACK_VIEWPORT_HEIGHT;
61
+ const firstVisibleLine = Math.max(0, Math.floor(scrollTop / lineHeight) - 1);
62
+ const lastVisibleLine = Math.min(
63
+ lineCount - 1,
64
+ Math.ceil((scrollTop + vh) / lineHeight) + 1
65
+ );
66
+
67
+ // Create cache key from all cursors, scroll position, and measurement values
68
+ const cursorKeys = cursors.map(c =>
69
+ `${c.id}:${c.selection.anchor.line}:${c.selection.anchor.column}-${c.selection.head.line}:${c.selection.head.column}`
70
+ ).join('|');
71
+ const key = `${cursorKeys}@${firstVisibleLine}-${lastVisibleLine}:${charWidth}:${lineHeight}:${gutterWidth}`;
72
+ if (key === cachedSelectionKey) {
73
+ return cachedSelectionRects;
74
+ }
75
+
76
+ const rects: Array<{ top: number; left: number; width: number; height: number; isPrimary: boolean }> = [];
77
+
78
+ // Process each cursor's selection
79
+ for (const cursor of cursors) {
80
+ if (isSelectionEmpty(cursor.selection)) continue;
81
+
82
+ const start = getSelectionStart(cursor.selection);
83
+ const end = getSelectionEnd(cursor.selection);
84
+
85
+ // Only iterate over lines that are both selected AND visible
86
+ const renderStart = Math.max(start.line, firstVisibleLine);
87
+ const renderEnd = Math.min(end.line, lastVisibleLine);
88
+
89
+ for (let line = renderStart; line <= renderEnd; line++) {
90
+ const lineContent = getLine(line);
91
+ if (!lineContent) continue;
92
+
93
+ let startCol = 0;
94
+ let endCol = lineContent.text.length;
95
+
96
+ if (line === start.line) {
97
+ startCol = start.column;
98
+ }
99
+ if (line === end.line) {
100
+ endCol = end.column;
101
+ }
102
+
103
+ // Ensure minimum width for empty selections at line end
104
+ const width = Math.max((endCol - startCol) * charWidth, 4);
105
+
106
+ rects.push({
107
+ top: line * lineHeight,
108
+ left: gutterWidth + contentPadding + startCol * charWidth,
109
+ width,
110
+ height: lineHeight,
111
+ isPrimary: cursor.isPrimary
112
+ });
113
+ }
114
+ }
115
+
116
+ cachedSelectionKey = key;
117
+ cachedSelectionRects = rects;
118
+ return rects;
119
+ }
120
+
121
+ // Get cursor style for a specific cursor position
122
+ function getCursorStyleForPosition(pos: Position): string {
123
+ const left = gutterWidth + contentPadding + pos.column * charWidth;
124
+ const top = pos.line * lineHeight;
125
+ return `left: ${left}px; top: ${top}px; height: ${lineHeight}px;`;
126
+ }
127
+ </script>
128
+
129
+ <!-- Selection layer (all cursor selections) -->
130
+ <div class="custom-editor__selections">
131
+ {#each getSelectionRects() as rect}
132
+ <div
133
+ class="custom-editor__selection"
134
+ class:custom-editor__selection--secondary={!rect.isPrimary}
135
+ style="top: {rect.top}px; left: {rect.left}px; width: {rect.width}px; height: {rect.height}px;"
136
+ ></div>
137
+ {/each}
138
+ </div>
139
+
140
+ <!-- Cursors (all cursors rendered with primary/secondary distinction) -->
141
+ {#if cursorVisible && !isReadonly}
142
+ {#each cursors as cursor (cursor.id)}
143
+ <div
144
+ class="custom-editor__cursor"
145
+ class:custom-editor__cursor--secondary={!cursor.isPrimary}
146
+ style={getCursorStyleForPosition(cursor.selection.head)}
147
+ ></div>
148
+ {/each}
149
+ {/if}
150
+
151
+ <style>
152
+ .custom-editor__selections {
153
+ position: absolute;
154
+ top: 0;
155
+ left: 0;
156
+ right: 0;
157
+ pointer-events: none;
158
+ z-index: 1;
159
+ }
160
+
161
+ .custom-editor__selection {
162
+ position: absolute;
163
+ /* Translucent wash so syntax-colored text remains legible underneath */
164
+ background: color-mix(in srgb, var(--ide-interactive) 28%, transparent);
165
+ }
166
+
167
+ /* Secondary selection (slightly different shade) */
168
+ .custom-editor__selection--secondary {
169
+ background: var(--ide-bg-selection-secondary);
170
+ }
171
+
172
+ .custom-editor__cursor {
173
+ position: absolute;
174
+ width: 2px;
175
+ background: var(--color-nocturnium-aurora-blue);
176
+ z-index: 10;
177
+ pointer-events: none;
178
+ transition: opacity 80ms;
179
+ }
180
+
181
+ /* Secondary cursor (slightly dimmer to distinguish from primary) */
182
+ .custom-editor__cursor--secondary {
183
+ background: var(--ide-interactive-muted);
184
+ opacity: 0.85;
185
+ }
186
+ </style>
@@ -0,0 +1,25 @@
1
+ /**
2
+ * EditorSelections - Renders selection rectangles and cursors for all cursors.
3
+ *
4
+ * Internal sub-component extracted from CustomEditor.svelte.
5
+ * Not exported from the library — used only by CustomEditor.
6
+ */
7
+ import { type Cursor } from './core';
8
+ interface Props {
9
+ cursors: readonly Cursor[];
10
+ cursorVisible: boolean;
11
+ readonly: boolean;
12
+ lineHeight: number;
13
+ charWidth: number;
14
+ gutterWidth: number;
15
+ contentPadding: number;
16
+ scrollTop: number;
17
+ viewportHeight: number;
18
+ getLine: (n: number) => {
19
+ text: string;
20
+ } | undefined;
21
+ lineCount: number;
22
+ }
23
+ declare const EditorSelections: import("svelte").Component<Props, {}, "">;
24
+ type EditorSelections = ReturnType<typeof EditorSelections>;
25
+ export default EditorSelections;