TextMateLib 1.0
Modern C++ implementation of the TextMate syntax highlighting engine
Loading...
Searching...
No Matches
basicScopesAttributeProvider.cpp
1#include "basicScopesAttributeProvider.h"
2#include <algorithm>
3
4namespace tml {
5
6// Static members initialization
7std::regex BasicScopeAttributesProvider::STANDARD_TOKEN_TYPE_REGEXP("\\b(comment|string|regex|meta\\.embedded)\\b");
8BasicScopeAttributes BasicScopeAttributesProvider::NULL_SCOPE_METADATA(0, OptionalStandardTokenType::Other);
9
10// BasicScopeAttributes implementation
11
12BasicScopeAttributes::BasicScopeAttributes(int languageId_, OptionalStandardTokenType tokenType_)
13 : languageId(languageId_), tokenType(tokenType_) {
14}
15
16// ScopeMatcher implementation
17
18template<typename TValue>
19ScopeMatcher<TValue>::ScopeMatcher(const std::vector<std::pair<std::string, TValue>>& valuesList)
20 : scopesRegExp(nullptr), hasValues(!valuesList.empty()) {
21
22 if (valuesList.empty()) {
23 return;
24 }
25
26 for (const auto& pair : valuesList) {
27 values[pair.first] = pair.second;
28 }
29
30 // Create the regex
31 std::vector<std::string> escapedScopes;
32 for (const auto& pair : valuesList) {
33 escapedScopes.push_back(escapeRegExpCharacters(pair.first));
34 }
35
36 std::sort(escapedScopes.begin(), escapedScopes.end());
37 std::reverse(escapedScopes.begin(), escapedScopes.end()); // Longest scope first
38
39 // Build regex pattern
40 std::string pattern = "^((";
41 for (size_t i = 0; i < escapedScopes.size(); i++) {
42 if (i > 0) pattern += ")|(";
43 pattern += escapedScopes[i];
44 }
45 pattern += "))($|\\.)";
46
47 scopesRegExp = new std::regex(pattern);
48}
49
50template<typename TValue>
51ScopeMatcher<TValue>::~ScopeMatcher() {
52 delete scopesRegExp;
53}
54
55template<typename TValue>
56TValue* ScopeMatcher<TValue>::match(const ScopeName& scope) {
57 if (!scopesRegExp) {
58 return nullptr;
59 }
60
61 std::smatch m;
62 if (!std::regex_search(scope, m, *scopesRegExp)) {
63 return nullptr;
64 }
65
66 std::string matchedScope = m[1].str();
67 auto it = values.find(matchedScope);
68 if (it != values.end()) {
69 return &it->second;
70 }
71
72 return nullptr;
73}
74
75// Explicit template instantiation
76template class ScopeMatcher<int>;
77
78// BasicScopeAttributesProvider implementation
79
80BasicScopeAttributesProvider::BasicScopeAttributesProvider(
81 int initialLanguageId,
82 const EmbeddedLanguagesMap* embeddedLanguages)
83 : _defaultAttributes(initialLanguageId, OptionalStandardTokenType::NotSet) {
84
85 std::vector<std::pair<std::string, int>> embeddedLanguagesList;
86 if (embeddedLanguages) {
87 for (const auto& pair : *embeddedLanguages) {
88 embeddedLanguagesList.push_back(pair);
89 }
90 }
91
92 _embeddedLanguagesMatcher = new ScopeMatcher<int>(embeddedLanguagesList);
93
94 _getBasicScopeAttributesCache = new CachedFn<ScopeName, BasicScopeAttributes>(
95 [this](const ScopeName& scopeName) {
96 int languageId = this->_scopeToLanguage(scopeName);
97 OptionalStandardTokenType standardTokenType = this->_toStandardTokenType(scopeName);
98 return BasicScopeAttributes(languageId, standardTokenType);
99 }
100 );
101}
102
103BasicScopeAttributesProvider::~BasicScopeAttributesProvider() {
104 delete _embeddedLanguagesMatcher;
105 delete _getBasicScopeAttributesCache;
106}
107
108BasicScopeAttributes BasicScopeAttributesProvider::getDefaultAttributes() const {
109 return _defaultAttributes;
110}
111
112BasicScopeAttributes BasicScopeAttributesProvider::getBasicScopeAttributes(const ScopeName* scopeName) {
113 if (scopeName == nullptr) {
114 return NULL_SCOPE_METADATA;
115 }
116 return _getBasicScopeAttributesCache->get(*scopeName);
117}
118
119int BasicScopeAttributesProvider::_scopeToLanguage(const ScopeName& scope) {
120 int* languageId = _embeddedLanguagesMatcher->match(scope);
121 return languageId ? *languageId : 0;
122}
123
124OptionalStandardTokenType BasicScopeAttributesProvider::_toStandardTokenType(const ScopeName& scopeName) {
125 std::smatch m;
126 if (!std::regex_search(scopeName, m, STANDARD_TOKEN_TYPE_REGEXP)) {
127 return OptionalStandardTokenType::NotSet;
128 }
129
130 std::string matchedType = m[1].str();
131 if (matchedType == "comment") {
132 return OptionalStandardTokenType::Comment;
133 } else if (matchedType == "string") {
134 return OptionalStandardTokenType::String;
135 } else if (matchedType == "regex") {
136 return OptionalStandardTokenType::RegEx;
137 } else if (matchedType == "meta.embedded") {
138 return OptionalStandardTokenType::Other;
139 }
140
141 return OptionalStandardTokenType::NotSet;
142}
143
144} // namespace tml
OptionalStandardTokenType
Standard token type with optional (unknown) state.
Definition types.h:145
@ Other
Not a recognized standard type.
@ NotSet
Type not determined or not applicable.