-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathextension.js
More file actions
154 lines (132 loc) · 6.33 KB
/
extension.js
File metadata and controls
154 lines (132 loc) · 6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
const vscode = require('vscode');
const path = require('path');
let resourceTemplates = {};
try {
const resourcesPath = path.join(__dirname, 'resources.json');
resourceTemplates = require(resourcesPath);
} catch (error) {
console.error('Error loading resource templates:', error);
vscode.window.showErrorMessage('Cloudscript Extension: Failed to load resource templates.');
}
function activate(context) {
// File creation listener
let disposable = vscode.workspace.onDidCreateFiles(async (event) => {
for (const file of event.files) {
if (file.fsPath.endsWith('.cloud')) {
const document = await vscode.workspace.openTextDocument(file);
const editor = await vscode.window.showTextDocument(document);
if (document.getText().length === 0) {
const snippet = new vscode.SnippetString(`providers {}
service "\${1:name}" {
provider = ""
infrastructure {}
configuration {}
containers {}
deployment {}
}`);
editor.insertSnippet(snippet, new vscode.Position(0, 0));
}
}
}
});
context.subscriptions.push(disposable);
// Register resource type completion provider
const resourceTypeProvider = vscode.languages.registerCompletionItemProvider(
'cloudscript',
{
provideCompletionItems(document, position) {
const linePrefix = document.lineAt(position).text.substr(0, position.character);
if (!linePrefix.trim().startsWith('resource_type')) {
return undefined;
}
// Create completion items for each resource type
return Object.keys(resourceTemplates).map(resourceType => {
const completionItem = new vscode.CompletionItem(resourceType, vscode.CompletionItemKind.Value);
// Add spaces before and after the resource type
completionItem.insertText = ` "${resourceType}" `;
completionItem.command = {
command: 'editor.action.triggerSuggest',
title: 'Re-trigger completions...'
};
return completionItem;
});
}
},
'=' // Trigger on equals sign
);
// Register template completion provider
const templateProvider = vscode.languages.registerCompletionItemProvider(
'cloudscript',
{
provideCompletionItems(document, position) {
const line = document.lineAt(position).text;
const resourceTypeRegex = /resource_type\s*=\s*"([^"]+)"/;
const match = resourceTypeRegex.exec(line);
if (match) {
const resourceType = match[1];
const template = resourceTemplates[resourceType];
if (template) {
// Find the current block name
let blockName = "default";
const currentLine = position.line;
const blockNameRegex = /(?:compute|network|iam)\s*"([^"]+)"/;
for (let i = currentLine - 1; i >= 0; i--) {
const lineText = document.lineAt(i).text;
const nameMatch = blockNameRegex.exec(lineText);
if (nameMatch) {
blockName = nameMatch[1];
break;
}
}
const snippet = new vscode.SnippetString('\n');
let placeholderIndex = 1;
// Build the template
for (const [key, value] of Object.entries(template)) {
if (key === 'resource_type') continue;
if (Array.isArray(value)) {
snippet.appendText(`${key} = [`);
if (value.length > 0) {
value.forEach((item, index) => {
snippet.appendPlaceholder(`"${item}"`, placeholderIndex++);
if (index < value.length - 1) {
snippet.appendText(', ');
}
});
}
snippet.appendText(']\n');
} else if (typeof value === 'object' && value !== null) {
snippet.appendText(`${key} = {\n`);
for (const [subKey, subValue] of Object.entries(value)) {
if (subKey.toLowerCase() === 'name' && key.toLowerCase() === 'tags') {
snippet.appendText(` ${subKey} = "${blockName}"\n`);
} else {
snippet.appendText(` ${subKey} = `);
snippet.appendPlaceholder(`"${subValue}"`, placeholderIndex++);
snippet.appendText('\n');
}
}
snippet.appendText('}\n');
} else {
snippet.appendText(`${key} = `);
snippet.appendPlaceholder(`"${value}"`, placeholderIndex++);
snippet.appendText('\n');
}
}
const completionItem = new vscode.CompletionItem('Insert Required Attributes', vscode.CompletionItemKind.Snippet);
completionItem.insertText = snippet;
completionItem.detail = `Insert required attributes for ${resourceType}`;
return [completionItem];
}
}
return undefined;
}
},
' ' // Trigger on space after resource_type = "aws_instance"
);
context.subscriptions.push(resourceTypeProvider, templateProvider);
}
function deactivate() {}
module.exports = {
activate,
deactivate
};