#ifndef _CodeEditor_Highlight_h_ #define _CodeEditor_Highlight_h_ #define CTIMING(x) // RTIMING(x) struct HlStyle { Color color; bool bold; bool italic; bool underline; }; struct Isx : Moveable { // '(', '[' position int line; int pos; void Serialize(Stream& s) { s % line % pos; } friend bool operator==(Isx a, Isx b) { return a.line == b.line && a.pos == b.pos; } friend bool operator!=(Isx a, Isx b) { return !(a == b); } }; struct IfState : Moveable { enum { IF = '0', ELIF, ELSE, ELSE_ERROR, ENDIF_ERROR }; WString iftext; short ifline; char state; void Serialize(Stream& s) { s % iftext % ifline % state; } bool operator==(const IfState& b) const { return iftext == b.iftext && state == b.state && ifline == b.ifline; } IfState() { ifline = state = 0; } }; struct HighlightSetup { // Global highlighting settings public: #define HL_COLOR(x, a, b) x, enum { #include "hl_color.i" HL_COUNT }; #undef HL_COLOR static HlStyle hl_style[HL_COUNT]; static byte hilite_scope; static byte hilite_ifdef; static byte hilite_bracket; static bool thousands_separator; static bool indent_spaces; static int indent_amount; static bool no_parenthesis_indent; static const HlStyle& GetHlStyle(int i); static void SetHlStyle(int i, Color c, bool bold = false, bool italic = false, bool underline = false); static void LoadHlStyles(const char *s); static String StoreHlStyles(); static void DefaultHlStyles(); static const char *GetHlName(int i); static bool HasHlFont(int i); }; struct HighlightOutput : HighlightSetup { Vector& v; LineEdit::Highlight def; int pos; public: void SetChar(int pos, int chr) { v[pos].chr = chr; } void Set(int pos, int count, const HlStyle& ink); void SetFlags(int pos, int count, word flags); void SetFont(int pos, int count, const HlStyle& f); void SetPaper(int pos, int count, Color paper); void SetInk(int pos, int count, Color ink); void SetFlags(int count, word flags) { SetFlags(pos, count, flags); } void Put(int count, const HlStyle& ink) { Set(pos, count, ink); pos += count; } void Put(int count, const HlStyle& ink, Color paper); void Put(int count, const HlStyle& ink, const HlStyle& paper); void Put(const HlStyle& ink) { Put(1, ink); } void Put(const HlStyle& ink, word flags) { Put(1, ink); v[pos - 1].flags = flags; } void Flags(word flags) { v[pos - 1].flags = flags; } int GetCount() const { return v.GetCount(); } const wchar *CString(const wchar *p); HighlightOutput(Vector& v); ~HighlightOutput(); }; class EditorSyntax : public HighlightSetup { // Inheriting to make static members available struct SyntaxDef { Event&> factory; String patterns; String description; }; static ArrayMap& defs(); protected: bool ignore_errors; int comments_lang; public: virtual void Clear(); virtual void ScanSyntax(const wchar *ln, const wchar *e, int line, int tab_size); virtual void Serialize(Stream& s); virtual void IndentInsert(CodeEditor& editor, int chr, int count); virtual bool CheckBrackets(CodeEditor& e, int& bpos0, int& bpos); // TODO: Replace with generic mechanism virtual void CheckSyntaxRefresh(CodeEditor& e, int pos, const WString& text); virtual bool CanAssist() const; virtual void Highlight(const wchar *s, const wchar *end, HighlightOutput& hls, CodeEditor *editor, int line, int pos); virtual Vector PickIfStack(); virtual void ReformatComment(CodeEditor& e); virtual ~EditorSyntax(); static Color IfColor(char ifstate); void Set(const String& s) { CTIMING("Set"); if(s.GetCount() == 0) Clear(); else LoadFromString(*this, s); } String Get() { CTIMING("Get"); return StoreAsString(*this); } void IgnoreErrors() { ignore_errors = true; } void SpellCheckComments(int lang) { comments_lang = lang; } EditorSyntax() { Clear(); ignore_errors = false; } static void Register(const char *id, Event&> factory, const char *exts, const char *description); static One Create(const char *id); static String GetSyntaxForFilename(const char *fn); static int GetSyntaxCount() { return defs().GetCount(); } static String GetSyntax(int i) { return defs().GetKey(i); } static String GetSyntaxDescription(int i) { return defs()[i].description; } static String GetSyntaxPatterns(int i) { return defs()[i].patterns; } }; #endif