Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/editor/script/syntax_highlighters.cpp
20860 views
1
/**************************************************************************/
2
/* syntax_highlighters.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "syntax_highlighters.h"
32
33
#include "core/config/project_settings.h"
34
#include "core/object/script_language.h"
35
#include "editor/settings/editor_settings.h"
36
37
String EditorSyntaxHighlighter::_get_name() const {
38
String ret = "Unnamed";
39
GDVIRTUAL_CALL(_get_name, ret);
40
return ret;
41
}
42
43
PackedStringArray EditorSyntaxHighlighter::_get_supported_languages() const {
44
PackedStringArray ret;
45
GDVIRTUAL_CALL(_get_supported_languages, ret);
46
return ret;
47
}
48
49
Ref<EditorSyntaxHighlighter> EditorSyntaxHighlighter::_create() const {
50
Ref<EditorSyntaxHighlighter> syntax_highlighter;
51
if (GDVIRTUAL_IS_OVERRIDDEN(_create)) {
52
GDVIRTUAL_CALL(_create, syntax_highlighter);
53
} else {
54
syntax_highlighter.instantiate();
55
if (get_script_instance()) {
56
syntax_highlighter->set_script(get_script_instance()->get_script());
57
}
58
}
59
return syntax_highlighter;
60
}
61
62
void EditorSyntaxHighlighter::_bind_methods() {
63
ClassDB::bind_method(D_METHOD("_get_edited_resource"), &EditorSyntaxHighlighter::_get_edited_resource);
64
65
GDVIRTUAL_BIND(_get_name)
66
GDVIRTUAL_BIND(_get_supported_languages)
67
GDVIRTUAL_BIND(_create)
68
}
69
70
////
71
72
void EditorStandardSyntaxHighlighter::_update_cache() {
73
highlighter->set_text_edit(text_edit);
74
highlighter->clear_keyword_colors();
75
highlighter->clear_member_keyword_colors();
76
highlighter->clear_color_regions();
77
78
highlighter->set_symbol_color(EDITOR_GET("text_editor/theme/highlighting/symbol_color"));
79
highlighter->set_function_color(EDITOR_GET("text_editor/theme/highlighting/function_color"));
80
highlighter->set_number_color(EDITOR_GET("text_editor/theme/highlighting/number_color"));
81
highlighter->set_member_variable_color(EDITOR_GET("text_editor/theme/highlighting/member_variable_color"));
82
83
/* Engine types. */
84
const Color type_color = EDITOR_GET("text_editor/theme/highlighting/engine_type_color");
85
LocalVector<StringName> types;
86
ClassDB::get_class_list(types);
87
for (const StringName &type : types) {
88
highlighter->add_keyword_color(type, type_color);
89
}
90
91
/* User types. */
92
const Color usertype_color = EDITOR_GET("text_editor/theme/highlighting/user_type_color");
93
LocalVector<StringName> global_classes;
94
ScriptServer::get_global_class_list(global_classes);
95
for (const StringName &class_name : global_classes) {
96
highlighter->add_keyword_color(class_name, usertype_color);
97
}
98
99
/* Autoloads. */
100
HashMap<StringName, ProjectSettings::AutoloadInfo> autoloads(ProjectSettings::get_singleton()->get_autoload_list());
101
for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : autoloads) {
102
const ProjectSettings::AutoloadInfo &info = E.value;
103
if (info.is_singleton) {
104
highlighter->add_keyword_color(info.name, usertype_color);
105
}
106
}
107
108
const ScriptLanguage *scr_lang = script_language;
109
StringName instance_base;
110
111
if (scr_lang == nullptr) {
112
const Ref<Script> scr = _get_edited_resource();
113
if (scr.is_valid()) {
114
scr_lang = scr->get_language();
115
instance_base = scr->get_instance_base_type();
116
}
117
}
118
119
if (scr_lang != nullptr) {
120
/* Core types. */
121
const Color basetype_color = EDITOR_GET("text_editor/theme/highlighting/base_type_color");
122
List<String> core_types;
123
scr_lang->get_core_type_words(&core_types);
124
for (const String &E : core_types) {
125
highlighter->add_keyword_color(E, basetype_color);
126
}
127
128
/* Reserved words. */
129
const Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color");
130
const Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color");
131
for (const String &keyword : scr_lang->get_reserved_words()) {
132
if (scr_lang->is_control_flow_keyword(keyword)) {
133
highlighter->add_keyword_color(keyword, control_flow_keyword_color);
134
} else {
135
highlighter->add_keyword_color(keyword, keyword_color);
136
}
137
}
138
139
/* Member types. */
140
const Color member_variable_color = EDITOR_GET("text_editor/theme/highlighting/member_variable_color");
141
if (instance_base != StringName()) {
142
List<PropertyInfo> plist;
143
ClassDB::get_property_list(instance_base, &plist);
144
for (const PropertyInfo &E : plist) {
145
String prop_name = E.name;
146
if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) {
147
continue;
148
}
149
if (prop_name.contains_char('/')) {
150
continue;
151
}
152
highlighter->add_member_keyword_color(prop_name, member_variable_color);
153
}
154
155
List<String> clist;
156
ClassDB::get_integer_constant_list(instance_base, &clist);
157
for (const String &E : clist) {
158
highlighter->add_member_keyword_color(E, member_variable_color);
159
}
160
}
161
162
/* Comments */
163
const Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color");
164
for (const String &comment : scr_lang->get_comment_delimiters()) {
165
String beg = comment.get_slicec(' ', 0);
166
String end = comment.get_slice_count(" ") > 1 ? comment.get_slicec(' ', 1) : String();
167
highlighter->add_color_region(beg, end, comment_color, end.is_empty());
168
}
169
170
/* Doc comments */
171
const Color doc_comment_color = EDITOR_GET("text_editor/theme/highlighting/doc_comment_color");
172
for (const String &doc_comment : scr_lang->get_doc_comment_delimiters()) {
173
String beg = doc_comment.get_slicec(' ', 0);
174
String end = doc_comment.get_slice_count(" ") > 1 ? doc_comment.get_slicec(' ', 1) : String();
175
highlighter->add_color_region(beg, end, doc_comment_color, end.is_empty());
176
}
177
178
/* Strings */
179
const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color");
180
for (const String &string : scr_lang->get_string_delimiters()) {
181
String beg = string.get_slicec(' ', 0);
182
String end = string.get_slice_count(" ") > 1 ? string.get_slicec(' ', 1) : String();
183
highlighter->add_color_region(beg, end, string_color, end.is_empty());
184
}
185
}
186
}
187
188
Ref<EditorSyntaxHighlighter> EditorStandardSyntaxHighlighter::_create() const {
189
Ref<EditorStandardSyntaxHighlighter> syntax_highlighter;
190
syntax_highlighter.instantiate();
191
return syntax_highlighter;
192
}
193
194
////
195
196
Ref<EditorSyntaxHighlighter> EditorPlainTextSyntaxHighlighter::_create() const {
197
Ref<EditorPlainTextSyntaxHighlighter> syntax_highlighter;
198
syntax_highlighter.instantiate();
199
return syntax_highlighter;
200
}
201
202
////
203
204
void EditorJSONSyntaxHighlighter::_update_cache() {
205
highlighter->set_text_edit(text_edit);
206
highlighter->clear_keyword_colors();
207
highlighter->clear_member_keyword_colors();
208
highlighter->clear_color_regions();
209
210
highlighter->set_symbol_color(EDITOR_GET("text_editor/theme/highlighting/symbol_color"));
211
highlighter->set_number_color(EDITOR_GET("text_editor/theme/highlighting/number_color"));
212
213
const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color");
214
highlighter->add_color_region("\"", "\"", string_color);
215
}
216
217
Ref<EditorSyntaxHighlighter> EditorJSONSyntaxHighlighter::_create() const {
218
Ref<EditorJSONSyntaxHighlighter> syntax_highlighter;
219
syntax_highlighter.instantiate();
220
return syntax_highlighter;
221
}
222
223
////
224
225
void EditorMarkdownSyntaxHighlighter::_update_cache() {
226
highlighter->set_text_edit(text_edit);
227
highlighter->clear_keyword_colors();
228
highlighter->clear_member_keyword_colors();
229
highlighter->clear_color_regions();
230
231
// Disable automatic symbolic highlights, as these don't make sense for prose.
232
highlighter->set_symbol_color(EDITOR_GET("text_editor/theme/highlighting/text_color"));
233
highlighter->set_number_color(EDITOR_GET("text_editor/theme/highlighting/text_color"));
234
highlighter->set_member_variable_color(EDITOR_GET("text_editor/theme/highlighting/text_color"));
235
highlighter->set_function_color(EDITOR_GET("text_editor/theme/highlighting/text_color"));
236
237
// Headings (any level).
238
const Color function_color = EDITOR_GET("text_editor/theme/highlighting/function_color");
239
highlighter->add_color_region("#", "", function_color);
240
241
// Bold.
242
highlighter->add_color_region("**", "**", function_color);
243
// `__bold__` syntax is not supported as color regions must begin with a symbol,
244
// not a character that is valid in an identifier.
245
246
// Code (both inline code and triple-backticks code blocks).
247
const Color code_color = EDITOR_GET("text_editor/theme/highlighting/engine_type_color");
248
highlighter->add_color_region("`", "`", code_color);
249
250
// Link (both references and inline links with URLs). The URL is not highlighted.
251
const Color link_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color");
252
highlighter->add_color_region("[", "]", link_color);
253
254
// Quote.
255
const Color quote_color = EDITOR_GET("text_editor/theme/highlighting/string_color");
256
highlighter->add_color_region(">", "", quote_color, true);
257
258
// HTML comment, which is also supported in Markdown.
259
const Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color");
260
highlighter->add_color_region("<!--", "-->", comment_color);
261
}
262
263
Ref<EditorSyntaxHighlighter> EditorMarkdownSyntaxHighlighter::_create() const {
264
Ref<EditorMarkdownSyntaxHighlighter> syntax_highlighter;
265
syntax_highlighter.instantiate();
266
return syntax_highlighter;
267
}
268
269
///
270
271
void EditorConfigFileSyntaxHighlighter::_update_cache() {
272
highlighter->set_text_edit(text_edit);
273
highlighter->clear_keyword_colors();
274
highlighter->clear_member_keyword_colors();
275
highlighter->clear_color_regions();
276
277
highlighter->set_symbol_color(EDITOR_GET("text_editor/theme/highlighting/symbol_color"));
278
highlighter->set_number_color(EDITOR_GET("text_editor/theme/highlighting/number_color"));
279
// Assume that all function-style syntax is for types such as `Vector2()` and `PackedStringArray()`.
280
highlighter->set_function_color(EDITOR_GET("text_editor/theme/highlighting/base_type_color"));
281
282
// Disable member variable highlighting as it's not relevant for ConfigFile.
283
highlighter->set_member_variable_color(EDITOR_GET("text_editor/theme/highlighting/text_color"));
284
285
const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color");
286
highlighter->add_color_region("\"", "\"", string_color);
287
288
// FIXME: Sections in ConfigFile must be at the beginning of a line. Otherwise, it can be an array within a line.
289
const Color function_color = EDITOR_GET("text_editor/theme/highlighting/function_color");
290
highlighter->add_color_region("[", "]", function_color);
291
292
const Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color");
293
highlighter->add_keyword_color("true", keyword_color);
294
highlighter->add_keyword_color("false", keyword_color);
295
highlighter->add_keyword_color("null", keyword_color);
296
highlighter->add_keyword_color("ExtResource", keyword_color);
297
highlighter->add_keyword_color("SubResource", keyword_color);
298
299
const Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color");
300
highlighter->add_color_region(";", "", comment_color);
301
}
302
303
Ref<EditorSyntaxHighlighter> EditorConfigFileSyntaxHighlighter::_create() const {
304
Ref<EditorConfigFileSyntaxHighlighter> syntax_highlighter;
305
syntax_highlighter.instantiate();
306
return syntax_highlighter;
307
}
308
309