@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,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;
|