import * as vscode from 'vscode'; import { FormatState } from './formatters/FormatState'; import { IndentationRules } from './formatters/IndentationRules'; import { AlignmentRules } from './formatters/AlignmentRules'; export class TplDocumentFormatter implements vscode.DocumentFormattingEditProvider { private indentRules = new IndentationRules(); private alignRules = new AlignmentRules(); public provideDocumentFormattingEdits( document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken ): vscode.ProviderResult { const edits: vscode.TextEdit[] = []; const state = new FormatState(); // Nutze die VS Code Settings (meist 4 Spaces), andernfalls Fallback state.tabSize = options.tabSize || 4; for (let i = 0; i < document.lineCount; i++) { const originalLine = document.lineAt(i); const rawText = originalLine.text; const trimmedText = rawText.trim(); // Leere Zeilen lassen wir leer if (trimmedText.length === 0) { if (rawText.length > 0) { // Löscht unnötige Whitespaces in eigentlich leeren Zeilen edits.push(vscode.TextEdit.replace(originalLine.range, '')); } continue; } // 1. Basis-Einrückung (if/else/pattern) berechnen let formattedText = this.indentRules.apply(trimmedText, state); // 2. Visual Alignment (Klammern) anwenden & Stack updaten formattedText = this.alignRules.apply(trimmedText, formattedText, state); // 3. Edit nur erstellen, wenn sich die Zeile wirklich ändert (spart Performance & Cursor-Sprünge) if (rawText !== formattedText) { edits.push(vscode.TextEdit.replace(originalLine.range, formattedText)); } } return edits; } }