@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,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-cursor selection helpers extracted from CustomEditor.
|
|
3
|
+
* Pure functions that operate on EditorState.
|
|
4
|
+
*/
|
|
5
|
+
import { findAllMatches, getSelectionStart, getSelectionEnd, isSelectionEmpty } from './core';
|
|
6
|
+
/**
|
|
7
|
+
* Test whether a character is a word character (\w). Used to enforce whole-word
|
|
8
|
+
* boundaries so that selecting `foo` does not also land cursors inside `foobar`.
|
|
9
|
+
*/
|
|
10
|
+
function isWordChar(c) {
|
|
11
|
+
return c !== undefined && /\w/.test(c);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Find all matches of `searchText` across the document.
|
|
15
|
+
*
|
|
16
|
+
* - When `wholeWord` is true, matches are filtered so that the characters
|
|
17
|
+
* immediately before and after the match are NOT word characters. This is the
|
|
18
|
+
* "select word under cursor" behaviour where `foo` should not match `foobar`.
|
|
19
|
+
* - Multi-line search text (containing a newline) is the caller's responsibility
|
|
20
|
+
* to handle; this helper only ever sees single-line search text because the
|
|
21
|
+
* per-line search engine cannot span lines.
|
|
22
|
+
*/
|
|
23
|
+
function findOccurrences(state, searchText, wholeWord) {
|
|
24
|
+
const matches = findAllMatches(state.lines, searchText, {
|
|
25
|
+
caseSensitive: true,
|
|
26
|
+
useRegex: false
|
|
27
|
+
});
|
|
28
|
+
if (!wholeWord)
|
|
29
|
+
return matches;
|
|
30
|
+
if (!isWordChar(searchText[0]) && !isWordChar(searchText[searchText.length - 1])) {
|
|
31
|
+
// The search text is not bounded by word characters at all (e.g. an
|
|
32
|
+
// operator or punctuation), so word-boundary filtering is meaningless.
|
|
33
|
+
return matches;
|
|
34
|
+
}
|
|
35
|
+
return matches.filter((m) => {
|
|
36
|
+
const lineText = state.getLine(m.start.line)?.text ?? '';
|
|
37
|
+
const before = m.start.column > 0 ? lineText[m.start.column - 1] : undefined;
|
|
38
|
+
const after = lineText[m.end.column];
|
|
39
|
+
return !isWordChar(before) && !isWordChar(after);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get word at cursor position
|
|
44
|
+
*/
|
|
45
|
+
export function getWordAtPosition(state, pos) {
|
|
46
|
+
const line = state.getLine(pos.line);
|
|
47
|
+
if (!line)
|
|
48
|
+
return null;
|
|
49
|
+
const text = line.text;
|
|
50
|
+
if (!text || pos.column >= text.length)
|
|
51
|
+
return null;
|
|
52
|
+
// Find word boundaries
|
|
53
|
+
let start = pos.column;
|
|
54
|
+
let end = pos.column;
|
|
55
|
+
const isWordChar = (c) => /\w/.test(c);
|
|
56
|
+
// Move start backwards
|
|
57
|
+
while (start > 0 && isWordChar(text[start - 1])) {
|
|
58
|
+
start--;
|
|
59
|
+
}
|
|
60
|
+
// Move end forwards
|
|
61
|
+
while (end < text.length && isWordChar(text[end])) {
|
|
62
|
+
end++;
|
|
63
|
+
}
|
|
64
|
+
if (start === end)
|
|
65
|
+
return null;
|
|
66
|
+
return {
|
|
67
|
+
text: text.slice(start, end),
|
|
68
|
+
start: { line: pos.line, column: start },
|
|
69
|
+
end: { line: pos.line, column: end }
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Select next occurrence of current word/selection (Ctrl+D)
|
|
74
|
+
*/
|
|
75
|
+
export function selectNextOccurrence(state) {
|
|
76
|
+
if (!state)
|
|
77
|
+
return;
|
|
78
|
+
const primary = state.primaryCursor;
|
|
79
|
+
let searchText;
|
|
80
|
+
// Whole-word matching only applies to the implicit "word under cursor" case;
|
|
81
|
+
// an explicit selection should match exactly as selected (substring).
|
|
82
|
+
let wholeWord = false;
|
|
83
|
+
// Get text to search for
|
|
84
|
+
if (!isSelectionEmpty(primary.selection)) {
|
|
85
|
+
// Use current selection
|
|
86
|
+
searchText = state.getTextInSelection(primary.selection);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// Select word at cursor first
|
|
90
|
+
const word = getWordAtPosition(state, primary.selection.head);
|
|
91
|
+
if (!word)
|
|
92
|
+
return;
|
|
93
|
+
searchText = word.text;
|
|
94
|
+
wholeWord = true;
|
|
95
|
+
// Select the word under cursor for the primary cursor
|
|
96
|
+
state.cursorManager.setSelection(primary.id, word.start, word.end);
|
|
97
|
+
}
|
|
98
|
+
if (!searchText)
|
|
99
|
+
return;
|
|
100
|
+
// A multi-line selection cannot be matched by the per-line search engine, so
|
|
101
|
+
// bail out cleanly rather than silently searching for the (never-found) text.
|
|
102
|
+
if (searchText.includes('\n'))
|
|
103
|
+
return;
|
|
104
|
+
// Find all matches (whole-word filtered for the word-under-cursor case)
|
|
105
|
+
const matches = findOccurrences(state, searchText, wholeWord);
|
|
106
|
+
if (matches.length === 0)
|
|
107
|
+
return;
|
|
108
|
+
// Get all current cursor positions to find next unselected match
|
|
109
|
+
const currentCursors = state.allCursors;
|
|
110
|
+
// Find next match after the last cursor that isn't already selected
|
|
111
|
+
let lastCursorEnd = { line: 0, column: 0 };
|
|
112
|
+
for (const cursor of currentCursors) {
|
|
113
|
+
const end = getSelectionEnd(cursor.selection);
|
|
114
|
+
if (end.line > lastCursorEnd.line ||
|
|
115
|
+
(end.line === lastCursorEnd.line && end.column > lastCursorEnd.column)) {
|
|
116
|
+
lastCursorEnd = end;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Find next match
|
|
120
|
+
let foundMatch = null;
|
|
121
|
+
for (const match of matches) {
|
|
122
|
+
const matchStart = match.start;
|
|
123
|
+
if (matchStart.line > lastCursorEnd.line ||
|
|
124
|
+
(matchStart.line === lastCursorEnd.line && matchStart.column >= lastCursorEnd.column)) {
|
|
125
|
+
// Check if this match is already covered by a cursor
|
|
126
|
+
const alreadySelected = currentCursors.some(cursor => {
|
|
127
|
+
const start = getSelectionStart(cursor.selection);
|
|
128
|
+
return start.line === matchStart.line && start.column === matchStart.column;
|
|
129
|
+
});
|
|
130
|
+
if (!alreadySelected) {
|
|
131
|
+
foundMatch = match;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// If no match found after last cursor, wrap around
|
|
137
|
+
if (!foundMatch) {
|
|
138
|
+
for (const match of matches) {
|
|
139
|
+
const matchStart = match.start;
|
|
140
|
+
const alreadySelected = currentCursors.some(cursor => {
|
|
141
|
+
const start = getSelectionStart(cursor.selection);
|
|
142
|
+
return start.line === matchStart.line && start.column === matchStart.column;
|
|
143
|
+
});
|
|
144
|
+
if (!alreadySelected) {
|
|
145
|
+
foundMatch = match;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (foundMatch) {
|
|
151
|
+
state.addCursorWithSelection(foundMatch.start, foundMatch.end);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Select all occurrences of current word/selection (Ctrl+Shift+L)
|
|
156
|
+
*/
|
|
157
|
+
export function selectAllOccurrences(state) {
|
|
158
|
+
if (!state)
|
|
159
|
+
return;
|
|
160
|
+
const primary = state.primaryCursor;
|
|
161
|
+
let searchText;
|
|
162
|
+
// Whole-word matching only applies to the implicit "word under cursor" case.
|
|
163
|
+
let wholeWord = false;
|
|
164
|
+
// Get text to search for
|
|
165
|
+
if (!isSelectionEmpty(primary.selection)) {
|
|
166
|
+
searchText = state.getTextInSelection(primary.selection);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const word = getWordAtPosition(state, primary.selection.head);
|
|
170
|
+
if (!word)
|
|
171
|
+
return;
|
|
172
|
+
searchText = word.text;
|
|
173
|
+
wholeWord = true;
|
|
174
|
+
// Select the word under cursor for the primary cursor
|
|
175
|
+
state.cursorManager.setSelection(primary.id, word.start, word.end);
|
|
176
|
+
}
|
|
177
|
+
if (!searchText)
|
|
178
|
+
return;
|
|
179
|
+
// A multi-line selection cannot be matched by the per-line search engine.
|
|
180
|
+
if (searchText.includes('\n'))
|
|
181
|
+
return;
|
|
182
|
+
// Find all matches (whole-word filtered for the word-under-cursor case)
|
|
183
|
+
const matches = findOccurrences(state, searchText, wholeWord);
|
|
184
|
+
if (matches.length <= 1)
|
|
185
|
+
return;
|
|
186
|
+
// Add cursors at all other matches
|
|
187
|
+
for (const match of matches) {
|
|
188
|
+
const matchStart = match.start;
|
|
189
|
+
// Skip the primary cursor's position
|
|
190
|
+
const primaryStart = getSelectionStart(primary.selection);
|
|
191
|
+
if (matchStart.line === primaryStart.line && matchStart.column === primaryStart.column) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
state.addCursorWithSelection(match.start, match.end);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Selection } from './core';
|
|
2
|
+
export interface ScrollConfig {
|
|
3
|
+
getEditorContent: () => HTMLDivElement | null;
|
|
4
|
+
getSelection: () => Selection;
|
|
5
|
+
getMeasurements: () => {
|
|
6
|
+
lineHeight: number;
|
|
7
|
+
charWidth: number;
|
|
8
|
+
gutterWidth: number;
|
|
9
|
+
contentPadding: number;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export declare function createEditorScroll(config: ScrollConfig): {
|
|
13
|
+
scrollCursorIntoView: () => Promise<void>;
|
|
14
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { tick } from 'svelte';
|
|
2
|
+
import { CONTENT_PADDING } from './constants';
|
|
3
|
+
export function createEditorScroll(config) {
|
|
4
|
+
async function scrollCursorIntoView() {
|
|
5
|
+
await tick();
|
|
6
|
+
const editorContent = config.getEditorContent();
|
|
7
|
+
if (!editorContent)
|
|
8
|
+
return;
|
|
9
|
+
const selection = config.getSelection();
|
|
10
|
+
const { lineHeight, charWidth, gutterWidth } = config.getMeasurements();
|
|
11
|
+
const cursorTop = selection.head.line * lineHeight;
|
|
12
|
+
const cursorLeft = gutterWidth + CONTENT_PADDING + selection.head.column * charWidth;
|
|
13
|
+
const viewportHeight = editorContent.clientHeight;
|
|
14
|
+
const viewportWidth = editorContent.clientWidth;
|
|
15
|
+
const scrollTop = editorContent.scrollTop;
|
|
16
|
+
const scrollLeft = editorContent.scrollLeft;
|
|
17
|
+
// Vertical scroll
|
|
18
|
+
if (cursorTop < scrollTop) {
|
|
19
|
+
editorContent.scrollTop = cursorTop;
|
|
20
|
+
}
|
|
21
|
+
else if (cursorTop + lineHeight > scrollTop + viewportHeight) {
|
|
22
|
+
editorContent.scrollTop = cursorTop + lineHeight - viewportHeight;
|
|
23
|
+
}
|
|
24
|
+
// Horizontal scroll
|
|
25
|
+
const contentStart = gutterWidth + CONTENT_PADDING;
|
|
26
|
+
if (cursorLeft < scrollLeft + contentStart) {
|
|
27
|
+
editorContent.scrollLeft = Math.max(0, cursorLeft - contentStart - 20);
|
|
28
|
+
}
|
|
29
|
+
else if (cursorLeft > scrollLeft + viewportWidth - 20) {
|
|
30
|
+
editorContent.scrollLeft = cursorLeft - viewportWidth + 40;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return { scrollCursorIntoView };
|
|
34
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editor components and utilities
|
|
3
|
+
*/
|
|
4
|
+
export { default as Editor } from './Editor.svelte';
|
|
5
|
+
export { default as CustomEditor } from './CustomEditor.svelte';
|
|
6
|
+
export { default as CollaborativeEditor } from './CollaborativeEditor.svelte';
|
|
7
|
+
export { default as EditorTabs } from './EditorTabs.svelte';
|
|
8
|
+
export { default as EditorPane } from './EditorPane.svelte';
|
|
9
|
+
export { default as FileIcon } from './FileIcon.svelte';
|
|
10
|
+
export { default as FileExplorer } from './FileExplorer.svelte';
|
|
11
|
+
export * from './core';
|
|
12
|
+
export * from './theme';
|
|
13
|
+
export { getLanguageExtension, getLanguageConfig, getLanguageFromExtension, getLanguageFromFilename, getLanguageFromMimeType, getAllLanguageConfigs, resolveLanguage, type LanguageConfig } from './languages';
|
|
14
|
+
export { getSupportedLanguages, isLanguageSupported } from './languages';
|
|
15
|
+
export { getTokenizer, tokenize, getTokenClass, tokensToHTML, PlaintextTokenizer, SimpleTokenizer, GrammarTokenizer, createToken, type Token, type TokenizedLine, type TokenizerState, type TokenType, type LanguageTokenizer, type TokenRule, type LanguageGrammar } from './tokenizer';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editor components and utilities
|
|
3
|
+
*/
|
|
4
|
+
// Components
|
|
5
|
+
export { default as Editor } from './Editor.svelte';
|
|
6
|
+
export { default as CustomEditor } from './CustomEditor.svelte';
|
|
7
|
+
export { default as CollaborativeEditor } from './CollaborativeEditor.svelte';
|
|
8
|
+
export { default as EditorTabs } from './EditorTabs.svelte';
|
|
9
|
+
export { default as EditorPane } from './EditorPane.svelte';
|
|
10
|
+
export { default as FileIcon } from './FileIcon.svelte';
|
|
11
|
+
export { default as FileExplorer } from './FileExplorer.svelte';
|
|
12
|
+
// Core utilities
|
|
13
|
+
export * from './core';
|
|
14
|
+
// Theme
|
|
15
|
+
export * from './theme';
|
|
16
|
+
// Languages (explicit exports to avoid conflicts with tokenizer)
|
|
17
|
+
export { getLanguageExtension, getLanguageConfig, getLanguageFromExtension, getLanguageFromFilename, getLanguageFromMimeType, getAllLanguageConfigs, resolveLanguage } from './languages';
|
|
18
|
+
// Re-export from languages (these exist in both but we prefer languages versions)
|
|
19
|
+
export { getSupportedLanguages, isLanguageSupported } from './languages';
|
|
20
|
+
// Tokenizer (explicit exports to avoid conflicts)
|
|
21
|
+
export { getTokenizer, tokenize, getTokenClass, tokensToHTML, PlaintextTokenizer, SimpleTokenizer, GrammarTokenizer, createToken } from './tokenizer';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language support for the custom editor
|
|
3
|
+
*
|
|
4
|
+
* This module provides language detection and configuration
|
|
5
|
+
* using the custom tokenizer system (no CodeMirror dependency).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Language configuration
|
|
9
|
+
*/
|
|
10
|
+
export interface LanguageConfig {
|
|
11
|
+
/** Language identifier */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Display name */
|
|
14
|
+
name: string;
|
|
15
|
+
/** File extensions (without dot) */
|
|
16
|
+
extensions: string[];
|
|
17
|
+
/** MIME types */
|
|
18
|
+
mimeTypes: string[];
|
|
19
|
+
/** Line comment prefix */
|
|
20
|
+
lineComment?: string;
|
|
21
|
+
/** Block comment delimiters */
|
|
22
|
+
blockComment?: [string, string];
|
|
23
|
+
/** Auto-closing pairs */
|
|
24
|
+
autoClosingPairs?: Array<[string, string]>;
|
|
25
|
+
/** Surrounding pairs */
|
|
26
|
+
surroundingPairs?: Array<[string, string]>;
|
|
27
|
+
/** Word pattern regex */
|
|
28
|
+
wordPattern?: RegExp;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get language ID from file extension
|
|
32
|
+
*/
|
|
33
|
+
export declare function getLanguageFromExtension(extension: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Get language ID from MIME type
|
|
36
|
+
*/
|
|
37
|
+
export declare function getLanguageFromMimeType(mimeType: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Get language ID from filename
|
|
40
|
+
*/
|
|
41
|
+
export declare function getLanguageFromFilename(filename: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Get language configuration
|
|
44
|
+
*/
|
|
45
|
+
export declare function getLanguageConfig(language: string): LanguageConfig;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a language is supported
|
|
48
|
+
*/
|
|
49
|
+
export declare function isLanguageSupported(language: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Get list of supported languages
|
|
52
|
+
*/
|
|
53
|
+
export declare function getSupportedLanguages(): string[];
|
|
54
|
+
/**
|
|
55
|
+
* Get all language configurations
|
|
56
|
+
*/
|
|
57
|
+
export declare function getAllLanguageConfigs(): LanguageConfig[];
|
|
58
|
+
/**
|
|
59
|
+
* @deprecated Use getLanguageConfig instead
|
|
60
|
+
*/
|
|
61
|
+
export declare function getLanguageExtension(language: string): Promise<string | null>;
|
|
62
|
+
export { resolveLanguage } from './tokenizer';
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language support for the custom editor
|
|
3
|
+
*
|
|
4
|
+
* This module provides language detection and configuration
|
|
5
|
+
* using the custom tokenizer system (no CodeMirror dependency).
|
|
6
|
+
*/
|
|
7
|
+
import { resolveLanguage, isLanguageSupported as tokenizerSupported, getSupportedLanguages as getTokenizerLanguages } from './tokenizer';
|
|
8
|
+
/**
|
|
9
|
+
* Language configurations
|
|
10
|
+
*/
|
|
11
|
+
const languages = {
|
|
12
|
+
javascript: {
|
|
13
|
+
id: 'javascript',
|
|
14
|
+
name: 'JavaScript',
|
|
15
|
+
extensions: ['js', 'mjs', 'cjs'],
|
|
16
|
+
mimeTypes: ['text/javascript', 'application/javascript'],
|
|
17
|
+
lineComment: '//',
|
|
18
|
+
blockComment: ['/*', '*/'],
|
|
19
|
+
autoClosingPairs: [
|
|
20
|
+
['{', '}'],
|
|
21
|
+
['[', ']'],
|
|
22
|
+
['(', ')'],
|
|
23
|
+
['"', '"'],
|
|
24
|
+
["'", "'"],
|
|
25
|
+
['`', '`']
|
|
26
|
+
],
|
|
27
|
+
surroundingPairs: [
|
|
28
|
+
['{', '}'],
|
|
29
|
+
['[', ']'],
|
|
30
|
+
['(', ')'],
|
|
31
|
+
['"', '"'],
|
|
32
|
+
["'", "'"],
|
|
33
|
+
['`', '`']
|
|
34
|
+
],
|
|
35
|
+
wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g
|
|
36
|
+
},
|
|
37
|
+
typescript: {
|
|
38
|
+
id: 'typescript',
|
|
39
|
+
name: 'TypeScript',
|
|
40
|
+
extensions: ['ts', 'mts', 'cts'],
|
|
41
|
+
mimeTypes: ['text/typescript', 'application/typescript'],
|
|
42
|
+
lineComment: '//',
|
|
43
|
+
blockComment: ['/*', '*/'],
|
|
44
|
+
autoClosingPairs: [
|
|
45
|
+
['{', '}'],
|
|
46
|
+
['[', ']'],
|
|
47
|
+
['(', ')'],
|
|
48
|
+
['"', '"'],
|
|
49
|
+
["'", "'"],
|
|
50
|
+
['`', '`'],
|
|
51
|
+
['<', '>']
|
|
52
|
+
],
|
|
53
|
+
surroundingPairs: [
|
|
54
|
+
['{', '}'],
|
|
55
|
+
['[', ']'],
|
|
56
|
+
['(', ')'],
|
|
57
|
+
['"', '"'],
|
|
58
|
+
["'", "'"],
|
|
59
|
+
['`', '`'],
|
|
60
|
+
['<', '>']
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
jsx: {
|
|
64
|
+
id: 'jsx',
|
|
65
|
+
name: 'JavaScript React',
|
|
66
|
+
extensions: ['jsx'],
|
|
67
|
+
mimeTypes: ['text/jsx'],
|
|
68
|
+
lineComment: '//',
|
|
69
|
+
blockComment: ['/*', '*/'],
|
|
70
|
+
autoClosingPairs: [
|
|
71
|
+
['{', '}'],
|
|
72
|
+
['[', ']'],
|
|
73
|
+
['(', ')'],
|
|
74
|
+
['"', '"'],
|
|
75
|
+
["'", "'"],
|
|
76
|
+
['`', '`'],
|
|
77
|
+
['<', '>']
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
tsx: {
|
|
81
|
+
id: 'tsx',
|
|
82
|
+
name: 'TypeScript React',
|
|
83
|
+
extensions: ['tsx'],
|
|
84
|
+
mimeTypes: ['text/tsx'],
|
|
85
|
+
lineComment: '//',
|
|
86
|
+
blockComment: ['/*', '*/'],
|
|
87
|
+
autoClosingPairs: [
|
|
88
|
+
['{', '}'],
|
|
89
|
+
['[', ']'],
|
|
90
|
+
['(', ')'],
|
|
91
|
+
['"', '"'],
|
|
92
|
+
["'", "'"],
|
|
93
|
+
['`', '`'],
|
|
94
|
+
['<', '>']
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
html: {
|
|
98
|
+
id: 'html',
|
|
99
|
+
name: 'HTML',
|
|
100
|
+
extensions: ['html', 'htm', 'xhtml'],
|
|
101
|
+
mimeTypes: ['text/html'],
|
|
102
|
+
blockComment: ['<!--', '-->'],
|
|
103
|
+
autoClosingPairs: [
|
|
104
|
+
['{', '}'],
|
|
105
|
+
['[', ']'],
|
|
106
|
+
['(', ')'],
|
|
107
|
+
['"', '"'],
|
|
108
|
+
["'", "'"],
|
|
109
|
+
['<', '>']
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
css: {
|
|
113
|
+
id: 'css',
|
|
114
|
+
name: 'CSS',
|
|
115
|
+
extensions: ['css'],
|
|
116
|
+
mimeTypes: ['text/css'],
|
|
117
|
+
blockComment: ['/*', '*/'],
|
|
118
|
+
autoClosingPairs: [
|
|
119
|
+
['{', '}'],
|
|
120
|
+
['[', ']'],
|
|
121
|
+
['(', ')'],
|
|
122
|
+
['"', '"'],
|
|
123
|
+
["'", "'"]
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
json: {
|
|
127
|
+
id: 'json',
|
|
128
|
+
name: 'JSON',
|
|
129
|
+
extensions: ['json', 'jsonc', 'json5'],
|
|
130
|
+
mimeTypes: ['application/json'],
|
|
131
|
+
autoClosingPairs: [
|
|
132
|
+
['{', '}'],
|
|
133
|
+
['[', ']'],
|
|
134
|
+
['"', '"']
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
python: {
|
|
138
|
+
id: 'python',
|
|
139
|
+
name: 'Python',
|
|
140
|
+
extensions: ['py', 'pyw', 'pyi'],
|
|
141
|
+
mimeTypes: ['text/x-python'],
|
|
142
|
+
lineComment: '#',
|
|
143
|
+
autoClosingPairs: [
|
|
144
|
+
['{', '}'],
|
|
145
|
+
['[', ']'],
|
|
146
|
+
['(', ')'],
|
|
147
|
+
['"', '"'],
|
|
148
|
+
["'", "'"]
|
|
149
|
+
]
|
|
150
|
+
},
|
|
151
|
+
go: {
|
|
152
|
+
id: 'go',
|
|
153
|
+
name: 'Go',
|
|
154
|
+
extensions: ['go'],
|
|
155
|
+
mimeTypes: ['text/x-go'],
|
|
156
|
+
lineComment: '//',
|
|
157
|
+
blockComment: ['/*', '*/'],
|
|
158
|
+
autoClosingPairs: [
|
|
159
|
+
['{', '}'],
|
|
160
|
+
['[', ']'],
|
|
161
|
+
['(', ')'],
|
|
162
|
+
['"', '"'],
|
|
163
|
+
["'", "'"],
|
|
164
|
+
['`', '`']
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
markdown: {
|
|
168
|
+
id: 'markdown',
|
|
169
|
+
name: 'Markdown',
|
|
170
|
+
extensions: ['md', 'markdown', 'mdown', 'mkd'],
|
|
171
|
+
mimeTypes: ['text/markdown'],
|
|
172
|
+
autoClosingPairs: [
|
|
173
|
+
['[', ']'],
|
|
174
|
+
['(', ')'],
|
|
175
|
+
['"', '"'],
|
|
176
|
+
["'", "'"],
|
|
177
|
+
['`', '`'],
|
|
178
|
+
['*', '*'],
|
|
179
|
+
['_', '_']
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
xml: {
|
|
183
|
+
id: 'xml',
|
|
184
|
+
name: 'XML',
|
|
185
|
+
extensions: ['xml', 'xsl', 'xslt', 'svg', 'rss', 'atom'],
|
|
186
|
+
mimeTypes: ['text/xml', 'application/xml'],
|
|
187
|
+
blockComment: ['<!--', '-->'],
|
|
188
|
+
autoClosingPairs: [
|
|
189
|
+
['"', '"'],
|
|
190
|
+
["'", "'"],
|
|
191
|
+
['<', '>']
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
yaml: {
|
|
195
|
+
id: 'yaml',
|
|
196
|
+
name: 'YAML',
|
|
197
|
+
extensions: ['yaml', 'yml'],
|
|
198
|
+
mimeTypes: ['text/yaml'],
|
|
199
|
+
lineComment: '#',
|
|
200
|
+
autoClosingPairs: [
|
|
201
|
+
['{', '}'],
|
|
202
|
+
['[', ']'],
|
|
203
|
+
['(', ')'],
|
|
204
|
+
['"', '"'],
|
|
205
|
+
["'", "'"]
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
plaintext: {
|
|
209
|
+
id: 'plaintext',
|
|
210
|
+
name: 'Plain Text',
|
|
211
|
+
extensions: ['txt', 'text'],
|
|
212
|
+
mimeTypes: ['text/plain'],
|
|
213
|
+
autoClosingPairs: []
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
// Extension to language mapping
|
|
217
|
+
const extensionMap = new Map();
|
|
218
|
+
for (const [id, config] of Object.entries(languages)) {
|
|
219
|
+
for (const ext of config.extensions) {
|
|
220
|
+
extensionMap.set(ext.toLowerCase(), id);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// MIME type to language mapping
|
|
224
|
+
const mimeMap = new Map();
|
|
225
|
+
for (const [id, config] of Object.entries(languages)) {
|
|
226
|
+
for (const mime of config.mimeTypes) {
|
|
227
|
+
mimeMap.set(mime.toLowerCase(), id);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Get language ID from file extension
|
|
232
|
+
*/
|
|
233
|
+
export function getLanguageFromExtension(extension) {
|
|
234
|
+
const ext = extension.toLowerCase().replace(/^\./, '');
|
|
235
|
+
return extensionMap.get(ext) ?? 'plaintext';
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Get language ID from MIME type
|
|
239
|
+
*/
|
|
240
|
+
export function getLanguageFromMimeType(mimeType) {
|
|
241
|
+
return mimeMap.get(mimeType.toLowerCase()) ?? 'plaintext';
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Get language ID from filename
|
|
245
|
+
*/
|
|
246
|
+
export function getLanguageFromFilename(filename) {
|
|
247
|
+
const ext = filename.split('.').pop() ?? '';
|
|
248
|
+
return getLanguageFromExtension(ext);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get language configuration
|
|
252
|
+
*/
|
|
253
|
+
export function getLanguageConfig(language) {
|
|
254
|
+
const resolved = resolveLanguage(language);
|
|
255
|
+
return languages[resolved] ?? languages['plaintext'];
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Check if a language is supported
|
|
259
|
+
*/
|
|
260
|
+
export function isLanguageSupported(language) {
|
|
261
|
+
return tokenizerSupported(language);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Get list of supported languages
|
|
265
|
+
*/
|
|
266
|
+
export function getSupportedLanguages() {
|
|
267
|
+
return getTokenizerLanguages();
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get all language configurations
|
|
271
|
+
*/
|
|
272
|
+
export function getAllLanguageConfigs() {
|
|
273
|
+
return Object.values(languages);
|
|
274
|
+
}
|
|
275
|
+
// For backwards compatibility - these functions previously loaded CodeMirror extensions
|
|
276
|
+
// Now they just return the language string since tokenization is handled internally
|
|
277
|
+
/**
|
|
278
|
+
* @deprecated Use getLanguageConfig instead
|
|
279
|
+
*/
|
|
280
|
+
export async function getLanguageExtension(language) {
|
|
281
|
+
const resolved = resolveLanguage(language);
|
|
282
|
+
return isLanguageSupported(resolved) ? resolved : null;
|
|
283
|
+
}
|
|
284
|
+
// Re-export tokenizer functions for convenience
|
|
285
|
+
export { resolveLanguage } from './tokenizer';
|