Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works
Anything · Lazarus or Delphi
Random projectRandom project

SyntaxRichEdit

RichEdit with live syntax highlighting

View on GitHub

Member rating

No ratings yet.

Sign in to rate this project.

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.

Screenshot|50%

Enthalten

  • TSyntaxRichEdit mit 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

text
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.md

Schnellstart

  1. In Delphi ein VCL-Projekt öffnen oder Demo/SyntaxRichEditDemo.dpr laden.
  2. Source dem Suchpfad hinzufügen.
  3. Das Projekt für Windows kompilieren.
  4. Alternativ die Komponente zur Laufzeit erzeugen:
delphi
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:

delphi
FEditor.ParserId := 'delphi';
FEditor.ParserId := 'json';
FEditor.ParserId := 'xml';
FEditor.ParserId := 'ini';

Debug-Ausgabe

delphi
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:

delphi
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.