SyntaxRichEdit
RichEdit with live syntax highlighting
- Active · last change 9-5-2026
- ★ 1 on GitHub
README
# SyntaxRichEdit für Delphi VCL
Eine eigenständige VCL-Komponente für syntaxformatierte Plaintext-Bearbeitung im TRichEdit. Der Quelltext bleibt unverändert; die Komponente verwendet RichEdit-Zeichen- und Absatzformate ausschließlich als Darstellungsschicht.

Enthalten
TSyntaxRichEditmit zeitverzögerter, kooperativ unterbrechbarer Verarbeitung- Textrevisionen, lokalisierte Änderungsbereiche, inkrementelle Checkpoints und Resynchronisation
- Segmenthash-Fallback und optionale versteckte Checkpoint-IDs über
CHARFORMAT2.dwCookie - flackerfreie Rendertransaktionen mit stabiler Auswahl und Scrollposition
- nur-Text-Einfügen, -Kopieren und -Ausschneiden
- austauschbare Parser für Markdown, Delphi/Object Pascal, JSON, XML und INI
- dieselben Sprachparser eigenständig oder eingebettet in Markdown-Code-Fences
- Zeichen- und Absatzformatierung, Diagnosen und Debug-Ausgabe
- codebasierte VCL-Demo ohne DFM-Abhängigkeit
- Konsolentests für zentrale Parserregeln
Unterstützte Markdown-Darstellung
- ATX- und Setext-Überschriften
- Fett, Kursiv, Durchstreichen
- Inline-Code und fenced Codeblöcke
- graue Fence-Sprachkennung, z. B.
delphi,json,xml,ini - Links und einzelne URLs
- ungeordnete Listen mit
-,+,* - geordnete/erweiterte Listen mit
1.,1),a),A)und#. - Aufgabenlisten
[ ]und[x] - Zitate mit
> - Inline- und Blockformeln mit
$...$und$$...$$ - Hochstellung
^...^und Tiefstellung~...~ - horizontale Linien aus mindestens drei
-oder*, optional getrennt durch Leerraum - Tabellen-Grunddarstellung mit hervorgehobener Kopf- und Trennzeile
- YAML-ähnliche Präambel am Dokumentanfang; gesamter Block grau, Schlüssel bis
:fett - Hinweise/Fehler für nicht geschlossene Konstrukte
Die Markdown-Steuerzeichen werden getrennt vom Inhalt ausgezeichnet. Sie bleiben sichtbar, erscheinen aber gedämpft. So ist erkennbar, dass die Syntax erkannt wurde und in einer späteren gerenderten Ausgabe nicht zum sichtbaren Inhalt gehören würde.
Verzeichnisstruktur
Source/
SyntaxEdit.Types.pas
SyntaxEdit.Parser.Intf.pas
SyntaxEdit.Parser.Registry.pas
SyntaxEdit.Parser.Markdown.pas
SyntaxEdit.Parser.Delphi.pas
SyntaxEdit.Parser.Json.pas
SyntaxEdit.Parser.Xml.pas
SyntaxEdit.Parser.Ini.pas
SyntaxEdit.DefaultParsers.pas
SyntaxEdit.Theme.pas
SyntaxEdit.RichEdit.pas
Demo/
SyntaxRichEditDemo.dpr
FormMain.pas
Tests/
SyntaxParserTests.dpr
Docs/
ARCHITECTURE.md
BUILD.md
STATIC_AUDIT.txt
FIX_NOTES.md
INCREMENTAL_RENDER_TEST.mdSchnellstart
- In Delphi ein VCL-Projekt öffnen oder
Demo/SyntaxRichEditDemo.dprladen. Sourcedem Suchpfad hinzufügen.- Das Projekt für Windows kompilieren.
- Alternativ die Komponente zur Laufzeit erzeugen:
uses
SyntaxEdit.DefaultParsers,
SyntaxEdit.RichEdit;
procedure TMainForm.FormCreate(Sender: TObject);
begin
RegisterDefaultSyntaxParsers;
FEditor := TSyntaxRichEdit.Create(Self);
FEditor.Parent := Self;
FEditor.Align := alClient;
FEditor.ParserId := 'markdown';
end;Eigenständige Sprachdarstellung:
FEditor.ParserId := 'delphi';
FEditor.ParserId := 'json';
FEditor.ParserId := 'xml';
FEditor.ParserId := 'ini';Debug-Ausgabe
if not Memo1.Focused and (Memo1.Text <> FEditor.DebugText) then
Memo1.Text := FEditor.DebugText;
Label1.Caption := FEditor.DebugInfo.Summary;Bei periodisch aktualisierten Debug-Memos sollte die Zuweisung ausgesetzt werden, solange das Memo fokussiert ist. Andernfalls geht eine Textmarkierung beim nächsten Timerlauf verloren. Die Demo verwendet dafür UpdateMemoText für Debug-, Diagnose- und Checkpoint-Ausgabe.
Auch Parserzustände, Checkpoints und Diagnosen besitzen eine lesbare ToString-Darstellung.
Zeitsteuerung
Die Verarbeitung verwendet kein Application.ProcessMessages. Stattdessen verarbeitet die Komponente kurze Scheiben und verlässt danach vollständig den Aufruf. Ein Timer setzt die Arbeit später fort. Jede Textänderung erhöht die Dokumentrevision; Ergebnisse einer älteren Revision werden nicht mehr übernommen.
Typische Startwerte:
Editor.ParseDelayMs := 150;
Editor.ParseSliceBudgetMs := 5;
Editor.RenderSliceBudgetMs := 3;Bei Änderungen wird ab dem vorherigen gültigen Checkpoint neu analysiert. Die sichtbare Neuformatierung beginnt davon unabhängig nur eine logische Zeile vor der tatsächlich geänderten Zeile, damit rückwirkende Markdown-Konstrukte korrekt erfasst werden. Sobald an einem unveränderten Folgemarker derselbe Parserzustand erreicht wird, resynchronisiert sich der Parser und beendet den Neulauf. Ein geöffneter oder entfernter Fence lässt die Verarbeitung daher genau so weit laufen, wie sich seine semantische Wirkung erstreckt.
Mehrere Render-Scheiben bilden eine gemeinsame Bildschirmtransaktion. Die bisher vollständig formatierte Darstellung bleibt sichtbar, bis Zeichen-, Absatz- und Diagnoseformate gemeinsam bereitstehen. Auswahl und Scrollposition werden nach jeder internen Scheibe wiederhergestellt; erst am Ende erfolgt ein einzelnes Neuzeichnen.
Wichtige Grenzen dieser ersten Arbeitsversion
- Die Scheibenbildung erfolgt derzeit an logischen Zeilengrenzen. Eine einzelne extrem lange, minifizierte Zeile kann daher länger als das konfigurierte Zeitbudget benötigen. Die Parserzustände sind für eine spätere Unterbrechung innerhalb einer Zeile vorbereitet, der Scheduler teilt solche Zeilen aber noch nicht auf.
- Die Komponente bewahrt
Modified, Auswahl und Scrollposition und unterdrückt sichtbare Zwischenzustände während der Formatierung. Eine zusätzliche TOM-basierte Suspendierung der Undo-Historie ist als nächste Härtungsstufe sinnvoll, falls die konkret eingesetzte RichEdit-Version reine Formatänderungen in den Undo-Stack aufnimmt. - Die Delphi-Auszeichnung ist ein Lexer mit strukturellen Diagnosen, kein Ersatz für den Delphi-Compiler oder DelphiLSP.
- Markdown-Tabellen werden visuell ausgezeichnet, aber nicht als echte Tabellen gerendert. Bilder bleiben Textsyntax.
- Absatzrahmen sind bewusst zurückhaltend umgesetzt; die Markierungen und Einzüge funktionieren unabhängig vom genauen RichEdit-Build.
Zielplattform
Die Implementierung verwendet VCL- und Win32-RichEdit-APIs und ist für moderne Delphi-Windows-Versionen gedacht. In dieser Linux-Ausführungsumgebung stand kein Delphi-Windows-Compiler zur Verfügung; deshalb wurde eine statische Plausibilitätsprüfung durchgeführt, aber kein echter Delphi-Build erzeugt. Siehe Docs/STATIC_AUDIT.txt.

