40 lines
1.7 KiB
TypeScript
40 lines
1.7 KiB
TypeScript
|
|
import * as vscode from 'vscode';
|
||
|
|
|
||
|
|
export class TplDocumentFormatter implements vscode.DocumentFormattingEditProvider {
|
||
|
|
provideDocumentFormattingEdits(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken): vscode.ProviderResult<vscode.TextEdit[]> {
|
||
|
|
const edits: vscode.TextEdit[] = [];
|
||
|
|
const lines = document.getText().split('\n');
|
||
|
|
|
||
|
|
let indentLevel = 0;
|
||
|
|
// Zwingt den Formatter strikt zu 3 Spaces (ignoriert VS Code Settings)
|
||
|
|
const indentString = ' ';
|
||
|
|
|
||
|
|
for (let i = 0; i < lines.length; i++) {
|
||
|
|
let line = lines[i].trim();
|
||
|
|
if (line.length === 0) { continue; }
|
||
|
|
|
||
|
|
// 1. Wenn die Zeile einen Block schließt, VORHER die Einrückung verringern
|
||
|
|
if (line.match(/^(end\s+(pattern|table|if|for|while)|else|elif)\b/)) {
|
||
|
|
indentLevel = Math.max(0, indentLevel - 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. Die Zeile neu aufbauen (korrekte Einrückung + getrimmter Text)
|
||
|
|
const newLineText = indentString.repeat(indentLevel) + line;
|
||
|
|
|
||
|
|
// 3. Nur wenn sich was geändert hat, ein Edit erzeugen
|
||
|
|
if (lines[i] !== newLineText && lines[i] !== newLineText + '\r') {
|
||
|
|
const range = new vscode.Range(i, 0, i, lines[i].length);
|
||
|
|
edits.push(vscode.TextEdit.replace(range, newLineText));
|
||
|
|
}
|
||
|
|
|
||
|
|
// 4. Wenn die Zeile einen Block öffnet, NACHHER die Einrückung erhöhen
|
||
|
|
if (line.match(/^(pattern|table|metadata|overview|constants|triggers|body|if|for|while|else|elif)\b/)) {
|
||
|
|
if (!line.startsWith('end ')) {
|
||
|
|
indentLevel++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return edits;
|
||
|
|
}
|
||
|
|
}
|