Skip to content

Commit bec5ff2

Browse files
committed
feat: more snippets
1 parent 3a4dc4f commit bec5ff2

File tree

5 files changed

+140
-6
lines changed

5 files changed

+140
-6
lines changed

src/completion/XmlSnippetProvider.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { last, uniq } from 'lodash-es';
12
import { minimatch } from 'minimatch';
23
import * as vscode from 'vscode';
34

45
interface Snippet {
56
prefix: string;
67
body: string[];
78
description: string;
9+
parent?: string;
810
}
911

1012
interface SnippetProvider {
@@ -18,7 +20,19 @@ export class XmlSnippetProvider implements vscode.CompletionItemProvider {
1820
private readonly snippetProviders: SnippetProvider[] = [
1921
{
2022
pattern: '**/di.xml',
21-
snippets: require('./xml/snippet/di-xml.json'),
23+
snippets: require('./xml/snippet/di.json'),
24+
},
25+
{
26+
pattern: '**/events.xml',
27+
snippets: require('./xml/snippet/events.json'),
28+
},
29+
{
30+
pattern: '**/crontab.xml',
31+
snippets: require('./xml/snippet/crontab.json'),
32+
},
33+
{
34+
pattern: '**/webapi.xml',
35+
snippets: require('./xml/snippet/webapi.json'),
2236
},
2337
];
2438

@@ -34,11 +48,17 @@ export class XmlSnippetProvider implements vscode.CompletionItemProvider {
3448
return null;
3549
}
3650

51+
const parentElementNames = this.getParentElementNames(document, position);
52+
const directParentName = last(parentElementNames);
3753
const completionItems: vscode.CompletionItem[] = [];
3854

3955
for (const name in snippets) {
4056
const snippet = snippets[name];
4157

58+
if (snippet.parent && snippet.parent !== directParentName) {
59+
continue;
60+
}
61+
4262
const completionItem = new vscode.CompletionItem(
4363
{
4464
label: name,
@@ -71,4 +91,44 @@ export class XmlSnippetProvider implements vscode.CompletionItemProvider {
7191

7292
return undefined;
7393
}
94+
95+
private getParentElementNames(
96+
document: vscode.TextDocument,
97+
position: vscode.Position
98+
): string[] {
99+
const text = document.getText(new vscode.Range(0, 0, position.line, position.character));
100+
// Match all opening elements except for self-closing ones
101+
const openingElementMatches = text.matchAll(/<([:_a-zA-Z]+)[^<]*(?<!\/)>/gms);
102+
// Match all closing elements
103+
const closingElementMatches = text.matchAll(/<\/([:_a-zA-Z]+)>/g);
104+
105+
if (!openingElementMatches || !closingElementMatches) {
106+
return [];
107+
}
108+
109+
const openingElementNames = Array.from(openingElementMatches).map(match => match[1]);
110+
const closingElementNames = Array.from(closingElementMatches).map(match => match[1]);
111+
112+
const openingElementCount = openingElementNames.reduce(
113+
(acc, name) => {
114+
acc[name] = (acc[name] || 0) + 1;
115+
return acc;
116+
},
117+
{} as Record<string, number>
118+
);
119+
120+
const closingElementCount = closingElementNames.reduce(
121+
(acc, name) => {
122+
acc[name] = (acc[name] || 0) + 1;
123+
return acc;
124+
},
125+
{} as Record<string, number>
126+
);
127+
128+
return uniq(
129+
openingElementNames.filter(name => {
130+
return openingElementCount[name] > (closingElementCount[name] || 0);
131+
})
132+
);
133+
}
74134
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"group": {
3+
"parent": "config",
4+
"prefix": "group",
5+
"body": [
6+
"<group id=\"${1:default}\">",
7+
" ${2}",
8+
"</group>"
9+
],
10+
"description": "Insert a cron group element"
11+
},
12+
"job": {
13+
"parent": "group",
14+
"prefix": "job",
15+
"body": [
16+
"<job name=\"${1}\" instance=\"${2}\" method=\"${3:execute}\">",
17+
" <schedule>${4:* * * * *}</schedule>",
18+
"</job>"
19+
],
20+
"description": "Insert a cron job element"
21+
}
22+
}

src/completion/xml/snippet/di-xml.json renamed to src/completion/xml/snippet/di.json

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,55 @@
11
{
22
"preference": {
3+
"parent": "config",
34
"prefix": "preference",
45
"body": [
5-
"<preference for=\"${1:ClassName}\" type=\"${2:ClassName}\" />"
6+
"<preference for=\"${1}\" type=\"${2}\" />"
67
],
78
"description": "Insert a preference element to the current file"
89
},
910
"type": {
11+
"parent": "config",
1012
"prefix": "type",
1113
"body": [
12-
"<type name=\"${1:ClassName}\">\n ${2}\n</type>"
14+
"<type name=\"${1}\">",
15+
" ${2}",
16+
"</type>"
1317
],
1418
"description": "Insert a type element to the current file"
1519
},
1620
"arguments": {
21+
"parent": "type",
1722
"prefix": "arguments",
1823
"body": [
19-
"<arguments>\n ${1}\n</arguments>"
24+
"<arguments>",
25+
" ${1}",
26+
"</arguments>"
2027
],
2128
"description": "Insert an arguments element to the current file"
2229
},
2330
"argument": {
31+
"parent": "arguments",
2432
"prefix": "argument",
2533
"body": [
26-
"<argument name=\"${1:Name}\" xsi:type=\"${2:Type}\">${3:Value}</argument>"
34+
"<argument name=\"${1}\" xsi:type=\"${2}\">${3}</argument>"
2735
],
2836
"description": "Insert an argument element to the current file"
2937
},
38+
"plugin": {
39+
"parent": "type",
40+
"prefix": "plugin",
41+
"body": [
42+
"<plugin name=\"${1}\" type=\"${2}\" />"
43+
],
44+
"description": "Insert a plugin element to the current file"
45+
},
3046
"virtualType": {
47+
"parent": "config",
3148
"prefix": "virtualType",
3249
"body": [
33-
"<virtualType name=\"${1:ClassName}\" type=\"${2:ClassName}\">\n ${3}\n</virtualType>"
50+
"<virtualType name=\"${1}\" type=\"${2}\">",
51+
" ${3}",
52+
"</virtualType>"
3453
],
3554
"description": "Insert a virtualType element to the current file"
3655
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"event": {
3+
"parent": "config",
4+
"prefix": "event",
5+
"body": [
6+
"<event name=\"${1}\">\n ${2}\n</event>"
7+
],
8+
"description": "Insert a event element to the current file"
9+
},
10+
"observer": {
11+
"parent": "event",
12+
"prefix": "observer",
13+
"body": [
14+
"<observer name=\"${1}\" instance=\"${2}\" />"
15+
],
16+
"description": "Insert a observer element to the current file"
17+
}
18+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"route": {
3+
"parent": "routes",
4+
"prefix": "route",
5+
"body": [
6+
"<route url=\"${1:/V1/endpoint}\" method=\"${2:GET}\">",
7+
" <service class=\"${3}\" method=\"${4}\" />",
8+
" <resources>",
9+
" <resource ref=\"${5:anonymous}\" />",
10+
" </resources>",
11+
"</route>"
12+
],
13+
"description": "Insert a route element to the current file"
14+
}
15+
}

0 commit comments

Comments
 (0)