1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#include "generate_textmate.h"
#include "json.h"
#include <library/cpp/json/json_value.h>
#include <util/string/builder.h>
#include <util/string/cast.h>
namespace NSQLHighlight {
namespace {
TString ToTextMateRegex(const TUnit& unit, const NSQLTranslationV1::TRegexPattern& pattern) {
TStringBuilder regex;
if (pattern.IsCaseInsensitive) {
regex << "(?i)";
}
if (unit.IsPlain) {
regex << R"re(\b)re";
}
regex << "(" << pattern.Body << ")";
if (!pattern.After.empty()) {
regex << "(?=" << pattern.After << ")";
}
if (unit.IsPlain) {
regex << R"re(\b)re";
}
return regex;
}
TStringBuf ToTextMateGroup(EUnitKind kind) {
switch (kind) {
case EUnitKind::Keyword:
return "keyword.control";
case EUnitKind::Punctuation:
return "keyword.operator";
case EUnitKind::QuotedIdentifier:
return "string.interpolated";
case EUnitKind::BindParameterIdentifier:
return "variable.parameter";
case EUnitKind::TypeIdentifier:
return "entity.name.type";
case EUnitKind::FunctionIdentifier:
return "entity.name.function";
case EUnitKind::Identifier:
return "variable.other";
case EUnitKind::Literal:
return "constant.numeric";
case EUnitKind::StringLiteral:
return "string.quoted.double";
case EUnitKind::Comment:
return "comment.block";
case EUnitKind::Whitespace:
return "";
case EUnitKind::Error:
return "";
}
}
TMaybe<NJson::TJsonMap> TextMateMultilinePattern(const TUnit& unit) {
auto range = unit.RangePattern;
if (!range) {
return Nothing();
}
return NJson::TJsonMap({
{"begin", range->Begin},
{"end", range->End},
{"name", ToTextMateGroup(unit.Kind)},
});
}
NJson::TJsonMap ToTextMatePattern(const TUnit& unit, const NSQLTranslationV1::TRegexPattern& pattern) {
return NJson::TJsonMap({
{"match", ToTextMateRegex(unit, pattern)},
{"name", ToTextMateGroup(unit.Kind)},
});
}
TString ToTextMateName(EUnitKind kind) {
return ToString(kind);
}
} // namespace
void GenerateTextMate(IOutputStream& out, const THighlighting& highlighting) {
NJson::TJsonMap root;
root["$schema"] = "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json";
root["name"] = "yql";
root["scopeName"] = "source.yql";
root["fileTypes"] = NJson::TJsonArray({"yql"});
for (const TUnit& unit : highlighting.Units) {
if (unit.IsCodeGenExcluded) {
continue;
}
TString name = ToTextMateName(unit.Kind);
root["patterns"].AppendValue(NJson::TJsonMap({
{"include", "#" + name},
}));
for (const NSQLTranslationV1::TRegexPattern& pattern : unit.Patterns) {
auto textmate = ToTextMatePattern(unit, pattern);
root["repository"][name]["patterns"].AppendValue(std::move(textmate));
}
if (auto textmate = TextMateMultilinePattern(unit)) {
root["repository"][name]["patterns"].AppendValue(*textmate);
}
}
Print(out, root);
}
} // namespace NSQLHighlight
|