Welcome to mirror list, hosted at ThFree Co, Russian Federation.

emptyFileSnippets.ts « commands « browser « snippets « contrib « workbench « vs « src - github.com/microsoft/vscode.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 963c92e60cb7b62f542591e61285236dac33731e (plain)
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
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import { groupBy, isFalsyOrEmpty } from 'vs/base/common/arrays';
import { compare } from 'vs/base/common/strings';
import { getCodeEditor } from 'vs/editor/browser/editorBrowser';
import { ILanguageService } from 'vs/editor/common/languages/language';
import { SnippetController2 } from 'vs/editor/contrib/snippet/browser/snippetController2';
import { localize } from 'vs/nls';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
import { SnippetsAction } from 'vs/workbench/contrib/snippets/browser/commands/abstractSnippetsActions';
import { ISnippetsService } from 'vs/workbench/contrib/snippets/browser/snippets';
import { Snippet } from 'vs/workbench/contrib/snippets/browser/snippetsFile';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';

export class SelectSnippetForEmptyFile extends SnippetsAction {

	static readonly Id = 'workbench.action.populateFromSnippet';

	constructor() {
		super({
			id: SelectSnippetForEmptyFile.Id,
			title: {
				value: localize('label', 'Populate from Snippet'),
				original: 'Populate from Snippet'
			},
			f1: true,
		});
	}

	async run(accessor: ServicesAccessor): Promise<void> {
		const snippetService = accessor.get(ISnippetsService);
		const quickInputService = accessor.get(IQuickInputService);
		const editorService = accessor.get(IEditorService);
		const langService = accessor.get(ILanguageService);

		const editor = getCodeEditor(editorService.activeTextEditorControl);
		if (!editor || !editor.hasModel()) {
			return;
		}

		const snippets = await snippetService.getSnippets(undefined, { topLevelSnippets: true, noRecencySort: true, includeNoPrefixSnippets: true });
		if (snippets.length === 0) {
			return;
		}

		const selection = await this._pick(quickInputService, langService, snippets);
		if (!selection) {
			return;
		}

		if (editor.hasModel()) {
			// apply snippet edit -> replaces everything
			SnippetController2.get(editor)?.apply([{
				range: editor.getModel().getFullModelRange(),
				template: selection.snippet.body
			}]);

			// set language if possible
			if (langService.isRegisteredLanguageId(selection.langId)) {
				editor.getModel().setMode(selection.langId);
			}
		}
	}

	private async _pick(quickInputService: IQuickInputService, langService: ILanguageService, snippets: Snippet[]) {

		// spread snippet onto each language it supports
		type SnippetAndLanguage = { langId: string; snippet: Snippet };
		const all: SnippetAndLanguage[] = [];
		for (const snippet of snippets) {
			if (isFalsyOrEmpty(snippet.scopes)) {
				all.push({ langId: '', snippet });
			} else {
				for (const langId of snippet.scopes) {
					all.push({ langId, snippet });
				}
			}
		}

		type SnippetAndLanguagePick = IQuickPickItem & { snippet: SnippetAndLanguage };
		const picks: (SnippetAndLanguagePick | IQuickPickSeparator)[] = [];

		const groups = groupBy(all, (a, b) => compare(a.langId, b.langId));

		for (const group of groups) {
			let first = true;
			for (const item of group) {

				if (first) {
					picks.push({
						type: 'separator',
						label: langService.getLanguageName(item.langId) ?? item.langId
					});
					first = false;
				}

				picks.push({
					snippet: item,
					label: item.snippet.prefix || item.snippet.name,
					detail: item.snippet.description
				});
			}
		}

		const pick = await quickInputService.pick(picks, {
			placeHolder: localize('placeholder', 'Select a snippet'),
			matchOnDetail: true,
		});

		return pick?.snippet;
	}
}