Skip to content

Commit cf8bca5

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

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-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.627, 0.741, 0.937));
753+
bracket_pair_colors_defaults.push_back(Color(0.396, 0.549, 0.953));
754+
bracket_pair_colors_defaults.push_back(Color(0.788, 0.835, 0));
755+
bracket_pair_colors_defaults.push_back(Color(0.729, 0.518, 0.898));
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: 79 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,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+
paren_level = prev_levels[0];
115+
square_bracket_level = prev_levels[1];
116+
curly_brace_level = prev_levels[2];
117+
}
96118
}
97119

98120
const String &str = text_edit->get_line_with_ime(p_line);
@@ -655,6 +677,51 @@ 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+
switch (str[j]) {
686+
case '(': {
687+
bracket_color = bracket_pair_colors[paren_level % bracket_pair_colors.size()];
688+
paren_level++;
689+
is_bracket = true;
690+
} break;
691+
case ')': {
692+
paren_level = MAX(0, paren_level - 1);
693+
bracket_color = bracket_pair_colors[paren_level % bracket_pair_colors.size()];
694+
is_bracket = true;
695+
} break;
696+
697+
case '[': {
698+
bracket_color = bracket_pair_colors[square_bracket_level % bracket_pair_colors.size()];
699+
square_bracket_level++;
700+
is_bracket = true;
701+
} break;
702+
case ']': {
703+
square_bracket_level = MAX(0, square_bracket_level - 1);
704+
bracket_color = bracket_pair_colors[square_bracket_level % bracket_pair_colors.size()];
705+
is_bracket = true;
706+
} break;
707+
708+
case '{': {
709+
bracket_color = bracket_pair_colors[curly_brace_level % bracket_pair_colors.size()];
710+
curly_brace_level++;
711+
is_bracket = true;
712+
} break;
713+
case '}': {
714+
curly_brace_level = MAX(0, curly_brace_level - 1);
715+
bracket_color = bracket_pair_colors[curly_brace_level % bracket_pair_colors.size()];
716+
is_bracket = true;
717+
} break;
718+
}
719+
720+
if (is_bracket) {
721+
color = bracket_color;
722+
}
723+
}
724+
658725
if (next_type != current_type) {
659726
if (current_type == NONE) {
660727
current_type = next_type;
@@ -688,6 +755,13 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
688755
color_map[j] = highlighter_info;
689756
}
690757
}
758+
759+
Vector<int> final_levels;
760+
final_levels.push_back(paren_level);
761+
final_levels.push_back(square_bracket_level);
762+
final_levels.push_back(curly_brace_level);
763+
bracket_level_cache[p_line] = final_levels;
764+
691765
return color_map;
692766
}
693767

@@ -910,6 +984,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
910984
annotation_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/annotation_color");
911985
string_name_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/string_name_color");
912986
type_color = EDITOR_GET("text_editor/theme/highlighting/base_type_color");
987+
bracket_pair_colors = EDITOR_GET("text_editor/theme/highlighting/gdscript/bracket_pair_colors");
913988
comment_marker_colors[COMMENT_MARKER_CRITICAL] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/critical_color");
914989
comment_marker_colors[COMMENT_MARKER_WARNING] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/warning_color");
915990
comment_marker_colors[COMMENT_MARKER_NOTICE] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/notice_color");
@@ -960,6 +1035,10 @@ void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const
9601035
clear_highlighting_cache();
9611036
}
9621037

1038+
void GDScriptSyntaxHighlighter::_clear_highlighting_cache() {
1039+
bracket_level_cache.clear();
1040+
}
1041+
9631042
Ref<EditorSyntaxHighlighter> GDScriptSyntaxHighlighter::_create() const {
9641043
Ref<GDScriptSyntaxHighlighter> syntax_highlighter;
9651044
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)