Extract Syntax highlighting from TextEdit and add EditorSyntaxHighlighter

- Extacted all syntax highlighting code from text edit
- Removed enable syntax highlighting from text edit
- Added line_edited_from signal to text_edit
- Renamed get/set_syntax_highlighting to get/set_syntax_highlighter
- Added EditorSyntaxHighligher
This commit is contained in:
Paulb23 2020-05-03 17:08:15 +01:00
parent 156daddaaf
commit bc4cee4458
25 changed files with 1330 additions and 932 deletions

View file

@ -51,6 +51,165 @@
#include "servers/display_server.h"
#include "text_editor.h"
/*** SYNTAX HIGHLIGHTER ****/
String EditorSyntaxHighlighter::_get_name() const {
ScriptInstance *si = get_script_instance();
if (si && si->has_method("_get_name")) {
return si->call("_get_name");
}
return "Unnamed";
}
Array EditorSyntaxHighlighter::_get_supported_languages() const {
ScriptInstance *si = get_script_instance();
if (si && si->has_method("_get_supported_languages")) {
return si->call("_get_supported_languages");
}
return Array();
}
Ref<EditorSyntaxHighlighter> EditorSyntaxHighlighter::_create() const {
Ref<EditorSyntaxHighlighter> syntax_highlighter;
syntax_highlighter.instance();
if (get_script_instance()) {
syntax_highlighter->set_script(get_script_instance()->get_script());
}
return syntax_highlighter;
}
void EditorSyntaxHighlighter::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_edited_resource"), &EditorSyntaxHighlighter::_get_edited_resource);
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_supported_languages"));
BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_supported_extentions"));
}
////
void EditorStandardSyntaxHighlighter::_update_cache() {
highlighter->set_text_edit(text_edit);
highlighter->clear_keyword_colors();
highlighter->clear_member_keyword_colors();
highlighter->clear_color_regions();
highlighter->set_symbol_color(EDITOR_GET("text_editor/highlighting/symbol_color"));
highlighter->set_function_color(EDITOR_GET("text_editor/highlighting/function_color"));
highlighter->set_number_color(EDITOR_GET("text_editor/highlighting/number_color"));
highlighter->set_member_variable_color(EDITOR_GET("text_editor/highlighting/member_variable_color"));
/* Engine types. */
const Color type_color = EDITOR_GET("text_editor/highlighting/engine_type_color");
List<StringName> types;
ClassDB::get_class_list(&types);
for (List<StringName>::Element *E = types.front(); E; E = E->next()) {
String n = E->get();
if (n.begins_with("_")) {
n = n.substr(1, n.length());
}
highlighter->add_keyword_color(n, type_color);
}
/* User types. */
const Color usertype_color = EDITOR_GET("text_editor/highlighting/user_type_color");
List<StringName> global_classes;
ScriptServer::get_global_class_list(&global_classes);
for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
highlighter->add_keyword_color(E->get(), usertype_color);
}
/* Autoloads. */
Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) {
const ProjectSettings::AutoloadInfo &info = E->value();
if (info.is_singleton) {
highlighter->add_keyword_color(info.name, usertype_color);
}
}
const Ref<Script> script = _get_edited_resource();
if (script.is_valid()) {
/* Core types. */
const Color basetype_color = EDITOR_GET("text_editor/highlighting/base_type_color");
List<String> core_types;
script->get_language()->get_core_type_words(&core_types);
for (List<String>::Element *E = core_types.front(); E; E = E->next()) {
highlighter->add_keyword_color(E->get(), basetype_color);
}
/* Reserved words. */
const Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
List<String> keywords;
script->get_language()->get_reserved_words(&keywords);
for (List<String>::Element *E = keywords.front(); E; E = E->next()) {
highlighter->add_keyword_color(E->get(), keyword_color);
}
/* Member types. */
const Color member_variable_color = EDITOR_GET("text_editor/highlighting/member_variable_color");
StringName instance_base = script->get_instance_base_type();
if (instance_base != StringName()) {
List<PropertyInfo> plist;
ClassDB::get_property_list(instance_base, &plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
String name = E->get().name;
if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP) {
continue;
}
if (name.find("/") != -1) {
continue;
}
highlighter->add_member_keyword_color(name, member_variable_color);
}
List<String> clist;
ClassDB::get_integer_constant_list(instance_base, &clist);
for (List<String>::Element *E = clist.front(); E; E = E->next()) {
highlighter->add_member_keyword_color(E->get(), member_variable_color);
}
}
/* Comments */
const Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
List<String> comments;
script->get_language()->get_comment_delimiters(&comments);
for (List<String>::Element *E = comments.front(); E; E = E->next()) {
String comment = E->get();
String beg = comment.get_slice(" ", 0);
String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
highlighter->add_color_region(beg, end, comment_color, end == "");
}
/* Strings */
const Color string_color = EDITOR_GET("text_editor/highlighting/string_color");
List<String> strings;
script->get_language()->get_string_delimiters(&strings);
for (List<String>::Element *E = strings.front(); E; E = E->next()) {
String string = E->get();
String beg = string.get_slice(" ", 0);
String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String();
highlighter->add_color_region(beg, end, string_color, end == "");
}
}
}
Ref<EditorSyntaxHighlighter> EditorStandardSyntaxHighlighter::_create() const {
Ref<EditorStandardSyntaxHighlighter> syntax_highlighter;
syntax_highlighter.instance();
return syntax_highlighter;
}
////
Ref<EditorSyntaxHighlighter> EditorPlainTextSyntaxHighlighter::_create() const {
Ref<EditorPlainTextSyntaxHighlighter> syntax_highlighter;
syntax_highlighter.instance();
return syntax_highlighter;
}
////////////////////////////////////////////////////////////////////////////////
/*** SCRIPT EDITOR ****/
void ScriptEditorBase::_bind_methods() {
@ -2022,7 +2181,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
if (p_resource->get_class_name() != StringName("VisualScript")) {
bool highlighter_set = false;
for (int i = 0; i < syntax_highlighters.size(); i++) {
Ref<SyntaxHighlighter> highlighter = syntax_highlighters[i]->_create();
Ref<EditorSyntaxHighlighter> highlighter = syntax_highlighters[i]->_create();
if (highlighter.is_null()) {
continue;
}
@ -2830,13 +2989,17 @@ void ScriptEditor::_open_script_request(const String &p_path) {
}
}
void ScriptEditor::register_syntax_highlighter(const Ref<SyntaxHighlighter> &p_syntax_highlighter) {
void ScriptEditor::register_syntax_highlighter(const Ref<EditorSyntaxHighlighter> &p_syntax_highlighter) {
ERR_FAIL_COND(p_syntax_highlighter.is_null());
if (syntax_highlighters.find(p_syntax_highlighter) == -1) {
syntax_highlighters.push_back(p_syntax_highlighter);
}
}
void ScriptEditor::unregister_syntax_highlighter(const Ref<SyntaxHighlighter> &p_syntax_highlighter) {
void ScriptEditor::unregister_syntax_highlighter(const Ref<EditorSyntaxHighlighter> &p_syntax_highlighter) {
ERR_FAIL_COND(p_syntax_highlighter.is_null());
syntax_highlighters.erase(p_syntax_highlighter);
}