Skip to content

Commit 57a9cb7

Browse files
Add bracket pair colorization for GDScript
1 parent 0fdbf05 commit 57a9cb7

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

doc/classes/EditorSettings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,11 @@
15931593
<member name="text_editor/theme/highlighting/gdscript/annotation_color" type="Color" setter="" getter="">
15941594
The GDScript syntax highlighter text color for annotations (e.g. [code]@export[/code]).
15951595
</member>
1596+
<member name="text_editor/theme/highlighting/gdscript/bracket_pair_colors" type="PackedColorArray" setter="" getter="">
1597+
The list of colors to use for bracket pair colorization.
1598+
The color for a bracket pair is determined by its nesting level. The first color in the array is used for the outermost level, the second for the first nested level, and so on. If the nesting level exceeds the number of colors in the array, the colors will cycle through from the beginning.
1599+
An empty array disables this feature.
1600+
</member>
15961601
<member name="text_editor/theme/highlighting/gdscript/function_definition_color" type="Color" setter="" getter="">
15971602
The GDScript syntax highlighter text color for function definitions (e.g. the [code]_ready[/code] in [code]func _ready():[/code]).
15981603
</member>

editor/settings/editor_settings.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,14 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
746746
_initial_set("text_editor/theme/highlighting/comment_markers/warning_list", "BUG,DEPRECATED,FIXME,HACK,TASK,TBD,TODO,WARNING");
747747
_initial_set("text_editor/theme/highlighting/comment_markers/notice_list", "INFO,NOTE,NOTICE,TEST,TESTING");
748748

749+
PackedColorArray bracket_pair_colors_defaults;
750+
bracket_pair_colors_defaults.push_back(Color(0.627, 0.741, 0.937));
751+
bracket_pair_colors_defaults.push_back(Color(0.396, 0.549, 0.953));
752+
bracket_pair_colors_defaults.push_back(Color(0.788, 0.835, 0));
753+
bracket_pair_colors_defaults.push_back(Color(0.729, 0.518, 0.898));
754+
755+
EDITOR_SETTING_BASIC(Variant::PACKED_COLOR_ARRAY, PROPERTY_HINT_NONE, "text_editor/theme/highlighting/gdscript/bracket_pair_colors", bracket_pair_colors_defaults, "")
756+
749757
// Appearance
750758
EDITOR_SETTING_BASIC(Variant::BOOL, PROPERTY_HINT_NONE, "text_editor/appearance/enable_inline_color_picker", true, "");
751759

modules/gdscript/editor/gdscript_highlighter.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
7676
int in_declaration_param_dicts = 0; // The number of opened `{` inside func params.
7777
int in_type_params = 0; // The number of opened `[` after type name.
7878

79+
int square_bracket_level = 0; // for ()
80+
int curly_brace_level = 0; // for {}
81+
int paren_level = 0; // for []
82+
7983
Color keyword_color;
8084
Color color;
8185

@@ -93,6 +97,22 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
9397
get_line_syntax_highlighting(p_line - 1);
9498
}
9599
in_region = color_region_cache[p_line - 1];
100+
101+
if (!bracket_level_cache.has(p_line - 1)) {
102+
int prev_line = p_line - 1;
103+
while (prev_line > 0 && !bracket_level_cache.has(prev_line)) {
104+
prev_line--;
105+
}
106+
107+
for (int i = prev_line; i < p_line; i++) {
108+
get_line_syntax_highlighting(i);
109+
}
110+
}
111+
112+
Vector<int> prev_levels = bracket_level_cache[p_line - 1];
113+
paren_level = prev_levels[0];
114+
square_bracket_level = prev_levels[1];
115+
curly_brace_level = prev_levels[2];
96116
}
97117

98118
const String &str = text_edit->get_line_with_ime(p_line);
@@ -655,6 +675,51 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
655675
next_type = IDENTIFIER;
656676
}
657677

678+
// Bracket pair colorization
679+
if (bracket_pair_colors.size() > 0) {
680+
bool is_bracket = false;
681+
Color bracket_color;
682+
683+
switch (str[j]) {
684+
case '(': {
685+
bracket_color = bracket_pair_colors[paren_level % bracket_pair_colors.size()];
686+
paren_level++;
687+
is_bracket = true;
688+
} break;
689+
case ')': {
690+
paren_level = MAX(0, paren_level - 1);
691+
bracket_color = bracket_pair_colors[paren_level % bracket_pair_colors.size()];
692+
is_bracket = true;
693+
} break;
694+
695+
case '[': {
696+
bracket_color = bracket_pair_colors[square_bracket_level % bracket_pair_colors.size()];
697+
square_bracket_level++;
698+
is_bracket = true;
699+
} break;
700+
case ']': {
701+
square_bracket_level = MAX(0, square_bracket_level - 1);
702+
bracket_color = bracket_pair_colors[square_bracket_level % bracket_pair_colors.size()];
703+
is_bracket = true;
704+
} break;
705+
706+
case '{': {
707+
bracket_color = bracket_pair_colors[curly_brace_level % bracket_pair_colors.size()];
708+
curly_brace_level++;
709+
is_bracket = true;
710+
} break;
711+
case '}': {
712+
curly_brace_level = MAX(0, curly_brace_level - 1);
713+
bracket_color = bracket_pair_colors[curly_brace_level % bracket_pair_colors.size()];
714+
is_bracket = true;
715+
} break;
716+
}
717+
718+
if (is_bracket) {
719+
color = bracket_color;
720+
}
721+
}
722+
658723
if (next_type != current_type) {
659724
if (current_type == NONE) {
660725
current_type = next_type;
@@ -688,6 +753,13 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
688753
color_map[j] = highlighter_info;
689754
}
690755
}
756+
757+
Vector<int> final_levels;
758+
final_levels.push_back(paren_level);
759+
final_levels.push_back(square_bracket_level);
760+
final_levels.push_back(curly_brace_level);
761+
bracket_level_cache[p_line] = final_levels;
762+
691763
return color_map;
692764
}
693765

@@ -910,6 +982,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
910982
annotation_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/annotation_color");
911983
string_name_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/string_name_color");
912984
type_color = EDITOR_GET("text_editor/theme/highlighting/base_type_color");
985+
bracket_pair_colors = EDITOR_GET("text_editor/theme/highlighting/gdscript/bracket_pair_colors");
913986
comment_marker_colors[COMMENT_MARKER_CRITICAL] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/critical_color");
914987
comment_marker_colors[COMMENT_MARKER_WARNING] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/warning_color");
915988
comment_marker_colors[COMMENT_MARKER_NOTICE] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/notice_color");
@@ -960,6 +1033,10 @@ void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const
9601033
clear_highlighting_cache();
9611034
}
9621035

1036+
void GDScriptSyntaxHighlighter::_clear_highlighting_cache() {
1037+
bracket_level_cache.clear();
1038+
}
1039+
9631040
Ref<EditorSyntaxHighlighter> GDScriptSyntaxHighlighter::_create() const {
9641041
Ref<GDScriptSyntaxHighlighter> syntax_highlighter;
9651042
syntax_highlighter.instantiate();

modules/gdscript/editor/gdscript_highlighter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class GDScriptSyntaxHighlighter : public EditorSyntaxHighlighter {
9595
Color string_name_color;
9696
Color type_color;
9797

98+
PackedColorArray bracket_pair_colors;
99+
98100
enum CommentMarkerLevel {
99101
COMMENT_MARKER_CRITICAL,
100102
COMMENT_MARKER_WARNING,
@@ -104,8 +106,14 @@ class GDScriptSyntaxHighlighter : public EditorSyntaxHighlighter {
104106
Color comment_marker_colors[COMMENT_MARKER_MAX];
105107
HashMap<String, CommentMarkerLevel> comment_markers;
106108

109+
// Index 0: paren_level, Index 1: square_bracket_level, Index 2: curly_brace_level
110+
HashMap<int, Vector<int>> bracket_level_cache;
111+
107112
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);
108113

114+
protected:
115+
virtual void _clear_highlighting_cache() override;
116+
109117
public:
110118
virtual void _update_cache() override;
111119
virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override;

0 commit comments

Comments
 (0)