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 +84 -0
- package/out/cottonParser.js +224 -0
- package/out/cottonParser.js.map +1 -0
- package/out/handlers/completion.js +251 -0
- package/out/handlers/completion.js.map +1 -0
- package/out/handlers/definition.js +149 -0
- package/out/handlers/definition.js.map +1 -0
- package/out/handlers/diagnostics.js +83 -0
- package/out/handlers/diagnostics.js.map +1 -0
- package/out/handlers/hover.js +72 -0
- package/out/handlers/hover.js.map +1 -0
- package/out/handlers/references.js +62 -0
- package/out/handlers/references.js.map +1 -0
- package/out/server.js +274 -0
- package/out/server.js.map +1 -0
- package/out/utils/componentIndex.js +325 -0
- package/out/utils/componentIndex.js.map +1 -0
- package/out/utils/usageIndex.js +258 -0
- package/out/utils/usageIndex.js.map +1 -0
- package/package.json +41 -0
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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"}
|