Update package version to 0.0.8, add new configuration options for templates path, file overwrite behavior, input mode, and language selection. Remove old .vsix files and update README for improved usage instructions.

This commit is contained in:
S.Gromov
2025-07-15 09:22:48 +03:00
parent bcb2c381fb
commit 0842268f28
14 changed files with 82 additions and 58 deletions

2
.gitignore vendored
View File

@@ -130,3 +130,5 @@ dist
.pnp.*
.DS_Store
*.vsix

View File

@@ -13,14 +13,14 @@
![Logo](https://raw.githubusercontent.com/gormov1122/MyTemplateGenerator/main/src/images/3.png)
**How to use:**
1. Create a folder with templates (default: `templates`).
1. Create a folder with templates (default: `.templates`).
2. Use variables in templates: `{{name}}`, `{{name.pascalCase}}`, etc.
3. Right-click any folder in your project → **Create from template...**
4. Select a template, fill in variables — the structure is generated automatically.
**Example template:**
```
templates/
.templates/
component/
{{name}}/
index.tsx
@@ -62,10 +62,12 @@ This extension works with **any framework** — you define your own templates fo
Just create a template for your favorite stack — and generate any structure you want! 🎉
**Configuration:**
All settings via `mycodegenerate.json` in the project root or the visual configurator.
All settings are managed via the standard VSCode user settings (or the visual configurator).
To open the settings menu, press <kbd>Ctrl</kbd>+<kbd>P</kbd>, type `Configure myTemplateGenerator...` and select the menu item.
You can also find all options in VSCode settings under `myTemplateGenerator`.
# MyTemplateGenerator (русский)
@@ -80,14 +82,14 @@ To open the settings menu, press <kbd>Ctrl</kbd>+<kbd>P</kbd>, type `Configure m
![Logo](https://raw.githubusercontent.com/gormov1122/MyTemplateGenerator/main/src/images/3.png)
**Как использовать:**
1. Создайте папку с шаблонами (по умолчанию `templates`).
1. Создайте папку с шаблонами (по умолчанию `.templates`).
2. Используйте переменные в шаблонах: `{{name}}`, `{{name.pascalCase}}` и т.д.
3. Кликните правой кнопкой по папке в проекте → **Создать из шаблона...**
4. Выберите шаблон, заполните переменные — структура будет создана автоматически.
**Пример шаблона:**
```
templates/
.templates/
component/
{{name}}/
index.tsx
@@ -129,6 +131,8 @@ templates/
Создайте шаблон под свой стек — и генерируйте любые структуры! 🎉
**Настройка:**
Всё настраивается через файл `mycodegenerate.json` в корне проекта или визуальный конфигуратор.
Все параметры задаются через стандартные пользовательские настройки VSCode (или визуальный конфигуратор).
Чтобы открыть меню настроек, нажмите <kbd>Ctrl</kbd>+<kbd>P</kbd>, введите `Настроить myTemplateGenerator...` (или `Configure myTemplateGenerator...` для английского интерфейса) и выберите соответствующий пункт.
Также вы можете найти все параметры в настройках VSCode по ключу `myTemplateGenerator`.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,7 +2,7 @@
"name": "mytemplategenerator",
"displayName": "myTemplateGenerator",
"description": "Generate files and folders from customizable templates with variable substitution in VSCode.",
"version": "0.0.7",
"version": "0.0.8",
"publisher": "MyTemplateGenerator",
"author": "Sergey Gromov",
"icon": "logo.png",
@@ -41,6 +41,41 @@
}
]
},
"configuration": {
"title": "myTemplateGenerator",
"properties": {
"myTemplateGenerator.templatesPath": {
"type": "string",
"default": ".templates",
"description": "%mytemplategenerator.config.templatesPath.description%",
"markdownDescription": "%mytemplategenerator.config.templatesPath.description%",
"scope": "application"
},
"myTemplateGenerator.overwriteFiles": {
"type": "boolean",
"default": false,
"description": "%mytemplategenerator.config.overwriteFiles.description%",
"markdownDescription": "%mytemplategenerator.config.overwriteFiles.description%",
"scope": "application"
},
"myTemplateGenerator.inputMode": {
"type": "string",
"enum": ["webview", "inputBox"],
"default": "webview",
"description": "%mytemplategenerator.config.inputMode.description%",
"markdownDescription": "%mytemplategenerator.config.inputMode.description%",
"scope": "application"
},
"myTemplateGenerator.language": {
"type": "string",
"enum": ["ru", "en"],
"default": "en",
"description": "%mytemplategenerator.config.language.description%",
"markdownDescription": "%mytemplategenerator.config.language.description%",
"scope": "application"
}
}
},
"semanticTokenColors": [
{
"token": "bracket",

View File

@@ -1,4 +1,8 @@
{
"mytemplategenerator.createFromTemplate.title": "Create from template...",
"mytemplategenerator.configure.title": "Configure myTemplateGenerator..."
"mytemplategenerator.configure.title": "Configure myTemplateGenerator...",
"mytemplategenerator.config.templatesPath.description": "Path to the templates folder (relative to the project root)",
"mytemplategenerator.config.overwriteFiles.description": "Overwrite existing files when generating from template",
"mytemplategenerator.config.inputMode.description": "Variable input mode: webview or inputBox",
"mytemplategenerator.config.language.description": "Extension interface language"
}

View File

@@ -1,4 +1,8 @@
{
"mytemplategenerator.createFromTemplate.title": "Создать из шаблона...",
"mytemplategenerator.configure.title": "Настроить myTemplateGenerator..."
"mytemplategenerator.configure.title": "Настроить myTemplateGenerator...",
"mytemplategenerator.config.templatesPath.description": "Путь к папке с шаблонами (относительно корня проекта)",
"mytemplategenerator.config.overwriteFiles.description": "Перезаписывать ли существующие файлы при генерации",
"mytemplategenerator.config.inputMode.description": "Режим ввода переменных: webview или inputBox",
"mytemplategenerator.config.language.description": "Язык интерфейса расширения"
}

View File

@@ -10,29 +10,28 @@ export interface MyTemplateGeneratorConfig {
language?: string;
}
export function getConfigPath(): string | undefined {
const folders = vscode.workspace.workspaceFolders;
if (!folders || folders.length === 0) return undefined;
return path.join(folders[0].uri.fsPath, 'mycodegenerate.json');
}
export function readConfig(): MyTemplateGeneratorConfig {
const configPath = getConfigPath();
if (configPath && fs.existsSync(configPath)) {
const raw = fs.readFileSync(configPath, 'utf8');
return JSON.parse(raw);
}
// Значения по умолчанию
const config = vscode.workspace.getConfiguration('myTemplateGenerator');
return {
templatesPath: 'templates',
overwriteFiles: false,
inputMode: 'inputBox',
language: 'en',
templatesPath: config.get<string>('templatesPath', '.templates'),
overwriteFiles: config.get<boolean>('overwriteFiles', false),
inputMode: config.get<'webview' | 'inputBox'>('inputMode', 'webview'),
language: config.get<string>('language', 'en'),
};
}
export function writeConfig(config: MyTemplateGeneratorConfig) {
const configPath = getConfigPath();
if (!configPath) return;
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
export async function writeConfig(newConfig: Partial<MyTemplateGeneratorConfig>) {
const config = vscode.workspace.getConfiguration('myTemplateGenerator');
if (newConfig.templatesPath !== undefined) {
await config.update('templatesPath', newConfig.templatesPath, vscode.ConfigurationTarget.Global);
}
if (newConfig.overwriteFiles !== undefined) {
await config.update('overwriteFiles', newConfig.overwriteFiles, vscode.ConfigurationTarget.Global);
}
if (newConfig.inputMode !== undefined) {
await config.update('inputMode', newConfig.inputMode, vscode.ConfigurationTarget.Global);
}
if (newConfig.language !== undefined) {
await config.update('language', newConfig.language, vscode.ConfigurationTarget.Global);
}
}

View File

@@ -41,7 +41,6 @@ export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "mytemplategenerator" is now active!');
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
@@ -56,25 +55,20 @@ export function activate(context: vscode.ExtensionContext) {
const config = readConfig();
const dict = I18N_DICTIONARIES[config.language || 'ru'] || I18N_DICTIONARIES['ru'];
const workspaceFolders = vscode.workspace.workspaceFolders;
console.log('[DEBUG] Запуск команды createFromTemplate');
if (!workspaceFolders || workspaceFolders.length === 0) {
vscode.window.showErrorMessage(dict.noFolders);
console.log('[DEBUG] Нет открытых папок рабочего пространства');
return;
}
const templatesDir = path.join(workspaceFolders[0].uri.fsPath, config.templatesPath);
if (!fs.existsSync(templatesDir) || !fs.statSync(templatesDir).isDirectory()) {
vscode.window.showErrorMessage(`${dict.templatesNotFound} ${templatesDir}`);
console.log('[DEBUG] Папка шаблонов не найдена:', templatesDir);
return;
}
let template: string | undefined;
let userVars: Record<string, string> | undefined;
if (config.inputMode === 'webview') {
vscode.window.showInformationMessage('[DEBUG] Вызов webview создания шаблона...');
console.log('[DEBUG] Вызов showTemplateAndVarsWebview', { templatesDir, uri: uri.fsPath, lang: config.language });
const result: { template: string, vars: Record<string, string> } | undefined = await showTemplateAndVarsWebview(context, templatesDir, uri.fsPath, config.language || 'ru');
console.log('[DEBUG] Результат showTemplateAndVarsWebview:', result);
if (!result) {
vscode.window.showInformationMessage('[DEBUG] Webview был закрыт или не вернул результат');
return;
@@ -104,7 +98,6 @@ export function activate(context: vscode.ExtensionContext) {
copyTemplateWithVars(templateDir, uri.fsPath, vars, config.overwriteFiles, dict, template);
} catch (e: any) {
vscode.window.showErrorMessage(`${dict.createError}: ${e.message}`);
console.log('[DEBUG] Ошибка при копировании шаблона:', e);
}
});
@@ -121,22 +114,7 @@ export function activate(context: vscode.ExtensionContext) {
clearDiagnosticsForTemplates(context); // <--- Очищаем diagnostics для шаблонов
// === Отслеживание изменений конфига ===
const workspaceFolders = vscode.workspace.workspaceFolders;
if (workspaceFolders && workspaceFolders.length > 0) {
const configPath = path.join(workspaceFolders[0].uri.fsPath, 'mycodegenerate.json');
if (fs.existsSync(configPath)) {
fs.watch(configPath, { persistent: false }, (eventType) => {
if (eventType === 'change' || eventType === 'rename') {
// Перерегистрируем провайдер подсветки
if (semanticHighlightDisposable) {
semanticHighlightDisposable.dispose();
}
semanticHighlightDisposable = registerTemplateSemanticHighlight(context);
console.log('[DEBUG] Провайдер семантической подсветки перерегистрирован после изменения конфига');
}
});
}
}
// (Удалено: теперь все настройки глобальные через VSCode settings)
}
// This method is called when your extension is deactivated

View File

@@ -20,8 +20,6 @@ export function registerTemplateSemanticHighlight(context: vscode.ExtensionConte
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!workspaceFolders || workspaceFolders.length === 0) return;
const templatesDir = path.join(workspaceFolders[0].uri.fsPath, templatesPath);
console.log('[DEBUG] semantic tokens called for', document.uri.fsPath);
console.log('[DEBUG] Проверка шаблонной папки:', document.uri.fsPath, templatesDir, isInTemplatesDir(document.uri.fsPath, templatesDir));
// Проверяем, что файл в папке шаблонов
if (!isInTemplatesDir(document.uri.fsPath, templatesDir)) {
return;

View File

@@ -120,16 +120,16 @@ export async function showConfigWebview(context: vscode.ExtensionContext) {
}
panel.webview.onDidReceiveMessage(
msg => {
async msg => {
if (msg.type === 'save') {
writeConfig(msg.data);
await writeConfig(msg.data);
vscode.window.showInformationMessage('Настройки сохранены!');
panel.dispose();
}
if (msg.type === 'setLanguage') {
// Сохраняем язык в конфиг и перерисовываем webview
config.language = msg.language;
writeConfig(config);
await writeConfig(config);
setHtml(msg.language === 'en' ? 'en' : 'ru');
}
},

View File

@@ -156,7 +156,7 @@ export async function showTemplateAndVarsWebview(
if (message.language) language = message.language;
// Сохраняем язык в конфиг
const oldConfig = readConfig();
writeConfig({ ...oldConfig, language });
await writeConfig({ ...oldConfig, language });
currentTemplate = message.template || templates[0] || '';
// Получаем переменные для выбранного шаблона
let baseVars: string[] = [];