Skip to content

Commit 9edd912

Browse files
Add bracket pair colorization for GDScript
1 parent 6fd949a commit 9edd912

File tree

4 files changed

+114
-0
lines changed

4 files changed

+114
-0
lines changed

doc/classes/EditorSettings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,11 @@
15961596
<member name="text_editor/theme/highlighting/gdscript/annotation_color" type="Color" setter="" getter="">
15971597
The GDScript syntax highlighter text color for annotations (e.g. [code]@export[/code]).
15981598
</member>
1599+
<member name="text_editor/theme/highlighting/gdscript/bracket_pair_colors" type="PackedColorArray" setter="" getter="">
1600+
The list of colors to use for bracket pair colorization.
1601+
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.
1602+
An empty array disables this feature.
1603+
</member>
15991604
<member name="text_editor/theme/highlighting/gdscript/function_definition_color" type="Color" setter="" getter="">
16001605
The GDScript syntax highlighter text color for function definitions (e.g. the [code]_ready[/code] in [code]func _ready():[/code]).
16011606
</member>

editor/settings/editor_settings.cpp

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

751+
PackedColorArray bracket_pair_colors_defaults;
752+
bracket_pair_colors_defaults.push_back(Color(0.4, 0.9, 1.0));
753+
bracket_pair_colors_defaults.push_back(Color(0.8, 0.4, 0.8));
754+
bracket_pair_colors_defaults.push_back(Color(0.3, 0.7, 0.9));
755+
bracket_pair_colors_defaults.push_back(Color(0.9, 0.5, 0.2));
756+
757+
EDITOR_SETTING_BASIC(Variant::PACKED_COLOR_ARRAY, PROPERTY_HINT_NONE, "text_editor/theme/highlighting/gdscript/bracket_pair_colors", bracket_pair_colors_defaults, "")
758+
751759
// Appearance
752760
EDITOR_SETTING_BASIC(Variant::BOOL, PROPERTY_HINT_NONE, "text_editor/appearance/enable_inline_color_picker", true, "");
753761

modules/gdscript/editor/gdscript_highlighter.cpp

Lines changed: 88 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 bracket_level_round = 0; // for ().
80+
int bracket_level_curly = 0; // for {}.
81+
int bracket_level_square = 0; // for [].
82+
7983
Color keyword_color;
8084
Color color;
8185

@@ -93,6 +97,24 @@ 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_pair_colors.size() > 0) {
102+
if (!bracket_level_cache.has(p_line - 1)) {
103+
int prev_line = p_line - 1;
104+
while (prev_line > 0 && !bracket_level_cache.has(prev_line)) {
105+
prev_line--;
106+
}
107+
108+
for (int i = prev_line; i < p_line; i++) {
109+
get_line_syntax_highlighting(i);
110+
}
111+
}
112+
113+
Vector<int> prev_levels = bracket_level_cache[p_line - 1];
114+
bracket_level_square = prev_levels[SQUARE];
115+
bracket_level_round = prev_levels[ROUND];
116+
bracket_level_curly = prev_levels[CURLY];
117+
}
96118
}
97119

98120
const String &str = text_edit->get_line_with_ime(p_line);
@@ -655,6 +677,59 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
655677
next_type = IDENTIFIER;
656678
}
657679

680+
// Bracket pair colorization.
681+
if (bracket_pair_colors.size() > 0) {
682+
bool is_bracket = false;
683+
Color bracket_color;
684+
685+
int *level_ptr = nullptr;
686+
bool is_opening_bracket = false;
687+
688+
switch (str[j]) {
689+
case '(':
690+
level_ptr = &bracket_level_round;
691+
is_opening_bracket = true;
692+
break;
693+
case ')':
694+
level_ptr = &bracket_level_round;
695+
is_opening_bracket = false;
696+
break;
697+
698+
case '[':
699+
level_ptr = &bracket_level_square;
700+
is_opening_bracket = true;
701+
break;
702+
case ']':
703+
level_ptr = &bracket_level_square;
704+
is_opening_bracket = false;
705+
break;
706+
707+
case '{':
708+
level_ptr = &bracket_level_curly;
709+
is_opening_bracket = true;
710+
break;
711+
case '}':
712+
level_ptr = &bracket_level_curly;
713+
is_opening_bracket = false;
714+
break;
715+
}
716+
717+
if (level_ptr != nullptr) {
718+
if (is_opening_bracket) {
719+
bracket_color = bracket_pair_colors[*level_ptr % bracket_pair_colors.size()];
720+
(*level_ptr)++;
721+
} else {
722+
*level_ptr = MAX(0, *level_ptr - 1);
723+
bracket_color = bracket_pair_colors[*level_ptr % bracket_pair_colors.size()];
724+
}
725+
is_bracket = true;
726+
}
727+
728+
if (is_bracket) {
729+
color = bracket_color;
730+
}
731+
}
732+
658733
if (next_type != current_type) {
659734
if (current_type == NONE) {
660735
current_type = next_type;
@@ -688,6 +763,14 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
688763
color_map[j] = highlighter_info;
689764
}
690765
}
766+
767+
Vector<int> final_levels;
768+
final_levels.resize(3);
769+
final_levels.set(SQUARE, bracket_level_square);
770+
final_levels.set(ROUND, bracket_level_round);
771+
final_levels.set(CURLY, bracket_level_curly);
772+
bracket_level_cache[p_line] = final_levels;
773+
691774
return color_map;
692775
}
693776

@@ -910,6 +993,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
910993
annotation_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/annotation_color");
911994
string_name_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/string_name_color");
912995
type_color = EDITOR_GET("text_editor/theme/highlighting/base_type_color");
996+
bracket_pair_colors = EDITOR_GET("text_editor/theme/highlighting/gdscript/bracket_pair_colors");
913997
comment_marker_colors[COMMENT_MARKER_CRITICAL] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/critical_color");
914998
comment_marker_colors[COMMENT_MARKER_WARNING] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/warning_color");
915999
comment_marker_colors[COMMENT_MARKER_NOTICE] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/notice_color");
@@ -960,6 +1044,10 @@ void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const
9601044
clear_highlighting_cache();
9611045
}
9621046

1047+
void GDScriptSyntaxHighlighter::_clear_highlighting_cache() {
1048+
bracket_level_cache.clear();
1049+
}
1050+
9631051
Ref<EditorSyntaxHighlighter> GDScriptSyntaxHighlighter::_create() const {
9641052
Ref<GDScriptSyntaxHighlighter> syntax_highlighter;
9651053
syntax_highlighter.instantiate();

modules/gdscript/editor/gdscript_highlighter.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ class GDScriptSyntaxHighlighter : public EditorSyntaxHighlighter {
7979
TYPE,
8080
};
8181

82+
enum BracketType {
83+
ROUND, // for ().
84+
CURLY, // for {}.
85+
SQUARE, // for [].
86+
};
87+
8288
// Colors.
8389
Color font_color;
8490
Color symbol_color;
@@ -95,6 +101,8 @@ class GDScriptSyntaxHighlighter : public EditorSyntaxHighlighter {
95101
Color string_name_color;
96102
Color type_color;
97103

104+
PackedColorArray bracket_pair_colors;
105+
98106
enum CommentMarkerLevel {
99107
COMMENT_MARKER_CRITICAL,
100108
COMMENT_MARKER_WARNING,
@@ -104,8 +112,13 @@ class GDScriptSyntaxHighlighter : public EditorSyntaxHighlighter {
104112
Color comment_marker_colors[COMMENT_MARKER_MAX];
105113
HashMap<String, CommentMarkerLevel> comment_markers;
106114

115+
HashMap<int, Vector<int>> bracket_level_cache;
116+
107117
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);
108118

119+
protected:
120+
virtual void _clear_highlighting_cache() override;
121+
109122
public:
110123
virtual void _update_cache() override;
111124
virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override;

0 commit comments

Comments
 (0)