@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,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tokenizer module for syntax highlighting
|
|
3
|
+
*
|
|
4
|
+
* This module provides zero-dependency syntax highlighting through custom tokenizers.
|
|
5
|
+
* Each language has its own tokenizer that produces tokens for styling.
|
|
6
|
+
*/
|
|
7
|
+
export * from './types';
|
|
8
|
+
export * from './base';
|
|
9
|
+
// Language tokenizers
|
|
10
|
+
export { JavaScriptTokenizer, createJavaScriptTokenizer, createTypeScriptTokenizer, createJSXTokenizer, createTSXTokenizer } from './languages/javascript';
|
|
11
|
+
export { HTMLTokenizer, createHTMLTokenizer, createXMLTokenizer } from './languages/html';
|
|
12
|
+
export { CSSTokenizer, createCSSTokenizer } from './languages/css';
|
|
13
|
+
export { JSONTokenizer, createJSONTokenizer } from './languages/json';
|
|
14
|
+
export { PythonTokenizer, createPythonTokenizer } from './languages/python';
|
|
15
|
+
export { GoTokenizer, createGoTokenizer } from './languages/go';
|
|
16
|
+
export { MarkdownTokenizer, createMarkdownTokenizer } from './languages/markdown';
|
|
17
|
+
export { SvelteTokenizer, createSvelteTokenizer } from './languages/svelte';
|
|
18
|
+
import { PlaintextTokenizer } from './base';
|
|
19
|
+
import { createJavaScriptTokenizer, createTypeScriptTokenizer, createJSXTokenizer, createTSXTokenizer } from './languages/javascript';
|
|
20
|
+
import { createHTMLTokenizer, createXMLTokenizer } from './languages/html';
|
|
21
|
+
import { createCSSTokenizer } from './languages/css';
|
|
22
|
+
import { createJSONTokenizer } from './languages/json';
|
|
23
|
+
import { createPythonTokenizer } from './languages/python';
|
|
24
|
+
import { createGoTokenizer } from './languages/go';
|
|
25
|
+
import { createMarkdownTokenizer } from './languages/markdown';
|
|
26
|
+
import { createSvelteTokenizer } from './languages/svelte';
|
|
27
|
+
/**
|
|
28
|
+
* Language aliases mapping file extensions and common names to canonical language names
|
|
29
|
+
*/
|
|
30
|
+
const languageAliases = {
|
|
31
|
+
// JavaScript
|
|
32
|
+
js: 'javascript',
|
|
33
|
+
mjs: 'javascript',
|
|
34
|
+
cjs: 'javascript',
|
|
35
|
+
// TypeScript
|
|
36
|
+
ts: 'typescript',
|
|
37
|
+
mts: 'typescript',
|
|
38
|
+
cts: 'typescript',
|
|
39
|
+
// JSX/TSX
|
|
40
|
+
jsx: 'jsx',
|
|
41
|
+
tsx: 'tsx',
|
|
42
|
+
// HTML
|
|
43
|
+
htm: 'html',
|
|
44
|
+
xhtml: 'html',
|
|
45
|
+
vue: 'html',
|
|
46
|
+
// Svelte
|
|
47
|
+
svelte: 'svelte',
|
|
48
|
+
// XML
|
|
49
|
+
svg: 'xml',
|
|
50
|
+
xsl: 'xml',
|
|
51
|
+
xslt: 'xml',
|
|
52
|
+
rss: 'xml',
|
|
53
|
+
atom: 'xml',
|
|
54
|
+
plist: 'xml',
|
|
55
|
+
// CSS
|
|
56
|
+
scss: 'css',
|
|
57
|
+
sass: 'css',
|
|
58
|
+
less: 'css',
|
|
59
|
+
// JSON
|
|
60
|
+
jsonc: 'json',
|
|
61
|
+
json5: 'json',
|
|
62
|
+
// Python
|
|
63
|
+
py: 'python',
|
|
64
|
+
pyw: 'python',
|
|
65
|
+
pyi: 'python',
|
|
66
|
+
// Go
|
|
67
|
+
golang: 'go',
|
|
68
|
+
// Markdown
|
|
69
|
+
md: 'markdown',
|
|
70
|
+
mkd: 'markdown',
|
|
71
|
+
mkdn: 'markdown',
|
|
72
|
+
mdown: 'markdown',
|
|
73
|
+
markdown: 'markdown',
|
|
74
|
+
// Plain text
|
|
75
|
+
txt: 'plaintext',
|
|
76
|
+
text: 'plaintext'
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Tokenizer factory functions by language
|
|
80
|
+
*/
|
|
81
|
+
const tokenizerFactories = {
|
|
82
|
+
javascript: createJavaScriptTokenizer,
|
|
83
|
+
typescript: createTypeScriptTokenizer,
|
|
84
|
+
jsx: createJSXTokenizer,
|
|
85
|
+
tsx: createTSXTokenizer,
|
|
86
|
+
html: createHTMLTokenizer,
|
|
87
|
+
xml: createXMLTokenizer,
|
|
88
|
+
css: createCSSTokenizer,
|
|
89
|
+
json: createJSONTokenizer,
|
|
90
|
+
python: createPythonTokenizer,
|
|
91
|
+
go: createGoTokenizer,
|
|
92
|
+
markdown: createMarkdownTokenizer,
|
|
93
|
+
svelte: createSvelteTokenizer,
|
|
94
|
+
plaintext: () => new PlaintextTokenizer()
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Cached tokenizer instances with LRU eviction
|
|
98
|
+
*/
|
|
99
|
+
const tokenizerCache = new Map();
|
|
100
|
+
/** Maximum number of tokenizers to keep in cache */
|
|
101
|
+
const MAX_TOKENIZER_CACHE_SIZE = 20;
|
|
102
|
+
/**
|
|
103
|
+
* Get the canonical language name from an alias or extension
|
|
104
|
+
*/
|
|
105
|
+
export function resolveLanguage(language) {
|
|
106
|
+
const normalized = language.toLowerCase().replace(/^\./, '');
|
|
107
|
+
return languageAliases[normalized] ?? normalized;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get a tokenizer for a language (with LRU cache eviction)
|
|
111
|
+
*/
|
|
112
|
+
export function getTokenizer(language) {
|
|
113
|
+
const resolved = resolveLanguage(language);
|
|
114
|
+
// Check cache - if found, move to end for LRU tracking
|
|
115
|
+
const cached = tokenizerCache.get(resolved);
|
|
116
|
+
if (cached) {
|
|
117
|
+
// Move to end (most recently used) by re-inserting
|
|
118
|
+
tokenizerCache.delete(resolved);
|
|
119
|
+
tokenizerCache.set(resolved, cached);
|
|
120
|
+
return cached;
|
|
121
|
+
}
|
|
122
|
+
// Evict least recently used if cache is full
|
|
123
|
+
if (tokenizerCache.size >= MAX_TOKENIZER_CACHE_SIZE) {
|
|
124
|
+
// Map iterates in insertion order, so first key is LRU
|
|
125
|
+
const lruKey = tokenizerCache.keys().next().value;
|
|
126
|
+
if (lruKey) {
|
|
127
|
+
tokenizerCache.delete(lruKey);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Create new tokenizer
|
|
131
|
+
const factory = tokenizerFactories[resolved] ?? tokenizerFactories['plaintext'];
|
|
132
|
+
const tokenizer = factory();
|
|
133
|
+
// Cache it
|
|
134
|
+
tokenizerCache.set(resolved, tokenizer);
|
|
135
|
+
return tokenizer;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Clear the tokenizer cache (useful for testing or memory management)
|
|
139
|
+
*/
|
|
140
|
+
export function clearTokenizerCache() {
|
|
141
|
+
tokenizerCache.clear();
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Check if a language is supported
|
|
145
|
+
*/
|
|
146
|
+
export function isLanguageSupported(language) {
|
|
147
|
+
const resolved = resolveLanguage(language);
|
|
148
|
+
return resolved in tokenizerFactories;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get list of supported languages
|
|
152
|
+
*/
|
|
153
|
+
export function getSupportedLanguages() {
|
|
154
|
+
return Object.keys(tokenizerFactories);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Tokenize content for a given language
|
|
158
|
+
*/
|
|
159
|
+
export function tokenize(content, language) {
|
|
160
|
+
const tokenizer = getTokenizer(language);
|
|
161
|
+
const lines = content.split('\n');
|
|
162
|
+
const result = [];
|
|
163
|
+
let state = tokenizer.getInitialState();
|
|
164
|
+
for (let i = 0; i < lines.length; i++) {
|
|
165
|
+
const tokenized = tokenizer.tokenizeLine(lines[i], i + 1, state);
|
|
166
|
+
result.push(tokenized);
|
|
167
|
+
state = tokenized.state ?? state;
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Valid CSS class name pattern (alphanumeric, hyphens, underscores only)
|
|
173
|
+
*/
|
|
174
|
+
const SAFE_CLASS_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
175
|
+
/**
|
|
176
|
+
* Get CSS class for a token type
|
|
177
|
+
* Sanitizes input to prevent XSS through class name injection
|
|
178
|
+
*/
|
|
179
|
+
export function getTokenClass(type) {
|
|
180
|
+
// Convert dots to hyphens for CSS class naming
|
|
181
|
+
const className = type.replace(/\./g, '-');
|
|
182
|
+
// Validate the resulting class name contains only safe characters
|
|
183
|
+
// This prevents any potential XSS if an invalid type somehow gets through
|
|
184
|
+
if (!SAFE_CLASS_PATTERN.test(className)) {
|
|
185
|
+
return 'token-text'; // Fallback to safe default
|
|
186
|
+
}
|
|
187
|
+
return `token-${className}`;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Convert tokens to HTML spans for rendering
|
|
191
|
+
*/
|
|
192
|
+
export function tokensToHTML(tokens) {
|
|
193
|
+
return tokens
|
|
194
|
+
.map((token) => {
|
|
195
|
+
const className = getTokenClass(token.type);
|
|
196
|
+
const escapedText = escapeHTML(token.text);
|
|
197
|
+
if (token.type === 'text') {
|
|
198
|
+
return escapedText;
|
|
199
|
+
}
|
|
200
|
+
return `<span class="${className}">${escapedText}</span>`;
|
|
201
|
+
})
|
|
202
|
+
.join('');
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Escape HTML special characters
|
|
206
|
+
* Unified HTML escaping function for all editor components
|
|
207
|
+
*/
|
|
208
|
+
export function escapeHTML(text) {
|
|
209
|
+
return text
|
|
210
|
+
.replace(/&/g, '&')
|
|
211
|
+
.replace(/</g, '<')
|
|
212
|
+
.replace(/>/g, '>')
|
|
213
|
+
.replace(/"/g, '"')
|
|
214
|
+
.replace(/'/g, ''');
|
|
215
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS tokenizer
|
|
3
|
+
*/
|
|
4
|
+
import type { TokenizedLine, TokenizerState } from '../types';
|
|
5
|
+
interface CSSTokenizerState extends TokenizerState {
|
|
6
|
+
inRule?: boolean;
|
|
7
|
+
inValue?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class CSSTokenizer {
|
|
10
|
+
language: string;
|
|
11
|
+
getInitialState(): CSSTokenizerState;
|
|
12
|
+
tokenizeLine(line: string, lineNumber: number, prevState?: CSSTokenizerState): TokenizedLine;
|
|
13
|
+
private getNextToken;
|
|
14
|
+
private tokenizeString;
|
|
15
|
+
}
|
|
16
|
+
export declare function createCSSTokenizer(): CSSTokenizer;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS tokenizer
|
|
3
|
+
*/
|
|
4
|
+
import { createToken } from '../base';
|
|
5
|
+
// CSS properties (common ones)
|
|
6
|
+
const properties = new Set([
|
|
7
|
+
'align-content', 'align-items', 'align-self', 'animation', 'animation-delay',
|
|
8
|
+
'animation-direction', 'animation-duration', 'animation-fill-mode', 'animation-iteration-count',
|
|
9
|
+
'animation-name', 'animation-play-state', 'animation-timing-function', 'background',
|
|
10
|
+
'background-attachment', 'background-blend-mode', 'background-clip', 'background-color',
|
|
11
|
+
'background-image', 'background-origin', 'background-position', 'background-repeat',
|
|
12
|
+
'background-size', 'border', 'border-bottom', 'border-color', 'border-left', 'border-radius',
|
|
13
|
+
'border-right', 'border-style', 'border-top', 'border-width', 'bottom', 'box-shadow',
|
|
14
|
+
'box-sizing', 'color', 'content', 'cursor', 'display', 'filter', 'flex', 'flex-basis',
|
|
15
|
+
'flex-direction', 'flex-flow', 'flex-grow', 'flex-shrink', 'flex-wrap', 'float', 'font',
|
|
16
|
+
'font-family', 'font-size', 'font-style', 'font-weight', 'gap', 'grid', 'grid-area',
|
|
17
|
+
'grid-column', 'grid-gap', 'grid-row', 'grid-template', 'grid-template-areas',
|
|
18
|
+
'grid-template-columns', 'grid-template-rows', 'height', 'justify-content', 'justify-items',
|
|
19
|
+
'justify-self', 'left', 'letter-spacing', 'line-height', 'list-style', 'margin',
|
|
20
|
+
'margin-bottom', 'margin-left', 'margin-right', 'margin-top', 'max-height', 'max-width',
|
|
21
|
+
'min-height', 'min-width', 'object-fit', 'opacity', 'order', 'outline', 'overflow',
|
|
22
|
+
'overflow-x', 'overflow-y', 'padding', 'padding-bottom', 'padding-left', 'padding-right',
|
|
23
|
+
'padding-top', 'place-content', 'place-items', 'place-self', 'pointer-events', 'position',
|
|
24
|
+
'resize', 'right', 'row-gap', 'text-align', 'text-decoration', 'text-indent', 'text-overflow',
|
|
25
|
+
'text-shadow', 'text-transform', 'top', 'transform', 'transform-origin', 'transition',
|
|
26
|
+
'transition-delay', 'transition-duration', 'transition-property', 'transition-timing-function',
|
|
27
|
+
'user-select', 'vertical-align', 'visibility', 'white-space', 'width', 'word-break',
|
|
28
|
+
'word-spacing', 'word-wrap', 'z-index'
|
|
29
|
+
]);
|
|
30
|
+
// CSS at-rules
|
|
31
|
+
const atRules = new Set([
|
|
32
|
+
'@media', '@keyframes', '@import', '@font-face', '@supports', '@page', '@charset',
|
|
33
|
+
'@namespace', '@viewport', '@counter-style', '@font-feature-values', '@property', '@layer'
|
|
34
|
+
]);
|
|
35
|
+
export class CSSTokenizer {
|
|
36
|
+
language = 'css';
|
|
37
|
+
getInitialState() {
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
tokenizeLine(line, lineNumber, prevState) {
|
|
41
|
+
const tokens = [];
|
|
42
|
+
let pos = 0;
|
|
43
|
+
const state = { ...prevState };
|
|
44
|
+
// Handle multi-line comment continuation
|
|
45
|
+
if (state.inBlockComment) {
|
|
46
|
+
const endIdx = line.indexOf('*/');
|
|
47
|
+
if (endIdx !== -1) {
|
|
48
|
+
tokens.push(createToken('comment.block', line.slice(0, endIdx + 2), 0));
|
|
49
|
+
pos = endIdx + 2;
|
|
50
|
+
state.inBlockComment = false;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
tokens.push(createToken('comment.block', line, 0));
|
|
54
|
+
return { lineNumber, tokens, text: line, state };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
while (pos < line.length) {
|
|
58
|
+
const remaining = line.slice(pos);
|
|
59
|
+
const token = this.getNextToken(remaining, pos, state);
|
|
60
|
+
if (token) {
|
|
61
|
+
tokens.push(token);
|
|
62
|
+
pos = token.end;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
tokens.push(createToken('text', remaining[0], pos));
|
|
66
|
+
pos += 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (tokens.length === 0) {
|
|
70
|
+
tokens.push(createToken('text', '', 0));
|
|
71
|
+
}
|
|
72
|
+
return { lineNumber, tokens, text: line, state };
|
|
73
|
+
}
|
|
74
|
+
getNextToken(text, pos, state) {
|
|
75
|
+
// Whitespace
|
|
76
|
+
const wsMatch = text.match(/^[ \t]+/);
|
|
77
|
+
if (wsMatch) {
|
|
78
|
+
return createToken('text', wsMatch[0], pos);
|
|
79
|
+
}
|
|
80
|
+
// Comments
|
|
81
|
+
if (text.startsWith('/*')) {
|
|
82
|
+
const endIdx = text.indexOf('*/', 2);
|
|
83
|
+
if (endIdx !== -1) {
|
|
84
|
+
return createToken('comment.block', text.slice(0, endIdx + 2), pos);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
state.inBlockComment = true;
|
|
88
|
+
return createToken('comment.block', text, pos);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// At-rules
|
|
92
|
+
const atRuleMatch = text.match(/^@[a-zA-Z-]+/);
|
|
93
|
+
if (atRuleMatch) {
|
|
94
|
+
return createToken('keyword', atRuleMatch[0], pos);
|
|
95
|
+
}
|
|
96
|
+
// Selectors - class
|
|
97
|
+
const classMatch = text.match(/^\.[a-zA-Z_-][a-zA-Z0-9_-]*/);
|
|
98
|
+
if (classMatch) {
|
|
99
|
+
return createToken('type.class', classMatch[0], pos);
|
|
100
|
+
}
|
|
101
|
+
// Selectors - id
|
|
102
|
+
const idMatch = text.match(/^#[a-zA-Z_-][a-zA-Z0-9_-]*/);
|
|
103
|
+
if (idMatch) {
|
|
104
|
+
return createToken('constant', idMatch[0], pos);
|
|
105
|
+
}
|
|
106
|
+
// Pseudo-classes and pseudo-elements
|
|
107
|
+
const pseudoMatch = text.match(/^:{1,2}[a-zA-Z-]+(?:\([^)]*\))?/);
|
|
108
|
+
if (pseudoMatch) {
|
|
109
|
+
return createToken('variable', pseudoMatch[0], pos);
|
|
110
|
+
}
|
|
111
|
+
// Property names
|
|
112
|
+
const propMatch = text.match(/^[a-zA-Z-]+(?=\s*:)/);
|
|
113
|
+
if (propMatch) {
|
|
114
|
+
const prop = propMatch[0];
|
|
115
|
+
if (properties.has(prop) || prop.startsWith('--')) {
|
|
116
|
+
return createToken('property', prop, pos);
|
|
117
|
+
}
|
|
118
|
+
return createToken('property', prop, pos);
|
|
119
|
+
}
|
|
120
|
+
// CSS variables
|
|
121
|
+
const varMatch = text.match(/^var\s*\(\s*--[a-zA-Z0-9_-]+\s*(?:,[^)]*)?\)/);
|
|
122
|
+
if (varMatch) {
|
|
123
|
+
return createToken('function.call', varMatch[0], pos);
|
|
124
|
+
}
|
|
125
|
+
// Functions
|
|
126
|
+
const funcMatch = text.match(/^[a-zA-Z-]+(?=\s*\()/);
|
|
127
|
+
if (funcMatch) {
|
|
128
|
+
return createToken('function', funcMatch[0], pos);
|
|
129
|
+
}
|
|
130
|
+
// Colors - hex
|
|
131
|
+
const hexMatch = text.match(/^#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3,4})\b/);
|
|
132
|
+
if (hexMatch) {
|
|
133
|
+
return createToken('constant', hexMatch[0], pos);
|
|
134
|
+
}
|
|
135
|
+
// Numbers with units
|
|
136
|
+
const numMatch = text.match(/^-?(?:\d+\.?\d*|\.\d+)(?:px|em|rem|%|vh|vw|vmin|vmax|ch|ex|cm|mm|in|pt|pc|deg|rad|grad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?/);
|
|
137
|
+
if (numMatch) {
|
|
138
|
+
return createToken('number', numMatch[0], pos);
|
|
139
|
+
}
|
|
140
|
+
// Strings
|
|
141
|
+
if (text.startsWith('"') || text.startsWith("'")) {
|
|
142
|
+
return this.tokenizeString(text, pos, text[0]);
|
|
143
|
+
}
|
|
144
|
+
// Keywords (color names, etc.)
|
|
145
|
+
const keywordMatch = text.match(/^[a-zA-Z-]+/);
|
|
146
|
+
if (keywordMatch) {
|
|
147
|
+
const word = keywordMatch[0];
|
|
148
|
+
// Common CSS keywords
|
|
149
|
+
if (['inherit', 'initial', 'unset', 'revert', 'none', 'auto', 'transparent', 'currentColor', 'important'].includes(word)) {
|
|
150
|
+
return createToken('keyword', word, pos);
|
|
151
|
+
}
|
|
152
|
+
// Color names
|
|
153
|
+
if (['red', 'blue', 'green', 'white', 'black', 'yellow', 'orange', 'purple', 'pink', 'gray', 'grey'].includes(word)) {
|
|
154
|
+
return createToken('constant', word, pos);
|
|
155
|
+
}
|
|
156
|
+
return createToken('text', word, pos);
|
|
157
|
+
}
|
|
158
|
+
// Punctuation
|
|
159
|
+
if (text[0] === '{' || text[0] === '}') {
|
|
160
|
+
if (text[0] === '{')
|
|
161
|
+
state.inRule = true;
|
|
162
|
+
if (text[0] === '}')
|
|
163
|
+
state.inRule = false;
|
|
164
|
+
return createToken('punctuation.brace', text[0], pos);
|
|
165
|
+
}
|
|
166
|
+
if (text[0] === '(' || text[0] === ')') {
|
|
167
|
+
return createToken('punctuation.paren', text[0], pos);
|
|
168
|
+
}
|
|
169
|
+
if (text[0] === '[' || text[0] === ']') {
|
|
170
|
+
return createToken('punctuation.bracket', text[0], pos);
|
|
171
|
+
}
|
|
172
|
+
if (text[0] === ':' || text[0] === ';' || text[0] === ',') {
|
|
173
|
+
return createToken('punctuation.separator', text[0], pos);
|
|
174
|
+
}
|
|
175
|
+
return createToken('text', text[0], pos);
|
|
176
|
+
}
|
|
177
|
+
tokenizeString(text, pos, delimiter) {
|
|
178
|
+
let i = 1;
|
|
179
|
+
while (i < text.length) {
|
|
180
|
+
if (text[i] === '\\' && i + 1 < text.length) {
|
|
181
|
+
i += 2;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (text[i] === delimiter) {
|
|
185
|
+
return createToken('string', text.slice(0, i + 1), pos);
|
|
186
|
+
}
|
|
187
|
+
i++;
|
|
188
|
+
}
|
|
189
|
+
return createToken('string', text, pos);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
export function createCSSTokenizer() {
|
|
193
|
+
return new CSSTokenizer();
|
|
194
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go tokenizer
|
|
3
|
+
*/
|
|
4
|
+
import type { TokenizedLine, TokenizerState } from '../types';
|
|
5
|
+
interface GoTokenizerState extends TokenizerState {
|
|
6
|
+
inRawString?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare class GoTokenizer {
|
|
9
|
+
language: string;
|
|
10
|
+
getInitialState(): GoTokenizerState;
|
|
11
|
+
tokenizeLine(line: string, lineNumber: number, prevState?: GoTokenizerState): TokenizedLine;
|
|
12
|
+
private getNextToken;
|
|
13
|
+
private classifyIdentifier;
|
|
14
|
+
private tokenizeString;
|
|
15
|
+
}
|
|
16
|
+
export declare function createGoTokenizer(): GoTokenizer;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go tokenizer
|
|
3
|
+
*/
|
|
4
|
+
import { createToken } from '../base';
|
|
5
|
+
// Go keywords
|
|
6
|
+
const keywords = new Set([
|
|
7
|
+
'break', 'case', 'chan', 'const', 'continue', 'default', 'defer', 'else',
|
|
8
|
+
'fallthrough', 'for', 'func', 'go', 'goto', 'if', 'import', 'interface',
|
|
9
|
+
'map', 'package', 'range', 'return', 'select', 'struct', 'switch', 'type', 'var'
|
|
10
|
+
]);
|
|
11
|
+
const controlKeywords = new Set([
|
|
12
|
+
'break', 'case', 'continue', 'default', 'defer', 'else', 'fallthrough',
|
|
13
|
+
'for', 'go', 'goto', 'if', 'range', 'return', 'select', 'switch'
|
|
14
|
+
]);
|
|
15
|
+
const builtins = new Set([
|
|
16
|
+
'true', 'false', 'nil', 'iota'
|
|
17
|
+
]);
|
|
18
|
+
const builtinFunctions = new Set([
|
|
19
|
+
'append', 'cap', 'close', 'complex', 'copy', 'delete', 'imag', 'len',
|
|
20
|
+
'make', 'new', 'panic', 'print', 'println', 'real', 'recover'
|
|
21
|
+
]);
|
|
22
|
+
const builtinTypes = new Set([
|
|
23
|
+
'bool', 'byte', 'complex64', 'complex128', 'error', 'float32', 'float64',
|
|
24
|
+
'int', 'int8', 'int16', 'int32', 'int64', 'rune', 'string',
|
|
25
|
+
'uint', 'uint8', 'uint16', 'uint32', 'uint64', 'uintptr'
|
|
26
|
+
]);
|
|
27
|
+
export class GoTokenizer {
|
|
28
|
+
language = 'go';
|
|
29
|
+
getInitialState() {
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
tokenizeLine(line, lineNumber, prevState) {
|
|
33
|
+
const tokens = [];
|
|
34
|
+
let pos = 0;
|
|
35
|
+
const state = { ...prevState };
|
|
36
|
+
// Handle block comment continuation
|
|
37
|
+
if (state.inBlockComment) {
|
|
38
|
+
const endIdx = line.indexOf('*/');
|
|
39
|
+
if (endIdx !== -1) {
|
|
40
|
+
tokens.push(createToken('comment.block', line.slice(0, endIdx + 2), 0));
|
|
41
|
+
pos = endIdx + 2;
|
|
42
|
+
state.inBlockComment = false;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
tokens.push(createToken('comment.block', line, 0));
|
|
46
|
+
return { lineNumber, tokens, text: line, state };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Handle raw string continuation
|
|
50
|
+
if (state.inRawString) {
|
|
51
|
+
const endIdx = line.indexOf('`');
|
|
52
|
+
if (endIdx !== -1) {
|
|
53
|
+
tokens.push(createToken('string', line.slice(0, endIdx + 1), 0));
|
|
54
|
+
pos = endIdx + 1;
|
|
55
|
+
state.inRawString = false;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
tokens.push(createToken('string', line, 0));
|
|
59
|
+
return { lineNumber, tokens, text: line, state };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
while (pos < line.length) {
|
|
63
|
+
const remaining = line.slice(pos);
|
|
64
|
+
const token = this.getNextToken(remaining, pos, state);
|
|
65
|
+
if (token) {
|
|
66
|
+
tokens.push(token);
|
|
67
|
+
pos = token.end;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
tokens.push(createToken('text', remaining[0], pos));
|
|
71
|
+
pos += 1;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (tokens.length === 0) {
|
|
75
|
+
tokens.push(createToken('text', '', 0));
|
|
76
|
+
}
|
|
77
|
+
return { lineNumber, tokens, text: line, state };
|
|
78
|
+
}
|
|
79
|
+
getNextToken(text, pos, state) {
|
|
80
|
+
// Whitespace
|
|
81
|
+
const wsMatch = text.match(/^[ \t]+/);
|
|
82
|
+
if (wsMatch) {
|
|
83
|
+
return createToken('text', wsMatch[0], pos);
|
|
84
|
+
}
|
|
85
|
+
// Line comments
|
|
86
|
+
if (text.startsWith('//')) {
|
|
87
|
+
return createToken('comment.line', text, pos);
|
|
88
|
+
}
|
|
89
|
+
// Block comments
|
|
90
|
+
if (text.startsWith('/*')) {
|
|
91
|
+
const endIdx = text.indexOf('*/', 2);
|
|
92
|
+
if (endIdx !== -1) {
|
|
93
|
+
return createToken('comment.block', text.slice(0, endIdx + 2), pos);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
state.inBlockComment = true;
|
|
97
|
+
return createToken('comment.block', text, pos);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Raw strings
|
|
101
|
+
if (text.startsWith('`')) {
|
|
102
|
+
const endIdx = text.indexOf('`', 1);
|
|
103
|
+
if (endIdx !== -1) {
|
|
104
|
+
return createToken('string', text.slice(0, endIdx + 1), pos);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
state.inRawString = true;
|
|
108
|
+
return createToken('string', text, pos);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Interpreted strings
|
|
112
|
+
if (text.startsWith('"')) {
|
|
113
|
+
return this.tokenizeString(text, pos);
|
|
114
|
+
}
|
|
115
|
+
// Rune literals
|
|
116
|
+
if (text.startsWith("'")) {
|
|
117
|
+
const runeMatch = text.match(/^'(?:[^'\\]|\\(?:[abfnrtv\\'"]|[0-7]{3}|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))'/);
|
|
118
|
+
if (runeMatch) {
|
|
119
|
+
return createToken('string', runeMatch[0], pos);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Numbers
|
|
123
|
+
const numMatch = text.match(/^(?:0[xX][0-9a-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|(?:\d[\d_]*\.?[\d_]*|\.\d[\d_]*)(?:[eE][+-]?\d[\d_]*)?i?)/);
|
|
124
|
+
if (numMatch) {
|
|
125
|
+
return createToken('number', numMatch[0], pos);
|
|
126
|
+
}
|
|
127
|
+
// Identifiers and keywords
|
|
128
|
+
const identMatch = text.match(/^[a-zA-Z_][a-zA-Z0-9_]*/);
|
|
129
|
+
if (identMatch) {
|
|
130
|
+
const word = identMatch[0];
|
|
131
|
+
return createToken(this.classifyIdentifier(word, text, identMatch[0].length), word, pos);
|
|
132
|
+
}
|
|
133
|
+
// Operators
|
|
134
|
+
const opMatch = text.match(/^(?:<-|:=|&&|\|\||<<|>>|&\^|[+\-*/%&|^!<>=]=?)/);
|
|
135
|
+
if (opMatch) {
|
|
136
|
+
return createToken('operator', opMatch[0], pos);
|
|
137
|
+
}
|
|
138
|
+
// Punctuation
|
|
139
|
+
const punctMatch = text.match(/^[{}[\](),.:;]/);
|
|
140
|
+
if (punctMatch) {
|
|
141
|
+
const char = punctMatch[0];
|
|
142
|
+
let type = 'punctuation';
|
|
143
|
+
if (char === '{' || char === '}')
|
|
144
|
+
type = 'punctuation.brace';
|
|
145
|
+
else if (char === '[' || char === ']')
|
|
146
|
+
type = 'punctuation.bracket';
|
|
147
|
+
else if (char === '(' || char === ')')
|
|
148
|
+
type = 'punctuation.paren';
|
|
149
|
+
else if (char === ',' || char === ';' || char === ':')
|
|
150
|
+
type = 'punctuation.separator';
|
|
151
|
+
else if (char === '.')
|
|
152
|
+
type = 'punctuation.accessor';
|
|
153
|
+
return createToken(type, char, pos);
|
|
154
|
+
}
|
|
155
|
+
return createToken('text', text[0], pos);
|
|
156
|
+
}
|
|
157
|
+
classifyIdentifier(word, context, wordLength) {
|
|
158
|
+
// Built-in constants
|
|
159
|
+
if (builtins.has(word)) {
|
|
160
|
+
if (word === 'true' || word === 'false')
|
|
161
|
+
return 'constant.boolean';
|
|
162
|
+
if (word === 'nil')
|
|
163
|
+
return 'constant.null';
|
|
164
|
+
return 'constant.builtin';
|
|
165
|
+
}
|
|
166
|
+
// Keywords
|
|
167
|
+
if (keywords.has(word)) {
|
|
168
|
+
if (controlKeywords.has(word))
|
|
169
|
+
return 'keyword.control';
|
|
170
|
+
if (word === 'func' || word === 'type' || word === 'struct' || word === 'interface') {
|
|
171
|
+
return 'keyword.definition';
|
|
172
|
+
}
|
|
173
|
+
if (word === 'import' || word === 'package')
|
|
174
|
+
return 'keyword.module';
|
|
175
|
+
return 'keyword';
|
|
176
|
+
}
|
|
177
|
+
// Built-in types
|
|
178
|
+
if (builtinTypes.has(word)) {
|
|
179
|
+
return 'type.builtin';
|
|
180
|
+
}
|
|
181
|
+
// Built-in functions
|
|
182
|
+
if (builtinFunctions.has(word)) {
|
|
183
|
+
const afterWord = context.slice(wordLength).trim();
|
|
184
|
+
if (afterWord.startsWith('(')) {
|
|
185
|
+
return 'function.call';
|
|
186
|
+
}
|
|
187
|
+
return 'function';
|
|
188
|
+
}
|
|
189
|
+
// Check if followed by ( - likely a function call
|
|
190
|
+
const afterWord = context.slice(wordLength).trim();
|
|
191
|
+
if (afterWord.startsWith('(')) {
|
|
192
|
+
return 'function.call';
|
|
193
|
+
}
|
|
194
|
+
// Check if it's a type (PascalCase)
|
|
195
|
+
if (/^[A-Z][a-zA-Z0-9]*$/.test(word)) {
|
|
196
|
+
return 'type.class';
|
|
197
|
+
}
|
|
198
|
+
return 'variable';
|
|
199
|
+
}
|
|
200
|
+
tokenizeString(text, pos) {
|
|
201
|
+
let i = 1;
|
|
202
|
+
while (i < text.length) {
|
|
203
|
+
if (text[i] === '\\' && i + 1 < text.length) {
|
|
204
|
+
i += 2;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (text[i] === '"') {
|
|
208
|
+
return createToken('string', text.slice(0, i + 1), pos);
|
|
209
|
+
}
|
|
210
|
+
if (text[i] === '\n') {
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
i++;
|
|
214
|
+
}
|
|
215
|
+
return createToken('string', text.slice(0, i), pos);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export function createGoTokenizer() {
|
|
219
|
+
return new GoTokenizer();
|
|
220
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML/XML tokenizer
|
|
3
|
+
*/
|
|
4
|
+
import type { TokenizedLine, TokenizerState } from '../types';
|
|
5
|
+
interface HTMLTokenizerState extends TokenizerState {
|
|
6
|
+
inTag?: boolean;
|
|
7
|
+
inScript?: boolean;
|
|
8
|
+
inStyle?: boolean;
|
|
9
|
+
tagName?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class HTMLTokenizer {
|
|
12
|
+
language: string;
|
|
13
|
+
private isXML;
|
|
14
|
+
constructor(options?: {
|
|
15
|
+
xml?: boolean;
|
|
16
|
+
});
|
|
17
|
+
getInitialState(): HTMLTokenizerState;
|
|
18
|
+
tokenizeLine(line: string, lineNumber: number, prevState?: HTMLTokenizerState): TokenizedLine;
|
|
19
|
+
private getNextToken;
|
|
20
|
+
private tokenizeTag;
|
|
21
|
+
}
|
|
22
|
+
export declare function createHTMLTokenizer(): HTMLTokenizer;
|
|
23
|
+
export declare function createXMLTokenizer(): HTMLTokenizer;
|
|
24
|
+
export {};
|