Browse Source

GDScript: Highlight code region comments

Danil Alexeev 1 year ago
parent
commit
faebb0895f

+ 24 - 24
modules/gdscript/editor/gdscript_highlighter.cpp

@@ -150,7 +150,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
 						// Check if it's the whole line.
 						// Check if it's the whole line.
 						if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) {
 						if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) {
 							// Don't skip comments, for highlighting markers.
 							// Don't skip comments, for highlighting markers.
-							if (color_regions[in_region].start_key.begins_with("#")) {
+							if (color_regions[in_region].type == ColorRegion::TYPE_COMMENT) {
 								break;
 								break;
 							}
 							}
 							if (from + end_key_length > line_length) {
 							if (from + end_key_length > line_length) {
@@ -172,7 +172,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
 					}
 					}
 
 
 					// Don't skip comments, for highlighting markers.
 					// Don't skip comments, for highlighting markers.
-					if (j == line_length && !color_regions[in_region].start_key.begins_with("#")) {
+					if (j == line_length && color_regions[in_region].type != ColorRegion::TYPE_COMMENT) {
 						continue;
 						continue;
 					}
 					}
 				}
 				}
@@ -180,13 +180,13 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
 				// If we are in one, find the end key.
 				// If we are in one, find the end key.
 				if (in_region != -1) {
 				if (in_region != -1) {
 					Color region_color = color_regions[in_region].color;
 					Color region_color = color_regions[in_region].color;
-					if (in_node_path && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
+					if (in_node_path && color_regions[in_region].type == ColorRegion::TYPE_STRING) {
 						region_color = node_path_color;
 						region_color = node_path_color;
 					}
 					}
-					if (in_node_ref && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
+					if (in_node_ref && color_regions[in_region].type == ColorRegion::TYPE_STRING) {
 						region_color = node_ref_color;
 						region_color = node_ref_color;
 					}
 					}
-					if (in_string_name && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
+					if (in_string_name && color_regions[in_region].type == ColorRegion::TYPE_STRING) {
 						region_color = string_name_color;
 						region_color = string_name_color;
 					}
 					}
 
 
@@ -194,7 +194,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
 					highlighter_info["color"] = region_color;
 					highlighter_info["color"] = region_color;
 					color_map[j] = highlighter_info;
 					color_map[j] = highlighter_info;
 
 
-					if (color_regions[in_region].start_key.begins_with("#")) {
+					if (color_regions[in_region].type == ColorRegion::TYPE_COMMENT) {
 						int marker_start_pos = from;
 						int marker_start_pos = from;
 						int marker_len = 0;
 						int marker_len = 0;
 						while (from <= line_length) {
 						while (from <= line_length) {
@@ -738,7 +738,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
 	for (const String &comment : comments) {
 	for (const String &comment : comments) {
 		String beg = comment.get_slice(" ", 0);
 		String beg = comment.get_slice(" ", 0);
 		String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
 		String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
-		add_color_region(beg, end, comment_color, end.is_empty());
+		add_color_region(ColorRegion::TYPE_COMMENT, beg, end, comment_color, end.is_empty());
 	}
 	}
 
 
 	/* Doc comments */
 	/* Doc comments */
@@ -748,18 +748,20 @@ void GDScriptSyntaxHighlighter::_update_cache() {
 	for (const String &doc_comment : doc_comments) {
 	for (const String &doc_comment : doc_comments) {
 		String beg = doc_comment.get_slice(" ", 0);
 		String beg = doc_comment.get_slice(" ", 0);
 		String end = doc_comment.get_slice_count(" ") > 1 ? doc_comment.get_slice(" ", 1) : String();
 		String end = doc_comment.get_slice_count(" ") > 1 ? doc_comment.get_slice(" ", 1) : String();
-		add_color_region(beg, end, doc_comment_color, end.is_empty());
+		add_color_region(ColorRegion::TYPE_COMMENT, beg, end, doc_comment_color, end.is_empty());
 	}
 	}
 
 
+	/* Code regions */
+	const Color code_region_color = Color(EDITOR_GET("text_editor/theme/highlighting/folded_code_region_color").operator Color(), 1.0);
+	add_color_region(ColorRegion::TYPE_CODE_REGION, "#region", "", code_region_color, true);
+	add_color_region(ColorRegion::TYPE_CODE_REGION, "#endregion", "", code_region_color, true);
+
 	/* Strings */
 	/* Strings */
 	string_color = EDITOR_GET("text_editor/theme/highlighting/string_color");
 	string_color = EDITOR_GET("text_editor/theme/highlighting/string_color");
-	List<String> strings;
-	gdscript->get_string_delimiters(&strings);
-	for (const String &string : strings) {
-		String beg = string.get_slice(" ", 0);
-		String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String();
-		add_color_region(beg, end, string_color, end.is_empty());
-	}
+	add_color_region(ColorRegion::TYPE_STRING, "\"", "\"", string_color);
+	add_color_region(ColorRegion::TYPE_STRING, "'", "'", string_color);
+	add_color_region(ColorRegion::TYPE_MULTILINE_STRING, "\"\"\"", "\"\"\"", string_color);
+	add_color_region(ColorRegion::TYPE_MULTILINE_STRING, "'''", "'''", string_color);
 
 
 	const Ref<Script> scr = _get_edited_resource();
 	const Ref<Script> scr = _get_edited_resource();
 	if (scr.is_valid()) {
 	if (scr.is_valid()) {
@@ -892,20 +894,17 @@ void GDScriptSyntaxHighlighter::_update_cache() {
 	}
 	}
 }
 }
 
 
-void GDScriptSyntaxHighlighter::add_color_region(const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only) {
-	for (int i = 0; i < p_start_key.length(); i++) {
-		ERR_FAIL_COND_MSG(!is_symbol(p_start_key[i]), "color regions must start with a symbol");
-	}
+void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only) {
+	ERR_FAIL_COND_MSG(p_start_key.is_empty(), "Color region start key cannot be empty.");
+	ERR_FAIL_COND_MSG(!is_symbol(p_start_key[0]), "Color region start key must start with a symbol.");
 
 
-	if (p_end_key.length() > 0) {
-		for (int i = 0; i < p_end_key.length(); i++) {
-			ERR_FAIL_COND_MSG(!is_symbol(p_end_key[i]), "color regions must end with a symbol");
-		}
+	if (!p_end_key.is_empty()) {
+		ERR_FAIL_COND_MSG(!is_symbol(p_end_key[0]), "Color region end key must start with a symbol.");
 	}
 	}
 
 
 	int at = 0;
 	int at = 0;
 	for (int i = 0; i < color_regions.size(); i++) {
 	for (int i = 0; i < color_regions.size(); i++) {
-		ERR_FAIL_COND_MSG(color_regions[i].start_key == p_start_key, "color region with start key '" + p_start_key + "' already exists.");
+		ERR_FAIL_COND_MSG(color_regions[i].start_key == p_start_key, "Color region with start key '" + p_start_key + "' already exists.");
 		if (p_start_key.length() < color_regions[i].start_key.length()) {
 		if (p_start_key.length() < color_regions[i].start_key.length()) {
 			at++;
 			at++;
 		} else {
 		} else {
@@ -914,6 +913,7 @@ void GDScriptSyntaxHighlighter::add_color_region(const String &p_start_key, cons
 	}
 	}
 
 
 	ColorRegion color_region;
 	ColorRegion color_region;
+	color_region.type = p_type;
 	color_region.color = p_color;
 	color_region.color = p_color;
 	color_region.start_key = p_start_key;
 	color_region.start_key = p_start_key;
 	color_region.end_key = p_end_key;
 	color_region.end_key = p_end_key;

+ 10 - 1
modules/gdscript/editor/gdscript_highlighter.h

@@ -39,6 +39,15 @@ class GDScriptSyntaxHighlighter : public EditorSyntaxHighlighter {
 
 
 private:
 private:
 	struct ColorRegion {
 	struct ColorRegion {
+		enum Type {
+			TYPE_NONE,
+			TYPE_STRING, // `"` and `'`, optional prefix `&`, `^`, or `r`.
+			TYPE_MULTILINE_STRING, // `"""` and `'''`, optional prefix `r`.
+			TYPE_COMMENT, // `#` and `##`.
+			TYPE_CODE_REGION, // `#region` and `#endregion`.
+		};
+
+		Type type = TYPE_NONE;
 		Color color;
 		Color color;
 		String start_key;
 		String start_key;
 		String end_key;
 		String end_key;
@@ -94,7 +103,7 @@ private:
 	Color comment_marker_colors[COMMENT_MARKER_MAX];
 	Color comment_marker_colors[COMMENT_MARKER_MAX];
 	HashMap<String, CommentMarkerLevel> comment_markers;
 	HashMap<String, CommentMarkerLevel> comment_markers;
 
 
-	void add_color_region(const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only = false);
+	void add_color_region(ColorRegion::Type p_type, const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only = false);
 
 
 public:
 public:
 	virtual void _update_cache() override;
 	virtual void _update_cache() override;