TSynAnySyn: Building Custom Syntax Highlighters in SynEdit TSynAnySyn is a specialized component within the SynEdit package designed to implement dynamic, custom syntax highlighting for any programming language or file format. Available by default in Lazarus and Delphi / C++ Builder environments, it serves as a flexible alternative to hardcoded, language-specific highlighters. Instead of compiling a static highlighter for a specific grammar, TSynAnySyn allows developers to feed in custom keyword lists and token attributes at runtime. Key Capabilities and Built-In Attributes
Unlike standard highlighters like TSynPasSyn (for Pascal) or TSynSQLSyn (for SQL), TSynAnySyn acts as a blank slate. It exposes 13 distinct token attributes that map to common programming constructs:
Identifiers & Keywords: IdentifierAttri, KeyAttri, and VariableAttri. Literals: ConstantAttri, NumberAttri, and StringAttri.
Syntax & Operators: SymbolAttri, DotAttri, ObjectAttri, and PreprocessorAttri. Layout: CommentAttri, SpaceAttri, and EntityAttri.
By binding a TSynAnySyn component to the Highlighter property of a TSynEdit control, text parser states immediately reflect the visual configurations defined within these attributes. Implementing TSynAnySyn: Step-by-Step
Setting up dynamic keywords within an application requires populating the component’s internal KeyWords list. 1. Define the Visual Attributes
First, assign foreground colors or text styles (like bold or italic) to the target attributes during form creation:
procedure TMainForm.FormCreate(Sender: TObject); begin // Set up the color scheme for keywords and comments SynAnySyn1.KeyAttri.Foreground := clBlue; SynAnySyn1.KeyAttri.Style := [fsBold]; SynAnySyn1.CommentAttri.Foreground := clGray; SynAnySyn1.CommentAttri.Style := [fsItalic]; end; Use code with caution. 2. Load Keywords Dynamically
Keywords can be updated programmatically via a TStringList or read straight from a configuration file:
procedure TMainForm.LoadCustomLanguage(const ConfigFilePath: string); var KeywordList: TStringList; begin if not FileExists(ConfigFilePath) then Exit; KeywordList := TStringList.Create; try KeywordList.LoadFromFile(ConfigFilePath); SynAnySyn1.KeyWords.Clear; // TSynAnySyn requires keywords to be upper-case for internal matching SynAnySyn1.KeyWords.Assign(KeywordList); SynAnySyn1.Enabled := True; SynEdit1.Refresh; // Force the editor to redraw with new styles finally KeywordList.Free; end; end; Use code with caution. Practical Use Cases
+——————————————————————-+ | TSynAnySyn | +———————————–+——————————-+ | Use Cases | Limitations | +———————————–+——————————-+ |On-the-fly text matching | * No complex nested grammar | | * Log file highlighting | * Single-character symbols | | * Custom INI/Config file viewing | * Lacks native code folding | | * User-defined scripting engines | * Slower on huge files | +———————————–+——————————-+
While highly effective for simple text patterns, log parsers, or custom configuration views, TSynAnySyn evaluates tokens via a simplified sequential lexer. It struggles with complex multi-line nested grammars or contextual language rules. TSynAnySyn Highlighting – Lazarus Forum – Free Pascal
Leave a Reply