Skip to content

Commit 714ea33

Browse files
Add bracket pair colorization for GDScript
1 parent 0fdbf05 commit 714ea33

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

doc/classes/EditorSettings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,10 @@
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 cycle through for colorizing bracket pairs.
1598+
Leave blank to disable.
1599+
</member>
15961600
<member name="text_editor/theme/highlighting/gdscript/function_definition_color" type="Color" setter="" getter="">
15971601
The GDScript syntax highlighter text color for function definitions (e.g. the [code]_ready[/code] in [code]func _ready():[/code]).
15981602
</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: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#include "core/config/project_settings.h"
3737
#include "core/core_constants.h"
38+
#include "core/typedefs.h"
3839
#include "editor/settings/editor_settings.h"
3940
#include "editor/themes/editor_theme_manager.h"
4041
#include "scene/gui/text_edit.h"
@@ -76,6 +77,10 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
7677
int in_declaration_param_dicts = 0; // The number of opened `{` inside func params.
7778
int in_type_params = 0; // The number of opened `[` after type name.
7879

80+
int square_bracket_level = 0; // for ()
81+
int curly_brace_level = 0; // for {}
82+
int paren_level = 0; // for []
83+
7984
Color keyword_color;
8085
Color color;
8186

@@ -93,6 +98,22 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
9398
get_line_syntax_highlighting(p_line - 1);
9499
}
95100
in_region = color_region_cache[p_line - 1];
101+
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];
96117
}
97118

98119
const String &str = text_edit->get_line_with_ime(p_line);
@@ -655,6 +676,51 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
655676
next_type = IDENTIFIER;
656677
}
657678

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

@@ -910,6 +983,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
910983
annotation_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/annotation_color");
911984
string_name_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/string_name_color");
912985
type_color = EDITOR_GET("text_editor/theme/highlighting/base_type_color");
986+
bracket_pair_colors = EDITOR_GET("text_editor/theme/highlighting/gdscript/bracket_pair_colors");
913987
comment_marker_colors[COMMENT_MARKER_CRITICAL] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/critical_color");
914988
comment_marker_colors[COMMENT_MARKER_WARNING] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/warning_color");
915989
comment_marker_colors[COMMENT_MARKER_NOTICE] = EDITOR_GET("text_editor/theme/highlighting/comment_markers/notice_color");
@@ -960,6 +1034,10 @@ void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const
9601034
clear_highlighting_cache();
9611035
}
9621036

1037+
void GDScriptSyntaxHighlighter::_clear_highlighting_cache() {
1038+
bracket_level_cache.clear();
1039+
}
1040+
9631041
Ref<EditorSyntaxHighlighter> GDScriptSyntaxHighlighter::_create() const {
9641042
Ref<GDScriptSyntaxHighlighter> syntax_highlighter;
9651043
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)