@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,521 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-cursor management for the custom editor
|
|
3
|
+
*
|
|
4
|
+
* Provides support for creating, managing, and editing with multiple cursors.
|
|
5
|
+
* Cursors can have selections and are automatically merged when they touch or overlap.
|
|
6
|
+
*/
|
|
7
|
+
/** Default maximum cursors */
|
|
8
|
+
const DEFAULT_MAX_CURSORS = 100;
|
|
9
|
+
/**
|
|
10
|
+
* Compare two positions
|
|
11
|
+
* Returns negative if a < b, positive if a > b, 0 if equal
|
|
12
|
+
*/
|
|
13
|
+
export function comparePositions(a, b) {
|
|
14
|
+
if (a.line !== b.line)
|
|
15
|
+
return a.line - b.line;
|
|
16
|
+
return a.column - b.column;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if position a is before position b
|
|
20
|
+
*/
|
|
21
|
+
export function isPositionBefore(a, b) {
|
|
22
|
+
return comparePositions(a, b) < 0;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if position a is before or equal to position b
|
|
26
|
+
*/
|
|
27
|
+
export function isPositionBeforeOrEqual(a, b) {
|
|
28
|
+
return comparePositions(a, b) <= 0;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if two positions are equal
|
|
32
|
+
*/
|
|
33
|
+
export function positionsEqual(a, b) {
|
|
34
|
+
return a.line === b.line && a.column === b.column;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get the start position of a selection (min of anchor and head)
|
|
38
|
+
*/
|
|
39
|
+
export function getSelectionStart(selection) {
|
|
40
|
+
return isPositionBefore(selection.anchor, selection.head)
|
|
41
|
+
? selection.anchor
|
|
42
|
+
: selection.head;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get the end position of a selection (max of anchor and head)
|
|
46
|
+
*/
|
|
47
|
+
export function getSelectionEnd(selection) {
|
|
48
|
+
return isPositionBefore(selection.anchor, selection.head)
|
|
49
|
+
? selection.head
|
|
50
|
+
: selection.anchor;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if a selection is empty (anchor equals head)
|
|
54
|
+
*/
|
|
55
|
+
export function isSelectionEmpty(selection) {
|
|
56
|
+
return positionsEqual(selection.anchor, selection.head);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if two selections overlap or touch
|
|
60
|
+
*/
|
|
61
|
+
export function selectionsOverlap(a, b) {
|
|
62
|
+
const aStart = getSelectionStart(a);
|
|
63
|
+
const aEnd = getSelectionEnd(a);
|
|
64
|
+
const bStart = getSelectionStart(b);
|
|
65
|
+
const bEnd = getSelectionEnd(b);
|
|
66
|
+
// They overlap if neither is completely before the other
|
|
67
|
+
return isPositionBeforeOrEqual(aStart, bEnd) && isPositionBeforeOrEqual(bStart, aEnd);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Merge two selections into one (union)
|
|
71
|
+
*/
|
|
72
|
+
export function mergeSelections(a, b) {
|
|
73
|
+
const aStart = getSelectionStart(a);
|
|
74
|
+
const aEnd = getSelectionEnd(a);
|
|
75
|
+
const bStart = getSelectionStart(b);
|
|
76
|
+
const bEnd = getSelectionEnd(b);
|
|
77
|
+
const start = isPositionBefore(aStart, bStart) ? aStart : bStart;
|
|
78
|
+
const end = isPositionBefore(aEnd, bEnd) ? bEnd : aEnd;
|
|
79
|
+
return { anchor: start, head: end };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Manages multiple cursors in the editor
|
|
83
|
+
*/
|
|
84
|
+
/** Maximum number of listeners allowed per manager */
|
|
85
|
+
const MAX_LISTENERS = 100;
|
|
86
|
+
export class CursorManager {
|
|
87
|
+
cursors = new Map();
|
|
88
|
+
primaryId = '';
|
|
89
|
+
nextId = 0;
|
|
90
|
+
maxCursors;
|
|
91
|
+
listeners = new Set();
|
|
92
|
+
constructor(config = {}) {
|
|
93
|
+
this.maxCursors = config.maxCursors ?? DEFAULT_MAX_CURSORS;
|
|
94
|
+
// Initialize with a single primary cursor at start
|
|
95
|
+
this.addCursor({ line: 0, column: 0 }, true);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get all cursors
|
|
99
|
+
*/
|
|
100
|
+
getCursors() {
|
|
101
|
+
return [...this.cursors.values()];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get all cursors sorted by position (top to bottom, left to right)
|
|
105
|
+
*/
|
|
106
|
+
getSortedCursors() {
|
|
107
|
+
return [...this.cursors.values()].sort((a, b) => {
|
|
108
|
+
const posA = getSelectionStart(a.selection);
|
|
109
|
+
const posB = getSelectionStart(b.selection);
|
|
110
|
+
return comparePositions(posA, posB);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get cursors sorted in reverse order (bottom to top)
|
|
115
|
+
* Useful for editing operations to maintain position validity
|
|
116
|
+
*/
|
|
117
|
+
getSortedCursorsReverse() {
|
|
118
|
+
return this.getSortedCursors().reverse();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get the primary cursor
|
|
122
|
+
*/
|
|
123
|
+
getPrimary() {
|
|
124
|
+
const primary = this.cursors.get(this.primaryId);
|
|
125
|
+
if (!primary) {
|
|
126
|
+
// Fallback: return first cursor
|
|
127
|
+
const first = this.cursors.values().next().value;
|
|
128
|
+
if (first) {
|
|
129
|
+
this.setPrimary(first.id);
|
|
130
|
+
return first;
|
|
131
|
+
}
|
|
132
|
+
// Should never happen, but create a default cursor
|
|
133
|
+
return this.addCursor({ line: 0, column: 0 }, true);
|
|
134
|
+
}
|
|
135
|
+
return primary;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get cursor count
|
|
139
|
+
*/
|
|
140
|
+
get count() {
|
|
141
|
+
return this.cursors.size;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Check if there are multiple cursors
|
|
145
|
+
*/
|
|
146
|
+
get hasMultiple() {
|
|
147
|
+
return this.cursors.size > 1;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Add a new cursor at a position
|
|
151
|
+
* @param position - Position for the new cursor
|
|
152
|
+
* @param makePrimary - Make this the primary cursor
|
|
153
|
+
* @returns The new cursor, or null if at max capacity
|
|
154
|
+
*/
|
|
155
|
+
addCursor(position, makePrimary = false) {
|
|
156
|
+
// Check if we're at capacity
|
|
157
|
+
if (this.cursors.size >= this.maxCursors && !makePrimary) {
|
|
158
|
+
// Return the closest existing cursor instead
|
|
159
|
+
return this.getClosestCursor(position);
|
|
160
|
+
}
|
|
161
|
+
const id = `cursor-${this.nextId++}`;
|
|
162
|
+
const cursor = {
|
|
163
|
+
id,
|
|
164
|
+
selection: { anchor: { ...position }, head: { ...position } },
|
|
165
|
+
isPrimary: makePrimary || this.cursors.size === 0
|
|
166
|
+
};
|
|
167
|
+
if (cursor.isPrimary) {
|
|
168
|
+
// Clear previous primary
|
|
169
|
+
const oldPrimary = this.cursors.get(this.primaryId);
|
|
170
|
+
if (oldPrimary) {
|
|
171
|
+
oldPrimary.isPrimary = false;
|
|
172
|
+
}
|
|
173
|
+
this.primaryId = id;
|
|
174
|
+
}
|
|
175
|
+
this.cursors.set(id, cursor);
|
|
176
|
+
this.mergeTouchingCursors();
|
|
177
|
+
this.emit();
|
|
178
|
+
return cursor;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Add a cursor with a selection
|
|
182
|
+
*/
|
|
183
|
+
addCursorWithSelection(anchor, head, makePrimary = false) {
|
|
184
|
+
const cursor = this.addCursor(anchor, makePrimary);
|
|
185
|
+
cursor.selection = {
|
|
186
|
+
anchor: { ...anchor },
|
|
187
|
+
head: { ...head }
|
|
188
|
+
};
|
|
189
|
+
this.mergeTouchingCursors();
|
|
190
|
+
this.emit();
|
|
191
|
+
return cursor;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Remove a cursor by ID
|
|
195
|
+
* @returns true if removed, false if it was the last cursor
|
|
196
|
+
*/
|
|
197
|
+
removeCursor(id) {
|
|
198
|
+
if (this.cursors.size <= 1) {
|
|
199
|
+
return false; // Must keep at least one cursor
|
|
200
|
+
}
|
|
201
|
+
const wasPrimary = this.primaryId === id;
|
|
202
|
+
this.cursors.delete(id);
|
|
203
|
+
if (wasPrimary) {
|
|
204
|
+
// Promote first remaining cursor to primary
|
|
205
|
+
const first = this.cursors.values().next().value;
|
|
206
|
+
if (first) {
|
|
207
|
+
this.setPrimary(first.id);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
this.emit();
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Remove the last added secondary cursor (for Ctrl+U)
|
|
215
|
+
* @returns true if a cursor was removed
|
|
216
|
+
*/
|
|
217
|
+
removeLastSecondary() {
|
|
218
|
+
if (this.cursors.size <= 1) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
// Get all non-primary cursors sorted by ID (most recent last)
|
|
222
|
+
const secondaries = [...this.cursors.values()]
|
|
223
|
+
.filter(c => !c.isPrimary)
|
|
224
|
+
.sort((a, b) => {
|
|
225
|
+
// Extract numeric part of ID for comparison
|
|
226
|
+
const idA = parseInt(a.id.replace('cursor-', ''), 10);
|
|
227
|
+
const idB = parseInt(b.id.replace('cursor-', ''), 10);
|
|
228
|
+
return idB - idA; // Descending (newest first)
|
|
229
|
+
});
|
|
230
|
+
if (secondaries.length > 0) {
|
|
231
|
+
this.cursors.delete(secondaries[0].id);
|
|
232
|
+
this.emit();
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Clear all secondary cursors, keeping only the primary
|
|
239
|
+
*/
|
|
240
|
+
clearSecondary() {
|
|
241
|
+
if (this.cursors.size <= 1) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const primary = this.getPrimary();
|
|
245
|
+
this.cursors.clear();
|
|
246
|
+
this.cursors.set(primary.id, primary);
|
|
247
|
+
this.emit();
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Set the primary cursor
|
|
251
|
+
*/
|
|
252
|
+
setPrimary(id) {
|
|
253
|
+
const newPrimary = this.cursors.get(id);
|
|
254
|
+
if (!newPrimary)
|
|
255
|
+
return;
|
|
256
|
+
// Clear old primary
|
|
257
|
+
const oldPrimary = this.cursors.get(this.primaryId);
|
|
258
|
+
if (oldPrimary) {
|
|
259
|
+
oldPrimary.isPrimary = false;
|
|
260
|
+
}
|
|
261
|
+
newPrimary.isPrimary = true;
|
|
262
|
+
this.primaryId = id;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Set cursor position (clears selection)
|
|
266
|
+
*/
|
|
267
|
+
setCursor(id, position) {
|
|
268
|
+
const cursor = this.cursors.get(id);
|
|
269
|
+
if (!cursor)
|
|
270
|
+
return;
|
|
271
|
+
cursor.selection = {
|
|
272
|
+
anchor: { ...position },
|
|
273
|
+
head: { ...position }
|
|
274
|
+
};
|
|
275
|
+
this.mergeTouchingCursors();
|
|
276
|
+
this.emit();
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Batch update cursor positions without triggering merge/emit on each update
|
|
280
|
+
* More efficient for updating multiple cursors at once
|
|
281
|
+
*/
|
|
282
|
+
batchUpdateCursors(updates) {
|
|
283
|
+
for (const update of updates) {
|
|
284
|
+
const cursor = this.cursors.get(update.id);
|
|
285
|
+
if (cursor) {
|
|
286
|
+
cursor.selection = {
|
|
287
|
+
anchor: { ...update.position },
|
|
288
|
+
head: { ...update.position }
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
this.mergeTouchingCursors();
|
|
293
|
+
this.emit();
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Set cursor selection
|
|
297
|
+
*/
|
|
298
|
+
setSelection(id, anchor, head) {
|
|
299
|
+
const cursor = this.cursors.get(id);
|
|
300
|
+
if (!cursor)
|
|
301
|
+
return;
|
|
302
|
+
cursor.selection = {
|
|
303
|
+
anchor: { ...anchor },
|
|
304
|
+
head: { ...head }
|
|
305
|
+
};
|
|
306
|
+
this.mergeTouchingCursors();
|
|
307
|
+
this.emit();
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Extend cursor selection (move head, keep anchor)
|
|
311
|
+
*/
|
|
312
|
+
extendSelection(id, head) {
|
|
313
|
+
const cursor = this.cursors.get(id);
|
|
314
|
+
if (!cursor)
|
|
315
|
+
return;
|
|
316
|
+
cursor.selection.head = { ...head };
|
|
317
|
+
this.mergeTouchingCursors();
|
|
318
|
+
this.emit();
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Set all cursors to new positions (for single cursor operations)
|
|
322
|
+
*/
|
|
323
|
+
setSingleCursor(position) {
|
|
324
|
+
this.clearSecondary();
|
|
325
|
+
const primary = this.getPrimary();
|
|
326
|
+
primary.selection = {
|
|
327
|
+
anchor: { ...position },
|
|
328
|
+
head: { ...position }
|
|
329
|
+
};
|
|
330
|
+
this.emit();
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Set single cursor with selection
|
|
334
|
+
*/
|
|
335
|
+
setSingleSelection(anchor, head) {
|
|
336
|
+
this.clearSecondary();
|
|
337
|
+
const primary = this.getPrimary();
|
|
338
|
+
primary.selection = {
|
|
339
|
+
anchor: { ...anchor },
|
|
340
|
+
head: { ...head }
|
|
341
|
+
};
|
|
342
|
+
this.emit();
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Check if any cursor contains a position
|
|
346
|
+
*/
|
|
347
|
+
isPositionInAnyCursor(position) {
|
|
348
|
+
for (const cursor of this.cursors.values()) {
|
|
349
|
+
const start = getSelectionStart(cursor.selection);
|
|
350
|
+
const end = getSelectionEnd(cursor.selection);
|
|
351
|
+
if ((isPositionBeforeOrEqual(start, position) && isPositionBeforeOrEqual(position, end)) ||
|
|
352
|
+
positionsEqual(cursor.selection.head, position)) {
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Get the closest cursor to a position
|
|
360
|
+
*/
|
|
361
|
+
getClosestCursor(position) {
|
|
362
|
+
let closest = this.getPrimary();
|
|
363
|
+
let closestDistance = Infinity;
|
|
364
|
+
for (const cursor of this.cursors.values()) {
|
|
365
|
+
const cursorPos = cursor.selection.head;
|
|
366
|
+
const distance = Math.abs(cursorPos.line - position.line) * 10000 +
|
|
367
|
+
Math.abs(cursorPos.column - position.column);
|
|
368
|
+
if (distance < closestDistance) {
|
|
369
|
+
closestDistance = distance;
|
|
370
|
+
closest = cursor;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return closest;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Merge overlapping or touching cursors
|
|
377
|
+
*/
|
|
378
|
+
mergeTouchingCursors() {
|
|
379
|
+
if (this.cursors.size <= 1)
|
|
380
|
+
return;
|
|
381
|
+
const sorted = this.getSortedCursors();
|
|
382
|
+
const merged = [];
|
|
383
|
+
let primaryWasMerged = false;
|
|
384
|
+
let mergedPrimaryInto = null;
|
|
385
|
+
for (const cursor of sorted) {
|
|
386
|
+
const last = merged[merged.length - 1];
|
|
387
|
+
if (last && selectionsOverlap(last.selection, cursor.selection)) {
|
|
388
|
+
// Merge into last cursor
|
|
389
|
+
last.selection = mergeSelections(last.selection, cursor.selection);
|
|
390
|
+
// Track if primary was merged
|
|
391
|
+
if (cursor.isPrimary) {
|
|
392
|
+
primaryWasMerged = true;
|
|
393
|
+
mergedPrimaryInto = last;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
merged.push(cursor);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// Rebuild the map
|
|
401
|
+
this.cursors.clear();
|
|
402
|
+
for (const cursor of merged) {
|
|
403
|
+
this.cursors.set(cursor.id, cursor);
|
|
404
|
+
}
|
|
405
|
+
// Ensure we have a valid primary
|
|
406
|
+
if (primaryWasMerged && mergedPrimaryInto) {
|
|
407
|
+
this.setPrimary(mergedPrimaryInto.id);
|
|
408
|
+
}
|
|
409
|
+
else if (!this.cursors.has(this.primaryId)) {
|
|
410
|
+
// Primary was removed in merge, set new primary
|
|
411
|
+
const first = this.cursors.values().next().value;
|
|
412
|
+
if (first) {
|
|
413
|
+
this.setPrimary(first.id);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Add cursor above the current primary cursor
|
|
419
|
+
* @param lineCount - Number of lines in the document
|
|
420
|
+
*/
|
|
421
|
+
addCursorAbove(lineCount) {
|
|
422
|
+
const primary = this.getPrimary();
|
|
423
|
+
const pos = primary.selection.head;
|
|
424
|
+
if (pos.line <= 0) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
// Add cursor on line above, same column (will be clamped by caller)
|
|
428
|
+
this.addCursor({ line: pos.line - 1, column: pos.column });
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Add cursor below the current primary cursor
|
|
433
|
+
* @param lineCount - Number of lines in the document
|
|
434
|
+
*/
|
|
435
|
+
addCursorBelow(lineCount) {
|
|
436
|
+
const primary = this.getPrimary();
|
|
437
|
+
const pos = primary.selection.head;
|
|
438
|
+
if (pos.line >= lineCount - 1) {
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
// Add cursor on line below, same column (will be clamped by caller)
|
|
442
|
+
this.addCursor({ line: pos.line + 1, column: pos.column });
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Subscribe to cursor changes
|
|
447
|
+
* In development mode, throws an error to catch memory leaks early.
|
|
448
|
+
* In production, warns and evicts the oldest listener.
|
|
449
|
+
*/
|
|
450
|
+
onChange(callback) {
|
|
451
|
+
if (this.listeners.size >= MAX_LISTENERS) {
|
|
452
|
+
const msg = `[CursorManager] Maximum listener count (${MAX_LISTENERS}) exceeded. Possible memory leak - ensure listeners are unsubscribed.`;
|
|
453
|
+
// Fail fast in development to catch bugs early
|
|
454
|
+
if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
|
|
455
|
+
throw new Error(msg);
|
|
456
|
+
}
|
|
457
|
+
// In production, warn and auto-cleanup oldest listener
|
|
458
|
+
console.warn(msg);
|
|
459
|
+
const firstListener = this.listeners.values().next().value;
|
|
460
|
+
if (firstListener) {
|
|
461
|
+
this.listeners.delete(firstListener);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
this.listeners.add(callback);
|
|
465
|
+
return () => this.listeners.delete(callback);
|
|
466
|
+
}
|
|
467
|
+
emit() {
|
|
468
|
+
for (const listener of this.listeners) {
|
|
469
|
+
try {
|
|
470
|
+
listener();
|
|
471
|
+
}
|
|
472
|
+
catch (error) {
|
|
473
|
+
console.error('[CursorManager] Listener callback failed:', error);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Restore cursors from a saved state (for undo/redo)
|
|
479
|
+
*/
|
|
480
|
+
restore(cursors, primaryId) {
|
|
481
|
+
this.cursors.clear();
|
|
482
|
+
for (const cursor of cursors) {
|
|
483
|
+
this.cursors.set(cursor.id, {
|
|
484
|
+
id: cursor.id,
|
|
485
|
+
selection: {
|
|
486
|
+
anchor: { ...cursor.selection.anchor },
|
|
487
|
+
head: { ...cursor.selection.head }
|
|
488
|
+
},
|
|
489
|
+
isPrimary: cursor.isPrimary
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
this.primaryId = primaryId;
|
|
493
|
+
// Ensure we have at least one cursor
|
|
494
|
+
if (this.cursors.size === 0) {
|
|
495
|
+
this.addCursor({ line: 0, column: 0 }, true);
|
|
496
|
+
}
|
|
497
|
+
this.emit();
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Clone the current state (for undo/redo)
|
|
501
|
+
*/
|
|
502
|
+
clone() {
|
|
503
|
+
return {
|
|
504
|
+
cursors: [...this.cursors.values()].map(c => ({
|
|
505
|
+
id: c.id,
|
|
506
|
+
selection: {
|
|
507
|
+
anchor: { ...c.selection.anchor },
|
|
508
|
+
head: { ...c.selection.head }
|
|
509
|
+
},
|
|
510
|
+
isPrimary: c.isPrimary
|
|
511
|
+
})),
|
|
512
|
+
primaryId: this.primaryId
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Create a new CursorManager
|
|
518
|
+
*/
|
|
519
|
+
export function createCursorManager(config) {
|
|
520
|
+
return new CursorManager(config);
|
|
521
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor navigation utilities
|
|
3
|
+
*
|
|
4
|
+
* This module provides cursor movement operations for the custom editor.
|
|
5
|
+
* Properly handles Unicode including emoji and characters outside the BMP.
|
|
6
|
+
*/
|
|
7
|
+
import type { EditorState, Position } from './state';
|
|
8
|
+
/**
|
|
9
|
+
* Check if character is a word character
|
|
10
|
+
* Supports Unicode identifiers (e.g., café, π, 日本語)
|
|
11
|
+
*/
|
|
12
|
+
export declare function isWordChar(char: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Navigation operations for the editor
|
|
15
|
+
*/
|
|
16
|
+
export declare class Navigation {
|
|
17
|
+
private state;
|
|
18
|
+
/**
|
|
19
|
+
* Sticky column (preferred column) for vertical navigation.
|
|
20
|
+
* Remembers the column position when moving through lines of varying lengths.
|
|
21
|
+
*/
|
|
22
|
+
private stickyColumn;
|
|
23
|
+
constructor(state: EditorState);
|
|
24
|
+
/**
|
|
25
|
+
* Reset sticky column - call this when cursor moves horizontally
|
|
26
|
+
*/
|
|
27
|
+
private resetStickyColumn;
|
|
28
|
+
/**
|
|
29
|
+
* Get the target column for vertical movement, using sticky column if set
|
|
30
|
+
*/
|
|
31
|
+
private getTargetColumn;
|
|
32
|
+
/**
|
|
33
|
+
* Move cursor left
|
|
34
|
+
* Properly handles Unicode surrogate pairs (emoji, etc.)
|
|
35
|
+
*/
|
|
36
|
+
moveLeft(extend?: boolean): void;
|
|
37
|
+
/**
|
|
38
|
+
* Move cursor right
|
|
39
|
+
* Properly handles Unicode surrogate pairs (emoji, etc.)
|
|
40
|
+
*/
|
|
41
|
+
moveRight(extend?: boolean): void;
|
|
42
|
+
/**
|
|
43
|
+
* Move cursor up
|
|
44
|
+
* Uses sticky column to preserve horizontal position through lines of varying lengths
|
|
45
|
+
*/
|
|
46
|
+
moveUp(extend?: boolean): void;
|
|
47
|
+
/**
|
|
48
|
+
* Move cursor down
|
|
49
|
+
* Uses sticky column to preserve horizontal position through lines of varying lengths
|
|
50
|
+
*/
|
|
51
|
+
moveDown(extend?: boolean): void;
|
|
52
|
+
/**
|
|
53
|
+
* Move to start of line
|
|
54
|
+
*/
|
|
55
|
+
moveToLineStart(extend?: boolean): void;
|
|
56
|
+
/**
|
|
57
|
+
* Move to end of line
|
|
58
|
+
*/
|
|
59
|
+
moveToLineEnd(extend?: boolean): void;
|
|
60
|
+
/**
|
|
61
|
+
* Move to start of previous word
|
|
62
|
+
* Properly handles Unicode surrogate pairs (emoji, etc.)
|
|
63
|
+
*/
|
|
64
|
+
moveWordLeft(extend?: boolean): void;
|
|
65
|
+
/**
|
|
66
|
+
* Move to start of next word
|
|
67
|
+
* Properly handles Unicode surrogate pairs (emoji, etc.)
|
|
68
|
+
*/
|
|
69
|
+
moveWordRight(extend?: boolean): void;
|
|
70
|
+
/**
|
|
71
|
+
* Move to start of document
|
|
72
|
+
*/
|
|
73
|
+
moveToDocumentStart(extend?: boolean): void;
|
|
74
|
+
/**
|
|
75
|
+
* Move to end of document
|
|
76
|
+
*/
|
|
77
|
+
moveToDocumentEnd(extend?: boolean): void;
|
|
78
|
+
/**
|
|
79
|
+
* Move up by a page
|
|
80
|
+
*/
|
|
81
|
+
movePageUp(pageSize: number, extend?: boolean): void;
|
|
82
|
+
/**
|
|
83
|
+
* Move down by a page
|
|
84
|
+
*/
|
|
85
|
+
movePageDown(pageSize: number, extend?: boolean): void;
|
|
86
|
+
/**
|
|
87
|
+
* Select current word
|
|
88
|
+
* Properly handles Unicode surrogate pairs (emoji, etc.)
|
|
89
|
+
*/
|
|
90
|
+
selectWord(): void;
|
|
91
|
+
/**
|
|
92
|
+
* Select current line
|
|
93
|
+
*/
|
|
94
|
+
selectLine(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Move to position, optionally extending selection
|
|
97
|
+
*/
|
|
98
|
+
private moveTo;
|
|
99
|
+
/**
|
|
100
|
+
* Get position from mouse coordinates
|
|
101
|
+
*/
|
|
102
|
+
positionFromPoint(x: number, y: number, lineHeight: number, charWidth: number, scrollTop: number, scrollLeft: number, paddingLeft: number, gutterWidth: number): Position;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create navigation helper
|
|
106
|
+
*/
|
|
107
|
+
export declare function createNavigation(state: EditorState): Navigation;
|