@codingame/monaco-vscode-snippets-service-override 25.1.2 → 26.0.1
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/package.json +3 -3
- package/vscode/src/vs/workbench/contrib/snippets/browser/commands/abstractSnippetsActions.js +9 -3
- package/vscode/src/vs/workbench/contrib/snippets/browser/commands/configureSnippets.js +145 -95
- package/vscode/src/vs/workbench/contrib/snippets/browser/commands/fileTemplateSnippets.js +26 -14
- package/vscode/src/vs/workbench/contrib/snippets/browser/commands/insertSnippet.js +52 -37
- package/vscode/src/vs/workbench/contrib/snippets/browser/commands/surroundWithSnippet.js +21 -10
- package/vscode/src/vs/workbench/contrib/snippets/browser/snippetCodeActionProvider.js +62 -48
- package/vscode/src/vs/workbench/contrib/snippets/browser/snippetPicker.d.ts +2 -1
- package/vscode/src/vs/workbench/contrib/snippets/browser/snippetPicker.js +33 -27
- package/vscode/src/vs/workbench/contrib/snippets/browser/snippets.contribution.js +70 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codingame/monaco-vscode-snippets-service-override",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "26.0.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "VSCode public API plugged on the monaco editor - snippets service-override",
|
|
6
6
|
"keywords": [],
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
},
|
|
16
16
|
"type": "module",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@codingame/monaco-vscode-api": "
|
|
19
|
-
"@codingame/monaco-vscode-files-service-override": "
|
|
18
|
+
"@codingame/monaco-vscode-api": "26.0.1",
|
|
19
|
+
"@codingame/monaco-vscode-files-service-override": "26.0.1"
|
|
20
20
|
},
|
|
21
21
|
"main": "index.js",
|
|
22
22
|
"module": "index.js",
|
package/vscode/src/vs/workbench/contrib/snippets/browser/commands/abstractSnippetsActions.js
CHANGED
|
@@ -4,16 +4,22 @@ import { localize2 } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
|
4
4
|
import { Action2 } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/common/actions';
|
|
5
5
|
|
|
6
6
|
const defaultOptions = {
|
|
7
|
-
category: ( localize2(
|
|
7
|
+
category: ( localize2(11286, "Snippets"))
|
|
8
8
|
};
|
|
9
9
|
class SnippetsAction extends Action2 {
|
|
10
10
|
constructor(desc) {
|
|
11
|
-
super({
|
|
11
|
+
super({
|
|
12
|
+
...defaultOptions,
|
|
13
|
+
...desc
|
|
14
|
+
});
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
17
|
class SnippetEditorAction extends EditorAction2 {
|
|
15
18
|
constructor(desc) {
|
|
16
|
-
super({
|
|
19
|
+
super({
|
|
20
|
+
...defaultOptions,
|
|
21
|
+
...desc
|
|
22
|
+
});
|
|
17
23
|
}
|
|
18
24
|
}
|
|
19
25
|
|
|
@@ -19,7 +19,7 @@ import { ITextFileService } from '@codingame/monaco-vscode-api/vscode/vs/workben
|
|
|
19
19
|
import { IUserDataProfileService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/userDataProfile/common/userDataProfile.service';
|
|
20
20
|
|
|
21
21
|
var ISnippetPick;
|
|
22
|
-
(function
|
|
22
|
+
(function(ISnippetPick) {
|
|
23
23
|
function is(thing) {
|
|
24
24
|
return !!thing && URI.isUri(thing.filepath);
|
|
25
25
|
}
|
|
@@ -38,7 +38,8 @@ async function computePicks(snippetService, userDataProfileService, languageServ
|
|
|
38
38
|
await file.load();
|
|
39
39
|
const names = ( new Set());
|
|
40
40
|
let source;
|
|
41
|
-
outer:
|
|
41
|
+
outer:
|
|
42
|
+
for (const snippet of file.data) {
|
|
42
43
|
if (!source) {
|
|
43
44
|
source = snippet.source;
|
|
44
45
|
}
|
|
@@ -48,8 +49,7 @@ async function computePicks(snippetService, userDataProfileService, languageServ
|
|
|
48
49
|
if (names.size >= 4) {
|
|
49
50
|
names.add(`${name}...`);
|
|
50
51
|
break outer;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
52
|
+
} else {
|
|
53
53
|
names.add(name);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -58,29 +58,26 @@ async function computePicks(snippetService, userDataProfileService, languageServ
|
|
|
58
58
|
const snippet = {
|
|
59
59
|
label: basename(file.location),
|
|
60
60
|
filepath: file.location,
|
|
61
|
-
description: names.size === 0
|
|
62
|
-
? ( localize(10968, "(global)"))
|
|
63
|
-
: ( localize(10969, "({0})", [...names].join(', ')))
|
|
61
|
+
description: names.size === 0 ? ( localize(11287, "(global)")) : ( localize(11288, "({0})", [...names].join(", ")))
|
|
64
62
|
};
|
|
65
63
|
existing.push(snippet);
|
|
66
64
|
if (!source) {
|
|
67
65
|
continue;
|
|
68
66
|
}
|
|
69
|
-
const detail = ( localize(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
source,
|
|
73
|
-
labelService.getUriLabel(file.location, { relative: true })
|
|
74
|
-
));
|
|
67
|
+
const detail = ( localize(11289, "({0}) {1}", source, labelService.getUriLabel(file.location, {
|
|
68
|
+
relative: true
|
|
69
|
+
})));
|
|
75
70
|
const lastItem = added.get(basename(file.location));
|
|
76
71
|
if (lastItem) {
|
|
77
72
|
snippet.detail = detail;
|
|
78
73
|
lastItem.snippet.detail = lastItem.detail;
|
|
79
74
|
}
|
|
80
|
-
added.set(basename(file.location), {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
added.set(basename(file.location), {
|
|
76
|
+
snippet,
|
|
77
|
+
detail
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
const mode = basename(file.location).replace(/\.json$/, "");
|
|
84
81
|
existing.push({
|
|
85
82
|
label: basename(file.location),
|
|
86
83
|
description: `(${languageService.getLanguageName(mode) ?? mode})`,
|
|
@@ -107,38 +104,44 @@ async function computePicks(snippetService, userDataProfileService, languageServ
|
|
|
107
104
|
const b_ext = extname(b.filepath.path);
|
|
108
105
|
if (a_ext === b_ext) {
|
|
109
106
|
return a.label.localeCompare(b.label);
|
|
110
|
-
}
|
|
111
|
-
else if (a_ext === '.code-snippets') {
|
|
107
|
+
} else if (a_ext === ".code-snippets") {
|
|
112
108
|
return -1;
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
109
|
+
} else {
|
|
115
110
|
return 1;
|
|
116
111
|
}
|
|
117
112
|
});
|
|
118
113
|
future.sort((a, b) => {
|
|
119
114
|
return a.label.localeCompare(b.label);
|
|
120
115
|
});
|
|
121
|
-
return {
|
|
116
|
+
return {
|
|
117
|
+
existing,
|
|
118
|
+
future
|
|
119
|
+
};
|
|
122
120
|
}
|
|
123
|
-
async function createSnippetFile(
|
|
121
|
+
async function createSnippetFile(
|
|
122
|
+
scope,
|
|
123
|
+
defaultPath,
|
|
124
|
+
quickInputService,
|
|
125
|
+
fileService,
|
|
126
|
+
textFileService,
|
|
127
|
+
opener
|
|
128
|
+
) {
|
|
124
129
|
function createSnippetUri(input) {
|
|
125
|
-
const filename = extname(input) !==
|
|
126
|
-
? `${input}.code-snippets`
|
|
127
|
-
: input;
|
|
130
|
+
const filename = extname(input) !== ".code-snippets" ? `${input}.code-snippets` : input;
|
|
128
131
|
return joinPath(defaultPath, filename);
|
|
129
132
|
}
|
|
130
133
|
await fileService.createFolder(defaultPath);
|
|
131
134
|
const input = await quickInputService.input({
|
|
132
|
-
placeHolder: ( localize(
|
|
135
|
+
placeHolder: ( localize(11290, "Type snippet file name")),
|
|
133
136
|
async validateInput(input) {
|
|
134
137
|
if (!input) {
|
|
135
|
-
return localize(
|
|
138
|
+
return localize(11291, "Invalid file name");
|
|
136
139
|
}
|
|
137
140
|
if (!isValidBasename(input)) {
|
|
138
|
-
return localize(
|
|
141
|
+
return localize(11292, "'{0}' is not a valid file name", input);
|
|
139
142
|
}
|
|
140
143
|
if (await fileService.exists(createSnippetUri(input))) {
|
|
141
|
-
return localize(
|
|
144
|
+
return localize(11293, "'{0}' already exists", input);
|
|
142
145
|
}
|
|
143
146
|
return undefined;
|
|
144
147
|
}
|
|
@@ -148,25 +151,35 @@ async function createSnippetFile(scope, defaultPath, quickInputService, fileServ
|
|
|
148
151
|
}
|
|
149
152
|
const resource = createSnippetUri(input);
|
|
150
153
|
await textFileService.write(resource, [
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
154
|
+
"{",
|
|
155
|
+
"\t// Place your " + scope + " snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and ",
|
|
156
|
+
"\t// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope ",
|
|
157
|
+
"\t// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is ",
|
|
158
|
+
"\t// used to trigger the snippet and the body will be expanded and inserted. Possible variables are: ",
|
|
159
|
+
"\t// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. ",
|
|
160
|
+
"\t// Placeholders with the same ids are connected.",
|
|
161
|
+
"\t// Example:",
|
|
162
|
+
"\t// \"Print to console\": {",
|
|
163
|
+
"\t// \t\"scope\": \"javascript,typescript\",",
|
|
164
|
+
"\t// \t\"prefix\": \"log\",",
|
|
165
|
+
"\t// \t\"body\": [",
|
|
166
|
+
"\t// \t\t\"console.log('$1');\",",
|
|
167
|
+
"\t// \t\t\"$2\"",
|
|
168
|
+
"\t// \t],",
|
|
169
|
+
"\t// \t\"description\": \"Log output to console\"",
|
|
170
|
+
"\t// }",
|
|
171
|
+
"\t//",
|
|
172
|
+
"\t// You can also restrict snippets to specific files using include/exclude patterns:",
|
|
173
|
+
"\t// \"Test snippet\": {",
|
|
174
|
+
"\t// \t\"scope\": \"javascript,typescript\",",
|
|
175
|
+
"\t// \t\"prefix\": \"test\",",
|
|
176
|
+
"\t// \t\"body\": \"test('$1', () => {\\n\\t$0\\n});\",",
|
|
177
|
+
"\t// \t\"include\": [\"**/*.test.ts\", \"*.spec.ts\"],",
|
|
178
|
+
"\t// \t\"exclude\": [\"**/temp/*.ts\"],",
|
|
179
|
+
"\t// \t\"description\": \"Insert test block\"",
|
|
180
|
+
"\t// }",
|
|
181
|
+
"}"
|
|
182
|
+
].join("\n"));
|
|
170
183
|
await opener.open(resource);
|
|
171
184
|
return undefined;
|
|
172
185
|
}
|
|
@@ -175,38 +188,52 @@ async function createLanguageSnippetFile(pick, fileService, textFileService) {
|
|
|
175
188
|
return;
|
|
176
189
|
}
|
|
177
190
|
const contents = [
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
"{",
|
|
192
|
+
"\t// Place your snippets for " + pick.label + " here. Each snippet is defined under a snippet name and has a prefix, body and ",
|
|
193
|
+
"\t// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:",
|
|
194
|
+
"\t// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the ",
|
|
195
|
+
"\t// same ids are connected.",
|
|
196
|
+
"\t// Example:",
|
|
197
|
+
"\t// \"Print to console\": {",
|
|
198
|
+
"\t// \t\"prefix\": \"log\",",
|
|
199
|
+
"\t// \t\"body\": [",
|
|
200
|
+
"\t// \t\t\"console.log('$1');\",",
|
|
201
|
+
"\t// \t\t\"$2\"",
|
|
202
|
+
"\t// \t],",
|
|
203
|
+
"\t// \t\"description\": \"Log output to console\"",
|
|
204
|
+
"\t// }",
|
|
205
|
+
"\t//",
|
|
206
|
+
"\t// You can also restrict snippets to specific files using include/exclude patterns:",
|
|
207
|
+
"\t// \"Test snippet\": {",
|
|
208
|
+
"\t// \t\"prefix\": \"test\",",
|
|
209
|
+
"\t// \t\"body\": \"test('$1', () => {\\n\\t$0\\n});\",",
|
|
210
|
+
"\t// \t\"include\": [\"**/*.test.ts\", \"*.spec.ts\"],",
|
|
211
|
+
"\t// \t\"exclude\": [\"**/temp/*.ts\"],",
|
|
212
|
+
"\t// \t\"description\": \"Insert test block\"",
|
|
213
|
+
"\t// }",
|
|
214
|
+
"}"
|
|
215
|
+
].join("\n");
|
|
194
216
|
await textFileService.write(pick.filepath, contents);
|
|
195
217
|
}
|
|
196
218
|
class ConfigureSnippetsAction extends SnippetsAction {
|
|
197
219
|
constructor() {
|
|
198
220
|
super({
|
|
199
|
-
id:
|
|
200
|
-
title: ( localize2(
|
|
221
|
+
id: "workbench.action.openSnippets",
|
|
222
|
+
title: ( localize2(11294, "Configure Snippets")),
|
|
201
223
|
shortTitle: {
|
|
202
|
-
...( localize2(
|
|
203
|
-
mnemonicTitle: ( localize(
|
|
224
|
+
...( localize2(11295, "Snippets")),
|
|
225
|
+
mnemonicTitle: ( localize(11296, "&&Snippets"))
|
|
204
226
|
},
|
|
205
227
|
f1: true,
|
|
206
|
-
menu: [
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
228
|
+
menu: [{
|
|
229
|
+
id: MenuId.MenubarPreferencesMenu,
|
|
230
|
+
group: "2_configuration",
|
|
231
|
+
order: 5
|
|
232
|
+
}, {
|
|
233
|
+
id: MenuId.GlobalActivity,
|
|
234
|
+
group: "2_configuration",
|
|
235
|
+
order: 5
|
|
236
|
+
}]
|
|
210
237
|
});
|
|
211
238
|
}
|
|
212
239
|
async run(accessor) {
|
|
@@ -222,36 +249,59 @@ class ConfigureSnippetsAction extends SnippetsAction {
|
|
|
222
249
|
const picks = await computePicks(snippetService, userDataProfileService, languageService, labelService);
|
|
223
250
|
const existing = picks.existing;
|
|
224
251
|
const globalSnippetPicks = [{
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
252
|
+
scope: ( localize(11297, "global")),
|
|
253
|
+
label: ( localize(11298, "New Global Snippets file...")),
|
|
254
|
+
uri: userDataProfileService.currentProfile.snippetsHome
|
|
255
|
+
}];
|
|
229
256
|
const workspaceSnippetPicks = [];
|
|
230
257
|
for (const folder of workspaceService.getWorkspace().folders) {
|
|
231
258
|
workspaceSnippetPicks.push({
|
|
232
|
-
scope: ( localize(
|
|
233
|
-
label: ( localize(
|
|
234
|
-
uri: folder.toResource(
|
|
259
|
+
scope: ( localize(11299, "{0} workspace", folder.name)),
|
|
260
|
+
label: ( localize(11300, "New Snippets file for '{0}'...", folder.name)),
|
|
261
|
+
uri: folder.toResource(".vscode")
|
|
235
262
|
});
|
|
236
263
|
}
|
|
237
264
|
if (existing.length > 0) {
|
|
238
|
-
existing.unshift({
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
existing.push({
|
|
265
|
+
existing.unshift({
|
|
266
|
+
type: "separator",
|
|
267
|
+
label: ( localize(11301, "Existing Snippets"))
|
|
268
|
+
});
|
|
269
|
+
existing.push({
|
|
270
|
+
type: "separator",
|
|
271
|
+
label: ( localize(11302, "New Snippets"))
|
|
272
|
+
});
|
|
273
|
+
} else {
|
|
274
|
+
existing.push({
|
|
275
|
+
type: "separator",
|
|
276
|
+
label: ( localize(11302, "New Snippets"))
|
|
277
|
+
});
|
|
243
278
|
}
|
|
244
|
-
const pick = await quickInputService.pick(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
279
|
+
const pick = await quickInputService.pick(
|
|
280
|
+
[].concat(existing, globalSnippetPicks, workspaceSnippetPicks, picks.future),
|
|
281
|
+
{
|
|
282
|
+
placeHolder: ( localize(11303, "Select Snippets File or Create Snippets")),
|
|
283
|
+
matchOnDescription: true
|
|
284
|
+
}
|
|
285
|
+
);
|
|
248
286
|
if (globalSnippetPicks.indexOf(pick) >= 0) {
|
|
249
|
-
return createSnippetFile(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
287
|
+
return createSnippetFile(
|
|
288
|
+
pick.scope,
|
|
289
|
+
pick.uri,
|
|
290
|
+
quickInputService,
|
|
291
|
+
fileService,
|
|
292
|
+
textFileService,
|
|
293
|
+
opener
|
|
294
|
+
);
|
|
295
|
+
} else if (workspaceSnippetPicks.indexOf(pick) >= 0) {
|
|
296
|
+
return createSnippetFile(
|
|
297
|
+
pick.scope,
|
|
298
|
+
pick.uri,
|
|
299
|
+
quickInputService,
|
|
300
|
+
fileService,
|
|
301
|
+
textFileService,
|
|
302
|
+
opener
|
|
303
|
+
);
|
|
304
|
+
} else if (ISnippetPick.is(pick)) {
|
|
255
305
|
if (pick.hint) {
|
|
256
306
|
await createLanguageSnippetFile(pick, fileService, textFileService);
|
|
257
307
|
}
|
|
@@ -11,12 +11,14 @@ import { ISnippetsService } from '@codingame/monaco-vscode-api/vscode/vs/workben
|
|
|
11
11
|
import { IEditorService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service';
|
|
12
12
|
|
|
13
13
|
class ApplyFileSnippetAction extends SnippetsAction {
|
|
14
|
-
static {
|
|
14
|
+
static {
|
|
15
|
+
this.Id = "workbench.action.populateFileFromSnippet";
|
|
16
|
+
}
|
|
15
17
|
constructor() {
|
|
16
18
|
super({
|
|
17
19
|
id: ApplyFileSnippetAction.Id,
|
|
18
|
-
title: ( localize2(
|
|
19
|
-
f1: true
|
|
20
|
+
title: ( localize2(11304, "Fill File with Snippet")),
|
|
21
|
+
f1: true
|
|
20
22
|
});
|
|
21
23
|
}
|
|
22
24
|
async run(accessor) {
|
|
@@ -28,7 +30,12 @@ class ApplyFileSnippetAction extends SnippetsAction {
|
|
|
28
30
|
if (!editor || !editor.hasModel()) {
|
|
29
31
|
return;
|
|
30
32
|
}
|
|
31
|
-
const
|
|
33
|
+
const resourceUri = editor.getModel().uri;
|
|
34
|
+
const snippets = await snippetService.getSnippets(undefined, resourceUri, {
|
|
35
|
+
fileTemplateSnippets: true,
|
|
36
|
+
noRecencySort: true,
|
|
37
|
+
includeNoPrefixSnippets: true
|
|
38
|
+
});
|
|
32
39
|
if (snippets.length === 0) {
|
|
33
40
|
return;
|
|
34
41
|
}
|
|
@@ -38,9 +45,9 @@ class ApplyFileSnippetAction extends SnippetsAction {
|
|
|
38
45
|
}
|
|
39
46
|
if (editor.hasModel()) {
|
|
40
47
|
SnippetController2.get(editor)?.apply([{
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
range: editor.getModel().getFullModelRange(),
|
|
49
|
+
template: selection.snippet.body
|
|
50
|
+
}]);
|
|
44
51
|
editor.getModel().setLanguage(langService.createById(selection.langId), ApplyFileSnippetAction.Id);
|
|
45
52
|
editor.focus();
|
|
46
53
|
}
|
|
@@ -49,11 +56,16 @@ class ApplyFileSnippetAction extends SnippetsAction {
|
|
|
49
56
|
const all = [];
|
|
50
57
|
for (const snippet of snippets) {
|
|
51
58
|
if (isFalsyOrEmpty(snippet.scopes)) {
|
|
52
|
-
all.push({
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
all.push({
|
|
60
|
+
langId: "",
|
|
61
|
+
snippet
|
|
62
|
+
});
|
|
63
|
+
} else {
|
|
55
64
|
for (const langId of snippet.scopes) {
|
|
56
|
-
all.push({
|
|
65
|
+
all.push({
|
|
66
|
+
langId,
|
|
67
|
+
snippet
|
|
68
|
+
});
|
|
57
69
|
}
|
|
58
70
|
}
|
|
59
71
|
}
|
|
@@ -64,7 +76,7 @@ class ApplyFileSnippetAction extends SnippetsAction {
|
|
|
64
76
|
for (const item of group) {
|
|
65
77
|
if (first) {
|
|
66
78
|
picks.push({
|
|
67
|
-
type:
|
|
79
|
+
type: "separator",
|
|
68
80
|
label: langService.getLanguageName(item.langId) ?? item.langId
|
|
69
81
|
});
|
|
70
82
|
first = false;
|
|
@@ -77,8 +89,8 @@ class ApplyFileSnippetAction extends SnippetsAction {
|
|
|
77
89
|
}
|
|
78
90
|
}
|
|
79
91
|
const pick = await quickInputService.pick(picks, {
|
|
80
|
-
placeHolder: ( localize(
|
|
81
|
-
matchOnDetail: true
|
|
92
|
+
placeHolder: ( localize(11305, "Select a snippet")),
|
|
93
|
+
matchOnDetail: true
|
|
82
94
|
});
|
|
83
95
|
return pick?.snippet;
|
|
84
96
|
}
|
|
@@ -12,22 +12,28 @@ import { Snippet, SnippetSource } from '@codingame/monaco-vscode-api/vscode/vs/w
|
|
|
12
12
|
|
|
13
13
|
class Args {
|
|
14
14
|
static fromUser(arg) {
|
|
15
|
-
if (!arg || typeof arg !==
|
|
15
|
+
if (!arg || typeof arg !== "object") {
|
|
16
16
|
return Args._empty;
|
|
17
17
|
}
|
|
18
|
-
let {
|
|
19
|
-
|
|
18
|
+
let {
|
|
19
|
+
snippet,
|
|
20
|
+
name,
|
|
21
|
+
langId
|
|
22
|
+
} = arg;
|
|
23
|
+
if (typeof snippet !== "string") {
|
|
20
24
|
snippet = undefined;
|
|
21
25
|
}
|
|
22
|
-
if (typeof name !==
|
|
26
|
+
if (typeof name !== "string") {
|
|
23
27
|
name = undefined;
|
|
24
28
|
}
|
|
25
|
-
if (typeof langId !==
|
|
29
|
+
if (typeof langId !== "string") {
|
|
26
30
|
langId = undefined;
|
|
27
31
|
}
|
|
28
32
|
return ( new Args(snippet, name, langId));
|
|
29
33
|
}
|
|
30
|
-
static {
|
|
34
|
+
static {
|
|
35
|
+
this._empty = ( new Args(undefined, undefined, undefined));
|
|
36
|
+
}
|
|
31
37
|
constructor(snippet, name, langId) {
|
|
32
38
|
this.snippet = snippet;
|
|
33
39
|
this.name = name;
|
|
@@ -37,29 +43,29 @@ class Args {
|
|
|
37
43
|
class InsertSnippetAction extends SnippetEditorAction {
|
|
38
44
|
constructor() {
|
|
39
45
|
super({
|
|
40
|
-
id:
|
|
41
|
-
title: ( localize2(
|
|
46
|
+
id: "editor.action.insertSnippet",
|
|
47
|
+
title: ( localize2(11306, "Insert Snippet")),
|
|
42
48
|
f1: true,
|
|
43
49
|
precondition: EditorContextKeys.writable,
|
|
44
50
|
metadata: {
|
|
45
51
|
description: `Insert Snippet`,
|
|
46
52
|
args: [{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
},
|
|
57
|
-
'name': {
|
|
58
|
-
'type': 'string'
|
|
59
|
-
}
|
|
53
|
+
name: "args",
|
|
54
|
+
schema: {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"properties": {
|
|
57
|
+
"snippet": {
|
|
58
|
+
"type": "string"
|
|
59
|
+
},
|
|
60
|
+
"langId": {
|
|
61
|
+
"type": "string"
|
|
60
62
|
},
|
|
63
|
+
"name": {
|
|
64
|
+
"type": "string"
|
|
65
|
+
}
|
|
61
66
|
}
|
|
62
|
-
}
|
|
67
|
+
}
|
|
68
|
+
}]
|
|
63
69
|
}
|
|
64
70
|
});
|
|
65
71
|
}
|
|
@@ -72,17 +78,24 @@ class InsertSnippetAction extends SnippetEditorAction {
|
|
|
72
78
|
const clipboardService = accessor.get(IClipboardService);
|
|
73
79
|
const instaService = accessor.get(IInstantiationService);
|
|
74
80
|
const snippet = await ( new Promise((resolve, reject) => {
|
|
75
|
-
const {
|
|
76
|
-
|
|
81
|
+
const {
|
|
82
|
+
lineNumber,
|
|
83
|
+
column
|
|
84
|
+
} = editor.getPosition();
|
|
85
|
+
const {
|
|
86
|
+
snippet,
|
|
87
|
+
name,
|
|
88
|
+
langId
|
|
89
|
+
} = Args.fromUser(arg);
|
|
77
90
|
if (snippet) {
|
|
78
91
|
return resolve(( new Snippet(
|
|
79
92
|
false,
|
|
80
93
|
[],
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
94
|
+
"",
|
|
95
|
+
"",
|
|
96
|
+
"",
|
|
84
97
|
snippet,
|
|
85
|
-
|
|
98
|
+
"",
|
|
86
99
|
SnippetSource.User,
|
|
87
100
|
`random/${Math.random()}`
|
|
88
101
|
)));
|
|
@@ -93,8 +106,7 @@ class InsertSnippetAction extends SnippetEditorAction {
|
|
|
93
106
|
return resolve(undefined);
|
|
94
107
|
}
|
|
95
108
|
languageId = langId;
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
109
|
+
} else {
|
|
98
110
|
editor.getModel().tokenization.tokenizeIfCheap(lineNumber);
|
|
99
111
|
languageId = editor.getModel().getLanguageIdAtPosition(lineNumber, column);
|
|
100
112
|
if (!languageService.getLanguageName(languageId)) {
|
|
@@ -102,12 +114,13 @@ class InsertSnippetAction extends SnippetEditorAction {
|
|
|
102
114
|
}
|
|
103
115
|
}
|
|
104
116
|
if (name) {
|
|
105
|
-
snippetService.getSnippets(languageId, {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
117
|
+
snippetService.getSnippets(languageId, undefined, {
|
|
118
|
+
includeNoPrefixSnippets: true
|
|
119
|
+
}).then(snippets => snippets.find(snippet => snippet.name === name)).then(resolve, reject);
|
|
120
|
+
} else {
|
|
121
|
+
resolve(
|
|
122
|
+
instaService.invokeFunction(pickSnippet, languageId, editor.getModel().uri)
|
|
123
|
+
);
|
|
111
124
|
}
|
|
112
125
|
}));
|
|
113
126
|
if (!snippet) {
|
|
@@ -118,7 +131,9 @@ class InsertSnippetAction extends SnippetEditorAction {
|
|
|
118
131
|
clipboardText = await clipboardService.readText();
|
|
119
132
|
}
|
|
120
133
|
editor.focus();
|
|
121
|
-
SnippetController2.get(editor)?.insert(snippet.codeSnippet, {
|
|
134
|
+
SnippetController2.get(editor)?.insert(snippet.codeSnippet, {
|
|
135
|
+
clipboardText
|
|
136
|
+
});
|
|
122
137
|
snippetService.updateUsageTimestamp(snippet);
|
|
123
138
|
}
|
|
124
139
|
}
|
|
@@ -10,22 +10,30 @@ import { ISnippetsService } from '@codingame/monaco-vscode-api/vscode/vs/workben
|
|
|
10
10
|
import { localize2 } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
11
11
|
|
|
12
12
|
async function getSurroundableSnippets(snippetsService, model, position, includeDisabledSnippets) {
|
|
13
|
-
const {
|
|
13
|
+
const {
|
|
14
|
+
lineNumber,
|
|
15
|
+
column
|
|
16
|
+
} = position;
|
|
14
17
|
model.tokenization.tokenizeIfCheap(lineNumber);
|
|
15
18
|
const languageId = model.getLanguageIdAtPosition(lineNumber, column);
|
|
16
|
-
const allSnippets = await snippetsService.getSnippets(languageId,
|
|
19
|
+
const allSnippets = await snippetsService.getSnippets(languageId, model.uri, {
|
|
20
|
+
includeNoPrefixSnippets: true,
|
|
21
|
+
includeDisabledSnippets
|
|
22
|
+
});
|
|
17
23
|
return allSnippets.filter(snippet => snippet.usesSelection);
|
|
18
24
|
}
|
|
19
25
|
class SurroundWithSnippetEditorAction extends SnippetEditorAction {
|
|
20
|
-
static {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
static {
|
|
27
|
+
this.options = {
|
|
28
|
+
id: "editor.action.surroundWithSnippet",
|
|
29
|
+
title: ( localize2(11307, "Surround with Snippet..."))
|
|
30
|
+
};
|
|
31
|
+
}
|
|
24
32
|
constructor() {
|
|
25
33
|
super({
|
|
26
34
|
...SurroundWithSnippetEditorAction.options,
|
|
27
35
|
precondition: ( ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasNonEmptySelection)),
|
|
28
|
-
f1: true
|
|
36
|
+
f1: true
|
|
29
37
|
});
|
|
30
38
|
}
|
|
31
39
|
async runEditorCommand(accessor, editor) {
|
|
@@ -35,11 +43,12 @@ class SurroundWithSnippetEditorAction extends SnippetEditorAction {
|
|
|
35
43
|
const instaService = accessor.get(IInstantiationService);
|
|
36
44
|
const snippetsService = accessor.get(ISnippetsService);
|
|
37
45
|
const clipboardService = accessor.get(IClipboardService);
|
|
38
|
-
const
|
|
46
|
+
const model = editor.getModel();
|
|
47
|
+
const snippets = await getSurroundableSnippets(snippetsService, model, editor.getPosition(), true);
|
|
39
48
|
if (!snippets.length) {
|
|
40
49
|
return;
|
|
41
50
|
}
|
|
42
|
-
const snippet = await instaService.invokeFunction(pickSnippet, snippets);
|
|
51
|
+
const snippet = await instaService.invokeFunction(pickSnippet, snippets, model.uri);
|
|
43
52
|
if (!snippet) {
|
|
44
53
|
return;
|
|
45
54
|
}
|
|
@@ -48,7 +57,9 @@ class SurroundWithSnippetEditorAction extends SnippetEditorAction {
|
|
|
48
57
|
clipboardText = await clipboardService.readText();
|
|
49
58
|
}
|
|
50
59
|
editor.focus();
|
|
51
|
-
SnippetController2.get(editor)?.insert(snippet.codeSnippet, {
|
|
60
|
+
SnippetController2.get(editor)?.insert(snippet.codeSnippet, {
|
|
61
|
+
clipboardText
|
|
62
|
+
});
|
|
52
63
|
snippetsService.updateUsageTimestamp(snippet);
|
|
53
64
|
}
|
|
54
65
|
}
|
|
@@ -13,16 +13,22 @@ import { ISnippetsService } from '@codingame/monaco-vscode-api/vscode/vs/workben
|
|
|
13
13
|
|
|
14
14
|
var SurroundWithSnippetCodeActionProvider_1, FileTemplateCodeActionProvider_1;
|
|
15
15
|
let SurroundWithSnippetCodeActionProvider = class SurroundWithSnippetCodeActionProvider {
|
|
16
|
-
static {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
static {
|
|
17
|
+
SurroundWithSnippetCodeActionProvider_1 = this;
|
|
18
|
+
}
|
|
19
|
+
static {
|
|
20
|
+
this._MAX_CODE_ACTIONS = 4;
|
|
21
|
+
}
|
|
22
|
+
static {
|
|
23
|
+
this._overflowCommandCodeAction = {
|
|
24
|
+
kind: CodeActionKind.SurroundWith.value,
|
|
25
|
+
title: ( localize(11308, "More...")),
|
|
26
|
+
command: {
|
|
27
|
+
id: SurroundWithSnippetEditorAction.options.id,
|
|
28
|
+
title: SurroundWithSnippetEditorAction.options.title.value
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
26
32
|
constructor(_snippetService) {
|
|
27
33
|
this._snippetService = _snippetService;
|
|
28
34
|
}
|
|
@@ -42,31 +48,35 @@ let SurroundWithSnippetCodeActionProvider = class SurroundWithSnippetCodeActionP
|
|
|
42
48
|
break;
|
|
43
49
|
}
|
|
44
50
|
actions.push({
|
|
45
|
-
title: ( localize(
|
|
51
|
+
title: ( localize(11309, "{0}", snippet.name)),
|
|
46
52
|
kind: CodeActionKind.SurroundWith.value,
|
|
47
53
|
edit: asWorkspaceEdit(model, range, snippet)
|
|
48
54
|
});
|
|
49
55
|
}
|
|
50
56
|
return {
|
|
51
57
|
actions,
|
|
52
|
-
dispose() {
|
|
58
|
+
dispose() {}
|
|
53
59
|
};
|
|
54
60
|
}
|
|
55
61
|
};
|
|
56
|
-
SurroundWithSnippetCodeActionProvider = SurroundWithSnippetCodeActionProvider_1 = ( __decorate([
|
|
57
|
-
( __param(0, ISnippetsService))
|
|
58
|
-
], SurroundWithSnippetCodeActionProvider));
|
|
62
|
+
SurroundWithSnippetCodeActionProvider = SurroundWithSnippetCodeActionProvider_1 = ( __decorate([( __param(0, ISnippetsService))], SurroundWithSnippetCodeActionProvider));
|
|
59
63
|
let FileTemplateCodeActionProvider = class FileTemplateCodeActionProvider {
|
|
60
|
-
static {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
static {
|
|
65
|
+
FileTemplateCodeActionProvider_1 = this;
|
|
66
|
+
}
|
|
67
|
+
static {
|
|
68
|
+
this._MAX_CODE_ACTIONS = 4;
|
|
69
|
+
}
|
|
70
|
+
static {
|
|
71
|
+
this._overflowCommandCodeAction = {
|
|
72
|
+
title: ( localize(11310, "Start with Snippet")),
|
|
73
|
+
kind: CodeActionKind.SurroundWith.value,
|
|
74
|
+
command: {
|
|
75
|
+
id: ApplyFileSnippetAction.Id,
|
|
76
|
+
title: ""
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
70
80
|
constructor(_snippetService) {
|
|
71
81
|
this._snippetService = _snippetService;
|
|
72
82
|
this.providedCodeActionKinds = [CodeActionKind.SurroundWith.value];
|
|
@@ -75,7 +85,10 @@ let FileTemplateCodeActionProvider = class FileTemplateCodeActionProvider {
|
|
|
75
85
|
if (model.getValueLength() !== 0) {
|
|
76
86
|
return undefined;
|
|
77
87
|
}
|
|
78
|
-
const snippets = await this._snippetService.getSnippets(model.getLanguageId(),
|
|
88
|
+
const snippets = await this._snippetService.getSnippets(model.getLanguageId(), model.uri, {
|
|
89
|
+
fileTemplateSnippets: true,
|
|
90
|
+
includeNoPrefixSnippets: true
|
|
91
|
+
});
|
|
79
92
|
const actions = [];
|
|
80
93
|
for (const snippet of snippets) {
|
|
81
94
|
if (actions.length >= FileTemplateCodeActionProvider_1._MAX_CODE_ACTIONS) {
|
|
@@ -83,57 +96,58 @@ let FileTemplateCodeActionProvider = class FileTemplateCodeActionProvider {
|
|
|
83
96
|
break;
|
|
84
97
|
}
|
|
85
98
|
actions.push({
|
|
86
|
-
title: ( localize(
|
|
99
|
+
title: ( localize(11311, "Start with: {0}", snippet.name)),
|
|
87
100
|
kind: CodeActionKind.SurroundWith.value,
|
|
88
101
|
edit: asWorkspaceEdit(model, model.getFullModelRange(), snippet)
|
|
89
102
|
});
|
|
90
103
|
}
|
|
91
104
|
return {
|
|
92
105
|
actions,
|
|
93
|
-
dispose() {
|
|
106
|
+
dispose() {}
|
|
94
107
|
};
|
|
95
108
|
}
|
|
96
109
|
};
|
|
97
|
-
FileTemplateCodeActionProvider = FileTemplateCodeActionProvider_1 = ( __decorate([
|
|
98
|
-
( __param(0, ISnippetsService))
|
|
99
|
-
], FileTemplateCodeActionProvider));
|
|
110
|
+
FileTemplateCodeActionProvider = FileTemplateCodeActionProvider_1 = ( __decorate([( __param(0, ISnippetsService))], FileTemplateCodeActionProvider));
|
|
100
111
|
function asWorkspaceEdit(model, range, snippet) {
|
|
101
112
|
return {
|
|
102
113
|
edits: [{
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
versionId: model.getVersionId(),
|
|
115
|
+
resource: model.uri,
|
|
116
|
+
textEdit: {
|
|
117
|
+
range,
|
|
118
|
+
text: snippet.body,
|
|
119
|
+
insertAsSnippet: true
|
|
120
|
+
}
|
|
121
|
+
}]
|
|
111
122
|
};
|
|
112
123
|
}
|
|
113
124
|
let SnippetCodeActions = class SnippetCodeActions {
|
|
114
125
|
constructor(instantiationService, languageFeaturesService, configService) {
|
|
115
126
|
this._store = ( new DisposableStore());
|
|
116
|
-
const setting =
|
|
127
|
+
const setting = "editor.snippets.codeActions.enabled";
|
|
117
128
|
const sessionStore = ( new DisposableStore());
|
|
118
129
|
const update = () => {
|
|
119
130
|
sessionStore.clear();
|
|
120
131
|
if (configService.getValue(setting)) {
|
|
121
|
-
sessionStore.add(languageFeaturesService.codeActionProvider.register(
|
|
122
|
-
|
|
132
|
+
sessionStore.add(languageFeaturesService.codeActionProvider.register(
|
|
133
|
+
"*",
|
|
134
|
+
instantiationService.createInstance(SurroundWithSnippetCodeActionProvider)
|
|
135
|
+
));
|
|
136
|
+
sessionStore.add(
|
|
137
|
+
languageFeaturesService.codeActionProvider.register("*", instantiationService.createInstance(FileTemplateCodeActionProvider))
|
|
138
|
+
);
|
|
123
139
|
}
|
|
124
140
|
};
|
|
125
141
|
update();
|
|
126
|
-
this._store.add(
|
|
142
|
+
this._store.add(
|
|
143
|
+
configService.onDidChangeConfiguration(e => e.affectsConfiguration(setting) && update())
|
|
144
|
+
);
|
|
127
145
|
this._store.add(sessionStore);
|
|
128
146
|
}
|
|
129
147
|
dispose() {
|
|
130
148
|
this._store.dispose();
|
|
131
149
|
}
|
|
132
150
|
};
|
|
133
|
-
SnippetCodeActions = ( __decorate([
|
|
134
|
-
( __param(0, IInstantiationService)),
|
|
135
|
-
( __param(1, ILanguageFeaturesService)),
|
|
136
|
-
( __param(2, IConfigurationService))
|
|
137
|
-
], SnippetCodeActions));
|
|
151
|
+
SnippetCodeActions = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, ILanguageFeaturesService)), ( __param(2, IConfigurationService))], SnippetCodeActions));
|
|
138
152
|
|
|
139
153
|
export { SnippetCodeActions };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { Snippet } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/snippets/browser/snippetsFile";
|
|
2
2
|
import { ServicesAccessor } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
|
|
3
|
-
|
|
3
|
+
import { URI } from "@codingame/monaco-vscode-api/vscode/vs/base/common/uri";
|
|
4
|
+
export declare function pickSnippet(accessor: ServicesAccessor, languageIdOrSnippets: string | Snippet[], resourceUri?: URI): Promise<Snippet | undefined>;
|
|
@@ -8,15 +8,17 @@ import { ThemeIcon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/th
|
|
|
8
8
|
import { Event } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
|
|
9
9
|
import { DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
10
10
|
|
|
11
|
-
async function pickSnippet(accessor, languageIdOrSnippets) {
|
|
11
|
+
async function pickSnippet(accessor, languageIdOrSnippets, resourceUri) {
|
|
12
12
|
const snippetService = accessor.get(ISnippetsService);
|
|
13
13
|
const quickInputService = accessor.get(IQuickInputService);
|
|
14
14
|
let snippets;
|
|
15
15
|
if (Array.isArray(languageIdOrSnippets)) {
|
|
16
16
|
snippets = languageIdOrSnippets;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
} else {
|
|
18
|
+
snippets = (await snippetService.getSnippets(languageIdOrSnippets, resourceUri, {
|
|
19
|
+
includeDisabledSnippets: true,
|
|
20
|
+
includeNoPrefixSnippets: true
|
|
21
|
+
}));
|
|
20
22
|
}
|
|
21
23
|
snippets.sort((a, b) => a.snippetSource - b.snippetSource);
|
|
22
24
|
const makeSnippetPicks = () => {
|
|
@@ -29,34 +31,36 @@ async function pickSnippet(accessor, languageIdOrSnippets) {
|
|
|
29
31
|
snippet
|
|
30
32
|
};
|
|
31
33
|
if (!prevSnippet || prevSnippet.snippetSource !== snippet.snippetSource || prevSnippet.source !== snippet.source) {
|
|
32
|
-
let label =
|
|
34
|
+
let label = "";
|
|
33
35
|
switch (snippet.snippetSource) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
case SnippetSource.User:
|
|
37
|
+
label = ( localize(11314, "User Snippets"));
|
|
38
|
+
break;
|
|
39
|
+
case SnippetSource.Extension:
|
|
40
|
+
label = snippet.source;
|
|
41
|
+
break;
|
|
42
|
+
case SnippetSource.Workspace:
|
|
43
|
+
label = ( localize(11315, "Workspace Snippets"));
|
|
44
|
+
break;
|
|
43
45
|
}
|
|
44
|
-
result.push({
|
|
46
|
+
result.push({
|
|
47
|
+
type: "separator",
|
|
48
|
+
label
|
|
49
|
+
});
|
|
45
50
|
}
|
|
46
51
|
if (snippet.snippetSource === SnippetSource.Extension) {
|
|
47
52
|
const isEnabled = snippetService.isEnabled(snippet);
|
|
48
53
|
if (isEnabled) {
|
|
49
54
|
pick.buttons = [{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
pick.description = ( localize(10998, "(hidden from IntelliSense)"));
|
|
55
|
+
iconClass: ThemeIcon.asClassName(Codicon.eyeClosed),
|
|
56
|
+
tooltip: ( localize(11316, "Hide from IntelliSense"))
|
|
57
|
+
}];
|
|
58
|
+
} else {
|
|
59
|
+
pick.description = ( localize(11317, "(hidden from IntelliSense)"));
|
|
56
60
|
pick.buttons = [{
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
iconClass: ThemeIcon.asClassName(Codicon.eye),
|
|
62
|
+
tooltip: ( localize(11318, "Show in IntelliSense"))
|
|
63
|
+
}];
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
66
|
result.push(pick);
|
|
@@ -65,8 +69,10 @@ async function pickSnippet(accessor, languageIdOrSnippets) {
|
|
|
65
69
|
return result;
|
|
66
70
|
};
|
|
67
71
|
const disposables = ( new DisposableStore());
|
|
68
|
-
const picker = disposables.add(quickInputService.createQuickPick({
|
|
69
|
-
|
|
72
|
+
const picker = disposables.add(quickInputService.createQuickPick({
|
|
73
|
+
useSeparators: true
|
|
74
|
+
}));
|
|
75
|
+
picker.placeholder = ( localize(11319, "Select a snippet"));
|
|
70
76
|
picker.matchOnDetail = true;
|
|
71
77
|
picker.ignoreFocusOut = false;
|
|
72
78
|
picker.keepScrollPosition = true;
|
|
@@ -77,7 +83,7 @@ async function pickSnippet(accessor, languageIdOrSnippets) {
|
|
|
77
83
|
}));
|
|
78
84
|
picker.items = makeSnippetPicks();
|
|
79
85
|
if (!picker.items.length) {
|
|
80
|
-
picker.validationMessage = ( localize(
|
|
86
|
+
picker.validationMessage = ( localize(11320, "No snippet available"));
|
|
81
87
|
}
|
|
82
88
|
picker.show();
|
|
83
89
|
await Promise.race([Event.toPromise(picker.onDidAccept), Event.toPromise(picker.onDidHide)]);
|
|
@@ -19,50 +19,68 @@ import '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/snippets/browse
|
|
|
19
19
|
import { editorConfigurationBaseNode } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/config/editorConfigurationSchema';
|
|
20
20
|
|
|
21
21
|
registerAction2(InsertSnippetAction);
|
|
22
|
-
CommandsRegistry.registerCommandAlias(
|
|
22
|
+
CommandsRegistry.registerCommandAlias("editor.action.showSnippets", "editor.action.insertSnippet");
|
|
23
23
|
registerAction2(SurroundWithSnippetEditorAction);
|
|
24
24
|
registerAction2(ApplyFileSnippetAction);
|
|
25
25
|
registerAction2(ConfigureSnippetsAction);
|
|
26
26
|
const workbenchContribRegistry = ( Registry.as(Extensions.Workbench));
|
|
27
27
|
workbenchContribRegistry.registerWorkbenchContribution(SnippetCodeActions, LifecyclePhase.Restored);
|
|
28
|
-
( Registry
|
|
29
|
-
.as(Extensions$1.Configuration))
|
|
30
|
-
.registerConfiguration({
|
|
28
|
+
( Registry.as(Extensions$1.Configuration)).registerConfiguration({
|
|
31
29
|
...editorConfigurationBaseNode,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
"properties": {
|
|
31
|
+
"editor.snippets.codeActions.enabled": {
|
|
32
|
+
"description": ( localize(
|
|
33
|
+
11321,
|
|
34
|
+
"Controls if surround-with-snippets or file template snippets show as Code Actions."
|
|
37
35
|
)),
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
"type": "boolean",
|
|
37
|
+
"default": true
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
40
|
});
|
|
43
|
-
const languageScopeSchemaId =
|
|
41
|
+
const languageScopeSchemaId = "vscode://schemas/snippets";
|
|
44
42
|
const snippetSchemaProperties = {
|
|
45
43
|
prefix: {
|
|
46
|
-
description: ( localize(
|
|
47
|
-
type: [
|
|
44
|
+
description: ( localize(11322, "The prefix to use when selecting the snippet in intellisense")),
|
|
45
|
+
type: ["string", "array"]
|
|
48
46
|
},
|
|
49
47
|
isFileTemplate: {
|
|
50
|
-
description: ( localize(
|
|
51
|
-
type:
|
|
48
|
+
description: ( localize(11323, "The snippet is meant to populate or replace a whole file")),
|
|
49
|
+
type: "boolean"
|
|
52
50
|
},
|
|
53
51
|
body: {
|
|
54
52
|
markdownDescription: ( localize(
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
11324,
|
|
54
|
+
"The snippet content. Use `$1`, `${1:defaultText}` to define cursor positions, use `$0` for the final cursor position. Insert variable values with `${varName}` and `${varName:defaultText}`, e.g. `This is file: $TM_FILENAME`."
|
|
57
55
|
)),
|
|
58
|
-
type: [
|
|
56
|
+
type: ["string", "array"],
|
|
59
57
|
items: {
|
|
60
|
-
type:
|
|
58
|
+
type: "string"
|
|
61
59
|
}
|
|
62
60
|
},
|
|
63
61
|
description: {
|
|
64
|
-
description: ( localize(
|
|
65
|
-
type: [
|
|
62
|
+
description: ( localize(11325, "The snippet description.")),
|
|
63
|
+
type: ["string", "array"]
|
|
64
|
+
},
|
|
65
|
+
include: {
|
|
66
|
+
markdownDescription: ( localize(
|
|
67
|
+
11326,
|
|
68
|
+
"A list of [glob patterns](https://aka.ms/vscode-glob-patterns) to include the snippet for specific files, e.g. `[\"**/*.test.ts\", \"*.spec.ts\"]` or `\"**/*.spec.ts\"`. Patterns will match on the absolute path of a file if they contain a path separator and will match on the name of the file otherwise. You can exclude matching files via the `exclude` property."
|
|
69
|
+
)),
|
|
70
|
+
type: ["string", "array"],
|
|
71
|
+
items: {
|
|
72
|
+
type: "string"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
exclude: {
|
|
76
|
+
markdownDescription: ( localize(
|
|
77
|
+
11327,
|
|
78
|
+
"A list of [glob patterns](https://aka.ms/vscode-glob-patterns) to exclude the snippet from specific files, e.g. `[\"**/*.min.js\"]` or `\"*.min.js\"`. Patterns will match on the absolute path of a file if they contain a path separator and will match on the name of the file otherwise. Exclude patterns take precedence over `include` patterns."
|
|
79
|
+
)),
|
|
80
|
+
type: ["string", "array"],
|
|
81
|
+
items: {
|
|
82
|
+
type: "string"
|
|
83
|
+
}
|
|
66
84
|
}
|
|
67
85
|
};
|
|
68
86
|
const languageScopeSchema = {
|
|
@@ -70,40 +88,53 @@ const languageScopeSchema = {
|
|
|
70
88
|
allowComments: true,
|
|
71
89
|
allowTrailingCommas: true,
|
|
72
90
|
defaultSnippets: [{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
91
|
+
label: ( localize(11328, "Empty snippet")),
|
|
92
|
+
body: {
|
|
93
|
+
"${1:snippetName}": {
|
|
94
|
+
"prefix": "${2:prefix}",
|
|
95
|
+
"body": "${3:snippet}",
|
|
96
|
+
"description": "${4:description}"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}],
|
|
100
|
+
type: "object",
|
|
101
|
+
description: ( localize(11329, "User snippet configuration")),
|
|
78
102
|
additionalProperties: {
|
|
79
|
-
type:
|
|
80
|
-
required: [
|
|
103
|
+
type: "object",
|
|
104
|
+
required: ["body"],
|
|
81
105
|
properties: snippetSchemaProperties,
|
|
82
106
|
additionalProperties: false
|
|
83
107
|
}
|
|
84
108
|
};
|
|
85
|
-
const globalSchemaId =
|
|
109
|
+
const globalSchemaId = "vscode://schemas/global-snippets";
|
|
86
110
|
const globalSchema = {
|
|
87
111
|
id: globalSchemaId,
|
|
88
112
|
allowComments: true,
|
|
89
113
|
allowTrailingCommas: true,
|
|
90
114
|
defaultSnippets: [{
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
115
|
+
label: ( localize(11328, "Empty snippet")),
|
|
116
|
+
body: {
|
|
117
|
+
"${1:snippetName}": {
|
|
118
|
+
"scope": "${2:scope}",
|
|
119
|
+
"prefix": "${3:prefix}",
|
|
120
|
+
"body": "${4:snippet}",
|
|
121
|
+
"description": "${5:description}"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}],
|
|
125
|
+
type: "object",
|
|
126
|
+
description: ( localize(11329, "User snippet configuration")),
|
|
96
127
|
additionalProperties: {
|
|
97
|
-
type:
|
|
98
|
-
required: [
|
|
128
|
+
type: "object",
|
|
129
|
+
required: ["body"],
|
|
99
130
|
properties: {
|
|
100
131
|
...snippetSchemaProperties,
|
|
101
132
|
scope: {
|
|
102
133
|
description: ( localize(
|
|
103
|
-
|
|
134
|
+
11330,
|
|
104
135
|
"A list of language names to which this snippet applies, e.g. 'typescript,javascript'."
|
|
105
136
|
)),
|
|
106
|
-
type:
|
|
137
|
+
type: "string"
|
|
107
138
|
}
|
|
108
139
|
},
|
|
109
140
|
additionalProperties: false
|