diff options
-rw-r--r-- | modules/gdscript/editor/gdscript_highlighter.cpp | 41 | ||||
-rw-r--r-- | modules/gdscript/editor/gdscript_highlighter.h | 5 |
2 files changed, 28 insertions, 18 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index b4f4e879d0..f83b784f85 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -53,7 +53,6 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l bool in_keyword = false; bool in_word = false; bool in_number = false; - bool in_raw_string = false; bool in_node_path = false; bool in_node_ref = false; bool in_annotation = false; @@ -127,6 +126,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l if (from != line_length) { // Check if we are in entering a region. if (in_region == -1) { + const bool r_prefix = from > 0 && str[from - 1] == 'r'; for (int c = 0; c < color_regions.size(); c++) { // Check there is enough room. int chars_left = line_length - from; @@ -136,6 +136,10 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l continue; } + if (color_regions[c].is_string && color_regions[c].r_prefix != r_prefix) { + continue; + } + // Search the line. bool match = true; const char32_t *start_key = color_regions[c].start_key.get_data(); @@ -154,7 +158,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l // Check if it's the whole line. if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) { // Don't skip comments, for highlighting markers. - if (color_regions[in_region].type == ColorRegion::TYPE_COMMENT) { + if (color_regions[in_region].is_comment) { break; } if (from + end_key_length > line_length) { @@ -176,7 +180,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } // Don't skip comments, for highlighting markers. - if (j == line_length && color_regions[in_region].type != ColorRegion::TYPE_COMMENT) { + if (j == line_length && !color_regions[in_region].is_comment) { continue; } } @@ -198,7 +202,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l highlighter_info["color"] = region_color; color_map[j] = highlighter_info; - if (color_regions[in_region].type == ColorRegion::TYPE_COMMENT) { + if (color_regions[in_region].is_comment) { int marker_start_pos = from; int marker_len = 0; while (from <= line_length) { @@ -242,7 +246,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } if (str[from] == '\\') { - if (!in_raw_string) { + if (!color_regions[in_region].r_prefix) { Dictionary escape_char_highlighter_info; escape_char_highlighter_info["color"] = symbol_color; color_map[from] = escape_char_highlighter_info; @@ -250,7 +254,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l from++; - if (!in_raw_string) { + if (!color_regions[in_region].r_prefix) { int esc_len = 0; if (str[from] == 'u') { esc_len = 4; @@ -556,12 +560,6 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } } - if (!in_raw_string && in_region == -1 && str[j] == 'r' && j < line_length - 1 && (str[j + 1] == '"' || str[j + 1] == '\'')) { - in_raw_string = true; - } else if (in_raw_string && in_region == -1) { - in_raw_string = false; - } - // Keep symbol color for binary '&&'. In the case of '&&&' use StringName color for the last ampersand. if (!in_string_name && in_region == -1 && str[j] == '&' && !is_binary_op) { if (j >= 2 && str[j - 1] == '&' && str[j - 2] != '&' && prev_is_binary_op) { @@ -593,7 +591,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l in_annotation = false; } - if (in_raw_string) { + const bool in_raw_string_prefix = in_region == -1 && str[j] == 'r' && j + 1 < line_length && (str[j + 1] == '"' || str[j + 1] == '\''); + + if (in_raw_string_prefix) { color = string_color; } else if (in_node_ref) { next_type = NODE_REF; @@ -795,6 +795,10 @@ void GDScriptSyntaxHighlighter::_update_cache() { 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); + add_color_region(ColorRegion::TYPE_STRING, "\"", "\"", string_color, false, true); + add_color_region(ColorRegion::TYPE_STRING, "'", "'", string_color, false, true); + add_color_region(ColorRegion::TYPE_MULTILINE_STRING, "\"\"\"", "\"\"\"", string_color, false, true); + add_color_region(ColorRegion::TYPE_MULTILINE_STRING, "'''", "'''", string_color, false, true); const Ref<Script> scr = _get_edited_resource(); if (scr.is_valid()) { @@ -927,7 +931,7 @@ void GDScriptSyntaxHighlighter::_update_cache() { } } -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) { +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, bool p_r_prefix) { 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."); @@ -936,9 +940,9 @@ void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const } int at = 0; - 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."); - if (p_start_key.length() < color_regions[i].start_key.length()) { + for (const ColorRegion ®ion : color_regions) { + ERR_FAIL_COND_MSG(region.start_key == p_start_key && region.r_prefix == p_r_prefix, "Color region with start key '" + p_start_key + "' already exists."); + if (p_start_key.length() < region.start_key.length()) { at++; } else { break; @@ -951,6 +955,9 @@ void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const color_region.start_key = p_start_key; color_region.end_key = p_end_key; color_region.line_only = p_line_only; + color_region.r_prefix = p_r_prefix; + color_region.is_string = p_type == ColorRegion::TYPE_STRING || p_type == ColorRegion::TYPE_MULTILINE_STRING; + color_region.is_comment = p_type == ColorRegion::TYPE_COMMENT || p_type == ColorRegion::TYPE_CODE_REGION; color_regions.insert(at, color_region); clear_highlighting_cache(); } diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h index eb7bb7d801..655557b3d9 100644 --- a/modules/gdscript/editor/gdscript_highlighter.h +++ b/modules/gdscript/editor/gdscript_highlighter.h @@ -52,6 +52,9 @@ private: String start_key; String end_key; bool line_only = false; + bool r_prefix = false; + bool is_string = false; // `TYPE_STRING` or `TYPE_MULTILINE_STRING`. + bool is_comment = false; // `TYPE_COMMENT` or `TYPE_CODE_REGION`. }; Vector<ColorRegion> color_regions; HashMap<int, int> color_region_cache; @@ -103,7 +106,7 @@ private: Color comment_marker_colors[COMMENT_MARKER_MAX]; HashMap<String, CommentMarkerLevel> comment_markers; - 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); + 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, bool p_r_prefix = false); public: virtual void _update_cache() override; |