Files
vscode-template-file-generator/src/vscode/decorations.ts

109 lines
4.5 KiB
TypeScript
Raw Normal View History

// Декорации и диагностика шаблонов
import * as vscode from 'vscode';
import * as path from 'path';
import { getAllTemplateVariables } from '../core/templateUtils';
import { readConfig } from '../core/config';
const bracketDecoration = vscode.window.createTextEditorDecorationType({
color: '#43A047', // зелёный для скобок
rangeBehavior: vscode.DecorationRangeBehavior.ClosedClosed,
fontWeight: 'bold'
});
const variableDecoration = vscode.window.createTextEditorDecorationType({
color: '#FF9800', // оранжевый для имени переменной
rangeBehavior: vscode.DecorationRangeBehavior.ClosedClosed,
fontWeight: 'bold'
});
const modifierDecoration = vscode.window.createTextEditorDecorationType({
color: '#00ACC1', // бирюзовый для модификатора
rangeBehavior: vscode.DecorationRangeBehavior.ClosedClosed,
fontWeight: 'bold'
});
function isInTemplatesDir(filePath: string, templatesDir: string): boolean {
const rel = path.relative(templatesDir, filePath);
return !rel.startsWith('..') && !path.isAbsolute(rel);
}
function updateTemplateDecorations(editor: vscode.TextEditor) {
if (!editor) return;
const config = readConfig();
const templatesPath = config.templatesPath || 'templates';
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!workspaceFolders || workspaceFolders.length === 0) return;
const templatesDir = path.join(workspaceFolders[0].uri.fsPath, templatesPath);
if (!isInTemplatesDir(editor.document.uri.fsPath, templatesDir)) return;
const brackets: vscode.DecorationOptions[] = [];
const variables: vscode.DecorationOptions[] = [];
const modifiers: vscode.DecorationOptions[] = [];
for (let lineNum = 0; lineNum < editor.document.lineCount; lineNum++) {
const line = editor.document.lineAt(lineNum).text;
// Ищем все {{variable.modifier}} или {{variable}}
const reg = /{{\s*([a-zA-Z0-9_]+)(?:\.([a-zA-Z0-9_]+))?\s*}}/g;
let match;
while ((match = reg.exec(line)) !== null) {
const start = match.index;
const end = start + match[0].length;
// Скобки {{ и }}
brackets.push({
range: new vscode.Range(lineNum, start, lineNum, start + 2)
});
brackets.push({
range: new vscode.Range(lineNum, end - 2, lineNum, end)
});
// Имя переменной
const varStart = start + 2 + line.slice(start + 2).search(/\S/); // после {{
variables.push({
range: new vscode.Range(lineNum, varStart, lineNum, varStart + match[1].length)
});
// Модификатор (если есть)
if (match[2]) {
const modStart = varStart + match[1].length + 1; // +1 за точку
modifiers.push({
range: new vscode.Range(lineNum, modStart, lineNum, modStart + match[2].length)
});
}
}
}
editor.setDecorations(bracketDecoration, brackets);
editor.setDecorations(variableDecoration, variables);
editor.setDecorations(modifierDecoration, modifiers);
}
export function registerTemplateDecorations(context: vscode.ExtensionContext) {
function decorateActiveEditor() {
const editor = vscode.window.activeTextEditor;
if (editor) {
updateTemplateDecorations(editor);
}
}
context.subscriptions.push(
vscode.window.onDidChangeActiveTextEditor(editor => {
if (editor) decorateActiveEditor();
}),
vscode.workspace.onDidChangeTextDocument(event => {
const editor = vscode.window.visibleTextEditors.find(e => e.document === event.document);
if (editor) updateTemplateDecorations(editor);
})
);
// Инициализация при активации
setTimeout(() => {
vscode.window.visibleTextEditors.forEach(editor => updateTemplateDecorations(editor));
}, 300);
}
export function decorateActiveEditor() {
// Логика декорирования активного редактора
// ...
}
export function clearDiagnosticsForEditor(editor: vscode.TextEditor, templatesDir: string) {
// Очистка диагностик для редактора
// ...
}
export function clearDiagnosticsForTemplates(context: vscode.ExtensionContext) {
// Очистка диагностик для всех шаблонов
// ...
}