Skip to content

Commit

Permalink
Add code region folding to CodeEdit
Browse files Browse the repository at this point in the history
  • Loading branch information
jmb462 committed Sep 11, 2023
1 parent 221884e commit 67dce30
Show file tree
Hide file tree
Showing 16 changed files with 506 additions and 27 deletions.
52 changes: 52 additions & 0 deletions doc/classes/CodeEdit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@
Values of [code]-1[/code] convert the entire text.
</description>
</method>
<method name="create_code_region">
<return type="void" />
<description>
Creates a new code region with the selection. At least one single line comment delimiter have to be defined (see [method add_comment_delimiter]).
A code region is a part of code that is highlighted when folded and can help organize your script.
Code region start and end tags can be customized (see [method set_code_region_tags]).
Code regions are delimited using start and end tags (respectively [code]region[/code] and [code]endregion[/code] by default) preceded by one line comment delimiter. (eg. [code]#region[/code] and [code]#endregion[/code])
</description>
</method>
<method name="do_indent">
<return type="void" />
<description>
Expand Down Expand Up @@ -200,6 +209,18 @@
Gets the index of the current selected completion option.
</description>
</method>
<method name="get_code_region_end_tag" qualifiers="const">
<return type="String" />
<description>
Returns the code region end tag (without comment delimiter).
</description>
</method>
<method name="get_code_region_start_tag" qualifiers="const">
<return type="String" />
<description>
Returns the code region start tag (without comment delimiter).
</description>
</method>
<method name="get_delimiter_end_key" qualifiers="const">
<return type="String" />
<param index="0" name="delimiter_index" type="int" />
Expand Down Expand Up @@ -326,6 +347,20 @@
Returns whether the line at the specified index is breakpointed or not.
</description>
</method>
<method name="is_line_code_region_end" qualifiers="const">
<return type="bool" />
<param index="0" name="line" type="int" />
<description>
Returns whether the line at the specified index is a code region end.
</description>
</method>
<method name="is_line_code_region_start" qualifiers="const">
<return type="bool" />
<param index="0" name="line" type="int" />
<description>
Returns whether the line at the specified index is a code region start.
</description>
</method>
<method name="is_line_executing" qualifiers="const">
<return type="bool" />
<param index="0" name="line" type="int" />
Expand Down Expand Up @@ -382,6 +417,14 @@
Sets if the code hint should draw below the text.
</description>
</method>
<method name="set_code_region_tags">
<return type="void" />
<param index="0" name="start" type="String" default="&quot;region&quot;" />
<param index="1" name="end" type="String" default="&quot;endregion&quot;" />
<description>
Sets the code region start and end tags (without comment delimiter).
</description>
</method>
<method name="set_line_as_bookmarked">
<return type="void" />
<param index="0" name="line" type="int" />
Expand Down Expand Up @@ -629,6 +672,9 @@
<theme_item name="executing_line_color" data_type="color" type="Color" default="Color(0.98, 0.89, 0.27, 1)">
[Color] of the executing icon for executing lines.
</theme_item>
<theme_item name="folded_code_region_color" data_type="color" type="Color" default="Color(0.68, 0.46, 0.77, 0.2)">
[Color] of background line highlight for folded code region.
</theme_item>
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 1)">
Sets the font [Color].
</theme_item>
Expand Down Expand Up @@ -693,12 +739,18 @@
<theme_item name="can_fold" data_type="icon" type="Texture2D">
Sets a custom [Texture2D] to draw in the line folding gutter when a line can be folded.
</theme_item>
<theme_item name="can_fold_code_region" data_type="icon" type="Texture2D">
Sets a custom [Texture2D] to draw in the line folding gutter when a code region can be folded.
</theme_item>
<theme_item name="executing_line" data_type="icon" type="Texture2D">
Icon to draw in the executing gutter for executing lines.
</theme_item>
<theme_item name="folded" data_type="icon" type="Texture2D">
Sets a custom [Texture2D] to draw in the line folding gutter when a line is folded and can be unfolded.
</theme_item>
<theme_item name="folded_code_region" data_type="icon" type="Texture2D">
Sets a custom [Texture2D] to draw in the line folding gutter when a code region is folded and can be unfolded.
</theme_item>
<theme_item name="folded_eol_icon" data_type="icon" type="Texture2D">
Sets a custom [Texture2D] to draw at the end of a folded line.
</theme_item>
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/EditorSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,9 @@
<member name="text_editor/theme/highlighting/executing_line_color" type="Color" setter="" getter="">
The script editor's color for the debugger's executing line icon (displayed in the gutter).
</member>
<member name="text_editor/theme/highlighting/folded_code_region_color" type="Color" setter="" getter="">
The script editor's background line highlighting color for folded code region.
</member>
<member name="text_editor/theme/highlighting/function_color" type="Color" setter="" getter="">
The script editor's function call color.
[b]Note:[/b] When using the GDScript syntax highlighter, this is replaced by the function definition color configured in the syntax theme for function definitions (e.g. [code]func _ready():[/code]).
Expand Down
1 change: 1 addition & 0 deletions editor/editor_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,7 @@ void EditorSettings::_load_godot2_text_editor_theme() {
_initial_set("text_editor/theme/highlighting/breakpoint_color", Color(0.9, 0.29, 0.3));
_initial_set("text_editor/theme/highlighting/executing_line_color", Color(0.98, 0.89, 0.27));
_initial_set("text_editor/theme/highlighting/code_folding_color", Color(0.8, 0.8, 0.8, 0.8));
_initial_set("text_editor/theme/highlighting/folded_code_region_color", Color(0.68, 0.46, 0.77, 0.2));
_initial_set("text_editor/theme/highlighting/search_result_color", Color(0.05, 0.25, 0.05, 1));
_initial_set("text_editor/theme/highlighting/search_result_border_color", Color(0.41, 0.61, 0.91, 0.38));
}
Expand Down
7 changes: 7 additions & 0 deletions editor/editor_themes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ void EditorColorMap::create() {
add_conversion_exception("GuiSpace");
add_conversion_exception("CodeFoldedRightArrow");
add_conversion_exception("CodeFoldDownArrow");
add_conversion_exception("CodeRegionFoldedRightArrow");
add_conversion_exception("CodeRegionFoldDownArrow");
add_conversion_exception("TextEditorPlay");
add_conversion_exception("Breakpoint");
}
Expand Down Expand Up @@ -2088,6 +2090,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color breakpoint_color = dark_theme ? error_color : Color(1, 0.27, 0.2, 1);
const Color executing_line_color = Color(0.98, 0.89, 0.27);
const Color code_folding_color = alpha3;
const Color folded_code_region_color = Color(0.68, 0.46, 0.77, 0.2);
const Color search_result_color = alpha1;
const Color search_result_border_color = dark_theme ? Color(0.41, 0.61, 0.91, 0.38) : Color(0, 0.4, 1, 0.38);

Expand Down Expand Up @@ -2128,6 +2131,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
setting->set_initial_value("text_editor/theme/highlighting/breakpoint_color", breakpoint_color, true);
setting->set_initial_value("text_editor/theme/highlighting/executing_line_color", executing_line_color, true);
setting->set_initial_value("text_editor/theme/highlighting/code_folding_color", code_folding_color, true);
setting->set_initial_value("text_editor/theme/highlighting/folded_code_region_color", folded_code_region_color, true);
setting->set_initial_value("text_editor/theme/highlighting/search_result_color", search_result_color, true);
setting->set_initial_value("text_editor/theme/highlighting/search_result_border_color", search_result_border_color, true);
} else if (text_editor_color_theme == "Godot 2") {
Expand All @@ -2147,6 +2151,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), EditorStringName(EditorIcons)));
theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("CodeFoldedRightArrow"), EditorStringName(EditorIcons)));
theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("CodeFoldDownArrow"), EditorStringName(EditorIcons)));
theme->set_icon("folded_code_region", "CodeEdit", theme->get_icon(SNAME("CodeRegionFoldedRightArrow"), EditorStringName(EditorIcons)));
theme->set_icon("can_fold_code_region", "CodeEdit", theme->get_icon(SNAME("CodeRegionFoldDownArrow"), EditorStringName(EditorIcons)));
theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("TextEditorPlay"), EditorStringName(EditorIcons)));
theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), EditorStringName(EditorIcons)));

Expand All @@ -2172,6 +2178,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("breakpoint_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/breakpoint_color"));
theme->set_color("executing_line_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/executing_line_color"));
theme->set_color("code_folding_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/code_folding_color"));
theme->set_color("folded_code_region_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/folded_code_region_color"));
theme->set_color("search_result_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/search_result_color"));
theme->set_color("search_result_border_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/search_result_border_color"));

Expand Down
1 change: 1 addition & 0 deletions editor/icons/CodeRegionFoldDownArrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions editor/icons/CodeRegionFoldedRightArrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 16 additions & 2 deletions editor/plugins/script_text_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,12 @@ void ScriptTextEditor::_load_theme_settings() {

Color updated_marked_line_color = EDITOR_GET("text_editor/theme/highlighting/mark_color");
Color updated_safe_line_number_color = EDITOR_GET("text_editor/theme/highlighting/safe_line_number_color");
Color updated_folded_code_region_color = EDITOR_GET("text_editor/theme/highlighting/folded_code_region_color");

bool safe_line_number_color_updated = updated_safe_line_number_color != safe_line_number_color;
bool marked_line_color_updated = updated_marked_line_color != marked_line_color;
if (safe_line_number_color_updated || marked_line_color_updated) {
bool folded_code_region_color_updated = updated_folded_code_region_color != folded_code_region_color;
if (safe_line_number_color_updated || marked_line_color_updated || folded_code_region_color_updated) {
safe_line_number_color = updated_safe_line_number_color;
for (int i = 0; i < text_edit->get_line_count(); i++) {
if (marked_line_color_updated && text_edit->get_line_background_color(i) == marked_line_color) {
Expand All @@ -194,8 +196,13 @@ void ScriptTextEditor::_load_theme_settings() {
if (safe_line_number_color_updated && text_edit->get_line_gutter_item_color(i, line_number_gutter) != default_line_number_color) {
text_edit->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
}

if (folded_code_region_color_updated && text_edit->get_line_background_color(i) == folded_code_region_color) {
text_edit->set_line_background_color(i, updated_folded_code_region_color);
}
}
marked_line_color = updated_marked_line_color;
folded_code_region_color = updated_folded_code_region_color;
}

theme_loaded = true;
Expand Down Expand Up @@ -647,7 +654,8 @@ void ScriptTextEditor::_update_errors() {
bool last_is_safe = false;
for (int i = 0; i < te->get_line_count(); i++) {
if (errors.is_empty()) {
te->set_line_background_color(i, Color(0, 0, 0, 0));
bool is_folded_code_region = te->is_line_code_region_start(i) && te->is_line_folded(i);
te->set_line_background_color(i, is_folded_code_region ? folded_code_region_color : Color(0, 0, 0, 0));
} else {
for (const ScriptLanguage::ScriptError &E : errors) {
bool error_line = i == E.line - 1;
Expand Down Expand Up @@ -1312,6 +1320,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
tx->unfold_all_lines();
tx->queue_redraw();
} break;
case EDIT_CREATE_CODE_REGION: {
tx->create_code_region();
} break;
case EDIT_TOGGLE_COMMENT: {
_edit_option_toggle_inline_comment();
} break;
Expand Down Expand Up @@ -2064,6 +2075,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/create_code_region"), EDIT_CREATE_CODE_REGION);
}
if (p_foldable) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
Expand Down Expand Up @@ -2178,6 +2190,7 @@ void ScriptTextEditor::_enable_code_editor() {
sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES);
sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES);
sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/create_code_region"), EDIT_CREATE_CODE_REGION);
sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option));
edit_menu->get_popup()->add_child(sub_menu);
edit_menu->get_popup()->add_submenu_item(TTR("Folding"), "folding_menu");
Expand Down Expand Up @@ -2373,6 +2386,7 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/toggle_fold_line", TTR("Fold/Unfold Line"), KeyModifierMask::ALT | Key::F);
ED_SHORTCUT_OVERRIDE("script_text_editor/toggle_fold_line", "macos", KeyModifierMask::CTRL | KeyModifierMask::META | Key::F);
ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), Key::NONE);
ED_SHORTCUT("script_text_editor/create_code_region", TTR("Create Code Region"), KeyModifierMask::ALT | Key::R);
ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), Key::NONE);
ED_SHORTCUT("script_text_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::SHIFT | KeyModifierMask::CTRL | Key::D);
ED_SHORTCUT_OVERRIDE("script_text_editor/duplicate_selection", "macos", KeyModifierMask::SHIFT | KeyModifierMask::META | Key::C);
Expand Down
2 changes: 2 additions & 0 deletions editor/plugins/script_text_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class ScriptTextEditor : public ScriptEditorBase {
Color safe_line_number_color = Color(1, 1, 1);

Color marked_line_color = Color(1, 1, 1);
Color folded_code_region_color = Color(1, 1, 1);

PopupPanel *color_panel = nullptr;
ColorPicker *color_picker = nullptr;
Expand Down Expand Up @@ -133,6 +134,7 @@ class ScriptTextEditor : public ScriptEditorBase {
EDIT_TOGGLE_WORD_WRAP,
EDIT_TOGGLE_FOLD_LINE,
EDIT_FOLD_ALL_LINES,
EDIT_CREATE_CODE_REGION,
EDIT_UNFOLD_ALL_LINES,
SEARCH_FIND,
SEARCH_FIND_NEXT,
Expand Down
Loading

0 comments on commit 67dce30

Please sign in to comment.