TextMateLib 1.0
Modern C++ implementation of the TextMate syntax highlighting engine
Loading...
Searching...
No Matches
theme.h
1#ifndef TEXTMATELIB_THEME_H
2#define TEXTMATELIB_THEME_H
3
4#include "types.h"
5#include "utils.h"
6#include <string>
7#include <vector>
8#include <map>
9#include <memory>
10
11namespace tml {
12
13// Forward declarations
14class Theme;
15class ThemeTrieElement;
16class ColorMap;
17
18// IRawTheme interface
19struct IRawThemeSetting {
20 std::string* name;
21 std::vector<std::string>* scope; // Can be single string or array
22 std::string scopeString; // Single scope string
23
24 struct Settings {
25 std::string* fontStyle;
26 std::string* foreground;
27 std::string* background;
28
29 Settings() : fontStyle(nullptr), foreground(nullptr), background(nullptr) {}
30 ~Settings() {
31 delete fontStyle;
32 delete foreground;
33 delete background;
34 }
35 } settings;
36
37 IRawThemeSetting() : name(nullptr), scope(nullptr) {}
38 ~IRawThemeSetting() {
39 delete name;
40 delete scope;
41 }
42};
43
44struct IRawTheme {
45 std::string* name;
46 std::vector<IRawThemeSetting*> settings;
47
48 IRawTheme() : name(nullptr) {}
49 ~IRawTheme() {
50 delete name;
51 for (auto* setting : settings) {
52 delete setting;
53 }
54 }
55};
56
57// ScopeStack class
58class ScopeStack {
59public:
60 ScopeStack* parent;
61 ScopeName scopeName;
62
63 ScopeStack(ScopeStack* parent_, const ScopeName& scopeName_);
64 ~ScopeStack();
65
66 static ScopeStack* push(ScopeStack* path, const std::vector<ScopeName>& scopeNames);
67 static ScopeStack* from(const std::vector<ScopeName>& segments);
68
69 ScopeStack* push(const ScopeName& scopeName);
70 std::vector<ScopeName> getSegments() const;
71 std::string toString() const;
72 bool extends(const ScopeStack* other) const;
73 std::vector<ScopeName>* getExtensionIfDefined(const ScopeStack* base) const;
74};
75
76// StyleAttributes class
77class StyleAttributes {
78public:
79 int fontStyle;
80 int foregroundId;
81 int backgroundId;
82
83 StyleAttributes(int fontStyle_, int foregroundId_, int backgroundId_);
84};
85
86// ParsedThemeRule class
87class ParsedThemeRule {
88public:
89 ScopeName scope;
90 std::vector<ScopeName>* parentScopes;
91 int index;
92 int fontStyle;
93 std::string* foreground;
94 std::string* background;
95
96 ParsedThemeRule(const ScopeName& scope_,
97 std::vector<ScopeName>* parentScopes_,
98 int index_,
99 int fontStyle_,
100 const std::string* foreground_,
101 const std::string* background_);
102 ~ParsedThemeRule();
103};
104
105// Parse theme from raw theme
106std::vector<ParsedThemeRule*> parseTheme(const IRawTheme* source);
107
108// Convert font style to string
109std::string fontStyleToString(int fontStyle);
110
111// ColorMap class
112class ColorMap {
113private:
114 bool _isFrozen;
115 int _lastColorId;
116 std::vector<std::string> _id2color;
117 std::map<std::string, int> _color2id;
118
119public:
120 ColorMap(const std::vector<std::string>* colorMap = nullptr);
121
122 int getId(const std::string* color);
123 std::vector<std::string> getColorMap() const;
124};
125
126// ThemeTrieElementRule class
127class ThemeTrieElementRule {
128public:
129 int scopeDepth;
130 std::vector<ScopeName> parentScopes;
131 int fontStyle;
132 int foreground;
133 int background;
134
135 ThemeTrieElementRule(int scopeDepth_,
136 const std::vector<ScopeName>* parentScopes_,
137 int fontStyle_,
138 int foreground_,
139 int background_);
140
141 ThemeTrieElementRule* clone() const;
142 static std::vector<ThemeTrieElementRule*> cloneArr(const std::vector<ThemeTrieElementRule*>& arr);
143
144 void acceptOverwrite(int scopeDepth_, int fontStyle_, int foreground_, int background_);
145};
146
147// ThemeTrieElement class
148class ThemeTrieElement {
149private:
150 ThemeTrieElementRule* _mainRule;
151 std::vector<ThemeTrieElementRule*> _rulesWithParentScopes;
152 std::map<std::string, ThemeTrieElement*> _children;
153
154public:
155 ThemeTrieElement(ThemeTrieElementRule* mainRule,
156 const std::vector<ThemeTrieElementRule*>& rulesWithParentScopes = std::vector<ThemeTrieElementRule*>());
157 ~ThemeTrieElement();
158
159 std::vector<ThemeTrieElementRule*> match(const ScopeName& scope);
160
161 void insert(int scopeDepth,
162 const std::string& scope,
163 const std::vector<ScopeName>* parentScopes,
164 int fontStyle,
165 int foreground,
166 int background);
167};
168
169// Theme class
170class Theme {
171private:
172 ColorMap* _colorMap;
173 StyleAttributes* _defaults;
174 ThemeTrieElement* _root;
175 CachedFn<ScopeName, std::vector<ThemeTrieElementRule*>>* _cachedMatchRoot;
176
177public:
178 Theme(ColorMap* colorMap, StyleAttributes* defaults, ThemeTrieElement* root);
179 ~Theme();
180
181 static Theme* createFromRawTheme(const IRawTheme* source, const std::vector<std::string>* colorMap = nullptr);
182 static Theme* createFromParsedTheme(const std::vector<ParsedThemeRule*>& source, const std::vector<std::string>* colorMap = nullptr);
183
184 std::vector<std::string> getColorMap() const;
185 StyleAttributes* getDefaults() const;
186 StyleAttributes* match(ScopeStack* scopePath);
187};
188
189// Helper functions
190bool _matchesScope(const ScopeName& scopeName, const ScopeName& scopePattern);
191bool _scopePathMatchesParentScopes(ScopeStack* scopePath, const std::vector<ScopeName>& parentScopes);
192
193// Resolve parsed theme rules
194Theme* resolveParsedThemeRules(std::vector<ParsedThemeRule*>& parsedThemeRules,
195 const std::vector<std::string>* colorMap);
196
197// ============================================================================
198// ManagedTheme Helper Class (for C API implementation)
199// ============================================================================
200
201/**
202 * Helper class to manage theme resources and provide C API implementation
203 *
204 * NOTE: We do NOT delete the Theme object in the destructor because the
205 * Theme class destructor has issues (from the ported C++ implementation).
206 * This is a workaround - the Theme object will leak when disposed, but
207 * this is preferable to hanging. See PHASE1B_FINDINGS.md for details.
208 */
210public:
211 Theme* theme;
212 StyleAttributes* defaults;
213
214 ManagedTheme(Theme* theme_, StyleAttributes* defaults_)
215 : theme(theme_), defaults(defaults_) {}
216
217 ~ManagedTheme() {
218 // NOTE: NOT deleting theme due to Theme destructor hanging issue
219 // Workaround: Theme will be leaked, but this prevents hanging
220 // if (theme) {
221 // delete theme; // DISABLED - causes hang
222 // }
223
224 // Only delete defaults if it's not owned by Theme
225 // (In this case it is, but the workaround is to leak both)
226 // if (defaults) {
227 // delete defaults; // DISABLED - defaults is cleaned up by theme destructor
228 // }
229 }
230};
231
232} // namespace tml
233
234#endif // TEXTMATELIB_THEME_H
Helper class to manage theme resources and provide C API implementation.
Definition theme.h:209
std::string ScopeName
Semantic name identifying a scope (e.g., "source.javascript", "comment.line")
Definition types.h:20
Core type definitions and interfaces for TextMateLib.