django-cotton-lsp 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/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # django-cotton-lsp
2
+
3
+ Language Server for [Django Cotton](https://django-cotton.com/) templates. Powers the [Django Cotton VS Code extension](https://marketplace.visualstudio.com/) and any other LSP-capable editor.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g django-cotton-lsp
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ The server communicates over stdio (standard LSP transport):
14
+
15
+ ```bash
16
+ django-cotton-lsp
17
+ ```
18
+
19
+ ### Neovim (nvim-lspconfig)
20
+
21
+ ```lua
22
+ local lspconfig = require('lspconfig')
23
+ local configs = require('lspconfig.configs')
24
+
25
+ if not configs.cotton_ls then
26
+ configs.cotton_ls = {
27
+ default_config = {
28
+ cmd = { 'django-cotton-lsp' },
29
+ filetypes = { 'html', 'django-html' },
30
+ root_dir = function(fname)
31
+ return lspconfig.util.root_pattern('manage.py', 'pyproject.toml', '.git')(fname)
32
+ end,
33
+ settings = {},
34
+ },
35
+ }
36
+ end
37
+
38
+ lspconfig.cotton_ls.setup({
39
+ init_options = {
40
+ templatePaths = { 'templates/cotton' },
41
+ },
42
+ })
43
+ ```
44
+
45
+ ### Helix
46
+
47
+ ```toml
48
+ [[language-server.cotton]]
49
+ command = "django-cotton-lsp"
50
+ language-id = "html"
51
+ ```
52
+
53
+ ## Configuration
54
+
55
+ Settings are resolved with this priority:
56
+
57
+ 1. Editor LSP settings / `initializationOptions`
58
+ 2. `cotton.config.json` in the workspace root
59
+ 3. Built-in default (`templates/cotton`)
60
+
61
+ ### cotton.config.json
62
+
63
+ ```json
64
+ {
65
+ "templatePaths": [
66
+ "templates/cotton",
67
+ "apps/*/templates/cotton"
68
+ ]
69
+ }
70
+ ```
71
+
72
+ `templatePaths` accepts plain directories and glob patterns.
73
+
74
+ ## Features
75
+
76
+ - Go to definition (components, props, slots, dynamic `<c-component is="...">`)
77
+ - Autocompletion (components, directives, props, slots)
78
+ - Hover documentation
79
+ - Find all references
80
+ - Diagnostics (missing components, slot name typos)
81
+
82
+ ## VS Code extension
83
+
84
+ For VS Code-specific features (unused component badges, Explorer context menu), use the [Django Cotton extension](https://github.com/twentyforty/cotton-vscode-ext/tree/main/packages/vscode-extension) instead of wiring the server manually.
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CottonParser = void 0;
4
+ const vscode_html_languageservice_1 = require("vscode-html-languageservice");
5
+ const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
6
+ class CottonParser {
7
+ constructor() {
8
+ this.htmlLanguageService = (0, vscode_html_languageservice_1.getLanguageService)();
9
+ }
10
+ parseDocument(content, uri) {
11
+ const textDocument = vscode_languageserver_textdocument_1.TextDocument.create(uri, 'html', 1, content);
12
+ return this.htmlLanguageService.parseHTMLDocument(textDocument);
13
+ }
14
+ findCottonComponents(htmlDoc) {
15
+ const components = [];
16
+ const walk = (node) => {
17
+ if (node.tag?.startsWith('c-')) {
18
+ components.push({
19
+ name: node.tag.slice(2),
20
+ fullTag: node.tag,
21
+ node,
22
+ startOffset: node.start,
23
+ endOffset: node.end
24
+ });
25
+ }
26
+ node.children?.forEach(walk);
27
+ };
28
+ htmlDoc.roots.forEach(walk);
29
+ return components;
30
+ }
31
+ findComponentAtOffset(htmlDoc, offset) {
32
+ const node = htmlDoc.findNodeAt(offset);
33
+ if (node?.tag?.startsWith('c-')) {
34
+ return {
35
+ name: node.tag.slice(2),
36
+ fullTag: node.tag,
37
+ node,
38
+ startOffset: node.start,
39
+ endOffset: node.end
40
+ };
41
+ }
42
+ return null;
43
+ }
44
+ getCursorContext(content, offset, htmlDoc) {
45
+ const result = {
46
+ isInsideCottonTag: false,
47
+ componentName: null,
48
+ isTypingTagName: false,
49
+ partialTagName: null,
50
+ partialAttributeName: null,
51
+ existingAttributes: new Set()
52
+ };
53
+ // Check if we're typing a new tag (after '<c-')
54
+ const textBeforeCursor = content.substring(0, offset);
55
+ const tagTypingMatch = textBeforeCursor.match(/<c-([\w.-]*)$/);
56
+ if (tagTypingMatch) {
57
+ result.isTypingTagName = true;
58
+ result.partialTagName = tagTypingMatch[1];
59
+ return result;
60
+ }
61
+ // Find if we're inside a Cotton tag
62
+ const node = htmlDoc.findNodeAt(offset);
63
+ if (node?.tag?.startsWith('c-')) {
64
+ const tagEndOffset = this.findTagEndOffset(content, node.start);
65
+ if (offset <= tagEndOffset) {
66
+ result.isInsideCottonTag = true;
67
+ result.componentName = node.tag.slice(2);
68
+ result.existingAttributes = new Set(Object.keys(node.attributes || {}));
69
+ // Check if we're typing an attribute
70
+ const attrMatch = this.getPartialAttribute(content, offset);
71
+ if (attrMatch) {
72
+ result.partialAttributeName = attrMatch;
73
+ }
74
+ }
75
+ }
76
+ return result;
77
+ }
78
+ getTagNameRange(node) {
79
+ if (!node.tag?.startsWith('c-'))
80
+ return null;
81
+ const tagStart = node.start + 1; // Skip '<'
82
+ const tagEnd = tagStart + node.tag.length;
83
+ return { start: tagStart, end: tagEnd };
84
+ }
85
+ /**
86
+ * Find the attribute name token (e.g. `label`, `:count`, or the escaped `::class`) at the
87
+ * given offset, within the opening tag of the given node. Returns null if the offset isn't
88
+ * over an attribute name (e.g. it's over the tag name, an attribute value, or outside the tag).
89
+ */
90
+ findAttributeNameAtOffset(content, node, offset) {
91
+ if (!node.tag)
92
+ return null;
93
+ const tagEnd = this.findTagEndOffset(content, node.start);
94
+ if (offset < node.start || offset > tagEnd)
95
+ return null;
96
+ const nameSearchStart = node.start + 1 + node.tag.length; // skip '<' and tag name
97
+ const tagContent = content.substring(nameSearchStart, tagEnd);
98
+ const attrRegex = /(:{0,2}[a-zA-Z_][\w-]*)(\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))?/g;
99
+ let match;
100
+ while ((match = attrRegex.exec(tagContent)) !== null) {
101
+ const fullName = match[1];
102
+ const nameStart = nameSearchStart + match.index;
103
+ const nameEnd = nameStart + fullName.length;
104
+ if (offset >= nameStart && offset <= nameEnd) {
105
+ // `::foo` is an escaped literal attribute (e.g. Alpine.js `::class`), not a
106
+ // Cotton dynamic-expression attribute - only a single leading `:` means dynamic.
107
+ const isEscaped = fullName.startsWith('::');
108
+ const hasColon = !isEscaped && fullName.startsWith(':');
109
+ const strippedName = fullName.replace(/^:+/, '');
110
+ return {
111
+ name: strippedName,
112
+ hasColon,
113
+ start: nameStart,
114
+ end: nameEnd
115
+ };
116
+ }
117
+ }
118
+ return null;
119
+ }
120
+ /**
121
+ * Find the value (and its offset span) of a specific attribute on the opening tag of the
122
+ * given node, e.g. reading `is="foo"` off a `<c-component is="foo" />` tag. Returns null if
123
+ * the attribute isn't present or has no quoted value.
124
+ */
125
+ getAttributeValue(content, node, attrName) {
126
+ if (!node.tag)
127
+ return null;
128
+ const tagEnd = this.findTagEndOffset(content, node.start);
129
+ const nameSearchStart = node.start + 1 + node.tag.length;
130
+ const tagContent = content.substring(nameSearchStart, tagEnd);
131
+ const escapedAttrName = attrName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
132
+ const attrRegex = new RegExp(`(:?)${escapedAttrName}\\s*=\\s*(?:"([^"]*)"|'([^']*)')`);
133
+ const match = attrRegex.exec(tagContent);
134
+ if (!match)
135
+ return null;
136
+ const value = match[2] !== undefined ? match[2] : match[3];
137
+ const quoteOffsetInMatch = match[0].length - value.length - 1; // just before the closing quote
138
+ const valueStart = nameSearchStart + match.index + quoteOffsetInMatch;
139
+ return {
140
+ value,
141
+ hasColon: match[1] === ':',
142
+ start: valueStart,
143
+ end: valueStart + value.length
144
+ };
145
+ }
146
+ /**
147
+ * If the given node is a <c-slot> tag and the offset is inside its `name` attribute value,
148
+ * return the slot name and the enclosing Cotton component (so callers can look up what slot
149
+ * names that component actually expects, or navigate to where it consumes this slot).
150
+ */
151
+ getSlotNameContext(content, node, offset) {
152
+ if (node.tag !== 'c-slot')
153
+ return null;
154
+ const nameAttr = this.getAttributeValue(content, node, 'name');
155
+ if (!nameAttr || offset < nameAttr.start || offset > nameAttr.end)
156
+ return null;
157
+ const componentName = this.findEnclosingComponentName(node);
158
+ if (!componentName)
159
+ return null;
160
+ return {
161
+ componentName,
162
+ slotName: nameAttr.value,
163
+ valueStart: nameAttr.start,
164
+ valueEnd: nameAttr.end
165
+ };
166
+ }
167
+ /**
168
+ * Walk up from a node to find the nearest ancestor that's a real Cotton component tag
169
+ * (skipping the built-in `<c-vars>`/`<c-slot>`/`<c-component>` directives) - e.g. to find
170
+ * which component a `<c-slot>` belongs to.
171
+ */
172
+ findEnclosingComponentName(node) {
173
+ let ancestor = node.parent;
174
+ while (ancestor) {
175
+ if (ancestor.tag?.startsWith('c-') && !['c-vars', 'c-slot', 'c-component'].includes(ancestor.tag)) {
176
+ return ancestor.tag.slice(2);
177
+ }
178
+ ancestor = ancestor.parent;
179
+ }
180
+ return null;
181
+ }
182
+ findTagEndOffset(content, tagStart) {
183
+ let i = tagStart;
184
+ let inQuote = false;
185
+ let quoteChar = '';
186
+ while (i < content.length) {
187
+ const char = content[i];
188
+ if (inQuote) {
189
+ if (char === quoteChar) {
190
+ inQuote = false;
191
+ }
192
+ }
193
+ else {
194
+ if (char === '"' || char === "'") {
195
+ inQuote = true;
196
+ quoteChar = char;
197
+ }
198
+ else if (char === '>') {
199
+ return i;
200
+ }
201
+ }
202
+ i++;
203
+ }
204
+ return content.length;
205
+ }
206
+ getPartialAttribute(content, offset) {
207
+ let start = offset;
208
+ while (start > 0) {
209
+ const char = content[start - 1];
210
+ if (char === ' ' || char === '\t' || char === '\n')
211
+ break;
212
+ if (char === '=' || char === '"' || char === "'" || char === '>' || char === '<')
213
+ return null;
214
+ start--;
215
+ }
216
+ const partial = content.substring(start, offset);
217
+ if (partial.length > 0 && /^:{0,2}[a-zA-Z_][\w.-]*$/.test(partial)) {
218
+ return partial;
219
+ }
220
+ return null;
221
+ }
222
+ }
223
+ exports.CottonParser = CottonParser;
224
+ //# sourceMappingURL=cottonParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cottonParser.js","sourceRoot":"","sources":["../src/cottonParser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CompletionHandler = void 0;
4
+ const vscode_languageserver_1 = require("vscode-languageserver");
5
+ class CompletionHandler {
6
+ constructor(parser, componentIndex) {
7
+ this.parser = parser;
8
+ this.componentIndex = componentIndex;
9
+ }
10
+ async handleCompletion(document, position) {
11
+ const content = document.getText();
12
+ const offset = document.offsetAt(position);
13
+ const htmlDoc = this.parser.parseDocument(content, document.uri);
14
+ const slotNode = this.parser.findComponentAtOffset(htmlDoc, offset);
15
+ if (slotNode?.fullTag === 'c-slot') {
16
+ const slotContext = this.parser.getSlotNameContext(content, slotNode.node, offset);
17
+ if (slotContext) {
18
+ return this.getSlotNameCompletions(slotContext, document);
19
+ }
20
+ }
21
+ const context = this.parser.getCursorContext(content, offset, htmlDoc);
22
+ if (context.isTypingTagName) {
23
+ return this.getTagCompletions(context.partialTagName || '', position, document, content, offset);
24
+ }
25
+ if (context.isInsideCottonTag && context.componentName) {
26
+ // `component` and `slot` are built-in directives, not real component files, so they
27
+ // don't have `<c-vars>` to drive attribute completion - offer their known attributes directly.
28
+ if (context.componentName === 'component') {
29
+ return this.getComponentDirectiveAttributeCompletions(context.existingAttributes, context.partialAttributeName, position);
30
+ }
31
+ if (context.componentName === 'slot') {
32
+ return this.getSlotDirectiveAttributeCompletions(context.existingAttributes, context.partialAttributeName, position);
33
+ }
34
+ return this.getAttributeCompletions(context.componentName, context.existingAttributes, context.partialAttributeName, position);
35
+ }
36
+ return [];
37
+ }
38
+ async getTagCompletions(partial, position, document, content, offset) {
39
+ const components = await this.componentIndex.getAllComponents();
40
+ const items = [];
41
+ const replaceRange = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(position.line, position.character - partial.length), position);
42
+ const closingTagEdit = this.findClosingTagEdit(content, offset, partial, document);
43
+ for (const component of components) {
44
+ if (!partial || component.name.toLowerCase().startsWith(partial.toLowerCase())) {
45
+ const doc = await this.componentIndex.getComponentDocumentation(component.filePath);
46
+ const item = {
47
+ label: component.name,
48
+ kind: vscode_languageserver_1.CompletionItemKind.Class,
49
+ detail: 'Cotton component',
50
+ documentation: doc || undefined,
51
+ sortText: `0_${component.name}`,
52
+ filterText: component.name,
53
+ textEdit: vscode_languageserver_1.TextEdit.replace(replaceRange, component.name),
54
+ insertTextFormat: vscode_languageserver_1.InsertTextFormat.PlainText
55
+ };
56
+ if (closingTagEdit) {
57
+ item.additionalTextEdits = [
58
+ vscode_languageserver_1.TextEdit.replace(closingTagEdit.range, component.name)
59
+ ];
60
+ }
61
+ items.push(item);
62
+ }
63
+ }
64
+ for (const directive of CompletionHandler.BUILTIN_DIRECTIVES) {
65
+ if (!partial || directive.name.toLowerCase().startsWith(partial.toLowerCase())) {
66
+ const item = {
67
+ label: directive.name,
68
+ kind: vscode_languageserver_1.CompletionItemKind.Keyword,
69
+ detail: 'Cotton directive',
70
+ documentation: { kind: 'markdown', value: directive.documentation },
71
+ sortText: `1_${directive.name}`,
72
+ filterText: directive.name,
73
+ textEdit: vscode_languageserver_1.TextEdit.replace(replaceRange, directive.name),
74
+ insertTextFormat: vscode_languageserver_1.InsertTextFormat.PlainText
75
+ };
76
+ if (closingTagEdit) {
77
+ item.additionalTextEdits = [
78
+ vscode_languageserver_1.TextEdit.replace(closingTagEdit.range, directive.name)
79
+ ];
80
+ }
81
+ items.push(item);
82
+ }
83
+ }
84
+ return items;
85
+ }
86
+ findClosingTagEdit(content, offset, partial, document) {
87
+ const textAfter = content.substring(offset);
88
+ const closingTagRegex = new RegExp(`</c-(${this.escapeRegex(partial)}[\\w.-]*)>`);
89
+ const closingMatch = textAfter.match(closingTagRegex);
90
+ if (closingMatch) {
91
+ const closingTagName = closingMatch[1];
92
+ if (closingTagName === partial || closingTagName.startsWith(partial)) {
93
+ const closingTagNameStart = offset + closingMatch.index + 4; // +4 for '</c-'
94
+ const closingTagNameEnd = closingTagNameStart + closingTagName.length;
95
+ return {
96
+ range: vscode_languageserver_1.Range.create(document.positionAt(closingTagNameStart), document.positionAt(closingTagNameEnd))
97
+ };
98
+ }
99
+ }
100
+ return null;
101
+ }
102
+ escapeRegex(str) {
103
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
104
+ }
105
+ async getAttributeCompletions(componentName, existingAttributes, partialAttr, position) {
106
+ const component = await this.componentIndex.findComponent(componentName);
107
+ if (!component || component.cVars.length === 0) {
108
+ return [];
109
+ }
110
+ const items = [];
111
+ let replaceRange;
112
+ if (partialAttr) {
113
+ replaceRange = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(position.line, position.character - partialAttr.length), position);
114
+ }
115
+ for (const cVar of component.cVars) {
116
+ if (!existingAttributes.has(cVar.name)) {
117
+ if (!partialAttr || cVar.name.toLowerCase().startsWith(partialAttr.toLowerCase())) {
118
+ items.push(this.createAttributeItem(cVar, false, replaceRange));
119
+ // A c-var declared with no default (e.g. `<c-vars errors />`) is commonly
120
+ // used as a boolean flag - Cotton lets you pass it with no value at all,
121
+ // which becomes `True`. Offer that as a distinct, valueless completion.
122
+ if (!cVar.defaultValue && !cVar.isDjangoExpression) {
123
+ items.push(this.createBooleanAttributeItem(cVar, replaceRange));
124
+ }
125
+ }
126
+ }
127
+ const expressionName = `:${cVar.name}`;
128
+ if (!existingAttributes.has(expressionName)) {
129
+ if (!partialAttr || expressionName.toLowerCase().startsWith(partialAttr.toLowerCase())) {
130
+ items.push(this.createAttributeItem(cVar, true, replaceRange));
131
+ }
132
+ }
133
+ }
134
+ return items;
135
+ }
136
+ createAttributeItem(cVar, isDjangoExpression, replaceRange) {
137
+ const fullName = isDjangoExpression ? `:${cVar.name}` : cVar.name;
138
+ const insertText = `${fullName}="\${1:${cVar.defaultValue || ''}}"`;
139
+ const type = isDjangoExpression ? 'Django expression' : 'text parameter';
140
+ const item = {
141
+ label: fullName,
142
+ kind: vscode_languageserver_1.CompletionItemKind.Field,
143
+ insertTextFormat: vscode_languageserver_1.InsertTextFormat.Snippet,
144
+ filterText: fullName,
145
+ detail: `Cotton ${type}`,
146
+ documentation: {
147
+ kind: 'markdown',
148
+ value: `**${fullName}** (${type})\n\nDefault: \`${cVar.defaultValue || 'undefined'}\``
149
+ },
150
+ sortText: `0_${fullName}`
151
+ };
152
+ if (replaceRange) {
153
+ item.textEdit = vscode_languageserver_1.TextEdit.replace(replaceRange, insertText);
154
+ }
155
+ else {
156
+ item.insertText = insertText;
157
+ }
158
+ return item;
159
+ }
160
+ getComponentDirectiveAttributeCompletions(existingAttributes, partialAttr, position) {
161
+ const replaceRange = this.getReplaceRange(partialAttr, position);
162
+ const items = [];
163
+ if (this.matchesPartial('is', existingAttributes, partialAttr)) {
164
+ items.push(this.createDirectiveAttributeItem('is', 'Name of the component to render dynamically, e.g. `is="button"` or a subfolder path `is="ui.button"`.', replaceRange));
165
+ }
166
+ if (this.matchesPartial(':is', existingAttributes, partialAttr)) {
167
+ items.push(this.createDirectiveAttributeItem(':is', 'Render a component whose name is a Django expression, e.g. `:is="field.type"`.', replaceRange));
168
+ }
169
+ return items;
170
+ }
171
+ getSlotDirectiveAttributeCompletions(existingAttributes, partialAttr, position) {
172
+ if (!this.matchesPartial('name', existingAttributes, partialAttr)) {
173
+ return [];
174
+ }
175
+ const replaceRange = this.getReplaceRange(partialAttr, position);
176
+ return [this.createDirectiveAttributeItem('name', 'Name of the slot this content fills, matching a `{{ name }}` reference in the target component.', replaceRange)];
177
+ }
178
+ matchesPartial(attrName, existingAttributes, partialAttr) {
179
+ if (existingAttributes.has(attrName))
180
+ return false;
181
+ return !partialAttr || attrName.toLowerCase().startsWith(partialAttr.toLowerCase());
182
+ }
183
+ getReplaceRange(partialAttr, position) {
184
+ if (!partialAttr)
185
+ return undefined;
186
+ return vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(position.line, position.character - partialAttr.length), position);
187
+ }
188
+ createDirectiveAttributeItem(fullName, documentation, replaceRange) {
189
+ const insertText = `${fullName}="\${1}"`;
190
+ const item = {
191
+ label: fullName,
192
+ kind: vscode_languageserver_1.CompletionItemKind.Field,
193
+ insertTextFormat: vscode_languageserver_1.InsertTextFormat.Snippet,
194
+ filterText: fullName,
195
+ detail: 'Cotton directive attribute',
196
+ documentation: { kind: 'markdown', value: documentation },
197
+ sortText: `0_${fullName}`
198
+ };
199
+ if (replaceRange) {
200
+ item.textEdit = vscode_languageserver_1.TextEdit.replace(replaceRange, insertText);
201
+ }
202
+ else {
203
+ item.insertText = insertText;
204
+ }
205
+ return item;
206
+ }
207
+ async getSlotNameCompletions(slotContext, document) {
208
+ const component = await this.componentIndex.findComponent(slotContext.componentName);
209
+ if (!component)
210
+ return [];
211
+ const excludeNames = new Set(component.cVars.map(v => v.name));
212
+ const slotNames = await this.componentIndex.getSlotCandidates(component.filePath, excludeNames);
213
+ const replaceRange = vscode_languageserver_1.Range.create(document.positionAt(slotContext.valueStart), document.positionAt(slotContext.valueEnd));
214
+ return slotNames.map(name => ({
215
+ label: name,
216
+ kind: vscode_languageserver_1.CompletionItemKind.EnumMember,
217
+ detail: 'Cotton named slot',
218
+ documentation: `Fills \`{{ ${name} }}\` in \`<c-${slotContext.componentName}>\``,
219
+ textEdit: vscode_languageserver_1.TextEdit.replace(replaceRange, name),
220
+ sortText: `0_${name}`
221
+ }));
222
+ }
223
+ createBooleanAttributeItem(cVar, replaceRange) {
224
+ const item = {
225
+ label: cVar.name,
226
+ kind: vscode_languageserver_1.CompletionItemKind.Value,
227
+ insertTextFormat: vscode_languageserver_1.InsertTextFormat.PlainText,
228
+ filterText: cVar.name,
229
+ detail: 'Cotton boolean flag',
230
+ documentation: {
231
+ kind: 'markdown',
232
+ value: `**${cVar.name}** (boolean flag)\n\nPass with no value to provide \`True\` to the component.`
233
+ },
234
+ sortText: `1_${cVar.name}`
235
+ };
236
+ if (replaceRange) {
237
+ item.textEdit = vscode_languageserver_1.TextEdit.replace(replaceRange, cVar.name);
238
+ }
239
+ else {
240
+ item.insertText = cVar.name;
241
+ }
242
+ return item;
243
+ }
244
+ }
245
+ exports.CompletionHandler = CompletionHandler;
246
+ CompletionHandler.BUILTIN_DIRECTIVES = [
247
+ { name: 'vars', documentation: 'Declare in-component variables and default prop values.\n\nUsage: `<c-vars title="default" :count="0" />` at the top of a component file.' },
248
+ { name: 'slot', documentation: 'Provide HTML content for a named slot inside a component.\n\nUsage:\n```html\n<c-slot name="icon">\n <svg>...</svg>\n</c-slot>\n```' },
249
+ { name: 'component', documentation: 'Render a component dynamically by name.\n\nUsage: `<c-component is="button" />` or `<c-component :is="expr" />`.' }
250
+ ];
251
+ //# sourceMappingURL=completion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/handlers/completion.ts"],"names":[],"mappings":"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"}