@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.
- package/LICENSE +21 -0
- package/README.md +251 -0
- package/dist/components/agents/AgentActivityPanel.svelte +565 -0
- package/dist/components/agents/AgentActivityPanel.svelte.d.ts +24 -0
- package/dist/components/agents/AgentAvatar.svelte +417 -0
- package/dist/components/agents/AgentAvatar.svelte.d.ts +23 -0
- package/dist/components/agents/AgentCursor.svelte +224 -0
- package/dist/components/agents/AgentCursor.svelte.d.ts +35 -0
- package/dist/components/agents/AgentPresenceBar.svelte +261 -0
- package/dist/components/agents/AgentPresenceBar.svelte.d.ts +20 -0
- package/dist/components/agents/index.d.ts +4 -0
- package/dist/components/agents/index.js +5 -0
- package/dist/components/ai/AIConversationList.svelte +524 -0
- package/dist/components/ai/AIConversationList.svelte.d.ts +17 -0
- package/dist/components/ai/AIEditPreview.svelte +132 -0
- package/dist/components/ai/AIEditPreview.svelte.d.ts +8 -0
- package/dist/components/ai/AIInlineEdit.svelte +155 -0
- package/dist/components/ai/AIInlineEdit.svelte.d.ts +10 -0
- package/dist/components/ai/AIMessage.svelte +239 -0
- package/dist/components/ai/AIMessage.svelte.d.ts +13 -0
- package/dist/components/ai/AIMessageActions.svelte +176 -0
- package/dist/components/ai/AIMessageActions.svelte.d.ts +12 -0
- package/dist/components/ai/AIMessageContent.svelte +355 -0
- package/dist/components/ai/AIMessageContent.svelte.d.ts +7 -0
- package/dist/components/ai/AIPanel.svelte +561 -0
- package/dist/components/ai/AIPanel.svelte.d.ts +7 -0
- package/dist/components/ai/AISuggestionWidget.svelte +132 -0
- package/dist/components/ai/AISuggestionWidget.svelte.d.ts +10 -0
- package/dist/components/ai/AIToolCallDisplay.svelte +317 -0
- package/dist/components/ai/AIToolCallDisplay.svelte.d.ts +12 -0
- package/dist/components/ai/index.d.ts +9 -0
- package/dist/components/ai/index.js +10 -0
- package/dist/components/core/Avatar.svelte +110 -0
- package/dist/components/core/Avatar.svelte.d.ts +12 -0
- package/dist/components/core/Badge.svelte +98 -0
- package/dist/components/core/Badge.svelte.d.ts +11 -0
- package/dist/components/core/Button.svelte +175 -0
- package/dist/components/core/Button.svelte.d.ts +18 -0
- package/dist/components/core/ConnectionStatus.svelte +294 -0
- package/dist/components/core/ConnectionStatus.svelte.d.ts +20 -0
- package/dist/components/core/ContextMenu.svelte +176 -0
- package/dist/components/core/ContextMenu.svelte.d.ts +19 -0
- package/dist/components/core/ErrorBoundary.svelte +277 -0
- package/dist/components/core/ErrorBoundary.svelte.d.ts +23 -0
- package/dist/components/core/Icon.svelte +107 -0
- package/dist/components/core/Icon.svelte.d.ts +8 -0
- package/dist/components/core/Input.svelte +138 -0
- package/dist/components/core/Input.svelte.d.ts +20 -0
- package/dist/components/core/Kbd.svelte +34 -0
- package/dist/components/core/Kbd.svelte.d.ts +7 -0
- package/dist/components/core/ResizeHandle.svelte +200 -0
- package/dist/components/core/ResizeHandle.svelte.d.ts +23 -0
- package/dist/components/core/Spinner.svelte +35 -0
- package/dist/components/core/Spinner.svelte.d.ts +7 -0
- package/dist/components/core/Textarea.svelte +112 -0
- package/dist/components/core/Textarea.svelte.d.ts +18 -0
- package/dist/components/core/Tooltip.svelte +103 -0
- package/dist/components/core/Tooltip.svelte.d.ts +11 -0
- package/dist/components/core/index.d.ts +13 -0
- package/dist/components/core/index.js +14 -0
- package/dist/components/editor/AIFocusLayer.svelte +430 -0
- package/dist/components/editor/AIFocusLayer.svelte.d.ts +32 -0
- package/dist/components/editor/Breadcrumbs.svelte +435 -0
- package/dist/components/editor/Breadcrumbs.svelte.d.ts +33 -0
- package/dist/components/editor/BreakpointLayer.svelte +642 -0
- package/dist/components/editor/BreakpointLayer.svelte.d.ts +20 -0
- package/dist/components/editor/CognitiveLoadMeter.svelte +324 -0
- package/dist/components/editor/CognitiveLoadMeter.svelte.d.ts +18 -0
- package/dist/components/editor/CollaborativeEditor.svelte +218 -0
- package/dist/components/editor/CollaborativeEditor.svelte.d.ts +32 -0
- package/dist/components/editor/CommandPalette.svelte +434 -0
- package/dist/components/editor/CommandPalette.svelte.d.ts +11 -0
- package/dist/components/editor/ComplexityLayer.svelte +293 -0
- package/dist/components/editor/ComplexityLayer.svelte.d.ts +23 -0
- package/dist/components/editor/ConflictZoneLayer.svelte +441 -0
- package/dist/components/editor/ConflictZoneLayer.svelte.d.ts +25 -0
- package/dist/components/editor/ContextLens.svelte +262 -0
- package/dist/components/editor/ContextLens.svelte.d.ts +27 -0
- package/dist/components/editor/CustomEditor.svelte +1242 -0
- package/dist/components/editor/CustomEditor.svelte.d.ts +37 -0
- package/dist/components/editor/DebugConsole.svelte +646 -0
- package/dist/components/editor/DebugConsole.svelte.d.ts +41 -0
- package/dist/components/editor/EchoCursorLayer.svelte +363 -0
- package/dist/components/editor/EchoCursorLayer.svelte.d.ts +24 -0
- package/dist/components/editor/Editor.svelte +61 -0
- package/dist/components/editor/Editor.svelte.d.ts +22 -0
- package/dist/components/editor/EditorGutter.svelte +119 -0
- package/dist/components/editor/EditorGutter.svelte.d.ts +19 -0
- package/dist/components/editor/EditorLines.svelte +182 -0
- package/dist/components/editor/EditorLines.svelte.d.ts +43 -0
- package/dist/components/editor/EditorPane.svelte +134 -0
- package/dist/components/editor/EditorPane.svelte.d.ts +9 -0
- package/dist/components/editor/EditorSelections.svelte +186 -0
- package/dist/components/editor/EditorSelections.svelte.d.ts +25 -0
- package/dist/components/editor/EditorTabs.svelte +170 -0
- package/dist/components/editor/EditorTabs.svelte.d.ts +12 -0
- package/dist/components/editor/FileExplorer.svelte +811 -0
- package/dist/components/editor/FileExplorer.svelte.d.ts +67 -0
- package/dist/components/editor/FileIcon.svelte +110 -0
- package/dist/components/editor/FileIcon.svelte.d.ts +10 -0
- package/dist/components/editor/FindReplace.svelte +448 -0
- package/dist/components/editor/FindReplace.svelte.d.ts +40 -0
- package/dist/components/editor/GhostBracketLayer.svelte +391 -0
- package/dist/components/editor/GhostBracketLayer.svelte.d.ts +24 -0
- package/dist/components/editor/GitBlameLayer.svelte +436 -0
- package/dist/components/editor/GitBlameLayer.svelte.d.ts +18 -0
- package/dist/components/editor/InlineDiagnosticsLayer.svelte +540 -0
- package/dist/components/editor/InlineDiagnosticsLayer.svelte.d.ts +35 -0
- package/dist/components/editor/InlineDiffLayer.svelte +337 -0
- package/dist/components/editor/InlineDiffLayer.svelte.d.ts +31 -0
- package/dist/components/editor/MinimalEditor.svelte +75 -0
- package/dist/components/editor/MinimalEditor.svelte.d.ts +6 -0
- package/dist/components/editor/MinimalEditor2.svelte +84 -0
- package/dist/components/editor/MinimalEditor2.svelte.d.ts +6 -0
- package/dist/components/editor/Minimap.svelte +327 -0
- package/dist/components/editor/Minimap.svelte.d.ts +34 -0
- package/dist/components/editor/PluginPreviewSandbox.svelte +793 -0
- package/dist/components/editor/PluginPreviewSandbox.svelte.d.ts +49 -0
- package/dist/components/editor/ProblemsPanel.svelte +628 -0
- package/dist/components/editor/ProblemsPanel.svelte.d.ts +25 -0
- package/dist/components/editor/QuickActionsMenu.svelte +403 -0
- package/dist/components/editor/QuickActionsMenu.svelte.d.ts +18 -0
- package/dist/components/editor/SnippetPalette.svelte +530 -0
- package/dist/components/editor/SnippetPalette.svelte.d.ts +16 -0
- package/dist/components/editor/StructureMap.svelte +431 -0
- package/dist/components/editor/StructureMap.svelte.d.ts +37 -0
- package/dist/components/editor/SymbolOutline.svelte +722 -0
- package/dist/components/editor/SymbolOutline.svelte.d.ts +44 -0
- package/dist/components/editor/TimelineScrubber.svelte +470 -0
- package/dist/components/editor/TimelineScrubber.svelte.d.ts +40 -0
- package/dist/components/editor/TokenRenderer.svelte +69 -0
- package/dist/components/editor/TokenRenderer.svelte.d.ts +15 -0
- package/dist/components/editor/constants.d.ts +32 -0
- package/dist/components/editor/constants.js +36 -0
- package/dist/components/editor/core/ai-awareness.d.ts +176 -0
- package/dist/components/editor/core/ai-awareness.js +210 -0
- package/dist/components/editor/core/bracket-healer.d.ts +189 -0
- package/dist/components/editor/core/bracket-healer.js +406 -0
- package/dist/components/editor/core/breakpoints.d.ts +203 -0
- package/dist/components/editor/core/breakpoints.js +414 -0
- package/dist/components/editor/core/commands.d.ts +108 -0
- package/dist/components/editor/core/commands.js +246 -0
- package/dist/components/editor/core/complexity-analyzer.d.ts +123 -0
- package/dist/components/editor/core/complexity-analyzer.js +376 -0
- package/dist/components/editor/core/conflict-predictor.d.ts +135 -0
- package/dist/components/editor/core/conflict-predictor.js +316 -0
- package/dist/components/editor/core/crdt-binding.d.ts +118 -0
- package/dist/components/editor/core/crdt-binding.js +286 -0
- package/dist/components/editor/core/diagnostics.d.ts +210 -0
- package/dist/components/editor/core/diagnostics.js +335 -0
- package/dist/components/editor/core/echo-cursor.d.ts +201 -0
- package/dist/components/editor/core/echo-cursor.js +267 -0
- package/dist/components/editor/core/folding.d.ts +124 -0
- package/dist/components/editor/core/folding.js +672 -0
- package/dist/components/editor/core/ghost-pair.d.ts +122 -0
- package/dist/components/editor/core/ghost-pair.js +221 -0
- package/dist/components/editor/core/git-blame.d.ts +170 -0
- package/dist/components/editor/core/git-blame.js +324 -0
- package/dist/components/editor/core/index.d.ts +26 -0
- package/dist/components/editor/core/index.js +24 -0
- package/dist/components/editor/core/keybindings.d.ts +79 -0
- package/dist/components/editor/core/keybindings.js +357 -0
- package/dist/components/editor/core/multi-cursor.d.ts +196 -0
- package/dist/components/editor/core/multi-cursor.js +521 -0
- package/dist/components/editor/core/navigation.d.ts +107 -0
- package/dist/components/editor/core/navigation.js +408 -0
- package/dist/components/editor/core/quick-actions.d.ts +189 -0
- package/dist/components/editor/core/quick-actions.js +427 -0
- package/dist/components/editor/core/search.d.ts +88 -0
- package/dist/components/editor/core/search.js +192 -0
- package/dist/components/editor/core/semantic-analyzer.d.ts +77 -0
- package/dist/components/editor/core/semantic-analyzer.js +424 -0
- package/dist/components/editor/core/snippet-manager.d.ts +202 -0
- package/dist/components/editor/core/snippet-manager.js +565 -0
- package/dist/components/editor/core/state.d.ts +367 -0
- package/dist/components/editor/core/state.js +900 -0
- package/dist/components/editor/core/timeline.d.ts +204 -0
- package/dist/components/editor/core/timeline.js +349 -0
- package/dist/components/editor/editor-find.d.ts +56 -0
- package/dist/components/editor/editor-find.js +148 -0
- package/dist/components/editor/editor-input.d.ts +77 -0
- package/dist/components/editor/editor-input.js +445 -0
- package/dist/components/editor/editor-multicursor.d.ts +21 -0
- package/dist/components/editor/editor-multicursor.js +196 -0
- package/dist/components/editor/editor-scroll.d.ts +14 -0
- package/dist/components/editor/editor-scroll.js +34 -0
- package/dist/components/editor/index.d.ts +15 -0
- package/dist/components/editor/index.js +21 -0
- package/dist/components/editor/languages.d.ts +62 -0
- package/dist/components/editor/languages.js +285 -0
- package/dist/components/editor/theme.d.ts +88 -0
- package/dist/components/editor/theme.js +139 -0
- package/dist/components/editor/tokenizer/base.d.ts +40 -0
- package/dist/components/editor/tokenizer/base.js +203 -0
- package/dist/components/editor/tokenizer/index.d.ts +56 -0
- package/dist/components/editor/tokenizer/index.js +215 -0
- package/dist/components/editor/tokenizer/languages/css.d.ts +17 -0
- package/dist/components/editor/tokenizer/languages/css.js +194 -0
- package/dist/components/editor/tokenizer/languages/go.d.ts +17 -0
- package/dist/components/editor/tokenizer/languages/go.js +220 -0
- package/dist/components/editor/tokenizer/languages/html.d.ts +24 -0
- package/dist/components/editor/tokenizer/languages/html.js +145 -0
- package/dist/components/editor/tokenizer/languages/javascript.d.ts +56 -0
- package/dist/components/editor/tokenizer/languages/javascript.js +452 -0
- package/dist/components/editor/tokenizer/languages/json.d.ts +12 -0
- package/dist/components/editor/tokenizer/languages/json.js +91 -0
- package/dist/components/editor/tokenizer/languages/markdown.d.ts +16 -0
- package/dist/components/editor/tokenizer/languages/markdown.js +156 -0
- package/dist/components/editor/tokenizer/languages/python.d.ts +20 -0
- package/dist/components/editor/tokenizer/languages/python.js +227 -0
- package/dist/components/editor/tokenizer/languages/svelte.d.ts +40 -0
- package/dist/components/editor/tokenizer/languages/svelte.js +326 -0
- package/dist/components/editor/tokenizer/types.d.ts +86 -0
- package/dist/components/editor/tokenizer/types.js +4 -0
- package/dist/components/layout/IDELayout.svelte +274 -0
- package/dist/components/layout/IDELayout.svelte.d.ts +29 -0
- package/dist/components/layout/StatusBar.svelte +511 -0
- package/dist/components/layout/StatusBar.svelte.d.ts +47 -0
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +3 -0
- package/dist/components/lsp/AutocompleteWidget.svelte +364 -0
- package/dist/components/lsp/AutocompleteWidget.svelte.d.ts +33 -0
- package/dist/components/lsp/DiagnosticMarker.svelte +166 -0
- package/dist/components/lsp/DiagnosticMarker.svelte.d.ts +19 -0
- package/dist/components/lsp/DiagnosticsPanel.svelte +388 -0
- package/dist/components/lsp/DiagnosticsPanel.svelte.d.ts +21 -0
- package/dist/components/lsp/HoverTooltip.svelte +274 -0
- package/dist/components/lsp/HoverTooltip.svelte.d.ts +24 -0
- package/dist/components/lsp/LSPEditor.svelte +486 -0
- package/dist/components/lsp/LSPEditor.svelte.d.ts +39 -0
- package/dist/components/lsp/SignatureHelpWidget.svelte +216 -0
- package/dist/components/lsp/SignatureHelpWidget.svelte.d.ts +22 -0
- package/dist/components/lsp/index.d.ts +6 -0
- package/dist/components/lsp/index.js +7 -0
- package/dist/components/plugins/PluginCard.svelte +153 -0
- package/dist/components/plugins/PluginCard.svelte.d.ts +19 -0
- package/dist/components/plugins/PluginPanel.svelte +280 -0
- package/dist/components/plugins/PluginPanel.svelte.d.ts +8 -0
- package/dist/components/plugins/PluginProposalForm.svelte +250 -0
- package/dist/components/plugins/PluginProposalForm.svelte.d.ts +6 -0
- package/dist/components/plugins/PluginStatusBadge.svelte +14 -0
- package/dist/components/plugins/PluginStatusBadge.svelte.d.ts +8 -0
- package/dist/components/plugins/index.d.ts +4 -0
- package/dist/components/plugins/index.js +5 -0
- package/dist/components/vfs/LockConflictDialog.svelte +705 -0
- package/dist/components/vfs/LockConflictDialog.svelte.d.ts +21 -0
- package/dist/components/vfs/LockIndicator.svelte +194 -0
- package/dist/components/vfs/LockIndicator.svelte.d.ts +29 -0
- package/dist/components/vfs/LockOverlay.svelte +344 -0
- package/dist/components/vfs/LockOverlay.svelte.d.ts +17 -0
- package/dist/components/vfs/VersionConflictDialog.svelte +549 -0
- package/dist/components/vfs/VersionConflictDialog.svelte.d.ts +24 -0
- package/dist/components/vfs/index.d.ts +4 -0
- package/dist/components/vfs/index.js +5 -0
- package/dist/crdt/awareness.d.ts +42 -0
- package/dist/crdt/awareness.js +109 -0
- package/dist/crdt/document.d.ts +101 -0
- package/dist/crdt/document.js +187 -0
- package/dist/crdt/index.d.ts +9 -0
- package/dist/crdt/index.js +8 -0
- package/dist/crdt/provider.d.ts +85 -0
- package/dist/crdt/provider.js +150 -0
- package/dist/crdt/types.d.ts +61 -0
- package/dist/crdt/types.js +4 -0
- package/dist/crdt/undo.d.ts +34 -0
- package/dist/crdt/undo.js +70 -0
- package/dist/index.d.ts +277 -0
- package/dist/index.js +280 -0
- package/dist/plugins/index.d.ts +103 -0
- package/dist/plugins/index.js +153 -0
- package/dist/services/error-handling.d.ts +95 -0
- package/dist/services/error-handling.js +413 -0
- package/dist/services/ide-integration.d.ts +83 -0
- package/dist/services/ide-integration.js +367 -0
- package/dist/services/lsp-client.d.ts +69 -0
- package/dist/services/lsp-client.js +667 -0
- package/dist/services/mock-ai.d.ts +37 -0
- package/dist/services/mock-ai.js +318 -0
- package/dist/services/optimistic.d.ts +141 -0
- package/dist/services/optimistic.js +367 -0
- package/dist/services/vfs-client.d.ts +81 -0
- package/dist/services/vfs-client.js +348 -0
- package/dist/stores/agents.svelte.d.ts +85 -0
- package/dist/stores/agents.svelte.js +459 -0
- package/dist/stores/ai-persistence.svelte.d.ts +76 -0
- package/dist/stores/ai-persistence.svelte.js +334 -0
- package/dist/stores/ai.svelte.d.ts +140 -0
- package/dist/stores/ai.svelte.js +383 -0
- package/dist/stores/collaboration.svelte.d.ts +164 -0
- package/dist/stores/collaboration.svelte.js +334 -0
- package/dist/stores/editor.svelte.d.ts +131 -0
- package/dist/stores/editor.svelte.js +250 -0
- package/dist/stores/index.d.ts +10 -0
- package/dist/stores/index.js +29 -0
- package/dist/stores/layout.svelte.d.ts +171 -0
- package/dist/stores/layout.svelte.js +351 -0
- package/dist/stores/plugin.svelte.d.ts +121 -0
- package/dist/stores/plugin.svelte.js +410 -0
- package/dist/stores/vfs.svelte.d.ts +123 -0
- package/dist/stores/vfs.svelte.js +680 -0
- package/dist/styles/theme.css +623 -0
- package/dist/types/agents.d.ts +127 -0
- package/dist/types/agents.js +5 -0
- package/dist/types/ai.d.ts +137 -0
- package/dist/types/ai.js +4 -0
- package/dist/types/crdt.d.ts +222 -0
- package/dist/types/crdt.js +5 -0
- package/dist/types/editor.d.ts +52 -0
- package/dist/types/editor.js +18 -0
- package/dist/types/events.d.ts +133 -0
- package/dist/types/events.js +4 -0
- package/dist/types/filesystem.d.ts +77 -0
- package/dist/types/filesystem.js +4 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.js +12 -0
- package/dist/types/lsp.d.ts +691 -0
- package/dist/types/lsp.js +108 -0
- package/dist/types/plugin.d.ts +239 -0
- package/dist/types/plugin.js +5 -0
- package/dist/types/vfs.d.ts +191 -0
- package/dist/types/vfs.js +18 -0
- package/dist/utils/format.d.ts +55 -0
- package/dist/utils/format.js +152 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/keybindings.d.ts +33 -0
- package/dist/utils/keybindings.js +171 -0
- package/dist/utils/language.d.ts +27 -0
- package/dist/utils/language.js +222 -0
- package/package.json +178 -0
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* LSPEditor - CustomEditor with LSP integration
|
|
4
|
+
*
|
|
5
|
+
* Wraps the CustomEditor component and adds LSP-powered features:
|
|
6
|
+
* - Autocomplete (Ctrl+Space or typing)
|
|
7
|
+
* - Hover information (mouse hover with delay)
|
|
8
|
+
* - Signature help (typing '(' or ',')
|
|
9
|
+
* - Inline diagnostics
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { onMount, tick } from 'svelte';
|
|
13
|
+
import type { EditorPreferences } from '../../types';
|
|
14
|
+
import type { LSPClient } from '../../services/lsp-client';
|
|
15
|
+
import type {
|
|
16
|
+
CompletionItem,
|
|
17
|
+
Hover,
|
|
18
|
+
SignatureHelp,
|
|
19
|
+
Diagnostic,
|
|
20
|
+
Position
|
|
21
|
+
} from '../../types/lsp';
|
|
22
|
+
import type { Cursor } from '../editor/core/multi-cursor';
|
|
23
|
+
import CustomEditor from '../editor/CustomEditor.svelte';
|
|
24
|
+
import AutocompleteWidget from './AutocompleteWidget.svelte';
|
|
25
|
+
import HoverTooltip from './HoverTooltip.svelte';
|
|
26
|
+
import SignatureHelpWidget from './SignatureHelpWidget.svelte';
|
|
27
|
+
|
|
28
|
+
interface Props {
|
|
29
|
+
/** Editor content */
|
|
30
|
+
content: string;
|
|
31
|
+
/** File URI for LSP */
|
|
32
|
+
uri: string;
|
|
33
|
+
/** Language identifier */
|
|
34
|
+
language?: string;
|
|
35
|
+
/** LSP client instance */
|
|
36
|
+
lspClient?: LSPClient;
|
|
37
|
+
/** Read-only mode */
|
|
38
|
+
readonly?: boolean;
|
|
39
|
+
/** Editor preferences */
|
|
40
|
+
preferences?: Partial<EditorPreferences>;
|
|
41
|
+
/** Enable code folding (default: true) */
|
|
42
|
+
folding?: boolean;
|
|
43
|
+
/** Enable multi-cursor editing (default: true) */
|
|
44
|
+
multiCursor?: boolean;
|
|
45
|
+
/** Maximum number of cursors (default: 100) */
|
|
46
|
+
maxCursors?: number;
|
|
47
|
+
/** Additional CSS class */
|
|
48
|
+
class?: string;
|
|
49
|
+
/** Called when content changes */
|
|
50
|
+
onChange?: (content: string) => void;
|
|
51
|
+
/** Called when cursor moves */
|
|
52
|
+
onCursorChange?: (line: number, column: number) => void;
|
|
53
|
+
/** Called when cursors change (for multi-cursor) */
|
|
54
|
+
onCursorsChange?: (cursors: readonly Cursor[]) => void;
|
|
55
|
+
/** Called on save (Ctrl+S) */
|
|
56
|
+
onSave?: () => void;
|
|
57
|
+
/** Called when diagnostics are received */
|
|
58
|
+
onDiagnostics?: (diagnostics: Diagnostic[]) => void;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let {
|
|
62
|
+
content = $bindable(),
|
|
63
|
+
uri,
|
|
64
|
+
language = 'plaintext',
|
|
65
|
+
lspClient,
|
|
66
|
+
readonly = false,
|
|
67
|
+
preferences = {},
|
|
68
|
+
folding = true,
|
|
69
|
+
multiCursor = true,
|
|
70
|
+
maxCursors = 100,
|
|
71
|
+
class: className = '',
|
|
72
|
+
onChange,
|
|
73
|
+
onCursorChange,
|
|
74
|
+
onCursorsChange,
|
|
75
|
+
onSave,
|
|
76
|
+
onDiagnostics
|
|
77
|
+
}: Props = $props();
|
|
78
|
+
|
|
79
|
+
// LSP feature states
|
|
80
|
+
let completionItems = $state<CompletionItem[]>([]);
|
|
81
|
+
let completionPosition = $state({ x: 0, y: 0 });
|
|
82
|
+
let completionSelectedIndex = $state(0);
|
|
83
|
+
let showCompletion = $state(false);
|
|
84
|
+
|
|
85
|
+
let hoverData = $state<Hover | null>(null);
|
|
86
|
+
let hoverPosition = $state({ x: 0, y: 0 });
|
|
87
|
+
let showHover = $state(false);
|
|
88
|
+
|
|
89
|
+
let signatureHelpData = $state<SignatureHelp | null>(null);
|
|
90
|
+
let signaturePosition = $state({ x: 0, y: 0 });
|
|
91
|
+
let showSignatureHelp = $state(false);
|
|
92
|
+
|
|
93
|
+
let diagnostics = $state<Diagnostic[]>([]);
|
|
94
|
+
|
|
95
|
+
// Cursor position tracking
|
|
96
|
+
let cursorLine = $state(1);
|
|
97
|
+
let cursorColumn = $state(1);
|
|
98
|
+
|
|
99
|
+
// Debounce timers
|
|
100
|
+
let hoverTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
101
|
+
let completionTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
102
|
+
|
|
103
|
+
// Editor reference for position calculations
|
|
104
|
+
let editorContainer: HTMLDivElement;
|
|
105
|
+
let editorRef: CustomEditor;
|
|
106
|
+
|
|
107
|
+
// Document version for LSP
|
|
108
|
+
let documentVersion = 1;
|
|
109
|
+
|
|
110
|
+
// Track if document is open in LSP
|
|
111
|
+
let documentOpen = false;
|
|
112
|
+
|
|
113
|
+
// Open document when client connects
|
|
114
|
+
async function openDocument() {
|
|
115
|
+
if (!lspClient || documentOpen) return;
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
lspClient.didOpen(uri, language, documentVersion, content);
|
|
119
|
+
documentOpen = true;
|
|
120
|
+
} catch (err) {
|
|
121
|
+
console.error('[LSP] Failed to open document:', err);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Handle content changes
|
|
126
|
+
async function handleChange(newContent: string) {
|
|
127
|
+
onChange?.(newContent);
|
|
128
|
+
|
|
129
|
+
if (!lspClient || !documentOpen) return;
|
|
130
|
+
|
|
131
|
+
documentVersion++;
|
|
132
|
+
try {
|
|
133
|
+
lspClient.didChange(uri, documentVersion, [{ text: newContent }]);
|
|
134
|
+
} catch (err) {
|
|
135
|
+
console.error('[LSP] Failed to send didChange:', err);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Handle cursor changes
|
|
140
|
+
function handleCursorChange(line: number, column: number) {
|
|
141
|
+
cursorLine = line;
|
|
142
|
+
cursorColumn = column;
|
|
143
|
+
onCursorChange?.(line, column);
|
|
144
|
+
|
|
145
|
+
// Hide popups when cursor moves
|
|
146
|
+
hideCompletion();
|
|
147
|
+
hideHover();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// === Completion ===
|
|
151
|
+
|
|
152
|
+
async function requestCompletion() {
|
|
153
|
+
if (!lspClient || !documentOpen) return;
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
const items = await lspClient.completion(uri, {
|
|
157
|
+
line: cursorLine - 1,
|
|
158
|
+
character: cursorColumn - 1
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
if (items.length === 0) {
|
|
162
|
+
hideCompletion();
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
completionItems = items;
|
|
167
|
+
completionSelectedIndex = 0;
|
|
168
|
+
completionPosition = calculatePopupPosition();
|
|
169
|
+
showCompletion = true;
|
|
170
|
+
} catch (err) {
|
|
171
|
+
console.error('[LSP] Completion error:', err);
|
|
172
|
+
hideCompletion();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function hideCompletion() {
|
|
177
|
+
showCompletion = false;
|
|
178
|
+
completionItems = [];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function handleCompletionSelect(item: CompletionItem) {
|
|
182
|
+
// Insert the completion
|
|
183
|
+
const insertText = item.insertText ?? item.label;
|
|
184
|
+
|
|
185
|
+
// TODO: Apply text edit from completion item
|
|
186
|
+
// For now, just insert at cursor position
|
|
187
|
+
// This would need integration with the editor's insert method
|
|
188
|
+
|
|
189
|
+
hideCompletion();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function handleCompletionSelectionChange(index: number) {
|
|
193
|
+
completionSelectedIndex = index;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// === Hover ===
|
|
197
|
+
|
|
198
|
+
async function requestHover(line: number, character: number) {
|
|
199
|
+
if (!lspClient || !documentOpen) return;
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
const result = await lspClient.hover(uri, { line, character });
|
|
203
|
+
|
|
204
|
+
if (!result || !result.contents) {
|
|
205
|
+
hideHover();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
hoverData = result;
|
|
210
|
+
showHover = true;
|
|
211
|
+
} catch (err) {
|
|
212
|
+
console.error('[LSP] Hover error:', err);
|
|
213
|
+
hideHover();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function hideHover() {
|
|
218
|
+
showHover = false;
|
|
219
|
+
hoverData = null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// === Signature Help ===
|
|
223
|
+
|
|
224
|
+
async function requestSignatureHelp() {
|
|
225
|
+
if (!lspClient || !documentOpen) return;
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
const result = await lspClient.signatureHelp(uri, {
|
|
229
|
+
line: cursorLine - 1,
|
|
230
|
+
character: cursorColumn - 1
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
if (!result || result.signatures.length === 0) {
|
|
234
|
+
hideSignatureHelp();
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
signatureHelpData = result;
|
|
239
|
+
signaturePosition = calculatePopupPosition();
|
|
240
|
+
showSignatureHelp = true;
|
|
241
|
+
} catch (err) {
|
|
242
|
+
console.error('[LSP] Signature help error:', err);
|
|
243
|
+
hideSignatureHelp();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function hideSignatureHelp() {
|
|
248
|
+
showSignatureHelp = false;
|
|
249
|
+
signatureHelpData = null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// === Diagnostics ===
|
|
253
|
+
|
|
254
|
+
function handleDiagnosticsUpdate(params: { uri: string; diagnostics: Diagnostic[] }) {
|
|
255
|
+
if (params.uri === uri) {
|
|
256
|
+
diagnostics = params.diagnostics;
|
|
257
|
+
onDiagnostics?.(params.diagnostics);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// === Keyboard Handling ===
|
|
262
|
+
|
|
263
|
+
function handleKeyDown(e: KeyboardEvent) {
|
|
264
|
+
// Handle completion navigation
|
|
265
|
+
if (showCompletion) {
|
|
266
|
+
switch (e.key) {
|
|
267
|
+
case 'ArrowUp':
|
|
268
|
+
e.preventDefault();
|
|
269
|
+
completionSelectedIndex = completionSelectedIndex > 0
|
|
270
|
+
? completionSelectedIndex - 1
|
|
271
|
+
: completionItems.length - 1;
|
|
272
|
+
return;
|
|
273
|
+
case 'ArrowDown':
|
|
274
|
+
e.preventDefault();
|
|
275
|
+
completionSelectedIndex = completionSelectedIndex < completionItems.length - 1
|
|
276
|
+
? completionSelectedIndex + 1
|
|
277
|
+
: 0;
|
|
278
|
+
return;
|
|
279
|
+
case 'Enter':
|
|
280
|
+
case 'Tab':
|
|
281
|
+
e.preventDefault();
|
|
282
|
+
if (completionItems[completionSelectedIndex]) {
|
|
283
|
+
handleCompletionSelect(completionItems[completionSelectedIndex]);
|
|
284
|
+
}
|
|
285
|
+
return;
|
|
286
|
+
case 'Escape':
|
|
287
|
+
e.preventDefault();
|
|
288
|
+
hideCompletion();
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Manual completion trigger (Ctrl+Space)
|
|
294
|
+
if ((e.ctrlKey || e.metaKey) && e.key === ' ') {
|
|
295
|
+
e.preventDefault();
|
|
296
|
+
requestCompletion();
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Trigger signature help on '(' or ','
|
|
301
|
+
if (e.key === '(' || e.key === ',') {
|
|
302
|
+
// Delay to allow character to be inserted
|
|
303
|
+
setTimeout(() => requestSignatureHelp(), 50);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Hide signature help on ')'
|
|
307
|
+
if (e.key === ')') {
|
|
308
|
+
hideSignatureHelp();
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Auto-complete after typing (debounced)
|
|
312
|
+
if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
313
|
+
if (completionTimeout) clearTimeout(completionTimeout);
|
|
314
|
+
completionTimeout = setTimeout(() => {
|
|
315
|
+
// Only trigger for identifier characters
|
|
316
|
+
if (/[a-zA-Z0-9_.]/.test(e.key)) {
|
|
317
|
+
requestCompletion();
|
|
318
|
+
}
|
|
319
|
+
}, 100);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// === Mouse Handling ===
|
|
324
|
+
|
|
325
|
+
function handleMouseMove(e: MouseEvent) {
|
|
326
|
+
// Clear previous hover timeout
|
|
327
|
+
if (hoverTimeout) clearTimeout(hoverTimeout);
|
|
328
|
+
|
|
329
|
+
// Calculate position from mouse
|
|
330
|
+
const rect = editorContainer?.getBoundingClientRect();
|
|
331
|
+
if (!rect) return;
|
|
332
|
+
|
|
333
|
+
// Store mouse position for hover popup
|
|
334
|
+
hoverPosition = { x: e.clientX, y: e.clientY + 20 };
|
|
335
|
+
|
|
336
|
+
// Debounce hover request
|
|
337
|
+
hoverTimeout = setTimeout(() => {
|
|
338
|
+
// Calculate line/column from mouse position
|
|
339
|
+
// This is approximate - would need editor internals for exact position
|
|
340
|
+
const lineHeight = 20; // Approximate
|
|
341
|
+
const charWidth = 8; // Approximate
|
|
342
|
+
const gutterWidth = 50; // Approximate
|
|
343
|
+
|
|
344
|
+
const x = e.clientX - rect.left - gutterWidth;
|
|
345
|
+
const y = e.clientY - rect.top;
|
|
346
|
+
|
|
347
|
+
if (x < 0) return; // In gutter
|
|
348
|
+
|
|
349
|
+
const line = Math.floor(y / lineHeight);
|
|
350
|
+
const character = Math.floor(x / charWidth);
|
|
351
|
+
|
|
352
|
+
if (line >= 0 && character >= 0) {
|
|
353
|
+
requestHover(line, character);
|
|
354
|
+
}
|
|
355
|
+
}, 500);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function handleMouseLeave() {
|
|
359
|
+
if (hoverTimeout) clearTimeout(hoverTimeout);
|
|
360
|
+
hideHover();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// === Position Calculation ===
|
|
364
|
+
|
|
365
|
+
function calculatePopupPosition(): { x: number; y: number } {
|
|
366
|
+
// Calculate popup position based on cursor
|
|
367
|
+
// This needs editor position + cursor offset
|
|
368
|
+
const rect = editorContainer?.getBoundingClientRect();
|
|
369
|
+
if (!rect) return { x: 0, y: 0 };
|
|
370
|
+
|
|
371
|
+
const lineHeight = 20; // Approximate
|
|
372
|
+
const charWidth = 8; // Approximate
|
|
373
|
+
const gutterWidth = 50; // Approximate
|
|
374
|
+
|
|
375
|
+
const x = rect.left + gutterWidth + (cursorColumn - 1) * charWidth;
|
|
376
|
+
const y = rect.top + (cursorLine) * lineHeight;
|
|
377
|
+
|
|
378
|
+
return { x, y };
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// === Lifecycle ===
|
|
382
|
+
|
|
383
|
+
let unsubscribeDiagnostics: (() => void) | null = null;
|
|
384
|
+
|
|
385
|
+
onMount(() => {
|
|
386
|
+
// Open document when mounted with client
|
|
387
|
+
if (lspClient) {
|
|
388
|
+
openDocument();
|
|
389
|
+
|
|
390
|
+
// Subscribe to diagnostics using the correct API
|
|
391
|
+
unsubscribeDiagnostics = lspClient.on('onDiagnostics', handleDiagnosticsUpdate);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return () => {
|
|
395
|
+
// Clear timers
|
|
396
|
+
if (hoverTimeout) clearTimeout(hoverTimeout);
|
|
397
|
+
if (completionTimeout) clearTimeout(completionTimeout);
|
|
398
|
+
|
|
399
|
+
// Unsubscribe from diagnostics
|
|
400
|
+
if (unsubscribeDiagnostics) {
|
|
401
|
+
unsubscribeDiagnostics();
|
|
402
|
+
unsubscribeDiagnostics = null;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Close document
|
|
406
|
+
if (lspClient && documentOpen) {
|
|
407
|
+
lspClient.didClose(uri);
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// Watch for client changes
|
|
413
|
+
$effect(() => {
|
|
414
|
+
if (lspClient && !documentOpen) {
|
|
415
|
+
openDocument();
|
|
416
|
+
// Unsubscribe previous subscription
|
|
417
|
+
if (unsubscribeDiagnostics) {
|
|
418
|
+
unsubscribeDiagnostics();
|
|
419
|
+
}
|
|
420
|
+
// Re-subscribe with correct API
|
|
421
|
+
unsubscribeDiagnostics = lspClient.on('onDiagnostics', handleDiagnosticsUpdate);
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
</script>
|
|
425
|
+
|
|
426
|
+
<div
|
|
427
|
+
bind:this={editorContainer}
|
|
428
|
+
class="lsp-editor {className}"
|
|
429
|
+
onkeydown={handleKeyDown}
|
|
430
|
+
onmousemove={handleMouseMove}
|
|
431
|
+
onmouseleave={handleMouseLeave}
|
|
432
|
+
role="application"
|
|
433
|
+
>
|
|
434
|
+
<CustomEditor
|
|
435
|
+
bind:this={editorRef}
|
|
436
|
+
bind:content
|
|
437
|
+
{language}
|
|
438
|
+
{readonly}
|
|
439
|
+
{preferences}
|
|
440
|
+
{folding}
|
|
441
|
+
{multiCursor}
|
|
442
|
+
{maxCursors}
|
|
443
|
+
onChange={handleChange}
|
|
444
|
+
onCursorChange={handleCursorChange}
|
|
445
|
+
{onCursorsChange}
|
|
446
|
+
{onSave}
|
|
447
|
+
/>
|
|
448
|
+
|
|
449
|
+
<!-- Autocomplete Widget -->
|
|
450
|
+
{#if showCompletion && completionItems.length > 0}
|
|
451
|
+
<AutocompleteWidget
|
|
452
|
+
items={completionItems}
|
|
453
|
+
selectedIndex={completionSelectedIndex}
|
|
454
|
+
position={completionPosition}
|
|
455
|
+
onSelect={handleCompletionSelect}
|
|
456
|
+
onDismiss={hideCompletion}
|
|
457
|
+
onSelectionChange={handleCompletionSelectionChange}
|
|
458
|
+
/>
|
|
459
|
+
{/if}
|
|
460
|
+
|
|
461
|
+
<!-- Hover Tooltip -->
|
|
462
|
+
{#if showHover && hoverData}
|
|
463
|
+
<HoverTooltip
|
|
464
|
+
hover={hoverData}
|
|
465
|
+
position={hoverPosition}
|
|
466
|
+
onDismiss={hideHover}
|
|
467
|
+
/>
|
|
468
|
+
{/if}
|
|
469
|
+
|
|
470
|
+
<!-- Signature Help -->
|
|
471
|
+
{#if showSignatureHelp && signatureHelpData}
|
|
472
|
+
<SignatureHelpWidget
|
|
473
|
+
signatureHelp={signatureHelpData}
|
|
474
|
+
position={signaturePosition}
|
|
475
|
+
onDismiss={hideSignatureHelp}
|
|
476
|
+
/>
|
|
477
|
+
{/if}
|
|
478
|
+
</div>
|
|
479
|
+
|
|
480
|
+
<style>
|
|
481
|
+
.lsp-editor {
|
|
482
|
+
position: relative;
|
|
483
|
+
width: 100%;
|
|
484
|
+
height: 100%;
|
|
485
|
+
}
|
|
486
|
+
</style>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { EditorPreferences } from '../../types';
|
|
2
|
+
import type { LSPClient } from '../../services/lsp-client';
|
|
3
|
+
import type { Diagnostic } from '../../types/lsp';
|
|
4
|
+
import type { Cursor } from '../editor/core/multi-cursor';
|
|
5
|
+
interface Props {
|
|
6
|
+
/** Editor content */
|
|
7
|
+
content: string;
|
|
8
|
+
/** File URI for LSP */
|
|
9
|
+
uri: string;
|
|
10
|
+
/** Language identifier */
|
|
11
|
+
language?: string;
|
|
12
|
+
/** LSP client instance */
|
|
13
|
+
lspClient?: LSPClient;
|
|
14
|
+
/** Read-only mode */
|
|
15
|
+
readonly?: boolean;
|
|
16
|
+
/** Editor preferences */
|
|
17
|
+
preferences?: Partial<EditorPreferences>;
|
|
18
|
+
/** Enable code folding (default: true) */
|
|
19
|
+
folding?: boolean;
|
|
20
|
+
/** Enable multi-cursor editing (default: true) */
|
|
21
|
+
multiCursor?: boolean;
|
|
22
|
+
/** Maximum number of cursors (default: 100) */
|
|
23
|
+
maxCursors?: number;
|
|
24
|
+
/** Additional CSS class */
|
|
25
|
+
class?: string;
|
|
26
|
+
/** Called when content changes */
|
|
27
|
+
onChange?: (content: string) => void;
|
|
28
|
+
/** Called when cursor moves */
|
|
29
|
+
onCursorChange?: (line: number, column: number) => void;
|
|
30
|
+
/** Called when cursors change (for multi-cursor) */
|
|
31
|
+
onCursorsChange?: (cursors: readonly Cursor[]) => void;
|
|
32
|
+
/** Called on save (Ctrl+S) */
|
|
33
|
+
onSave?: () => void;
|
|
34
|
+
/** Called when diagnostics are received */
|
|
35
|
+
onDiagnostics?: (diagnostics: Diagnostic[]) => void;
|
|
36
|
+
}
|
|
37
|
+
declare const LSPEditor: import("svelte").Component<Props, {}, "content">;
|
|
38
|
+
type LSPEditor = ReturnType<typeof LSPEditor>;
|
|
39
|
+
export default LSPEditor;
|