From 05e274c77a2396f204f1ae54cac8d42f7b600cf7 Mon Sep 17 00:00:00 2001 From: aaronp64 Date: Tue, 25 Feb 2025 13:50:53 -0500 Subject: [PATCH] Use same color over multiple lines for each string type in GDScript editor StringNames, NodePaths, and Node references that spanned multiple lines would use the correct color on the first line, then revert to the default String color on following lines. Updated to cache the string type on lines with unterminated strings, so we can check which type is carried over from the previous line. Also updated to keep reference to the current line's color_region_cache value, to avoid repeated lookups. --- .../gdscript/editor/gdscript_highlighter.cpp | 37 +++++++++++++++++-- .../gdscript/editor/gdscript_highlighter.h | 9 +++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 88e634f425c..022ab65e9c8 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -78,8 +78,10 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l Color keyword_color; Color color; - color_region_cache[p_line] = -1; + int &cached_region = color_region_cache[p_line]; + cached_region = -1; int in_region = -1; + if (p_line != 0) { int prev_region_line = p_line - 1; while (prev_region_line > 0 && !color_region_cache.has(prev_region_line)) { @@ -92,6 +94,18 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l get_line_syntax_highlighting(p_line - 1); } in_region = color_region_cache[p_line - 1]; + if (in_region != -1 && color_regions[in_region].type == ColorRegion::TYPE_STRING) { + StringType *string_type = unterminated_string_cache.getptr(p_line - 1); + if (string_type) { + if (*string_type == StringType::TYPE_STRING_NAME) { + in_string_name = true; + } else if (*string_type == StringType::TYPE_NODE_PATH) { + in_node_path = true; + } else if (*string_type == StringType::TYPE_NODE_REF) { + in_node_ref = true; + } + } + } } const String &str = text_edit->get_line_with_ime(p_line); @@ -99,7 +113,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l Color prev_color; if (in_region != -1 && line_length == 0) { - color_region_cache[p_line] = in_region; + cached_region = in_region; } for (int j = 0; j < line_length; j++) { Dictionary highlighter_info; @@ -174,7 +188,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l j = line_length; if (!color_regions[c].line_only) { - color_region_cache[p_line] = c; + cached_region = c; } } break; @@ -291,7 +305,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } j = from + (end_key_length - 1); if (region_end_index == -1) { - color_region_cache[p_line] = in_region; + cached_region = in_region; } } @@ -675,6 +689,21 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l color_map[j] = highlighter_info; } } + + if (cached_region != -1 && color_regions[cached_region].type == ColorRegion::TYPE_STRING) { + if (in_string_name) { + unterminated_string_cache[p_line] = StringType::TYPE_STRING_NAME; + } else if (in_node_path) { + unterminated_string_cache[p_line] = StringType::TYPE_NODE_PATH; + } else if (in_node_ref) { + unterminated_string_cache[p_line] = StringType::TYPE_NODE_REF; + } else { + unterminated_string_cache[p_line] = StringType::TYPE_STRING; + } + } else { + unterminated_string_cache[p_line] = StringType::TYPE_NONE; + } + return color_map; } diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h index ec471956d5f..0259506f525 100644 --- a/modules/gdscript/editor/gdscript_highlighter.h +++ b/modules/gdscript/editor/gdscript_highlighter.h @@ -58,6 +58,15 @@ private: Vector color_regions; HashMap color_region_cache; + enum StringType { + TYPE_NONE, + TYPE_STRING, + TYPE_STRING_NAME, + TYPE_NODE_PATH, + TYPE_NODE_REF, + }; + HashMap unterminated_string_cache; + HashMap class_names; HashMap reserved_keywords; HashMap member_keywords;