50 lines
2.0 KiB
TypeScript
50 lines
2.0 KiB
TypeScript
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<vscode.TextEdit[]> {
|
|
|
|
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;
|
|
}
|
|
} |