@nocturnium/svelte-ide 1.0.0 → 1.0.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/README.md +43 -47
- package/dist/components/agents/AgentActivityPanel.svelte +3 -1
- package/dist/components/agents/AgentAvatar.svelte +127 -35
- package/dist/components/agents/AgentCursor.svelte +15 -5
- package/dist/components/agents/AgentPresenceBar.svelte +7 -2
- package/dist/components/ai/AIConversationList.svelte +39 -34
- package/dist/components/ai/AIInlineEdit.svelte +1 -3
- package/dist/components/ai/AIMessage.svelte +5 -5
- package/dist/components/ai/AIMessageActions.svelte +18 -3
- package/dist/components/ai/AIMessageContent.svelte +22 -20
- package/dist/components/ai/AIPanel.svelte +17 -9
- package/dist/components/ai/AISuggestionWidget.svelte +1 -3
- package/dist/components/ai/AIToolCallDisplay.svelte +10 -14
- package/dist/components/core/Badge.svelte +9 -1
- package/dist/components/core/ConnectionStatus.svelte +73 -68
- package/dist/components/core/ErrorBoundary.svelte +56 -56
- package/dist/components/core/ErrorBoundary.svelte.d.ts +5 -5
- package/dist/components/core/Icon.svelte +22 -11
- package/dist/components/core/ResizeHandle.svelte +1 -1
- package/dist/components/core/Tooltip.svelte +1 -7
- package/dist/components/editor/AIFocusLayer.svelte +15 -7
- package/dist/components/editor/Breadcrumbs.svelte +18 -6
- package/dist/components/editor/BreakpointLayer.svelte +51 -60
- package/dist/components/editor/CognitiveLoadMeter.svelte +4 -2
- package/dist/components/editor/CollaborativeEditor.svelte +1 -5
- package/dist/components/editor/CommandPalette.svelte +1 -4
- package/dist/components/editor/ComplexityLayer.svelte +8 -6
- package/dist/components/editor/ConflictZoneLayer.svelte +2 -8
- package/dist/components/editor/ContextLens.svelte +1 -4
- package/dist/components/editor/CustomEditor.svelte +85 -41
- package/dist/components/editor/DebugConsole.svelte +8 -17
- package/dist/components/editor/EchoCursorLayer.svelte +3 -1
- package/dist/components/editor/EditorGutter.svelte +8 -2
- package/dist/components/editor/EditorLines.svelte +6 -3
- package/dist/components/editor/EditorPane.svelte +1 -6
- package/dist/components/editor/EditorSelections.svelte +29 -11
- package/dist/components/editor/FileExplorer.svelte +26 -4
- package/dist/components/editor/FileIcon.svelte +3 -1
- package/dist/components/editor/FindReplace.svelte +16 -4
- package/dist/components/editor/GhostBracketLayer.svelte +2 -2
- package/dist/components/editor/GitBlameLayer.svelte +2 -1
- package/dist/components/editor/InlineDiagnosticsLayer.svelte +4 -13
- package/dist/components/editor/InlineDiffLayer.svelte +18 -9
- package/dist/components/editor/Minimap.svelte +16 -9
- package/dist/components/editor/PluginPreviewSandbox.svelte +3 -2
- package/dist/components/editor/ProblemsPanel.svelte +11 -35
- package/dist/components/editor/QuickActionsMenu.svelte +5 -14
- package/dist/components/editor/SnippetPalette.svelte +11 -12
- package/dist/components/editor/StructureMap.svelte +2 -1
- package/dist/components/editor/SymbolOutline.svelte +14 -19
- package/dist/components/editor/TimelineScrubber.svelte +7 -6
- package/dist/components/editor/core/complexity-analyzer.js +42 -12
- package/dist/components/editor/core/conflict-predictor.js +2 -4
- package/dist/components/editor/core/folding.d.ts +9 -0
- package/dist/components/editor/core/folding.js +40 -5
- package/dist/components/editor/core/multi-cursor.js +4 -8
- package/dist/components/editor/core/navigation.js +2 -6
- package/dist/components/editor/core/quick-actions.js +22 -17
- package/dist/components/editor/core/search.js +2 -6
- package/dist/components/editor/core/semantic-analyzer.js +1 -3
- package/dist/components/editor/core/snippet-manager.js +4 -3
- package/dist/components/editor/core/state.js +2 -2
- package/dist/components/editor/core/timeline.js +1 -3
- package/dist/components/editor/editor-input.js +9 -6
- package/dist/components/editor/editor-multicursor.js +2 -2
- package/dist/components/editor/tokenizer/languages/css.js +146 -24
- package/dist/components/editor/tokenizer/languages/go.js +76 -13
- package/dist/components/editor/tokenizer/languages/javascript.js +210 -29
- package/dist/components/editor/tokenizer/languages/python.js +116 -19
- package/dist/components/editor/tokenizer/languages/svelte.js +20 -7
- package/dist/components/layout/IDELayout.svelte +6 -2
- package/dist/components/layout/StatusBar.svelte +32 -20
- package/dist/components/lsp/AutocompleteWidget.svelte +19 -19
- package/dist/components/lsp/DiagnosticMarker.svelte +61 -52
- package/dist/components/lsp/DiagnosticsPanel.svelte +45 -27
- package/dist/components/lsp/HoverTooltip.svelte +56 -61
- package/dist/components/lsp/LSPEditor.svelte +7 -18
- package/dist/components/lsp/SignatureHelpWidget.svelte +12 -9
- package/dist/components/plugins/PluginCard.svelte +3 -13
- package/dist/components/plugins/PluginProposalForm.svelte +19 -31
- package/dist/components/vfs/LockConflictDialog.svelte +112 -45
- package/dist/components/vfs/LockIndicator.svelte +0 -1
- package/dist/components/vfs/LockOverlay.svelte +53 -53
- package/dist/components/vfs/LockOverlay.svelte.d.ts +5 -5
- package/dist/components/vfs/VersionConflictDialog.svelte +107 -77
- package/dist/services/error-handling.js +1 -7
- package/dist/services/mock-ai.js +9 -7
- package/dist/stores/agents.svelte.js +50 -10
- package/dist/stores/ai.svelte.js +66 -18
- package/dist/stores/collaboration.svelte.js +70 -14
- package/dist/stores/editor.svelte.js +50 -10
- package/dist/stores/plugin.svelte.js +60 -12
- package/dist/stores/vfs.svelte.js +77 -19
- package/dist/styles/theme.css +16 -7
- package/package.json +186 -1
|
@@ -4,29 +4,126 @@
|
|
|
4
4
|
import { createToken } from '../base';
|
|
5
5
|
// Python keywords
|
|
6
6
|
const keywords = new Set([
|
|
7
|
-
'and',
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
7
|
+
'and',
|
|
8
|
+
'as',
|
|
9
|
+
'assert',
|
|
10
|
+
'async',
|
|
11
|
+
'await',
|
|
12
|
+
'break',
|
|
13
|
+
'class',
|
|
14
|
+
'continue',
|
|
15
|
+
'def',
|
|
16
|
+
'del',
|
|
17
|
+
'elif',
|
|
18
|
+
'else',
|
|
19
|
+
'except',
|
|
20
|
+
'finally',
|
|
21
|
+
'for',
|
|
22
|
+
'from',
|
|
23
|
+
'global',
|
|
24
|
+
'if',
|
|
25
|
+
'import',
|
|
26
|
+
'in',
|
|
27
|
+
'is',
|
|
28
|
+
'lambda',
|
|
29
|
+
'nonlocal',
|
|
30
|
+
'not',
|
|
31
|
+
'or',
|
|
32
|
+
'pass',
|
|
33
|
+
'raise',
|
|
34
|
+
'return',
|
|
35
|
+
'try',
|
|
36
|
+
'while',
|
|
37
|
+
'with',
|
|
38
|
+
'yield'
|
|
11
39
|
]);
|
|
12
40
|
const controlKeywords = new Set([
|
|
13
|
-
'if',
|
|
14
|
-
'
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
'
|
|
41
|
+
'if',
|
|
42
|
+
'elif',
|
|
43
|
+
'else',
|
|
44
|
+
'for',
|
|
45
|
+
'while',
|
|
46
|
+
'try',
|
|
47
|
+
'except',
|
|
48
|
+
'finally',
|
|
49
|
+
'with',
|
|
50
|
+
'break',
|
|
51
|
+
'continue',
|
|
52
|
+
'return',
|
|
53
|
+
'raise',
|
|
54
|
+
'yield',
|
|
55
|
+
'await'
|
|
18
56
|
]);
|
|
57
|
+
const builtins = new Set(['True', 'False', 'None', 'self', 'cls']);
|
|
19
58
|
const builtinFunctions = new Set([
|
|
20
|
-
'abs',
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
59
|
+
'abs',
|
|
60
|
+
'all',
|
|
61
|
+
'any',
|
|
62
|
+
'ascii',
|
|
63
|
+
'bin',
|
|
64
|
+
'bool',
|
|
65
|
+
'bytearray',
|
|
66
|
+
'bytes',
|
|
67
|
+
'callable',
|
|
68
|
+
'chr',
|
|
69
|
+
'classmethod',
|
|
70
|
+
'compile',
|
|
71
|
+
'complex',
|
|
72
|
+
'delattr',
|
|
73
|
+
'dict',
|
|
74
|
+
'dir',
|
|
75
|
+
'divmod',
|
|
76
|
+
'enumerate',
|
|
77
|
+
'eval',
|
|
78
|
+
'exec',
|
|
79
|
+
'filter',
|
|
80
|
+
'float',
|
|
81
|
+
'format',
|
|
82
|
+
'frozenset',
|
|
83
|
+
'getattr',
|
|
84
|
+
'globals',
|
|
85
|
+
'hasattr',
|
|
86
|
+
'hash',
|
|
87
|
+
'help',
|
|
88
|
+
'hex',
|
|
89
|
+
'id',
|
|
90
|
+
'input',
|
|
91
|
+
'int',
|
|
92
|
+
'isinstance',
|
|
93
|
+
'issubclass',
|
|
94
|
+
'iter',
|
|
95
|
+
'len',
|
|
96
|
+
'list',
|
|
97
|
+
'locals',
|
|
98
|
+
'map',
|
|
99
|
+
'max',
|
|
100
|
+
'memoryview',
|
|
101
|
+
'min',
|
|
102
|
+
'next',
|
|
103
|
+
'object',
|
|
104
|
+
'oct',
|
|
105
|
+
'open',
|
|
106
|
+
'ord',
|
|
107
|
+
'pow',
|
|
108
|
+
'print',
|
|
109
|
+
'property',
|
|
110
|
+
'range',
|
|
111
|
+
'repr',
|
|
112
|
+
'reversed',
|
|
113
|
+
'round',
|
|
114
|
+
'set',
|
|
115
|
+
'setattr',
|
|
116
|
+
'slice',
|
|
117
|
+
'sorted',
|
|
118
|
+
'staticmethod',
|
|
119
|
+
'str',
|
|
120
|
+
'sum',
|
|
121
|
+
'super',
|
|
122
|
+
'tuple',
|
|
123
|
+
'type',
|
|
124
|
+
'vars',
|
|
125
|
+
'zip',
|
|
126
|
+
'__import__'
|
|
30
127
|
]);
|
|
31
128
|
export class PythonTokenizer {
|
|
32
129
|
language = 'python';
|
|
@@ -27,13 +27,26 @@ function reindexTokens(tokens) {
|
|
|
27
27
|
* Svelte keywords and directives
|
|
28
28
|
*/
|
|
29
29
|
const SVELTE_BLOCK_KEYWORDS = new Set([
|
|
30
|
-
'if',
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
'
|
|
30
|
+
'if',
|
|
31
|
+
'else',
|
|
32
|
+
'each',
|
|
33
|
+
'await',
|
|
34
|
+
'then',
|
|
35
|
+
'catch',
|
|
36
|
+
'key',
|
|
37
|
+
'snippet'
|
|
34
38
|
]);
|
|
39
|
+
const SVELTE_TAG_KEYWORDS = new Set(['html', 'debug', 'const', 'render']);
|
|
35
40
|
const SVELTE_ATTRIBUTE_PREFIXES = [
|
|
36
|
-
'bind:',
|
|
41
|
+
'bind:',
|
|
42
|
+
'on:',
|
|
43
|
+
'use:',
|
|
44
|
+
'transition:',
|
|
45
|
+
'in:',
|
|
46
|
+
'out:',
|
|
47
|
+
'animate:',
|
|
48
|
+
'let:',
|
|
49
|
+
'class:'
|
|
37
50
|
];
|
|
38
51
|
/**
|
|
39
52
|
* Svelte tokenizer
|
|
@@ -266,10 +279,10 @@ export class SvelteTokenizer {
|
|
|
266
279
|
const attrMatch = tag.substring(pos).match(/^([\w:-]+)(?:=)?/);
|
|
267
280
|
if (attrMatch) {
|
|
268
281
|
const attrName = attrMatch[1];
|
|
269
|
-
const isSvelteAttr = SVELTE_ATTRIBUTE_PREFIXES.some(prefix => attrName.startsWith(prefix));
|
|
282
|
+
const isSvelteAttr = SVELTE_ATTRIBUTE_PREFIXES.some((prefix) => attrName.startsWith(prefix));
|
|
270
283
|
if (isSvelteAttr) {
|
|
271
284
|
// Highlight Svelte-specific attributes
|
|
272
|
-
const prefixMatch = SVELTE_ATTRIBUTE_PREFIXES.find(p => attrName.startsWith(p));
|
|
285
|
+
const prefixMatch = SVELTE_ATTRIBUTE_PREFIXES.find((p) => attrName.startsWith(p));
|
|
273
286
|
if (prefixMatch) {
|
|
274
287
|
tokens.push({ type: 'keyword.control', text: prefixMatch });
|
|
275
288
|
tokens.push({ type: 'tag.attribute', text: attrName.substring(prefixMatch.length) });
|
|
@@ -231,7 +231,9 @@
|
|
|
231
231
|
.ide-layout--resizing .ide-layout__sidebar > :global(*) {
|
|
232
232
|
opacity: 0.5;
|
|
233
233
|
filter: blur(1px);
|
|
234
|
-
transition:
|
|
234
|
+
transition:
|
|
235
|
+
opacity 0.1s ease,
|
|
236
|
+
filter 0.1s ease;
|
|
235
237
|
}
|
|
236
238
|
|
|
237
239
|
.ide-layout__main {
|
|
@@ -278,7 +280,9 @@
|
|
|
278
280
|
.ide-layout--resizing .ide-layout__panel > :global(*) {
|
|
279
281
|
opacity: 0.5;
|
|
280
282
|
filter: blur(1px);
|
|
281
|
-
transition:
|
|
283
|
+
transition:
|
|
284
|
+
opacity 0.1s ease,
|
|
285
|
+
filter 0.1s ease;
|
|
282
286
|
}
|
|
283
287
|
|
|
284
288
|
.ide-layout__status-bar {
|
|
@@ -87,9 +87,7 @@
|
|
|
87
87
|
let featuredAgent = $derived.by(() => {
|
|
88
88
|
// Prefer agent working on current file
|
|
89
89
|
if (currentFilePath) {
|
|
90
|
-
const agentOnFile = busyAgents.find(a =>
|
|
91
|
-
a.currentTask?.files?.includes(currentFilePath)
|
|
92
|
-
);
|
|
90
|
+
const agentOnFile = busyAgents.find((a) => a.currentTask?.files?.includes(currentFilePath));
|
|
93
91
|
if (agentOnFile) return agentOnFile;
|
|
94
92
|
}
|
|
95
93
|
// Otherwise show first busy agent
|
|
@@ -107,10 +105,18 @@
|
|
|
107
105
|
const phase = featuredAgent.currentTask?.progress?.phase;
|
|
108
106
|
let action = 'working';
|
|
109
107
|
switch (phase) {
|
|
110
|
-
case 'planning':
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
case '
|
|
108
|
+
case 'planning':
|
|
109
|
+
action = 'planning';
|
|
110
|
+
break;
|
|
111
|
+
case 'implementing':
|
|
112
|
+
action = 'coding';
|
|
113
|
+
break;
|
|
114
|
+
case 'testing':
|
|
115
|
+
action = 'testing';
|
|
116
|
+
break;
|
|
117
|
+
case 'complete':
|
|
118
|
+
action = 'done';
|
|
119
|
+
break;
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
const otherBusy = busyAgents.length - 1;
|
|
@@ -120,14 +126,10 @@
|
|
|
120
126
|
|
|
121
127
|
// Lock context for current file
|
|
122
128
|
let currentFileLock = $derived(
|
|
123
|
-
currentFilePath ? locks.find(l => l.path === currentFilePath) : undefined
|
|
124
|
-
);
|
|
125
|
-
let isMyLock = $derived(
|
|
126
|
-
currentFileLock && userId ? currentFileLock.holder === userId : false
|
|
127
|
-
);
|
|
128
|
-
let otherLocks = $derived(
|
|
129
|
-
locks.filter(l => l.path !== currentFilePath)
|
|
129
|
+
currentFilePath ? locks.find((l) => l.path === currentFilePath) : undefined
|
|
130
130
|
);
|
|
131
|
+
let isMyLock = $derived(currentFileLock && userId ? currentFileLock.holder === userId : false);
|
|
132
|
+
let otherLocks = $derived(locks.filter((l) => l.path !== currentFilePath));
|
|
131
133
|
|
|
132
134
|
// Lock expiry countdown
|
|
133
135
|
let lockExpiryText = $state<string | null>(null);
|
|
@@ -196,7 +198,7 @@
|
|
|
196
198
|
return `${currentFileLock.holder} is editing this file.`;
|
|
197
199
|
}
|
|
198
200
|
if (locks.length === 0) return 'No files locked';
|
|
199
|
-
const holders = [...new Set(locks.map(l => l.holder))];
|
|
201
|
+
const holders = [...new Set(locks.map((l) => l.holder))];
|
|
200
202
|
return `Locked by: ${holders.join(', ')}`;
|
|
201
203
|
});
|
|
202
204
|
</script>
|
|
@@ -434,8 +436,13 @@
|
|
|
434
436
|
}
|
|
435
437
|
|
|
436
438
|
@keyframes ai-dot-shimmer {
|
|
437
|
-
0%,
|
|
438
|
-
|
|
439
|
+
0%,
|
|
440
|
+
100% {
|
|
441
|
+
background-position: 0% 50%;
|
|
442
|
+
}
|
|
443
|
+
50% {
|
|
444
|
+
background-position: 100% 50%;
|
|
445
|
+
}
|
|
439
446
|
}
|
|
440
447
|
|
|
441
448
|
/* Lock Status */
|
|
@@ -468,8 +475,13 @@
|
|
|
468
475
|
}
|
|
469
476
|
|
|
470
477
|
@keyframes expiry-pulse {
|
|
471
|
-
0%,
|
|
472
|
-
|
|
478
|
+
0%,
|
|
479
|
+
100% {
|
|
480
|
+
opacity: 1;
|
|
481
|
+
}
|
|
482
|
+
50% {
|
|
483
|
+
opacity: 0.6;
|
|
484
|
+
}
|
|
473
485
|
}
|
|
474
486
|
|
|
475
487
|
.status-bar__separator {
|
|
@@ -493,7 +505,7 @@
|
|
|
493
505
|
|
|
494
506
|
/* Responsive: hide less important info on narrow screens */
|
|
495
507
|
@media (max-width: 600px) {
|
|
496
|
-
.status-bar__right > :nth-child(n+3):nth-child(-n+5) {
|
|
508
|
+
.status-bar__right > :nth-child(n + 3):nth-child(-n + 5) {
|
|
497
509
|
display: none;
|
|
498
510
|
}
|
|
499
511
|
}
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
// SVG icons for completion item kinds
|
|
3
|
+
function getKindSVG(kind?: number): string {
|
|
4
|
+
const icons: Record<number, string> = {
|
|
5
|
+
2: '<path d="M4 4h4v2H4v4H2V4h2zm10 0h2v6h-4V8h2V4zm-6 8h4v4H8v-4zm8 0h2v4h-4v-2h2v-2z" fill="currentColor"/>',
|
|
6
|
+
3: '<path d="M4 4h8v2H4v8H2V4h2zm6 4h4v8h-2v-6H8V8h2z" fill="currentColor"/>',
|
|
7
|
+
6: '<path d="M4 4h8v4H8V6H6v4H4V4zm0 8h2v4H4v-4zm4 0h8v4H8v-4z" fill="currentColor"/>',
|
|
8
|
+
7: '<path d="M4 4h8v2H4v8H2V4h2zm4 4h6v8H6V8h2zm2 2v4h2v-4h-2z" fill="currentColor"/>',
|
|
9
|
+
8: '<path d="M6 4h8v2H6v8H4V4h2zm6 4h2v8H8v-2h4V8z" fill="currentColor"/>',
|
|
10
|
+
9: '<path d="M2 4h4v2H2v8h8v2H2V4zm6 2h8v10H8V6zm2 2v6h4V8h-4z" fill="currentColor"/>',
|
|
11
|
+
13: '<path d="M4 4h8v2H4v8H2V4h2zm4 4h6v8H6V8h2zm2 2v2h2v-2h-2z" fill="currentColor"/>',
|
|
12
|
+
14: '<path d="M4 6h10v2H4v6H2V6h2zm4 4h6v6H6v-6h2zm2 2v2h2v-2h-2z" fill="currentColor"/>',
|
|
13
|
+
15: '<path d="M4 4v12h12V4H4zm2 2h8v8H6V6z" fill="currentColor"/>',
|
|
14
|
+
21: '<path d="M8 2l6 6-6 6-6-6 6-6zm0 2.83L4.83 8 8 11.17 11.17 8 8 4.83z" fill="currentColor"/>'
|
|
15
|
+
};
|
|
16
|
+
return `<svg viewBox="0 0 16 16" width="16" height="16">${icons[kind ?? 1] ?? '<circle cx="8" cy="8" r="4" fill="currentColor"/>'}</svg>`;
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
1
20
|
<script lang="ts">
|
|
2
21
|
/**
|
|
3
22
|
* AutocompleteWidget - LSP completion suggestions dropdown
|
|
@@ -206,25 +225,6 @@
|
|
|
206
225
|
{/if}
|
|
207
226
|
</div>
|
|
208
227
|
|
|
209
|
-
<script module lang="ts">
|
|
210
|
-
// SVG icons for completion item kinds
|
|
211
|
-
function getKindSVG(kind?: number): string {
|
|
212
|
-
const icons: Record<number, string> = {
|
|
213
|
-
2: '<path d="M4 4h4v2H4v4H2V4h2zm10 0h2v6h-4V8h2V4zm-6 8h4v4H8v-4zm8 0h2v4h-4v-2h2v-2z" fill="currentColor"/>',
|
|
214
|
-
3: '<path d="M4 4h8v2H4v8H2V4h2zm6 4h4v8h-2v-6H8V8h2z" fill="currentColor"/>',
|
|
215
|
-
6: '<path d="M4 4h8v4H8V6H6v4H4V4zm0 8h2v4H4v-4zm4 0h8v4H8v-4z" fill="currentColor"/>',
|
|
216
|
-
7: '<path d="M4 4h8v2H4v8H2V4h2zm4 4h6v8H6V8h2zm2 2v4h2v-4h-2z" fill="currentColor"/>',
|
|
217
|
-
8: '<path d="M6 4h8v2H6v8H4V4h2zm6 4h2v8H8v-2h4V8z" fill="currentColor"/>',
|
|
218
|
-
9: '<path d="M2 4h4v2H2v8h8v2H2V4zm6 2h8v10H8V6zm2 2v6h4V8h-4z" fill="currentColor"/>',
|
|
219
|
-
13: '<path d="M4 4h8v2H4v8H2V4h2zm4 4h6v8H6V8h2zm2 2v2h2v-2h-2z" fill="currentColor"/>',
|
|
220
|
-
14: '<path d="M4 6h10v2H4v6H2V6h2zm4 4h6v6H6v-6h2zm2 2v2h2v-2h-2z" fill="currentColor"/>',
|
|
221
|
-
15: '<path d="M4 4v12h12V4H4zm2 2h8v8H6V6z" fill="currentColor"/>',
|
|
222
|
-
21: '<path d="M8 2l6 6-6 6-6-6 6-6zm0 2.83L4.83 8 8 11.17 11.17 8 8 4.83z" fill="currentColor"/>'
|
|
223
|
-
};
|
|
224
|
-
return `<svg viewBox="0 0 16 16" width="16" height="16">${icons[kind ?? 1] ?? '<circle cx="8" cy="8" r="4" fill="currentColor"/>'}</svg>`;
|
|
225
|
-
}
|
|
226
|
-
</script>
|
|
227
|
-
|
|
228
228
|
<style>
|
|
229
229
|
.autocomplete-widget {
|
|
230
230
|
position: fixed;
|
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
function getGutterIcon(severity?: number): string {
|
|
3
|
+
const color =
|
|
4
|
+
severity === 1
|
|
5
|
+
? 'var(--ide-error)'
|
|
6
|
+
: severity === 2
|
|
7
|
+
? 'var(--ide-warning)'
|
|
8
|
+
: severity === 3
|
|
9
|
+
? 'var(--ide-info)'
|
|
10
|
+
: 'var(--ide-text-muted)';
|
|
11
|
+
|
|
12
|
+
switch (severity) {
|
|
13
|
+
case 1: // Error - filled circle with X
|
|
14
|
+
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
15
|
+
<circle cx="8" cy="8" r="6" fill="${color}"/>
|
|
16
|
+
<path d="M5.5 5.5l5 5M10.5 5.5l-5 5" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/>
|
|
17
|
+
</svg>`;
|
|
18
|
+
case 2: // Warning - triangle
|
|
19
|
+
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
20
|
+
<path d="M8 2L1 14h14L8 2z" fill="${color}"/>
|
|
21
|
+
<path d="M8 6v4M8 12v1" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/>
|
|
22
|
+
</svg>`;
|
|
23
|
+
case 3: // Info - circle with i
|
|
24
|
+
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
25
|
+
<circle cx="8" cy="8" r="6" fill="${color}"/>
|
|
26
|
+
<path d="M8 5v1M8 8v4" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/>
|
|
27
|
+
</svg>`;
|
|
28
|
+
case 4: // Hint - lightbulb outline
|
|
29
|
+
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
30
|
+
<path d="M8 1a5 5 0 013 9v2a1 1 0 01-1 1H6a1 1 0 01-1-1v-2a5 5 0 013-9z" fill="none" stroke="${color}" stroke-width="1.2"/>
|
|
31
|
+
<path d="M6 14h4" stroke="${color}" stroke-width="1.2" stroke-linecap="round"/>
|
|
32
|
+
</svg>`;
|
|
33
|
+
default:
|
|
34
|
+
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
35
|
+
<circle cx="8" cy="8" r="4" fill="${color}"/>
|
|
36
|
+
</svg>`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
1
41
|
<script lang="ts">
|
|
2
42
|
/**
|
|
3
43
|
* DiagnosticMarker - Inline diagnostic indicator
|
|
@@ -18,30 +58,35 @@
|
|
|
18
58
|
class?: string;
|
|
19
59
|
}
|
|
20
60
|
|
|
21
|
-
let {
|
|
22
|
-
diagnostic,
|
|
23
|
-
type = 'inline',
|
|
24
|
-
onClick,
|
|
25
|
-
class: className = ''
|
|
26
|
-
}: Props = $props();
|
|
61
|
+
let { diagnostic, type = 'inline', onClick, class: className = '' }: Props = $props();
|
|
27
62
|
|
|
28
63
|
function getSeverityClass(severity?: DiagnosticSeverity): string {
|
|
29
64
|
switch (severity) {
|
|
30
|
-
case 1:
|
|
31
|
-
|
|
32
|
-
case
|
|
33
|
-
|
|
34
|
-
|
|
65
|
+
case 1:
|
|
66
|
+
return 'error';
|
|
67
|
+
case 2:
|
|
68
|
+
return 'warning';
|
|
69
|
+
case 3:
|
|
70
|
+
return 'info';
|
|
71
|
+
case 4:
|
|
72
|
+
return 'hint';
|
|
73
|
+
default:
|
|
74
|
+
return 'info';
|
|
35
75
|
}
|
|
36
76
|
}
|
|
37
77
|
|
|
38
78
|
function getSeverityLabel(severity?: DiagnosticSeverity): string {
|
|
39
79
|
switch (severity) {
|
|
40
|
-
case 1:
|
|
41
|
-
|
|
42
|
-
case
|
|
43
|
-
|
|
44
|
-
|
|
80
|
+
case 1:
|
|
81
|
+
return 'Error';
|
|
82
|
+
case 2:
|
|
83
|
+
return 'Warning';
|
|
84
|
+
case 3:
|
|
85
|
+
return 'Info';
|
|
86
|
+
case 4:
|
|
87
|
+
return 'Hint';
|
|
88
|
+
default:
|
|
89
|
+
return 'Diagnostic';
|
|
45
90
|
}
|
|
46
91
|
}
|
|
47
92
|
</script>
|
|
@@ -67,42 +112,6 @@
|
|
|
67
112
|
></span>
|
|
68
113
|
{/if}
|
|
69
114
|
|
|
70
|
-
<script module lang="ts">
|
|
71
|
-
function getGutterIcon(severity?: number): string {
|
|
72
|
-
const color = severity === 1 ? 'var(--ide-error)' :
|
|
73
|
-
severity === 2 ? 'var(--ide-warning)' :
|
|
74
|
-
severity === 3 ? 'var(--ide-info)' :
|
|
75
|
-
'var(--ide-text-muted)';
|
|
76
|
-
|
|
77
|
-
switch (severity) {
|
|
78
|
-
case 1: // Error - filled circle with X
|
|
79
|
-
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
80
|
-
<circle cx="8" cy="8" r="6" fill="${color}"/>
|
|
81
|
-
<path d="M5.5 5.5l5 5M10.5 5.5l-5 5" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/>
|
|
82
|
-
</svg>`;
|
|
83
|
-
case 2: // Warning - triangle
|
|
84
|
-
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
85
|
-
<path d="M8 2L1 14h14L8 2z" fill="${color}"/>
|
|
86
|
-
<path d="M8 6v4M8 12v1" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/>
|
|
87
|
-
</svg>`;
|
|
88
|
-
case 3: // Info - circle with i
|
|
89
|
-
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
90
|
-
<circle cx="8" cy="8" r="6" fill="${color}"/>
|
|
91
|
-
<path d="M8 5v1M8 8v4" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/>
|
|
92
|
-
</svg>`;
|
|
93
|
-
case 4: // Hint - lightbulb outline
|
|
94
|
-
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
95
|
-
<path d="M8 1a5 5 0 013 9v2a1 1 0 01-1 1H6a1 1 0 01-1-1v-2a5 5 0 013-9z" fill="none" stroke="${color}" stroke-width="1.2"/>
|
|
96
|
-
<path d="M6 14h4" stroke="${color}" stroke-width="1.2" stroke-linecap="round"/>
|
|
97
|
-
</svg>`;
|
|
98
|
-
default:
|
|
99
|
-
return `<svg viewBox="0 0 16 16" width="12" height="12">
|
|
100
|
-
<circle cx="8" cy="8" r="4" fill="${color}"/>
|
|
101
|
-
</svg>`;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
</script>
|
|
105
|
-
|
|
106
115
|
<style>
|
|
107
116
|
.diagnostic-gutter {
|
|
108
117
|
display: flex;
|
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
const errorIcon = `<svg viewBox="0 0 16 16" width="14" height="14"><circle cx="8" cy="8" r="7" fill="currentColor"/><path d="M5.5 5.5l5 5M10.5 5.5l-5 5" stroke="var(--ide-bg-primary)" stroke-width="1.5"/></svg>`;
|
|
3
|
+
const warningIcon = `<svg viewBox="0 0 16 16" width="14" height="14"><path d="M8 1L1 15h14L8 1z" fill="currentColor"/><path d="M8 6v4M8 12v1" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/></svg>`;
|
|
4
|
+
const infoIcon = `<svg viewBox="0 0 16 16" width="14" height="14"><circle cx="8" cy="8" r="7" fill="currentColor"/><path d="M8 5v1M8 8v4" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/></svg>`;
|
|
5
|
+
const checkIcon = `<svg viewBox="0 0 16 16" width="24" height="24"><circle cx="8" cy="8" r="7" fill="var(--ide-success)" opacity="0.2"/><path d="M5 8l2 2 4-4" stroke="var(--ide-success)" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
6
|
+
|
|
7
|
+
function getSeveritySVG(severity?: number): string {
|
|
8
|
+
switch (severity) {
|
|
9
|
+
case 1:
|
|
10
|
+
return errorIcon;
|
|
11
|
+
case 2:
|
|
12
|
+
return warningIcon;
|
|
13
|
+
case 3:
|
|
14
|
+
return infoIcon;
|
|
15
|
+
case 4:
|
|
16
|
+
return `<svg viewBox="0 0 16 16" width="14" height="14"><circle cx="8" cy="8" r="7" fill="currentColor"/><path d="M8 4v5M8 11v1" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/></svg>`;
|
|
17
|
+
default:
|
|
18
|
+
return infoIcon;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
|
|
1
23
|
<script lang="ts">
|
|
2
24
|
/**
|
|
3
25
|
* DiagnosticsPanel - LSP diagnostics list display
|
|
@@ -62,10 +84,18 @@
|
|
|
62
84
|
diagnostics.forEach((diags) => {
|
|
63
85
|
for (const diag of diags) {
|
|
64
86
|
switch (diag.severity) {
|
|
65
|
-
case 1:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
case
|
|
87
|
+
case 1:
|
|
88
|
+
result.errors++;
|
|
89
|
+
break;
|
|
90
|
+
case 2:
|
|
91
|
+
result.warnings++;
|
|
92
|
+
break;
|
|
93
|
+
case 3:
|
|
94
|
+
result.info++;
|
|
95
|
+
break;
|
|
96
|
+
case 4:
|
|
97
|
+
result.hints++;
|
|
98
|
+
break;
|
|
69
99
|
}
|
|
70
100
|
}
|
|
71
101
|
});
|
|
@@ -74,11 +104,16 @@
|
|
|
74
104
|
|
|
75
105
|
function getSeverityIcon(severity?: DiagnosticSeverity): string {
|
|
76
106
|
switch (severity) {
|
|
77
|
-
case 1:
|
|
78
|
-
|
|
79
|
-
case
|
|
80
|
-
|
|
81
|
-
|
|
107
|
+
case 1:
|
|
108
|
+
return 'error';
|
|
109
|
+
case 2:
|
|
110
|
+
return 'warning';
|
|
111
|
+
case 3:
|
|
112
|
+
return 'info';
|
|
113
|
+
case 4:
|
|
114
|
+
return 'hint';
|
|
115
|
+
default:
|
|
116
|
+
return 'info';
|
|
82
117
|
}
|
|
83
118
|
}
|
|
84
119
|
|
|
@@ -149,7 +184,7 @@
|
|
|
149
184
|
{#if allDiagnostics().length === 0}
|
|
150
185
|
<div class="diagnostics-panel__empty">
|
|
151
186
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -- SVG icons are static string literals defined in this file, not user content -->
|
|
152
|
-
|
|
187
|
+
<span class="diagnostics-panel__empty-icon">{@html checkIcon}</span>
|
|
153
188
|
<span>No problems detected</span>
|
|
154
189
|
</div>
|
|
155
190
|
{:else}
|
|
@@ -180,23 +215,6 @@
|
|
|
180
215
|
</div>
|
|
181
216
|
</div>
|
|
182
217
|
|
|
183
|
-
<script module lang="ts">
|
|
184
|
-
const errorIcon = `<svg viewBox="0 0 16 16" width="14" height="14"><circle cx="8" cy="8" r="7" fill="currentColor"/><path d="M5.5 5.5l5 5M10.5 5.5l-5 5" stroke="var(--ide-bg-primary)" stroke-width="1.5"/></svg>`;
|
|
185
|
-
const warningIcon = `<svg viewBox="0 0 16 16" width="14" height="14"><path d="M8 1L1 15h14L8 1z" fill="currentColor"/><path d="M8 6v4M8 12v1" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/></svg>`;
|
|
186
|
-
const infoIcon = `<svg viewBox="0 0 16 16" width="14" height="14"><circle cx="8" cy="8" r="7" fill="currentColor"/><path d="M8 5v1M8 8v4" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/></svg>`;
|
|
187
|
-
const checkIcon = `<svg viewBox="0 0 16 16" width="24" height="24"><circle cx="8" cy="8" r="7" fill="var(--ide-success)" opacity="0.2"/><path d="M5 8l2 2 4-4" stroke="var(--ide-success)" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
188
|
-
|
|
189
|
-
function getSeveritySVG(severity?: number): string {
|
|
190
|
-
switch (severity) {
|
|
191
|
-
case 1: return errorIcon;
|
|
192
|
-
case 2: return warningIcon;
|
|
193
|
-
case 3: return infoIcon;
|
|
194
|
-
case 4: return `<svg viewBox="0 0 16 16" width="14" height="14"><circle cx="8" cy="8" r="7" fill="currentColor"/><path d="M8 4v5M8 11v1" stroke="var(--ide-bg-primary)" stroke-width="1.5" stroke-linecap="round"/></svg>`;
|
|
195
|
-
default: return infoIcon;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
</script>
|
|
199
|
-
|
|
200
218
|
<style>
|
|
201
219
|
.diagnostics-panel {
|
|
202
220
|
display: flex;
|