@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,427 @@
1
+ /**
2
+ * Quick Actions (Code Actions) Manager
3
+ *
4
+ * Provides contextual code actions like:
5
+ * - Quick fixes for errors/warnings
6
+ * - Refactoring operations
7
+ * - Code generation
8
+ * - Import suggestions
9
+ */
10
+ /**
11
+ * Quick Actions Manager
12
+ */
13
+ export class QuickActionsManager {
14
+ _config = {
15
+ enabled: true,
16
+ showLightbulb: true,
17
+ autoShow: true,
18
+ showDelay: 300
19
+ };
20
+ _providers = new Map();
21
+ _currentActions = [];
22
+ _currentContext = null;
23
+ _listeners = new Set();
24
+ _showTimeout = null;
25
+ constructor() {
26
+ // Register built-in providers
27
+ this.registerBuiltinProviders();
28
+ }
29
+ /**
30
+ * Register built-in action providers
31
+ */
32
+ registerBuiltinProviders() {
33
+ // Quick fix provider for common issues
34
+ this.registerProvider('quickfix', (ctx) => {
35
+ const actions = [];
36
+ // Fix for unused variables
37
+ if (ctx.lineContent.includes('const ') || ctx.lineContent.includes('let ')) {
38
+ const match = ctx.lineContent.match(/(?:const|let)\s+(\w+)/);
39
+ if (match) {
40
+ actions.push({
41
+ id: `remove-unused-${match[1]}`,
42
+ title: `Remove unused variable '${match[1]}'`,
43
+ kind: 'quickfix',
44
+ description: 'Remove the declaration of unused variable',
45
+ edit: {
46
+ changes: [{
47
+ range: {
48
+ start: { line: ctx.position.line, column: 0 },
49
+ end: { line: ctx.position.line + 1, column: 0 }
50
+ },
51
+ newText: ''
52
+ }]
53
+ }
54
+ });
55
+ }
56
+ }
57
+ // Add missing semicolon
58
+ if (!ctx.lineContent.trim().endsWith(';') &&
59
+ !ctx.lineContent.trim().endsWith('{') &&
60
+ !ctx.lineContent.trim().endsWith('}') &&
61
+ !ctx.lineContent.trim().endsWith(',') &&
62
+ ctx.lineContent.trim().length > 0) {
63
+ actions.push({
64
+ id: 'add-semicolon',
65
+ title: 'Add missing semicolon',
66
+ kind: 'quickfix',
67
+ isPreferred: true,
68
+ edit: {
69
+ changes: [{
70
+ range: {
71
+ start: { line: ctx.position.line, column: ctx.lineContent.trimEnd().length },
72
+ end: { line: ctx.position.line, column: ctx.lineContent.trimEnd().length }
73
+ },
74
+ newText: ';'
75
+ }]
76
+ }
77
+ });
78
+ }
79
+ return actions;
80
+ });
81
+ // Refactoring provider
82
+ this.registerProvider('refactor', (ctx) => {
83
+ const actions = [];
84
+ // Extract to variable
85
+ if (ctx.selectedText && ctx.selectedText.length > 0) {
86
+ actions.push({
87
+ id: 'extract-variable',
88
+ title: 'Extract to variable',
89
+ kind: 'refactor.extract',
90
+ shortcut: 'Ctrl+Alt+V',
91
+ command: {
92
+ command: 'refactor.extractVariable',
93
+ title: 'Extract Variable',
94
+ arguments: [ctx.selection, ctx.selectedText]
95
+ }
96
+ });
97
+ // Extract to function
98
+ if (ctx.selectedText.includes('\n') || ctx.selectedText.length > 50) {
99
+ actions.push({
100
+ id: 'extract-function',
101
+ title: 'Extract to function',
102
+ kind: 'refactor.extract',
103
+ shortcut: 'Ctrl+Alt+M',
104
+ command: {
105
+ command: 'refactor.extractFunction',
106
+ title: 'Extract Function',
107
+ arguments: [ctx.selection, ctx.selectedText]
108
+ }
109
+ });
110
+ }
111
+ }
112
+ // Rename symbol
113
+ const wordMatch = ctx.lineContent.substring(0, ctx.position.column).match(/\w+$/);
114
+ if (wordMatch) {
115
+ actions.push({
116
+ id: 'rename-symbol',
117
+ title: `Rename '${wordMatch[0]}'`,
118
+ kind: 'refactor.rename',
119
+ shortcut: 'F2',
120
+ command: {
121
+ command: 'refactor.rename',
122
+ title: 'Rename Symbol',
123
+ arguments: [ctx.position, wordMatch[0]]
124
+ }
125
+ });
126
+ }
127
+ // Convert to arrow function
128
+ if (ctx.lineContent.includes('function ')) {
129
+ actions.push({
130
+ id: 'convert-to-arrow',
131
+ title: 'Convert to arrow function',
132
+ kind: 'refactor',
133
+ description: 'Convert function declaration to arrow function expression'
134
+ });
135
+ }
136
+ // Convert to template literal
137
+ if (ctx.lineContent.includes(' + ') && (ctx.lineContent.includes('"') || ctx.lineContent.includes("'"))) {
138
+ actions.push({
139
+ id: 'convert-to-template',
140
+ title: 'Convert to template literal',
141
+ kind: 'refactor',
142
+ description: 'Convert string concatenation to template literal'
143
+ });
144
+ }
145
+ return actions;
146
+ });
147
+ // Source actions provider
148
+ this.registerProvider('source', (ctx) => {
149
+ const actions = [];
150
+ // Organize imports
151
+ if (ctx.lineContent.includes('import ') || ctx.position.line < 20) {
152
+ actions.push({
153
+ id: 'organize-imports',
154
+ title: 'Organize imports',
155
+ kind: 'source.organizeImports',
156
+ shortcut: 'Shift+Alt+O',
157
+ command: {
158
+ command: 'source.organizeImports',
159
+ title: 'Organize Imports'
160
+ }
161
+ });
162
+ }
163
+ // Fix all auto-fixable issues
164
+ actions.push({
165
+ id: 'fix-all',
166
+ title: 'Fix all auto-fixable problems',
167
+ kind: 'source.fixAll',
168
+ command: {
169
+ command: 'source.fixAll',
170
+ title: 'Fix All'
171
+ }
172
+ });
173
+ return actions;
174
+ });
175
+ // Generate actions provider
176
+ this.registerProvider('generate', (ctx) => {
177
+ const actions = [];
178
+ // Generate JSDoc
179
+ if (ctx.lineContent.includes('function ') ||
180
+ ctx.lineContent.includes('const ') ||
181
+ ctx.lineContent.includes('class ')) {
182
+ actions.push({
183
+ id: 'generate-jsdoc',
184
+ title: 'Generate JSDoc comment',
185
+ kind: 'generate',
186
+ description: 'Add documentation comment above declaration'
187
+ });
188
+ }
189
+ // Generate getter/setter (for class properties)
190
+ if (ctx.lineContent.includes('private ') || ctx.lineContent.includes('protected ')) {
191
+ const propMatch = ctx.lineContent.match(/(?:private|protected)\s+(\w+)/);
192
+ if (propMatch) {
193
+ actions.push({
194
+ id: 'generate-getter',
195
+ title: `Generate getter for '${propMatch[1]}'`,
196
+ kind: 'generate'
197
+ });
198
+ actions.push({
199
+ id: 'generate-setter',
200
+ title: `Generate setter for '${propMatch[1]}'`,
201
+ kind: 'generate'
202
+ });
203
+ }
204
+ }
205
+ // Generate constructor
206
+ if (ctx.lineContent.includes('class ')) {
207
+ actions.push({
208
+ id: 'generate-constructor',
209
+ title: 'Generate constructor',
210
+ kind: 'generate'
211
+ });
212
+ }
213
+ return actions;
214
+ });
215
+ }
216
+ /**
217
+ * Register a code action provider
218
+ */
219
+ registerProvider(id, provider) {
220
+ this._providers.set(id, provider);
221
+ return () => this._providers.delete(id);
222
+ }
223
+ /**
224
+ * Get available actions for context
225
+ */
226
+ getActions(context) {
227
+ if (!this._config.enabled)
228
+ return [];
229
+ const actions = [];
230
+ for (const provider of this._providers.values()) {
231
+ try {
232
+ const providerActions = provider(context);
233
+ actions.push(...providerActions);
234
+ }
235
+ catch (e) {
236
+ console.error('Code action provider error:', e);
237
+ }
238
+ }
239
+ // Sort by kind and preferred status
240
+ return actions.sort((a, b) => {
241
+ // Preferred actions first
242
+ if (a.isPreferred && !b.isPreferred)
243
+ return -1;
244
+ if (!a.isPreferred && b.isPreferred)
245
+ return 1;
246
+ // Then by kind priority
247
+ const kindPriority = {
248
+ 'quickfix': 0,
249
+ 'refactor.extract': 1,
250
+ 'refactor.inline': 2,
251
+ 'refactor.rename': 3,
252
+ 'refactor': 4,
253
+ 'source.organizeImports': 5,
254
+ 'source.fixAll': 6,
255
+ 'source': 7,
256
+ 'generate': 8
257
+ };
258
+ return (kindPriority[a.kind] ?? 99) - (kindPriority[b.kind] ?? 99);
259
+ });
260
+ }
261
+ /**
262
+ * Update context and refresh actions
263
+ */
264
+ updateContext(context) {
265
+ if (this._showTimeout) {
266
+ clearTimeout(this._showTimeout);
267
+ }
268
+ if (!this._config.autoShow) {
269
+ this._currentContext = context;
270
+ return;
271
+ }
272
+ this._showTimeout = setTimeout(() => {
273
+ this._currentContext = context;
274
+ this._currentActions = this.getActions(context);
275
+ this.notify();
276
+ }, this._config.showDelay);
277
+ }
278
+ /**
279
+ * Force refresh actions
280
+ */
281
+ refresh() {
282
+ if (this._currentContext) {
283
+ this._currentActions = this.getActions(this._currentContext);
284
+ this.notify();
285
+ }
286
+ }
287
+ /**
288
+ * Execute a code action
289
+ */
290
+ async executeAction(action) {
291
+ if (action.disabled) {
292
+ console.warn('Cannot execute disabled action:', action.disabledReason);
293
+ return false;
294
+ }
295
+ // If action has an edit, apply it
296
+ if (action.edit) {
297
+ // The edit would be applied by the editor
298
+ // Return the edit for the caller to handle
299
+ return true;
300
+ }
301
+ // If action has a command, execute it
302
+ if (action.command) {
303
+ // The command would be executed by the editor
304
+ // Return true to indicate the action was triggered
305
+ return true;
306
+ }
307
+ return false;
308
+ }
309
+ /**
310
+ * Get current actions
311
+ */
312
+ get currentActions() {
313
+ return this._currentActions;
314
+ }
315
+ /**
316
+ * Check if actions are available
317
+ */
318
+ get hasActions() {
319
+ return this._currentActions.length > 0;
320
+ }
321
+ /**
322
+ * Get config
323
+ */
324
+ get config() {
325
+ return { ...this._config };
326
+ }
327
+ /**
328
+ * Update config
329
+ */
330
+ setConfig(config) {
331
+ this._config = { ...this._config, ...config };
332
+ this.notify();
333
+ }
334
+ /**
335
+ * Enable/disable quick actions
336
+ */
337
+ setEnabled(enabled) {
338
+ this._config.enabled = enabled;
339
+ if (!enabled) {
340
+ this._currentActions = [];
341
+ }
342
+ this.notify();
343
+ }
344
+ /**
345
+ * Check if enabled
346
+ */
347
+ isEnabled() {
348
+ return this._config.enabled;
349
+ }
350
+ /**
351
+ * Subscribe to changes
352
+ */
353
+ subscribe(listener) {
354
+ this._listeners.add(listener);
355
+ return () => this._listeners.delete(listener);
356
+ }
357
+ /**
358
+ * Notify listeners
359
+ */
360
+ notify() {
361
+ for (const listener of this._listeners) {
362
+ listener();
363
+ }
364
+ }
365
+ /**
366
+ * Clean up
367
+ */
368
+ destroy() {
369
+ if (this._showTimeout) {
370
+ clearTimeout(this._showTimeout);
371
+ }
372
+ this._listeners.clear();
373
+ this._providers.clear();
374
+ }
375
+ }
376
+ /**
377
+ * Create a new QuickActionsManager instance
378
+ */
379
+ export function createQuickActionsManager() {
380
+ return new QuickActionsManager();
381
+ }
382
+ /**
383
+ * Group actions by kind for display
384
+ */
385
+ export function groupActionsByKind(actions) {
386
+ const groups = new Map();
387
+ for (const action of actions) {
388
+ // Get the base kind (e.g., "refactor" from "refactor.extract")
389
+ const baseKind = action.kind.split('.')[0];
390
+ const kindLabel = getKindLabel(baseKind);
391
+ if (!groups.has(kindLabel)) {
392
+ groups.set(kindLabel, []);
393
+ }
394
+ groups.get(kindLabel).push(action);
395
+ }
396
+ return groups;
397
+ }
398
+ /**
399
+ * Get display label for action kind
400
+ */
401
+ export function getKindLabel(kind) {
402
+ const labels = {
403
+ 'quickfix': 'Quick Fix',
404
+ 'refactor': 'Refactor',
405
+ 'source': 'Source Action',
406
+ 'generate': 'Generate'
407
+ };
408
+ const baseKind = kind.split('.')[0];
409
+ return labels[baseKind] || kind;
410
+ }
411
+ /**
412
+ * Get icon for action kind
413
+ */
414
+ export function getKindIcon(kind) {
415
+ const icons = {
416
+ 'quickfix': '🔧',
417
+ 'refactor': '✨',
418
+ 'refactor.extract': '📤',
419
+ 'refactor.inline': '📥',
420
+ 'refactor.rename': '✏️',
421
+ 'source': '📋',
422
+ 'source.organizeImports': '📦',
423
+ 'source.fixAll': '✅',
424
+ 'generate': '⚡'
425
+ };
426
+ return icons[kind] || icons[kind.split('.')[0]] || '💡';
427
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Search utilities for find and replace functionality
3
+ */
4
+ import type { Position } from './state';
5
+ export interface SearchMatch {
6
+ /** Start position of match */
7
+ start: Position;
8
+ /** End position of match */
9
+ end: Position;
10
+ /** The matched text */
11
+ text: string;
12
+ /** Line index (0-based) */
13
+ line: number;
14
+ /** Start column in line */
15
+ startColumn: number;
16
+ /** End column in line */
17
+ endColumn: number;
18
+ }
19
+ export interface SearchOptions {
20
+ /** Case sensitive search */
21
+ caseSensitive?: boolean;
22
+ /** Use regular expression */
23
+ useRegex?: boolean;
24
+ /** Wrap around when reaching end of document */
25
+ wrapAround?: boolean;
26
+ }
27
+ export interface SearchState {
28
+ /** Current search query */
29
+ query: string;
30
+ /** Search options */
31
+ options: SearchOptions;
32
+ /** All matches in document */
33
+ matches: SearchMatch[];
34
+ /** Current match index (0-based) */
35
+ currentIndex: number;
36
+ }
37
+ /**
38
+ * Create initial search state
39
+ */
40
+ export declare function createSearchState(): SearchState;
41
+ /**
42
+ * Find all matches in content
43
+ */
44
+ export declare function findAllMatches(lines: readonly {
45
+ text: string;
46
+ }[], query: string, options?: SearchOptions): SearchMatch[];
47
+ /**
48
+ * Find the match index closest to a position (at or after)
49
+ */
50
+ export declare function findMatchIndexAtOrAfter(matches: SearchMatch[], position: Position): number;
51
+ /**
52
+ * Find the match index closest to a position (at or before)
53
+ */
54
+ export declare function findMatchIndexAtOrBefore(matches: SearchMatch[], position: Position): number;
55
+ /**
56
+ * Get next match index (with wrap-around)
57
+ */
58
+ export declare function getNextMatchIndex(matches: SearchMatch[], currentIndex: number, wrapAround?: boolean): number;
59
+ /**
60
+ * Get previous match index (with wrap-around)
61
+ */
62
+ export declare function getPrevMatchIndex(matches: SearchMatch[], currentIndex: number, wrapAround?: boolean): number;
63
+ /**
64
+ * Replace text at a match position
65
+ * Returns the new content and adjusted cursor position
66
+ */
67
+ export declare function replaceMatch(lines: readonly {
68
+ text: string;
69
+ }[], match: SearchMatch, replacement: string): {
70
+ newLines: string[];
71
+ cursorPosition: Position;
72
+ lengthDiff: number;
73
+ };
74
+ /**
75
+ * Replace all matches
76
+ * Returns the new content
77
+ */
78
+ export declare function replaceAllMatches(lines: readonly {
79
+ text: string;
80
+ }[], matches: SearchMatch[], replacement: string): string[];
81
+ /**
82
+ * Check if a position is within a match
83
+ */
84
+ export declare function isPositionInMatch(position: Position, match: SearchMatch): boolean;
85
+ /**
86
+ * Find match at exact position (if cursor is inside a match)
87
+ */
88
+ export declare function findMatchAtPosition(matches: SearchMatch[], position: Position): number;
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Search utilities for find and replace functionality
3
+ */
4
+ /**
5
+ * Create initial search state
6
+ */
7
+ export function createSearchState() {
8
+ return {
9
+ query: '',
10
+ options: {
11
+ caseSensitive: false,
12
+ useRegex: false,
13
+ wrapAround: true
14
+ },
15
+ matches: [],
16
+ currentIndex: -1
17
+ };
18
+ }
19
+ /**
20
+ * Find all matches in content
21
+ */
22
+ export function findAllMatches(lines, query, options = {}) {
23
+ if (!query)
24
+ return [];
25
+ const matches = [];
26
+ const { caseSensitive = false, useRegex = false } = options;
27
+ let searchPattern;
28
+ try {
29
+ if (useRegex) {
30
+ searchPattern = new RegExp(query, caseSensitive ? 'g' : 'gi');
31
+ }
32
+ else {
33
+ // Escape regex special characters for literal search
34
+ const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
35
+ searchPattern = new RegExp(escaped, caseSensitive ? 'g' : 'gi');
36
+ }
37
+ }
38
+ catch {
39
+ // Invalid regex - return empty matches
40
+ return [];
41
+ }
42
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
43
+ const line = lines[lineIndex];
44
+ const text = line.text;
45
+ let match;
46
+ // Reset lastIndex for each line
47
+ searchPattern.lastIndex = 0;
48
+ while ((match = searchPattern.exec(text)) !== null) {
49
+ const startColumn = match.index;
50
+ const endColumn = match.index + match[0].length;
51
+ matches.push({
52
+ start: { line: lineIndex, column: startColumn },
53
+ end: { line: lineIndex, column: endColumn },
54
+ text: match[0],
55
+ line: lineIndex,
56
+ startColumn,
57
+ endColumn
58
+ });
59
+ // Prevent infinite loop on zero-width matches
60
+ if (match[0].length === 0) {
61
+ searchPattern.lastIndex++;
62
+ }
63
+ }
64
+ }
65
+ return matches;
66
+ }
67
+ /**
68
+ * Find the match index closest to a position (at or after)
69
+ */
70
+ export function findMatchIndexAtOrAfter(matches, position) {
71
+ if (matches.length === 0)
72
+ return -1;
73
+ for (let i = 0; i < matches.length; i++) {
74
+ const match = matches[i];
75
+ // Match is at or after position
76
+ if (match.line > position.line ||
77
+ (match.line === position.line && match.startColumn >= position.column)) {
78
+ return i;
79
+ }
80
+ }
81
+ // No match at or after position - wrap to first match
82
+ return 0;
83
+ }
84
+ /**
85
+ * Find the match index closest to a position (at or before)
86
+ */
87
+ export function findMatchIndexAtOrBefore(matches, position) {
88
+ if (matches.length === 0)
89
+ return -1;
90
+ for (let i = matches.length - 1; i >= 0; i--) {
91
+ const match = matches[i];
92
+ // Match is at or before position
93
+ if (match.line < position.line ||
94
+ (match.line === position.line && match.endColumn <= position.column)) {
95
+ return i;
96
+ }
97
+ }
98
+ // No match at or before position - wrap to last match
99
+ return matches.length - 1;
100
+ }
101
+ /**
102
+ * Get next match index (with wrap-around)
103
+ */
104
+ export function getNextMatchIndex(matches, currentIndex, wrapAround = true) {
105
+ if (matches.length === 0)
106
+ return -1;
107
+ if (currentIndex < 0)
108
+ return 0;
109
+ const next = currentIndex + 1;
110
+ if (next >= matches.length) {
111
+ return wrapAround ? 0 : currentIndex;
112
+ }
113
+ return next;
114
+ }
115
+ /**
116
+ * Get previous match index (with wrap-around)
117
+ */
118
+ export function getPrevMatchIndex(matches, currentIndex, wrapAround = true) {
119
+ if (matches.length === 0)
120
+ return -1;
121
+ if (currentIndex < 0)
122
+ return matches.length - 1;
123
+ const prev = currentIndex - 1;
124
+ if (prev < 0) {
125
+ return wrapAround ? matches.length - 1 : currentIndex;
126
+ }
127
+ return prev;
128
+ }
129
+ /**
130
+ * Replace text at a match position
131
+ * Returns the new content and adjusted cursor position
132
+ */
133
+ export function replaceMatch(lines, match, replacement) {
134
+ const newLines = lines.map((l) => l.text);
135
+ const line = newLines[match.line];
136
+ // Replace the match
137
+ newLines[match.line] =
138
+ line.substring(0, match.startColumn) +
139
+ replacement +
140
+ line.substring(match.endColumn);
141
+ const lengthDiff = replacement.length - match.text.length;
142
+ return {
143
+ newLines,
144
+ cursorPosition: {
145
+ line: match.line,
146
+ column: match.startColumn + replacement.length
147
+ },
148
+ lengthDiff
149
+ };
150
+ }
151
+ /**
152
+ * Replace all matches
153
+ * Returns the new content
154
+ */
155
+ export function replaceAllMatches(lines, matches, replacement) {
156
+ if (matches.length === 0)
157
+ return lines.map((l) => l.text);
158
+ const newLines = lines.map((l) => l.text);
159
+ // Process matches in reverse order to maintain correct positions
160
+ const sortedMatches = [...matches].sort((a, b) => {
161
+ if (a.line !== b.line)
162
+ return b.line - a.line;
163
+ return b.startColumn - a.startColumn;
164
+ });
165
+ for (const match of sortedMatches) {
166
+ const line = newLines[match.line];
167
+ newLines[match.line] =
168
+ line.substring(0, match.startColumn) +
169
+ replacement +
170
+ line.substring(match.endColumn);
171
+ }
172
+ return newLines;
173
+ }
174
+ /**
175
+ * Check if a position is within a match
176
+ */
177
+ export function isPositionInMatch(position, match) {
178
+ if (position.line !== match.line)
179
+ return false;
180
+ return position.column >= match.startColumn && position.column < match.endColumn;
181
+ }
182
+ /**
183
+ * Find match at exact position (if cursor is inside a match)
184
+ */
185
+ export function findMatchAtPosition(matches, position) {
186
+ for (let i = 0; i < matches.length; i++) {
187
+ if (isPositionInMatch(position, matches[i])) {
188
+ return i;
189
+ }
190
+ }
191
+ return -1;
192
+ }