coherent-language-support 1.0.0
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/.vscodeignore +8 -0
- package/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +108 -0
- package/coherent-language-support-1.0.0.vsix +0 -0
- package/dist/extension.js +18075 -0
- package/dist/extension.js.map +7 -0
- package/esbuild.config.mjs +24 -0
- package/icon.png +0 -0
- package/icon.svg +10 -0
- package/package.json +78 -0
- package/server/analysis/coherent-analyzer.d.ts +93 -0
- package/server/analysis/coherent-analyzer.d.ts.map +1 -0
- package/server/analysis/coherent-analyzer.js +288 -0
- package/server/analysis/coherent-analyzer.js.map +1 -0
- package/server/analysis/element-validator.d.ts +45 -0
- package/server/analysis/element-validator.d.ts.map +1 -0
- package/server/analysis/element-validator.js +84 -0
- package/server/analysis/element-validator.js.map +1 -0
- package/server/analysis/nesting-validator.d.ts +49 -0
- package/server/analysis/nesting-validator.d.ts.map +1 -0
- package/server/analysis/nesting-validator.js +68 -0
- package/server/analysis/nesting-validator.js.map +1 -0
- package/server/data/element-attributes.d.ts +92 -0
- package/server/data/element-attributes.d.ts.map +1 -0
- package/server/data/element-attributes.generated.json +7085 -0
- package/server/data/element-attributes.js +282 -0
- package/server/data/element-attributes.js.map +1 -0
- package/server/data/nesting-rules.d.ts +67 -0
- package/server/data/nesting-rules.d.ts.map +1 -0
- package/server/data/nesting-rules.js +240 -0
- package/server/data/nesting-rules.js.map +1 -0
- package/server/providers/code-actions.d.ts +15 -0
- package/server/providers/code-actions.d.ts.map +1 -0
- package/server/providers/code-actions.js +191 -0
- package/server/providers/code-actions.js.map +1 -0
- package/server/providers/completion.d.ts +15 -0
- package/server/providers/completion.d.ts.map +1 -0
- package/server/providers/completion.js +247 -0
- package/server/providers/completion.js.map +1 -0
- package/server/providers/diagnostics.d.ts +26 -0
- package/server/providers/diagnostics.d.ts.map +1 -0
- package/server/providers/diagnostics.js +143 -0
- package/server/providers/diagnostics.js.map +1 -0
- package/server/providers/hover.d.ts +15 -0
- package/server/providers/hover.d.ts.map +1 -0
- package/server/providers/hover.js +215 -0
- package/server/providers/hover.js.map +1 -0
- package/server/server.d.ts +17 -0
- package/server/server.d.ts.map +1 -0
- package/server/server.js +82 -0
- package/server/server.js.map +1 -0
- package/snippets/coherent.json +226 -0
- package/src/extension.ts +75 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hover Provider
|
|
3
|
+
*
|
|
4
|
+
* Provides hover information (documentation) for Coherent.js elements and attributes.
|
|
5
|
+
*/
|
|
6
|
+
import { Connection, TextDocuments } from 'vscode-languageserver';
|
|
7
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
8
|
+
/**
|
|
9
|
+
* Register the hover provider.
|
|
10
|
+
*
|
|
11
|
+
* @param connection - LSP connection
|
|
12
|
+
* @param documents - Text document manager
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerHoverProvider(connection: Connection, documents: TextDocuments<TextDocument>): void;
|
|
15
|
+
//# sourceMappingURL=hover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hover.d.ts","sourceRoot":"","sources":["../../src/providers/hover.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,UAAU,EACV,aAAa,EAId,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAalE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,GACrC,IAAI,CAuCN"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hover Provider
|
|
3
|
+
*
|
|
4
|
+
* Provides hover information (documentation) for Coherent.js elements and attributes.
|
|
5
|
+
*/
|
|
6
|
+
import { MarkupKind, } from 'vscode-languageserver';
|
|
7
|
+
import { createSourceFile, getPositionContext, } from '../analysis/coherent-analyzer.js';
|
|
8
|
+
import { getElementDescription, getAttributeType, getAttributeDescription, getAttributesForElement, isVoidElement, } from '../data/element-attributes.js';
|
|
9
|
+
/**
|
|
10
|
+
* Register the hover provider.
|
|
11
|
+
*
|
|
12
|
+
* @param connection - LSP connection
|
|
13
|
+
* @param documents - Text document manager
|
|
14
|
+
*/
|
|
15
|
+
export function registerHoverProvider(connection, documents) {
|
|
16
|
+
connection.onHover((params) => {
|
|
17
|
+
const document = documents.get(params.textDocument.uri);
|
|
18
|
+
if (!document) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const content = document.getText();
|
|
23
|
+
const sourceFile = createSourceFile(content, params.textDocument.uri);
|
|
24
|
+
const context = getPositionContext(sourceFile, params.position);
|
|
25
|
+
switch (context.type) {
|
|
26
|
+
case 'tag-name':
|
|
27
|
+
if (context.element) {
|
|
28
|
+
return createElementHover(context.element.tagName);
|
|
29
|
+
}
|
|
30
|
+
break;
|
|
31
|
+
case 'attribute-name':
|
|
32
|
+
if (context.element && context.attribute) {
|
|
33
|
+
return createAttributeHover(context.element.tagName, context.attribute.name);
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
case 'attribute-value':
|
|
37
|
+
// Could show value type information
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error('[coherent-lsp] Hover error:', error);
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create hover content for an HTML element.
|
|
52
|
+
*/
|
|
53
|
+
function createElementHover(tagName) {
|
|
54
|
+
const description = getElementDescription(tagName);
|
|
55
|
+
const isVoid = isVoidElement(tagName);
|
|
56
|
+
const attrs = getAttributesForElement(tagName);
|
|
57
|
+
let markdown = `## <${tagName}>\n\n`;
|
|
58
|
+
markdown += `${description}\n\n`;
|
|
59
|
+
if (isVoid) {
|
|
60
|
+
markdown += `> **Void element** - cannot have children\n\n`;
|
|
61
|
+
}
|
|
62
|
+
// Example usage
|
|
63
|
+
markdown += `### Example\n\n`;
|
|
64
|
+
markdown += '```javascript\n';
|
|
65
|
+
if (isVoid) {
|
|
66
|
+
markdown += `{ ${tagName}: { /* attributes */ } }\n`;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
markdown += `{ ${tagName}: {\n`;
|
|
70
|
+
markdown += ` className: 'example',\n`;
|
|
71
|
+
markdown += ` children: [/* child elements */]\n`;
|
|
72
|
+
markdown += `} }\n`;
|
|
73
|
+
}
|
|
74
|
+
markdown += '```\n\n';
|
|
75
|
+
// Common attributes
|
|
76
|
+
const elementSpecificAttrs = attrs.filter(a => !['id', 'className', 'class', 'style', 'title', 'hidden', 'tabIndex',
|
|
77
|
+
'text', 'html', 'children', 'key'].includes(a.name) &&
|
|
78
|
+
!a.name.startsWith('on') &&
|
|
79
|
+
!a.name.startsWith('aria-') &&
|
|
80
|
+
!a.name.startsWith('data-')).slice(0, 8);
|
|
81
|
+
if (elementSpecificAttrs.length > 0) {
|
|
82
|
+
markdown += `### Element-Specific Attributes\n\n`;
|
|
83
|
+
for (const attr of elementSpecificAttrs) {
|
|
84
|
+
markdown += `- \`${attr.name}\`: \`${attr.type}\`\n`;
|
|
85
|
+
}
|
|
86
|
+
markdown += '\n';
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
contents: {
|
|
90
|
+
kind: MarkupKind.Markdown,
|
|
91
|
+
value: markdown,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Create hover content for an attribute.
|
|
97
|
+
*/
|
|
98
|
+
function createAttributeHover(tagName, attributeName) {
|
|
99
|
+
const type = getAttributeType(tagName, attributeName);
|
|
100
|
+
const description = getAttributeDescription(tagName, attributeName);
|
|
101
|
+
let markdown = `## ${attributeName}\n\n`;
|
|
102
|
+
// Type information
|
|
103
|
+
if (type) {
|
|
104
|
+
markdown += `**Type:** \`${type}\`\n\n`;
|
|
105
|
+
}
|
|
106
|
+
// Description
|
|
107
|
+
if (description) {
|
|
108
|
+
markdown += `${description}\n\n`;
|
|
109
|
+
}
|
|
110
|
+
// Special handling for common attributes
|
|
111
|
+
const examples = getAttributeExamples(attributeName, type);
|
|
112
|
+
if (examples) {
|
|
113
|
+
markdown += `### Examples\n\n`;
|
|
114
|
+
markdown += '```javascript\n';
|
|
115
|
+
markdown += examples;
|
|
116
|
+
markdown += '\n```\n';
|
|
117
|
+
}
|
|
118
|
+
// Event handler information
|
|
119
|
+
if (attributeName.startsWith('on') && attributeName[2] === attributeName[2].toUpperCase()) {
|
|
120
|
+
const eventType = getEventType(attributeName);
|
|
121
|
+
if (eventType) {
|
|
122
|
+
markdown += `\n**Event type:** \`${eventType}\`\n`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
contents: {
|
|
127
|
+
kind: MarkupKind.Markdown,
|
|
128
|
+
value: markdown,
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get example usage for common attributes.
|
|
134
|
+
*/
|
|
135
|
+
function getAttributeExamples(attributeName, type) {
|
|
136
|
+
const examples = {
|
|
137
|
+
className: "className: 'my-class another-class'",
|
|
138
|
+
id: "id: 'unique-id'",
|
|
139
|
+
style: "style: { color: 'red', fontSize: '16px' }",
|
|
140
|
+
onClick: "onClick: (event) => {\n console.log('Clicked!', event);\n}",
|
|
141
|
+
onChange: "onChange: (event) => {\n const value = event.target.value;\n}",
|
|
142
|
+
onSubmit: "onSubmit: (event) => {\n event.preventDefault();\n // Handle form submission\n}",
|
|
143
|
+
children: "children: [\n { span: { text: 'Child 1' } },\n { span: { text: 'Child 2' } }\n]",
|
|
144
|
+
text: "text: 'Text content (escaped)'",
|
|
145
|
+
html: "html: '<strong>Raw HTML</strong>' // Use with caution!",
|
|
146
|
+
key: "key: 'unique-item-key'",
|
|
147
|
+
href: "href: 'https://example.com'",
|
|
148
|
+
src: "src: '/images/photo.jpg'",
|
|
149
|
+
alt: "alt: 'Description of the image'",
|
|
150
|
+
type: "type: 'submit' // or 'button', 'text', etc.",
|
|
151
|
+
value: "value: 'input value'",
|
|
152
|
+
placeholder: "placeholder: 'Enter text...'",
|
|
153
|
+
disabled: "disabled: true",
|
|
154
|
+
checked: "checked: true",
|
|
155
|
+
required: "required: true",
|
|
156
|
+
name: "name: 'field-name'",
|
|
157
|
+
};
|
|
158
|
+
return examples[attributeName] || null;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get the DOM event type for an event handler.
|
|
162
|
+
*/
|
|
163
|
+
function getEventType(handlerName) {
|
|
164
|
+
const eventTypes = {
|
|
165
|
+
onClick: 'MouseEvent',
|
|
166
|
+
onDblClick: 'MouseEvent',
|
|
167
|
+
onMouseDown: 'MouseEvent',
|
|
168
|
+
onMouseUp: 'MouseEvent',
|
|
169
|
+
onMouseEnter: 'MouseEvent',
|
|
170
|
+
onMouseLeave: 'MouseEvent',
|
|
171
|
+
onMouseMove: 'MouseEvent',
|
|
172
|
+
onMouseOver: 'MouseEvent',
|
|
173
|
+
onMouseOut: 'MouseEvent',
|
|
174
|
+
onContextMenu: 'MouseEvent',
|
|
175
|
+
onKeyDown: 'KeyboardEvent',
|
|
176
|
+
onKeyUp: 'KeyboardEvent',
|
|
177
|
+
onKeyPress: 'KeyboardEvent',
|
|
178
|
+
onFocus: 'FocusEvent',
|
|
179
|
+
onBlur: 'FocusEvent',
|
|
180
|
+
onFocusIn: 'FocusEvent',
|
|
181
|
+
onFocusOut: 'FocusEvent',
|
|
182
|
+
onChange: 'Event',
|
|
183
|
+
onInput: 'Event',
|
|
184
|
+
onSubmit: 'SubmitEvent',
|
|
185
|
+
onReset: 'Event',
|
|
186
|
+
onInvalid: 'Event',
|
|
187
|
+
onDrag: 'DragEvent',
|
|
188
|
+
onDragEnd: 'DragEvent',
|
|
189
|
+
onDragEnter: 'DragEvent',
|
|
190
|
+
onDragLeave: 'DragEvent',
|
|
191
|
+
onDragOver: 'DragEvent',
|
|
192
|
+
onDragStart: 'DragEvent',
|
|
193
|
+
onDrop: 'DragEvent',
|
|
194
|
+
onCopy: 'ClipboardEvent',
|
|
195
|
+
onCut: 'ClipboardEvent',
|
|
196
|
+
onPaste: 'ClipboardEvent',
|
|
197
|
+
onTouchStart: 'TouchEvent',
|
|
198
|
+
onTouchMove: 'TouchEvent',
|
|
199
|
+
onTouchEnd: 'TouchEvent',
|
|
200
|
+
onTouchCancel: 'TouchEvent',
|
|
201
|
+
onWheel: 'WheelEvent',
|
|
202
|
+
onScroll: 'Event',
|
|
203
|
+
onAnimationStart: 'AnimationEvent',
|
|
204
|
+
onAnimationEnd: 'AnimationEvent',
|
|
205
|
+
onAnimationIteration: 'AnimationEvent',
|
|
206
|
+
onTransitionStart: 'TransitionEvent',
|
|
207
|
+
onTransitionEnd: 'TransitionEvent',
|
|
208
|
+
onTransitionCancel: 'TransitionEvent',
|
|
209
|
+
onTransitionRun: 'TransitionEvent',
|
|
210
|
+
onLoad: 'Event',
|
|
211
|
+
onError: 'Event',
|
|
212
|
+
};
|
|
213
|
+
return eventTypes[handlerName] || null;
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=hover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hover.js","sourceRoot":"","sources":["../../src/providers/hover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Coherent.js Language Server
|
|
4
|
+
*
|
|
5
|
+
* Provides Language Server Protocol (LSP) support for Coherent.js components:
|
|
6
|
+
* - Autocomplete for tag names and attributes
|
|
7
|
+
* - Validation of attributes and HTML nesting
|
|
8
|
+
* - Hover documentation for elements and attributes
|
|
9
|
+
* - Quick fix code actions for common issues
|
|
10
|
+
*
|
|
11
|
+
* @see https://microsoft.github.io/language-server-protocol/
|
|
12
|
+
*/
|
|
13
|
+
import { TextDocuments } from 'vscode-languageserver/node.js';
|
|
14
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
15
|
+
export declare const connection: import("vscode-languageserver/node.js")._Connection<import("vscode-languageserver/node.js")._, import("vscode-languageserver/node.js")._, import("vscode-languageserver/node.js")._, import("vscode-languageserver/node.js")._, import("vscode-languageserver/node.js")._, import("vscode-languageserver/node.js")._, import("vscode-languageserver/lib/common/inlineCompletion.proposed.js").InlineCompletionFeatureShape, import("vscode-languageserver/node.js")._>;
|
|
16
|
+
export declare const documents: TextDocuments<TextDocument>;
|
|
17
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,aAAa,EAOd,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AASlE,eAAO,MAAM,UAAU,wcAAyC,CAAC;AAGjE,eAAO,MAAM,SAAS,EAAE,aAAa,CAAC,YAAY,CAAmC,CAAC"}
|
package/server/server.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Coherent.js Language Server
|
|
4
|
+
*
|
|
5
|
+
* Provides Language Server Protocol (LSP) support for Coherent.js components:
|
|
6
|
+
* - Autocomplete for tag names and attributes
|
|
7
|
+
* - Validation of attributes and HTML nesting
|
|
8
|
+
* - Hover documentation for elements and attributes
|
|
9
|
+
* - Quick fix code actions for common issues
|
|
10
|
+
*
|
|
11
|
+
* @see https://microsoft.github.io/language-server-protocol/
|
|
12
|
+
*/
|
|
13
|
+
import { createConnection, TextDocuments, ProposedFeatures, TextDocumentSyncKind, CodeActionKind, DidChangeConfigurationNotification, } from 'vscode-languageserver/node.js';
|
|
14
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
15
|
+
// Import providers
|
|
16
|
+
import { registerDiagnosticProvider } from './providers/diagnostics.js';
|
|
17
|
+
import { registerCompletionProvider } from './providers/completion.js';
|
|
18
|
+
import { registerHoverProvider } from './providers/hover.js';
|
|
19
|
+
import { registerCodeActionProvider } from './providers/code-actions.js';
|
|
20
|
+
// Create connection using all proposed features
|
|
21
|
+
export const connection = createConnection(ProposedFeatures.all);
|
|
22
|
+
// Text document manager for syncing documents
|
|
23
|
+
export const documents = new TextDocuments(TextDocument);
|
|
24
|
+
// Server capabilities
|
|
25
|
+
let hasConfigurationCapability = false;
|
|
26
|
+
let hasWorkspaceFolderCapability = false;
|
|
27
|
+
connection.onInitialize((params) => {
|
|
28
|
+
const capabilities = params.capabilities;
|
|
29
|
+
// Check client capabilities
|
|
30
|
+
hasConfigurationCapability = !!(capabilities.workspace && !!capabilities.workspace.configuration);
|
|
31
|
+
hasWorkspaceFolderCapability = !!(capabilities.workspace && !!capabilities.workspace.workspaceFolders);
|
|
32
|
+
const result = {
|
|
33
|
+
capabilities: {
|
|
34
|
+
// Incremental document sync for performance
|
|
35
|
+
textDocumentSync: TextDocumentSyncKind.Incremental,
|
|
36
|
+
// Autocomplete provider
|
|
37
|
+
completionProvider: {
|
|
38
|
+
resolveProvider: true,
|
|
39
|
+
triggerCharacters: ['{', ':', '"', "'"],
|
|
40
|
+
},
|
|
41
|
+
// Hover provider for documentation
|
|
42
|
+
hoverProvider: true,
|
|
43
|
+
// Code action provider for quick fixes
|
|
44
|
+
codeActionProvider: {
|
|
45
|
+
codeActionKinds: [CodeActionKind.QuickFix],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
// Add workspace folder support if available
|
|
50
|
+
if (hasWorkspaceFolderCapability) {
|
|
51
|
+
result.capabilities.workspace = {
|
|
52
|
+
workspaceFolders: {
|
|
53
|
+
supported: true,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// Log capabilities for debugging
|
|
58
|
+
console.error('[coherent-lsp] Initialized with capabilities:', JSON.stringify(result.capabilities, null, 2));
|
|
59
|
+
return result;
|
|
60
|
+
});
|
|
61
|
+
connection.onInitialized(() => {
|
|
62
|
+
if (hasConfigurationCapability) {
|
|
63
|
+
// Register for configuration changes
|
|
64
|
+
connection.client.register(DidChangeConfigurationNotification.type, undefined);
|
|
65
|
+
}
|
|
66
|
+
if (hasWorkspaceFolderCapability) {
|
|
67
|
+
connection.workspace.onDidChangeWorkspaceFolders((_event) => {
|
|
68
|
+
console.error('[coherent-lsp] Workspace folder change event received');
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
// Register providers
|
|
72
|
+
registerDiagnosticProvider(connection, documents);
|
|
73
|
+
registerCompletionProvider(connection, documents);
|
|
74
|
+
registerHoverProvider(connection, documents);
|
|
75
|
+
registerCodeActionProvider(connection, documents);
|
|
76
|
+
console.error('[coherent-lsp] Server initialized successfully');
|
|
77
|
+
});
|
|
78
|
+
// Start listening for document events
|
|
79
|
+
documents.listen(connection);
|
|
80
|
+
// Start the connection
|
|
81
|
+
connection.listen();
|
|
82
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Coherent Element": {
|
|
3
|
+
"prefix": "cel",
|
|
4
|
+
"body": [
|
|
5
|
+
"{ ${1:div}: {",
|
|
6
|
+
"\tclassName: '${2:class}',",
|
|
7
|
+
"\t${3:children: [",
|
|
8
|
+
"\t\t$0",
|
|
9
|
+
"\t]}",
|
|
10
|
+
"}}"
|
|
11
|
+
],
|
|
12
|
+
"description": "Create a Coherent.js element"
|
|
13
|
+
},
|
|
14
|
+
"Coherent Component": {
|
|
15
|
+
"prefix": "ccomp",
|
|
16
|
+
"body": [
|
|
17
|
+
"const ${1:ComponentName} = (${2:props}) => ({",
|
|
18
|
+
"\t${3:div}: {",
|
|
19
|
+
"\t\tclassName: '${4:component-class}',",
|
|
20
|
+
"\t\tchildren: [",
|
|
21
|
+
"\t\t\t$0",
|
|
22
|
+
"\t\t]",
|
|
23
|
+
"\t}",
|
|
24
|
+
"});",
|
|
25
|
+
"",
|
|
26
|
+
"export { ${1:ComponentName} };"
|
|
27
|
+
],
|
|
28
|
+
"description": "Create a Coherent.js functional component"
|
|
29
|
+
},
|
|
30
|
+
"Coherent Text": {
|
|
31
|
+
"prefix": "ctext",
|
|
32
|
+
"body": [
|
|
33
|
+
"{ ${1:p}: { text: '${2:content}' }}"
|
|
34
|
+
],
|
|
35
|
+
"description": "Create a text element"
|
|
36
|
+
},
|
|
37
|
+
"Coherent Link": {
|
|
38
|
+
"prefix": "clink",
|
|
39
|
+
"body": [
|
|
40
|
+
"{ a: {",
|
|
41
|
+
"\thref: '${1:/path}',",
|
|
42
|
+
"\ttext: '${2:Link text}'",
|
|
43
|
+
"}}"
|
|
44
|
+
],
|
|
45
|
+
"description": "Create an anchor element"
|
|
46
|
+
},
|
|
47
|
+
"Coherent Image": {
|
|
48
|
+
"prefix": "cimg",
|
|
49
|
+
"body": [
|
|
50
|
+
"{ img: {",
|
|
51
|
+
"\tsrc: '${1:url}',",
|
|
52
|
+
"\talt: '${2:description}'",
|
|
53
|
+
"}}"
|
|
54
|
+
],
|
|
55
|
+
"description": "Create an image element"
|
|
56
|
+
},
|
|
57
|
+
"Coherent Input": {
|
|
58
|
+
"prefix": "cinput",
|
|
59
|
+
"body": [
|
|
60
|
+
"{ input: {",
|
|
61
|
+
"\ttype: '${1|text,email,password,number,checkbox,radio|}',",
|
|
62
|
+
"\tname: '${2:fieldName}',",
|
|
63
|
+
"\tplaceholder: '${3:Enter value}'",
|
|
64
|
+
"}}"
|
|
65
|
+
],
|
|
66
|
+
"description": "Create an input element"
|
|
67
|
+
},
|
|
68
|
+
"Coherent Button": {
|
|
69
|
+
"prefix": "cbtn",
|
|
70
|
+
"body": [
|
|
71
|
+
"{ button: {",
|
|
72
|
+
"\ttype: '${1|button,submit,reset|}',",
|
|
73
|
+
"\tclassName: '${2:btn}',",
|
|
74
|
+
"\ttext: '${3:Click me}'",
|
|
75
|
+
"}}"
|
|
76
|
+
],
|
|
77
|
+
"description": "Create a button element"
|
|
78
|
+
},
|
|
79
|
+
"Coherent Form": {
|
|
80
|
+
"prefix": "cform",
|
|
81
|
+
"body": [
|
|
82
|
+
"{ form: {",
|
|
83
|
+
"\tmethod: '${1|POST,GET|}',",
|
|
84
|
+
"\taction: '${2:/api/submit}',",
|
|
85
|
+
"\tchildren: [",
|
|
86
|
+
"\t\t$0",
|
|
87
|
+
"\t]",
|
|
88
|
+
"}}"
|
|
89
|
+
],
|
|
90
|
+
"description": "Create a form element"
|
|
91
|
+
},
|
|
92
|
+
"Coherent List": {
|
|
93
|
+
"prefix": "clist",
|
|
94
|
+
"body": [
|
|
95
|
+
"{ ${1|ul,ol|}: {",
|
|
96
|
+
"\tchildren: ${2:items}.map((${3:item}) => ({",
|
|
97
|
+
"\t\tli: { text: ${3:item} }",
|
|
98
|
+
"\t}))",
|
|
99
|
+
"}}"
|
|
100
|
+
],
|
|
101
|
+
"description": "Create a list with mapped items"
|
|
102
|
+
},
|
|
103
|
+
"Coherent Conditional": {
|
|
104
|
+
"prefix": "cif",
|
|
105
|
+
"body": [
|
|
106
|
+
"${1:condition} ? { ${2:div}: { text: '${3:shown}' }} : null"
|
|
107
|
+
],
|
|
108
|
+
"description": "Conditional rendering pattern"
|
|
109
|
+
},
|
|
110
|
+
"Coherent Event Handler": {
|
|
111
|
+
"prefix": "cevent",
|
|
112
|
+
"body": [
|
|
113
|
+
"on${1|Click,Change,Submit,Focus,Blur|}: '${2:handlerName}'"
|
|
114
|
+
],
|
|
115
|
+
"description": "Add an event handler"
|
|
116
|
+
},
|
|
117
|
+
"Coherent Data Attributes": {
|
|
118
|
+
"prefix": "cdata",
|
|
119
|
+
"body": [
|
|
120
|
+
"'data-${1:name}': '${2:value}'"
|
|
121
|
+
],
|
|
122
|
+
"description": "Add a data attribute"
|
|
123
|
+
},
|
|
124
|
+
"Coherent Page Layout": {
|
|
125
|
+
"prefix": "cpage",
|
|
126
|
+
"body": [
|
|
127
|
+
"const ${1:PageName} = () => ({",
|
|
128
|
+
"\thtml: {",
|
|
129
|
+
"\t\tlang: 'en',",
|
|
130
|
+
"\t\tchildren: [",
|
|
131
|
+
"\t\t\t{ head: {",
|
|
132
|
+
"\t\t\t\tchildren: [",
|
|
133
|
+
"\t\t\t\t\t{ meta: { charset: 'utf-8' }},",
|
|
134
|
+
"\t\t\t\t\t{ meta: { name: 'viewport', content: 'width=device-width, initial-scale=1' }},",
|
|
135
|
+
"\t\t\t\t\t{ title: { text: '${2:Page Title}' }}",
|
|
136
|
+
"\t\t\t\t]",
|
|
137
|
+
"\t\t\t}},",
|
|
138
|
+
"\t\t\t{ body: {",
|
|
139
|
+
"\t\t\t\tchildren: [",
|
|
140
|
+
"\t\t\t\t\t$0",
|
|
141
|
+
"\t\t\t\t]",
|
|
142
|
+
"\t\t\t}}",
|
|
143
|
+
"\t\t]",
|
|
144
|
+
"\t}",
|
|
145
|
+
"});",
|
|
146
|
+
"",
|
|
147
|
+
"export { ${1:PageName} };"
|
|
148
|
+
],
|
|
149
|
+
"description": "Create a full page layout"
|
|
150
|
+
},
|
|
151
|
+
"Coherent Card": {
|
|
152
|
+
"prefix": "ccard",
|
|
153
|
+
"body": [
|
|
154
|
+
"{ div: {",
|
|
155
|
+
"\tclassName: '${1:card}',",
|
|
156
|
+
"\tchildren: [",
|
|
157
|
+
"\t\t{ ${2:img}: { src: '${3:url}', alt: '${4:description}' }},",
|
|
158
|
+
"\t\t{ div: {",
|
|
159
|
+
"\t\t\tclassName: '${1:card}-body',",
|
|
160
|
+
"\t\t\tchildren: [",
|
|
161
|
+
"\t\t\t\t{ h3: { text: '${5:Title}' }},",
|
|
162
|
+
"\t\t\t\t{ p: { text: '${6:Description}' }}",
|
|
163
|
+
"\t\t\t]",
|
|
164
|
+
"\t\t}}",
|
|
165
|
+
"\t]",
|
|
166
|
+
"}}"
|
|
167
|
+
],
|
|
168
|
+
"description": "Create a card component structure"
|
|
169
|
+
},
|
|
170
|
+
"Coherent Table": {
|
|
171
|
+
"prefix": "ctable",
|
|
172
|
+
"body": [
|
|
173
|
+
"{ table: {",
|
|
174
|
+
"\tchildren: [",
|
|
175
|
+
"\t\t{ thead: {",
|
|
176
|
+
"\t\t\tchildren: [",
|
|
177
|
+
"\t\t\t\t{ tr: {",
|
|
178
|
+
"\t\t\t\t\tchildren: [",
|
|
179
|
+
"\t\t\t\t\t\t{ th: { text: '${1:Column 1}' }},",
|
|
180
|
+
"\t\t\t\t\t\t{ th: { text: '${2:Column 2}' }}",
|
|
181
|
+
"\t\t\t\t\t]",
|
|
182
|
+
"\t\t\t\t}}",
|
|
183
|
+
"\t\t\t]",
|
|
184
|
+
"\t\t}},",
|
|
185
|
+
"\t\t{ tbody: {",
|
|
186
|
+
"\t\t\tchildren: ${3:data}.map((${4:row}) => ({",
|
|
187
|
+
"\t\t\t\ttr: {",
|
|
188
|
+
"\t\t\t\t\tchildren: [",
|
|
189
|
+
"\t\t\t\t\t\t{ td: { text: ${4:row}.${5:field1} }},",
|
|
190
|
+
"\t\t\t\t\t\t{ td: { text: ${4:row}.${6:field2} }}",
|
|
191
|
+
"\t\t\t\t\t]",
|
|
192
|
+
"\t\t\t\t}",
|
|
193
|
+
"\t\t\t}))",
|
|
194
|
+
"\t\t}}",
|
|
195
|
+
"\t]",
|
|
196
|
+
"}}"
|
|
197
|
+
],
|
|
198
|
+
"description": "Create a table with header and mapped body"
|
|
199
|
+
},
|
|
200
|
+
"Coherent Render Import": {
|
|
201
|
+
"prefix": "cimport",
|
|
202
|
+
"body": [
|
|
203
|
+
"import { ${1|render,renderToString,createComponent|} } from '@coherent.js/core';"
|
|
204
|
+
],
|
|
205
|
+
"description": "Import Coherent.js core functions"
|
|
206
|
+
},
|
|
207
|
+
"Coherent Server Setup": {
|
|
208
|
+
"prefix": "cserver",
|
|
209
|
+
"body": [
|
|
210
|
+
"import { render } from '@coherent.js/core';",
|
|
211
|
+
"import { createServer } from '@coherent.js/${1|express,fastify,koa|}';",
|
|
212
|
+
"",
|
|
213
|
+
"const app = createServer();",
|
|
214
|
+
"",
|
|
215
|
+
"app.get('/', (req, res) => {",
|
|
216
|
+
"\tconst html = render({ div: { text: 'Hello, Coherent.js!' }});",
|
|
217
|
+
"\tres.send(html);",
|
|
218
|
+
"});",
|
|
219
|
+
"",
|
|
220
|
+
"app.listen(${2:3000}, () => {",
|
|
221
|
+
"\tconsole.log('Server running on port ${2:3000}');",
|
|
222
|
+
"});"
|
|
223
|
+
],
|
|
224
|
+
"description": "Create a basic Coherent.js server"
|
|
225
|
+
}
|
|
226
|
+
}
|
package/src/extension.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { ExtensionContext, workspace } from 'vscode';
|
|
3
|
+
import {
|
|
4
|
+
LanguageClient,
|
|
5
|
+
LanguageClientOptions,
|
|
6
|
+
ServerOptions,
|
|
7
|
+
TransportKind,
|
|
8
|
+
} from 'vscode-languageclient/node';
|
|
9
|
+
|
|
10
|
+
let client: LanguageClient | undefined;
|
|
11
|
+
|
|
12
|
+
export function activate(context: ExtensionContext): void {
|
|
13
|
+
// Server is BUNDLED with extension in server/ directory
|
|
14
|
+
// This avoids npm dependency resolution issues and works offline
|
|
15
|
+
const serverModule = context.asAbsolutePath(path.join('server', 'server.js'));
|
|
16
|
+
|
|
17
|
+
// Server options - use IPC for better performance
|
|
18
|
+
const serverOptions: ServerOptions = {
|
|
19
|
+
run: {
|
|
20
|
+
module: serverModule,
|
|
21
|
+
transport: TransportKind.ipc,
|
|
22
|
+
},
|
|
23
|
+
debug: {
|
|
24
|
+
module: serverModule,
|
|
25
|
+
transport: TransportKind.ipc,
|
|
26
|
+
options: {
|
|
27
|
+
execArgv: ['--nolazy', '--inspect=6009'],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Client options
|
|
33
|
+
const clientOptions: LanguageClientOptions = {
|
|
34
|
+
// Register for JavaScript and TypeScript files
|
|
35
|
+
documentSelector: [
|
|
36
|
+
{ scheme: 'file', language: 'javascript' },
|
|
37
|
+
{ scheme: 'file', language: 'typescript' },
|
|
38
|
+
{ scheme: 'file', language: 'javascriptreact' },
|
|
39
|
+
{ scheme: 'file', language: 'typescriptreact' },
|
|
40
|
+
],
|
|
41
|
+
synchronize: {
|
|
42
|
+
// Synchronize the setting section 'coherent' to the server
|
|
43
|
+
configurationSection: 'coherent',
|
|
44
|
+
// Notify the server about file changes
|
|
45
|
+
fileEvents: workspace.createFileSystemWatcher('**/*.{js,ts,jsx,tsx}'),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Create and start the language client
|
|
50
|
+
client = new LanguageClient(
|
|
51
|
+
'coherentLanguageServer',
|
|
52
|
+
'Coherent.js Language Server',
|
|
53
|
+
serverOptions,
|
|
54
|
+
clientOptions
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Start the client (also launches the server)
|
|
58
|
+
client.start();
|
|
59
|
+
|
|
60
|
+
// Push client to subscriptions for cleanup on deactivation
|
|
61
|
+
context.subscriptions.push({
|
|
62
|
+
dispose: () => {
|
|
63
|
+
if (client) {
|
|
64
|
+
client.stop();
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function deactivate(): Thenable<void> | undefined {
|
|
71
|
+
if (!client) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
return client.stop();
|
|
75
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": "src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationMap": true,
|
|
14
|
+
"sourceMap": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|