Merge pull request #74843 from jmb462/code_region
Add code region folding to CodeEdit
This commit is contained in:
commit
2c2ca3d958
|
@ -137,6 +137,15 @@
|
||||||
Values of [code]-1[/code] convert the entire text.
|
Values of [code]-1[/code] convert the entire text.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</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">
|
<method name="do_indent">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<description>
|
<description>
|
||||||
|
@ -200,6 +209,18 @@
|
||||||
Gets the index of the current selected completion option.
|
Gets the index of the current selected completion option.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</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">
|
<method name="get_delimiter_end_key" qualifiers="const">
|
||||||
<return type="String" />
|
<return type="String" />
|
||||||
<param index="0" name="delimiter_index" type="int" />
|
<param index="0" name="delimiter_index" type="int" />
|
||||||
|
@ -326,6 +347,20 @@
|
||||||
Returns whether the line at the specified index is breakpointed or not.
|
Returns whether the line at the specified index is breakpointed or not.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</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">
|
<method name="is_line_executing" qualifiers="const">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<param index="0" name="line" type="int" />
|
<param index="0" name="line" type="int" />
|
||||||
|
@ -382,6 +417,14 @@
|
||||||
Sets if the code hint should draw below the text.
|
Sets if the code hint should draw below the text.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="set_code_region_tags">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="start" type="String" default=""region"" />
|
||||||
|
<param index="1" name="end" type="String" default=""endregion"" />
|
||||||
|
<description>
|
||||||
|
Sets the code region start and end tags (without comment delimiter).
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="set_line_as_bookmarked">
|
<method name="set_line_as_bookmarked">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="line" type="int" />
|
<param index="0" name="line" type="int" />
|
||||||
|
@ -629,6 +672,9 @@
|
||||||
<theme_item name="executing_line_color" data_type="color" type="Color" default="Color(0.98, 0.89, 0.27, 1)">
|
<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.
|
[Color] of the executing icon for executing lines.
|
||||||
</theme_item>
|
</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)">
|
<theme_item name="font_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 1)">
|
||||||
Sets the font [Color].
|
Sets the font [Color].
|
||||||
</theme_item>
|
</theme_item>
|
||||||
|
@ -693,12 +739,18 @@
|
||||||
<theme_item name="can_fold" data_type="icon" type="Texture2D">
|
<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.
|
Sets a custom [Texture2D] to draw in the line folding gutter when a line can be folded.
|
||||||
</theme_item>
|
</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">
|
<theme_item name="executing_line" data_type="icon" type="Texture2D">
|
||||||
Icon to draw in the executing gutter for executing lines.
|
Icon to draw in the executing gutter for executing lines.
|
||||||
</theme_item>
|
</theme_item>
|
||||||
<theme_item name="folded" data_type="icon" type="Texture2D">
|
<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.
|
Sets a custom [Texture2D] to draw in the line folding gutter when a line is folded and can be unfolded.
|
||||||
</theme_item>
|
</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">
|
<theme_item name="folded_eol_icon" data_type="icon" type="Texture2D">
|
||||||
Sets a custom [Texture2D] to draw at the end of a folded line.
|
Sets a custom [Texture2D] to draw at the end of a folded line.
|
||||||
</theme_item>
|
</theme_item>
|
||||||
|
|
|
@ -959,6 +959,9 @@
|
||||||
<member name="text_editor/theme/highlighting/executing_line_color" type="Color" setter="" getter="">
|
<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).
|
The script editor's color for the debugger's executing line icon (displayed in the gutter).
|
||||||
</member>
|
</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="">
|
<member name="text_editor/theme/highlighting/function_color" type="Color" setter="" getter="">
|
||||||
The script editor's function call color.
|
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]).
|
[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]).
|
||||||
|
|
|
@ -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/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/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/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_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));
|
_initial_set("text_editor/theme/highlighting/search_result_border_color", Color(0.41, 0.61, 0.91, 0.38));
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,6 +208,8 @@ void EditorColorMap::create() {
|
||||||
add_conversion_exception("GuiSpace");
|
add_conversion_exception("GuiSpace");
|
||||||
add_conversion_exception("CodeFoldedRightArrow");
|
add_conversion_exception("CodeFoldedRightArrow");
|
||||||
add_conversion_exception("CodeFoldDownArrow");
|
add_conversion_exception("CodeFoldDownArrow");
|
||||||
|
add_conversion_exception("CodeRegionFoldedRightArrow");
|
||||||
|
add_conversion_exception("CodeRegionFoldDownArrow");
|
||||||
add_conversion_exception("TextEditorPlay");
|
add_conversion_exception("TextEditorPlay");
|
||||||
add_conversion_exception("Breakpoint");
|
add_conversion_exception("Breakpoint");
|
||||||
}
|
}
|
||||||
|
@ -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 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 executing_line_color = Color(0.98, 0.89, 0.27);
|
||||||
const Color code_folding_color = alpha3;
|
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_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);
|
const Color search_result_border_color = dark_theme ? Color(0.41, 0.61, 0.91, 0.38) : Color(0, 0.4, 1, 0.38);
|
||||||
|
|
||||||
|
@ -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/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/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/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_color", search_result_color, true);
|
||||||
setting->set_initial_value("text_editor/theme/highlighting/search_result_border_color", search_result_border_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") {
|
} else if (text_editor_color_theme == "Godot 2") {
|
||||||
|
@ -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("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), EditorStringName(EditorIcons)));
|
||||||
theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("CodeFoldedRightArrow"), 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("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("executing_line", "CodeEdit", theme->get_icon(SNAME("TextEditorPlay"), EditorStringName(EditorIcons)));
|
||||||
theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), EditorStringName(EditorIcons)));
|
theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), EditorStringName(EditorIcons)));
|
||||||
|
|
||||||
|
@ -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("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("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("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_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"));
|
theme->set_color("search_result_border_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/search_result_border_color"));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<svg height="12" width="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H6V2a1 1 0 0 0-1-1zm1 5a1 1 0 0 1 1.414-1.414L6 6.172l1.586-1.586A1 1 0 0 1 9 6L6.707 8.293a1 1 0 0 1-1.414 0Z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 289 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg height="12" width="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H6V2a1 1 0 0 0-1-1zm3.5 8a1 1 0 0 1-1.414-1.414L5.672 6 4.086 4.414A1 1 0 0 1 5.5 3l2.293 2.293a1 1 0 0 1 0 1.414Z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 293 B |
|
@ -181,10 +181,12 @@ void ScriptTextEditor::_load_theme_settings() {
|
||||||
|
|
||||||
Color updated_marked_line_color = EDITOR_GET("text_editor/theme/highlighting/mark_color");
|
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_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 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;
|
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;
|
safe_line_number_color = updated_safe_line_number_color;
|
||||||
for (int i = 0; i < text_edit->get_line_count(); i++) {
|
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) {
|
if (marked_line_color_updated && text_edit->get_line_background_color(i) == marked_line_color) {
|
||||||
|
@ -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) {
|
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);
|
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;
|
marked_line_color = updated_marked_line_color;
|
||||||
|
folded_code_region_color = updated_folded_code_region_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
theme_loaded = true;
|
theme_loaded = true;
|
||||||
|
@ -647,7 +654,8 @@ void ScriptTextEditor::_update_errors() {
|
||||||
bool last_is_safe = false;
|
bool last_is_safe = false;
|
||||||
for (int i = 0; i < te->get_line_count(); i++) {
|
for (int i = 0; i < te->get_line_count(); i++) {
|
||||||
if (errors.is_empty()) {
|
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 {
|
} else {
|
||||||
for (const ScriptLanguage::ScriptError &E : errors) {
|
for (const ScriptLanguage::ScriptError &E : errors) {
|
||||||
bool error_line = i == E.line - 1;
|
bool error_line = i == E.line - 1;
|
||||||
|
@ -1312,6 +1320,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
tx->unfold_all_lines();
|
tx->unfold_all_lines();
|
||||||
tx->queue_redraw();
|
tx->queue_redraw();
|
||||||
} break;
|
} break;
|
||||||
|
case EDIT_CREATE_CODE_REGION: {
|
||||||
|
tx->create_code_region();
|
||||||
|
} break;
|
||||||
case EDIT_TOGGLE_COMMENT: {
|
case EDIT_TOGGLE_COMMENT: {
|
||||||
_edit_option_toggle_inline_comment();
|
_edit_option_toggle_inline_comment();
|
||||||
} break;
|
} break;
|
||||||
|
@ -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_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/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/evaluate_selection"), EDIT_EVALUATE);
|
||||||
|
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/create_code_region"), EDIT_CREATE_CODE_REGION);
|
||||||
}
|
}
|
||||||
if (p_foldable) {
|
if (p_foldable) {
|
||||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
|
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
|
||||||
|
@ -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/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/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/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));
|
sub_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option));
|
||||||
edit_menu->get_popup()->add_child(sub_menu);
|
edit_menu->get_popup()->add_child(sub_menu);
|
||||||
edit_menu->get_popup()->add_submenu_item(TTR("Folding"), "folding_menu");
|
edit_menu->get_popup()->add_submenu_item(TTR("Folding"), "folding_menu");
|
||||||
|
@ -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("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_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/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/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("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);
|
ED_SHORTCUT_OVERRIDE("script_text_editor/duplicate_selection", "macos", KeyModifierMask::SHIFT | KeyModifierMask::META | Key::C);
|
||||||
|
|
|
@ -98,6 +98,7 @@ class ScriptTextEditor : public ScriptEditorBase {
|
||||||
Color safe_line_number_color = Color(1, 1, 1);
|
Color safe_line_number_color = Color(1, 1, 1);
|
||||||
|
|
||||||
Color marked_line_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;
|
PopupPanel *color_panel = nullptr;
|
||||||
ColorPicker *color_picker = nullptr;
|
ColorPicker *color_picker = nullptr;
|
||||||
|
@ -133,6 +134,7 @@ class ScriptTextEditor : public ScriptEditorBase {
|
||||||
EDIT_TOGGLE_WORD_WRAP,
|
EDIT_TOGGLE_WORD_WRAP,
|
||||||
EDIT_TOGGLE_FOLD_LINE,
|
EDIT_TOGGLE_FOLD_LINE,
|
||||||
EDIT_FOLD_ALL_LINES,
|
EDIT_FOLD_ALL_LINES,
|
||||||
|
EDIT_CREATE_CODE_REGION,
|
||||||
EDIT_UNFOLD_ALL_LINES,
|
EDIT_UNFOLD_ALL_LINES,
|
||||||
SEARCH_FIND,
|
SEARCH_FIND,
|
||||||
SEARCH_FIND_NEXT,
|
SEARCH_FIND_NEXT,
|
||||||
|
|
|
@ -1523,7 +1523,19 @@ void CodeEdit::_fold_gutter_draw_callback(int p_line, int p_gutter, Rect2 p_regi
|
||||||
p_region.position += Point2(horizontal_padding, vertical_padding);
|
p_region.position += Point2(horizontal_padding, vertical_padding);
|
||||||
p_region.size -= Point2(horizontal_padding, vertical_padding) * 2;
|
p_region.size -= Point2(horizontal_padding, vertical_padding) * 2;
|
||||||
|
|
||||||
if (can_fold_line(p_line)) {
|
bool can_fold = can_fold_line(p_line);
|
||||||
|
|
||||||
|
if (is_line_code_region_start(p_line)) {
|
||||||
|
Color region_icon_color = theme_cache.folded_code_region_color;
|
||||||
|
region_icon_color.a = MAX(region_icon_color.a, 0.4f);
|
||||||
|
if (can_fold) {
|
||||||
|
theme_cache.can_fold_code_region_icon->draw_rect(get_canvas_item(), p_region, false, region_icon_color);
|
||||||
|
} else {
|
||||||
|
theme_cache.folded_code_region_icon->draw_rect(get_canvas_item(), p_region, false, region_icon_color);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (can_fold) {
|
||||||
theme_cache.can_fold_icon->draw_rect(get_canvas_item(), p_region, false, theme_cache.code_folding_color);
|
theme_cache.can_fold_icon->draw_rect(get_canvas_item(), p_region, false, theme_cache.code_folding_color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1554,6 +1566,27 @@ bool CodeEdit::can_fold_line(int p_line) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for code region.
|
||||||
|
if (is_line_code_region_end(p_line)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (is_line_code_region_start(p_line)) {
|
||||||
|
int region_level = 0;
|
||||||
|
// Check if there is a valid end region tag.
|
||||||
|
for (int next_line = p_line + 1; next_line < get_line_count(); next_line++) {
|
||||||
|
if (is_line_code_region_end(next_line)) {
|
||||||
|
region_level -= 1;
|
||||||
|
if (region_level == -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_line_code_region_start(next_line)) {
|
||||||
|
region_level += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for full multiline line or block strings / comments. */
|
/* Check for full multiline line or block strings / comments. */
|
||||||
int in_comment = is_in_comment(p_line);
|
int in_comment = is_in_comment(p_line);
|
||||||
int in_string = (in_comment == -1) ? is_in_string(p_line) : -1;
|
int in_string = (in_comment == -1) ? is_in_string(p_line) : -1;
|
||||||
|
@ -1562,13 +1595,13 @@ bool CodeEdit::can_fold_line(int p_line) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int delimter_end_line = get_delimiter_end_position(p_line, get_line(p_line).size() - 1).y;
|
int delimiter_end_line = get_delimiter_end_position(p_line, get_line(p_line).size() - 1).y;
|
||||||
/* No end line, therefore we have a multiline region over the rest of the file. */
|
/* No end line, therefore we have a multiline region over the rest of the file. */
|
||||||
if (delimter_end_line == -1) {
|
if (delimiter_end_line == -1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* End line is the same therefore we have a block. */
|
/* End line is the same therefore we have a block. */
|
||||||
if (delimter_end_line == p_line) {
|
if (delimiter_end_line == p_line) {
|
||||||
/* Check we are the start of the block. */
|
/* Check we are the start of the block. */
|
||||||
if (p_line - 1 >= 0) {
|
if (p_line - 1 >= 0) {
|
||||||
if ((in_string != -1 && is_in_string(p_line - 1) != -1) || (in_comment != -1 && is_in_comment(p_line - 1) != -1)) {
|
if ((in_string != -1 && is_in_string(p_line - 1) != -1) || (in_comment != -1 && is_in_comment(p_line - 1) != -1)) {
|
||||||
|
@ -1578,7 +1611,7 @@ bool CodeEdit::can_fold_line(int p_line) const {
|
||||||
/* Check it continues for at least one line. */
|
/* Check it continues for at least one line. */
|
||||||
return ((in_string != -1 && is_in_string(p_line + 1) != -1) || (in_comment != -1 && is_in_comment(p_line + 1) != -1));
|
return ((in_string != -1 && is_in_string(p_line + 1) != -1) || (in_comment != -1 && is_in_comment(p_line + 1) != -1));
|
||||||
}
|
}
|
||||||
return ((in_string != -1 && is_in_string(delimter_end_line) != -1) || (in_comment != -1 && is_in_comment(delimter_end_line) != -1));
|
return ((in_string != -1 && is_in_string(delimiter_end_line) != -1) || (in_comment != -1 && is_in_comment(delimiter_end_line) != -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise check indent levels. */
|
/* Otherwise check indent levels. */
|
||||||
|
@ -1602,31 +1635,51 @@ void CodeEdit::fold_line(int p_line) {
|
||||||
const int line_count = get_line_count() - 1;
|
const int line_count = get_line_count() - 1;
|
||||||
int end_line = line_count;
|
int end_line = line_count;
|
||||||
|
|
||||||
int in_comment = is_in_comment(p_line);
|
// Fold code region.
|
||||||
int in_string = (in_comment == -1) ? is_in_string(p_line) : -1;
|
if (is_line_code_region_start(p_line)) {
|
||||||
if (in_string != -1 || in_comment != -1) {
|
int region_level = 0;
|
||||||
end_line = get_delimiter_end_position(p_line, get_line(p_line).size() - 1).y;
|
for (int endregion_line = p_line + 1; endregion_line < get_line_count(); endregion_line++) {
|
||||||
/* End line is the same therefore we have a block of single line delimiters. */
|
if (is_line_code_region_start(endregion_line)) {
|
||||||
if (end_line == p_line) {
|
region_level += 1;
|
||||||
for (int i = p_line + 1; i <= line_count; i++) {
|
}
|
||||||
if ((in_string != -1 && is_in_string(i) == -1) || (in_comment != -1 && is_in_comment(i) == -1)) {
|
if (is_line_code_region_end(endregion_line)) {
|
||||||
|
region_level -= 1;
|
||||||
|
if (region_level == -1) {
|
||||||
|
end_line = endregion_line;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
end_line = i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
set_line_background_color(p_line, theme_cache.folded_code_region_color);
|
||||||
int start_indent = get_indent_level(p_line);
|
}
|
||||||
for (int i = p_line + 1; i <= line_count; i++) {
|
|
||||||
if (get_line(i).strip_edges().size() == 0) {
|
int in_comment = is_in_comment(p_line);
|
||||||
continue;
|
int in_string = (in_comment == -1) ? is_in_string(p_line) : -1;
|
||||||
|
if (!is_line_code_region_start(p_line)) {
|
||||||
|
if (in_string != -1 || in_comment != -1) {
|
||||||
|
end_line = get_delimiter_end_position(p_line, get_line(p_line).size() - 1).y;
|
||||||
|
// End line is the same therefore we have a block of single line delimiters.
|
||||||
|
if (end_line == p_line) {
|
||||||
|
for (int i = p_line + 1; i <= line_count; i++) {
|
||||||
|
if ((in_string != -1 && is_in_string(i) == -1) || (in_comment != -1 && is_in_comment(i) == -1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
end_line = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (get_indent_level(i) > start_indent) {
|
} else {
|
||||||
end_line = i;
|
int start_indent = get_indent_level(p_line);
|
||||||
continue;
|
for (int i = p_line + 1; i <= line_count; i++) {
|
||||||
}
|
if (get_line(i).strip_edges().size() == 0) {
|
||||||
if (is_in_string(i) == -1 && is_in_comment(i) == -1) {
|
continue;
|
||||||
break;
|
}
|
||||||
|
if (get_indent_level(i) > start_indent) {
|
||||||
|
end_line = i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (is_in_string(i) == -1 && is_in_comment(i) == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1677,6 +1730,9 @@ void CodeEdit::unfold_line(int p_line) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_set_line_as_hidden(i, false);
|
_set_line_as_hidden(i, false);
|
||||||
|
if (is_line_code_region_start(i - 1)) {
|
||||||
|
set_line_background_color(i - 1, Color(0.0, 0.0, 0.0, 0.0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
queue_redraw();
|
queue_redraw();
|
||||||
}
|
}
|
||||||
|
@ -1716,6 +1772,95 @@ TypedArray<int> CodeEdit::get_folded_lines() const {
|
||||||
return folded_lines;
|
return folded_lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Code region */
|
||||||
|
void CodeEdit::create_code_region() {
|
||||||
|
// Abort if there is no selected text.
|
||||||
|
if (!has_selection()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check that region tag find a comment delimiter and is valid.
|
||||||
|
if (code_region_start_string.is_empty()) {
|
||||||
|
WARN_PRINT_ONCE("Cannot create code region without any one line comment delimiters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
begin_complex_operation();
|
||||||
|
// Merge selections if selection starts on the same line the previous one ends.
|
||||||
|
Vector<int> caret_edit_order = get_caret_index_edit_order();
|
||||||
|
Vector<int> carets_to_remove;
|
||||||
|
for (int i = 1; i < caret_edit_order.size(); i++) {
|
||||||
|
int current_caret = caret_edit_order[i - 1];
|
||||||
|
int next_caret = caret_edit_order[i];
|
||||||
|
if (get_selection_from_line(current_caret) == get_selection_to_line(next_caret)) {
|
||||||
|
select(get_selection_from_line(next_caret), get_selection_from_column(next_caret), get_selection_to_line(current_caret), get_selection_to_column(current_caret), next_caret);
|
||||||
|
carets_to_remove.append(current_caret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Sort and remove backwards to preserve indices.
|
||||||
|
carets_to_remove.sort();
|
||||||
|
for (int i = carets_to_remove.size() - 1; i >= 0; i--) {
|
||||||
|
remove_caret(carets_to_remove[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding start and end region tags.
|
||||||
|
int first_region_start = -1;
|
||||||
|
for (int caret_idx : get_caret_index_edit_order()) {
|
||||||
|
if (!has_selection(caret_idx)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int from_line = get_selection_from_line(caret_idx);
|
||||||
|
if (first_region_start == -1 || from_line < first_region_start) {
|
||||||
|
first_region_start = from_line;
|
||||||
|
}
|
||||||
|
int to_line = get_selection_to_line(caret_idx);
|
||||||
|
set_line(to_line, get_line(to_line) + "\n" + code_region_end_string);
|
||||||
|
insert_line_at(from_line, code_region_start_string + " " + RTR("New Code Region"));
|
||||||
|
fold_line(from_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select name of the first region to allow quick edit.
|
||||||
|
remove_secondary_carets();
|
||||||
|
set_caret_line(first_region_start);
|
||||||
|
int tag_length = code_region_start_string.length() + RTR("New Code Region").length() + 1;
|
||||||
|
set_caret_column(tag_length);
|
||||||
|
select(first_region_start, code_region_start_string.length() + 1, first_region_start, tag_length);
|
||||||
|
|
||||||
|
end_complex_operation();
|
||||||
|
queue_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
String CodeEdit::get_code_region_start_tag() const {
|
||||||
|
return code_region_start_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
String CodeEdit::get_code_region_end_tag() const {
|
||||||
|
return code_region_end_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodeEdit::set_code_region_tags(const String &p_start, const String &p_end) {
|
||||||
|
ERR_FAIL_COND_MSG(p_start == p_end, "Starting and ending region tags cannot be identical.");
|
||||||
|
ERR_FAIL_COND_MSG(p_start.is_empty(), "Starting region tag cannot be empty.");
|
||||||
|
ERR_FAIL_COND_MSG(p_end.is_empty(), "Ending region tag cannot be empty.");
|
||||||
|
code_region_start_tag = p_start;
|
||||||
|
code_region_end_tag = p_end;
|
||||||
|
_update_code_region_tags();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CodeEdit::is_line_code_region_start(int p_line) const {
|
||||||
|
ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
|
||||||
|
if (code_region_start_string.is_empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return get_line(p_line).strip_edges().begins_with(code_region_start_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CodeEdit::is_line_code_region_end(int p_line) const {
|
||||||
|
ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
|
||||||
|
if (code_region_start_string.is_empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return get_line(p_line).strip_edges().begins_with(code_region_end_string);
|
||||||
|
}
|
||||||
|
|
||||||
/* Delimiters */
|
/* Delimiters */
|
||||||
// Strings
|
// Strings
|
||||||
void CodeEdit::add_string_delimiter(const String &p_start_key, const String &p_end_key, bool p_line_only) {
|
void CodeEdit::add_string_delimiter(const String &p_start_key, const String &p_end_key, bool p_line_only) {
|
||||||
|
@ -2344,6 +2489,14 @@ void CodeEdit::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("is_line_folded", "line"), &CodeEdit::is_line_folded);
|
ClassDB::bind_method(D_METHOD("is_line_folded", "line"), &CodeEdit::is_line_folded);
|
||||||
ClassDB::bind_method(D_METHOD("get_folded_lines"), &CodeEdit::get_folded_lines);
|
ClassDB::bind_method(D_METHOD("get_folded_lines"), &CodeEdit::get_folded_lines);
|
||||||
|
|
||||||
|
/* Code region */
|
||||||
|
ClassDB::bind_method(D_METHOD("create_code_region"), &CodeEdit::create_code_region);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_code_region_start_tag"), &CodeEdit::get_code_region_start_tag);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_code_region_end_tag"), &CodeEdit::get_code_region_end_tag);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_code_region_tags", "start", "end"), &CodeEdit::set_code_region_tags, DEFVAL("region"), DEFVAL("endregion"));
|
||||||
|
ClassDB::bind_method(D_METHOD("is_line_code_region_start", "line"), &CodeEdit::is_line_code_region_start);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_line_code_region_end", "line"), &CodeEdit::is_line_code_region_end);
|
||||||
|
|
||||||
/* Delimiters */
|
/* Delimiters */
|
||||||
// Strings
|
// Strings
|
||||||
ClassDB::bind_method(D_METHOD("add_string_delimiter", "start_key", "end_key", "line_only"), &CodeEdit::add_string_delimiter, DEFVAL(false));
|
ClassDB::bind_method(D_METHOD("add_string_delimiter", "start_key", "end_key", "line_only"), &CodeEdit::add_string_delimiter, DEFVAL(false));
|
||||||
|
@ -2483,8 +2636,11 @@ void CodeEdit::_bind_methods() {
|
||||||
/* Theme items */
|
/* Theme items */
|
||||||
/* Gutters */
|
/* Gutters */
|
||||||
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, code_folding_color);
|
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, code_folding_color);
|
||||||
|
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, folded_code_region_color);
|
||||||
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, can_fold_icon, "can_fold");
|
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, can_fold_icon, "can_fold");
|
||||||
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, folded_icon, "folded");
|
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, folded_icon, "folded");
|
||||||
|
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, can_fold_code_region_icon, "can_fold_code_region");
|
||||||
|
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, folded_code_region_icon, "folded_code_region");
|
||||||
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, CodeEdit, folded_eol_icon);
|
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, CodeEdit, folded_eol_icon);
|
||||||
|
|
||||||
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, breakpoint_color);
|
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, breakpoint_color);
|
||||||
|
@ -2628,6 +2784,27 @@ void CodeEdit::_update_gutter_indexes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Code Region */
|
||||||
|
void CodeEdit::_update_code_region_tags() {
|
||||||
|
code_region_start_string = "";
|
||||||
|
code_region_end_string = "";
|
||||||
|
|
||||||
|
if (code_region_start_tag.is_empty() || code_region_end_tag.is_empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < delimiters.size(); i++) {
|
||||||
|
if (delimiters[i].type != DelimiterType::TYPE_COMMENT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (delimiters[i].end_key.is_empty() && delimiters[i].line_only == true) {
|
||||||
|
code_region_start_string = delimiters[i].start_key + code_region_start_tag;
|
||||||
|
code_region_end_string = delimiters[i].start_key + code_region_end_tag;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Delimiters */
|
/* Delimiters */
|
||||||
void CodeEdit::_update_delimiter_cache(int p_from_line, int p_to_line) {
|
void CodeEdit::_update_delimiter_cache(int p_from_line, int p_to_line) {
|
||||||
if (delimiters.size() == 0) {
|
if (delimiters.size() == 0) {
|
||||||
|
@ -2871,6 +3048,9 @@ void CodeEdit::_add_delimiter(const String &p_start_key, const String &p_end_key
|
||||||
delimiter_cache.clear();
|
delimiter_cache.clear();
|
||||||
_update_delimiter_cache();
|
_update_delimiter_cache();
|
||||||
}
|
}
|
||||||
|
if (p_type == DelimiterType::TYPE_COMMENT) {
|
||||||
|
_update_code_region_tags();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeEdit::_remove_delimiter(const String &p_start_key, DelimiterType p_type) {
|
void CodeEdit::_remove_delimiter(const String &p_start_key, DelimiterType p_type) {
|
||||||
|
@ -2888,6 +3068,9 @@ void CodeEdit::_remove_delimiter(const String &p_start_key, DelimiterType p_type
|
||||||
delimiter_cache.clear();
|
delimiter_cache.clear();
|
||||||
_update_delimiter_cache();
|
_update_delimiter_cache();
|
||||||
}
|
}
|
||||||
|
if (p_type == DelimiterType::TYPE_COMMENT) {
|
||||||
|
_update_code_region_tags();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2931,6 +3114,9 @@ void CodeEdit::_clear_delimiters(DelimiterType p_type) {
|
||||||
if (!setting_delimiters) {
|
if (!setting_delimiters) {
|
||||||
_update_delimiter_cache();
|
_update_delimiter_cache();
|
||||||
}
|
}
|
||||||
|
if (p_type == DelimiterType::TYPE_COMMENT) {
|
||||||
|
_update_code_region_tags();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedArray<String> CodeEdit::_get_delimiters(DelimiterType p_type) const {
|
TypedArray<String> CodeEdit::_get_delimiters(DelimiterType p_type) const {
|
||||||
|
|
|
@ -125,6 +125,11 @@ private:
|
||||||
|
|
||||||
/* Line Folding */
|
/* Line Folding */
|
||||||
bool line_folding_enabled = false;
|
bool line_folding_enabled = false;
|
||||||
|
String code_region_start_string;
|
||||||
|
String code_region_end_string;
|
||||||
|
String code_region_start_tag = "region";
|
||||||
|
String code_region_end_tag = "endregion";
|
||||||
|
void _update_code_region_tags();
|
||||||
|
|
||||||
/* Delimiters */
|
/* Delimiters */
|
||||||
enum DelimiterType {
|
enum DelimiterType {
|
||||||
|
@ -232,8 +237,11 @@ private:
|
||||||
struct ThemeCache {
|
struct ThemeCache {
|
||||||
/* Gutters */
|
/* Gutters */
|
||||||
Color code_folding_color = Color(1, 1, 1);
|
Color code_folding_color = Color(1, 1, 1);
|
||||||
|
Color folded_code_region_color = Color(1, 1, 1);
|
||||||
Ref<Texture2D> can_fold_icon;
|
Ref<Texture2D> can_fold_icon;
|
||||||
Ref<Texture2D> folded_icon;
|
Ref<Texture2D> folded_icon;
|
||||||
|
Ref<Texture2D> can_fold_code_region_icon;
|
||||||
|
Ref<Texture2D> folded_code_region_icon;
|
||||||
Ref<Texture2D> folded_eol_icon;
|
Ref<Texture2D> folded_eol_icon;
|
||||||
|
|
||||||
Color breakpoint_color = Color(1, 1, 1);
|
Color breakpoint_color = Color(1, 1, 1);
|
||||||
|
@ -397,6 +405,14 @@ public:
|
||||||
bool is_line_folded(int p_line) const;
|
bool is_line_folded(int p_line) const;
|
||||||
TypedArray<int> get_folded_lines() const;
|
TypedArray<int> get_folded_lines() const;
|
||||||
|
|
||||||
|
/* Code region */
|
||||||
|
void create_code_region();
|
||||||
|
String get_code_region_start_tag() const;
|
||||||
|
String get_code_region_end_tag() const;
|
||||||
|
void set_code_region_tags(const String &p_start = "region", const String &p_end = "endregion");
|
||||||
|
bool is_line_code_region_start(int p_line) const;
|
||||||
|
bool is_line_code_region_end(int p_line) const;
|
||||||
|
|
||||||
/* Delimiters */
|
/* Delimiters */
|
||||||
void add_string_delimiter(const String &p_start_key, const String &p_end_key, bool p_line_only = false);
|
void add_string_delimiter(const String &p_start_key, const String &p_end_key, bool p_line_only = false);
|
||||||
void remove_string_delimiter(const String &p_start_key);
|
void remove_string_delimiter(const String &p_start_key);
|
||||||
|
|
|
@ -3000,6 +3000,7 @@ void TextEdit::_update_theme_item_cache() {
|
||||||
Control::_update_theme_item_cache();
|
Control::_update_theme_item_cache();
|
||||||
|
|
||||||
theme_cache.base_scale = get_theme_default_base_scale();
|
theme_cache.base_scale = get_theme_default_base_scale();
|
||||||
|
theme_cache.folded_code_region_color = get_theme_color(SNAME("folded_code_region_color"), SNAME("CodeEdit"));
|
||||||
use_selected_font_color = theme_cache.font_selected_color != Color(0, 0, 0, 0);
|
use_selected_font_color = theme_cache.font_selected_color != Color(0, 0, 0, 0);
|
||||||
|
|
||||||
if (text.get_line_height() + theme_cache.line_spacing < 1) {
|
if (text.get_line_height() + theme_cache.line_spacing < 1) {
|
||||||
|
@ -6476,6 +6477,7 @@ void TextEdit::_bind_methods() {
|
||||||
/* Internal API for CodeEdit */
|
/* Internal API for CodeEdit */
|
||||||
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, brace_mismatch_color, "brace_mismatch_color", "CodeEdit");
|
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, brace_mismatch_color, "brace_mismatch_color", "CodeEdit");
|
||||||
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, code_folding_color, "code_folding_color", "CodeEdit");
|
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, code_folding_color, "code_folding_color", "CodeEdit");
|
||||||
|
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, folded_code_region_color, "folded_code_region_color", "CodeEdit");
|
||||||
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_ICON, TextEdit, folded_eol_icon, "folded_eol_icon", "CodeEdit");
|
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_ICON, TextEdit, folded_eol_icon, "folded_eol_icon", "CodeEdit");
|
||||||
|
|
||||||
/* Search */
|
/* Search */
|
||||||
|
|
|
@ -546,6 +546,7 @@ private:
|
||||||
/* Internal API for CodeEdit */
|
/* Internal API for CodeEdit */
|
||||||
Color brace_mismatch_color;
|
Color brace_mismatch_color;
|
||||||
Color code_folding_color = Color(1, 1, 1);
|
Color code_folding_color = Color(1, 1, 1);
|
||||||
|
Color folded_code_region_color = Color(1, 1, 1);
|
||||||
Ref<Texture2D> folded_eol_icon;
|
Ref<Texture2D> folded_eol_icon;
|
||||||
|
|
||||||
/* Search */
|
/* Search */
|
||||||
|
|
|
@ -478,6 +478,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
||||||
theme->set_icon("executing_line", "CodeEdit", icons["arrow_right"]);
|
theme->set_icon("executing_line", "CodeEdit", icons["arrow_right"]);
|
||||||
theme->set_icon("can_fold", "CodeEdit", icons["arrow_down"]);
|
theme->set_icon("can_fold", "CodeEdit", icons["arrow_down"]);
|
||||||
theme->set_icon("folded", "CodeEdit", icons["arrow_right"]);
|
theme->set_icon("folded", "CodeEdit", icons["arrow_right"]);
|
||||||
|
theme->set_icon("can_fold_code_region", "CodeEdit", icons["folder_down_arrow"]);
|
||||||
|
theme->set_icon("folded_code_region", "CodeEdit", icons["folder_right_arrow"]);
|
||||||
theme->set_icon("folded_eol_icon", "CodeEdit", icons["text_edit_ellipsis"]);
|
theme->set_icon("folded_eol_icon", "CodeEdit", icons["text_edit_ellipsis"]);
|
||||||
|
|
||||||
theme->set_font("font", "CodeEdit", Ref<Font>());
|
theme->set_font("font", "CodeEdit", Ref<Font>());
|
||||||
|
@ -501,6 +503,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
||||||
theme->set_color("executing_line_color", "CodeEdit", Color(0.98, 0.89, 0.27));
|
theme->set_color("executing_line_color", "CodeEdit", Color(0.98, 0.89, 0.27));
|
||||||
theme->set_color("current_line_color", "CodeEdit", Color(0.25, 0.25, 0.26, 0.8));
|
theme->set_color("current_line_color", "CodeEdit", Color(0.25, 0.25, 0.26, 0.8));
|
||||||
theme->set_color("code_folding_color", "CodeEdit", Color(0.8, 0.8, 0.8, 0.8));
|
theme->set_color("code_folding_color", "CodeEdit", Color(0.8, 0.8, 0.8, 0.8));
|
||||||
|
theme->set_color("folded_code_region_color", "CodeEdit", Color(0.68, 0.46, 0.77, 0.2));
|
||||||
theme->set_color("caret_color", "CodeEdit", control_font_color);
|
theme->set_color("caret_color", "CodeEdit", control_font_color);
|
||||||
theme->set_color("caret_background_color", "CodeEdit", Color(0, 0, 0));
|
theme->set_color("caret_background_color", "CodeEdit", Color(0, 0, 0));
|
||||||
theme->set_color("brace_mismatch_color", "CodeEdit", Color(1, 0.2, 0.2));
|
theme->set_color("brace_mismatch_color", "CodeEdit", Color(1, 0.2, 0.2));
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<svg height="12" width="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H6V2a1 1 0 0 0-1-1zm1 5a1 1 0 0 1 1.414-1.414L6 6.172l1.586-1.586A1 1 0 0 1 9 6L6.707 8.293a1 1 0 0 1-1.414 0Z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 289 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg height="12" width="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H6V2a1 1 0 0 0-1-1zm3.5 8a1 1 0 0 1-1.414-1.414L5.672 6 4.086 4.414A1 1 0 0 1 5.5 3l2.293 2.293a1 1 0 0 1 0 1.414Z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 293 B |
|
@ -2839,6 +2839,194 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
|
||||||
memdelete(code_edit);
|
memdelete(code_edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[SceneTree][CodeEdit] region folding") {
|
||||||
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
code_edit->grab_focus();
|
||||||
|
|
||||||
|
SUBCASE("[CodeEdit] region folding") {
|
||||||
|
code_edit->set_line_folding_enabled(true);
|
||||||
|
|
||||||
|
// Region tag detection.
|
||||||
|
code_edit->set_text("#region region_name\nline2\n#endregion");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
CHECK(code_edit->is_line_code_region_start(0));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_start(1));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_start(2));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_end(0));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_end(1));
|
||||||
|
CHECK(code_edit->is_line_code_region_end(2));
|
||||||
|
|
||||||
|
// Region tag customization.
|
||||||
|
code_edit->set_text("#region region_name\nline2\n#endregion\n#open region_name\nline2\n#close");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
CHECK(code_edit->is_line_code_region_start(0));
|
||||||
|
CHECK(code_edit->is_line_code_region_end(2));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_start(3));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_end(5));
|
||||||
|
code_edit->set_code_region_tags("open", "close");
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_start(0));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_end(2));
|
||||||
|
CHECK(code_edit->is_line_code_region_start(3));
|
||||||
|
CHECK(code_edit->is_line_code_region_end(5));
|
||||||
|
code_edit->set_code_region_tags("region", "endregion");
|
||||||
|
|
||||||
|
// Setting identical start and end region tags should fail.
|
||||||
|
CHECK(code_edit->get_code_region_start_tag() == "region");
|
||||||
|
CHECK(code_edit->get_code_region_end_tag() == "endregion");
|
||||||
|
ERR_PRINT_OFF;
|
||||||
|
code_edit->set_code_region_tags("same_tag", "same_tag");
|
||||||
|
ERR_PRINT_ON;
|
||||||
|
CHECK(code_edit->get_code_region_start_tag() == "region");
|
||||||
|
CHECK(code_edit->get_code_region_end_tag() == "endregion");
|
||||||
|
|
||||||
|
// Region creation with selection adds start / close region lines.
|
||||||
|
code_edit->set_text("line1\nline2\nline3");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
code_edit->select(1, 0, 1, 4);
|
||||||
|
code_edit->create_code_region();
|
||||||
|
CHECK(code_edit->is_line_code_region_start(1));
|
||||||
|
CHECK(code_edit->get_line(2).contains("line2"));
|
||||||
|
CHECK(code_edit->is_line_code_region_end(3));
|
||||||
|
|
||||||
|
// Region creation without any selection has no effect.
|
||||||
|
code_edit->set_text("line1\nline2\nline3");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
code_edit->create_code_region();
|
||||||
|
CHECK(code_edit->get_text() == "line1\nline2\nline3");
|
||||||
|
|
||||||
|
// Region creation with multiple selections.
|
||||||
|
code_edit->set_text("line1\nline2\nline3");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
code_edit->select(0, 0, 0, 4, 0);
|
||||||
|
code_edit->add_caret(2, 5);
|
||||||
|
code_edit->select(2, 0, 2, 5, 1);
|
||||||
|
code_edit->create_code_region();
|
||||||
|
CHECK(code_edit->get_text() == "#region New Code Region\nline1\n#endregion\nline2\n#region New Code Region\nline3\n#endregion");
|
||||||
|
|
||||||
|
// Two selections on the same line create only one region.
|
||||||
|
code_edit->set_text("test line1\ntest line2\ntest line3");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
code_edit->select(0, 0, 1, 2, 0);
|
||||||
|
code_edit->add_caret(1, 4);
|
||||||
|
code_edit->select(1, 4, 2, 5, 1);
|
||||||
|
code_edit->create_code_region();
|
||||||
|
CHECK(code_edit->get_text() == "#region New Code Region\ntest line1\ntest line2\ntest line3\n#endregion");
|
||||||
|
|
||||||
|
// Region tag with // comment delimiter.
|
||||||
|
code_edit->set_text("//region region_name\nline2\n//endregion");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("//", "");
|
||||||
|
CHECK(code_edit->is_line_code_region_start(0));
|
||||||
|
CHECK(code_edit->is_line_code_region_end(2));
|
||||||
|
|
||||||
|
// Creating region with no valid one line comment delimiter has no effect.
|
||||||
|
code_edit->set_text("line1\nline2\nline3");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->create_code_region();
|
||||||
|
CHECK(code_edit->get_text() == "line1\nline2\nline3");
|
||||||
|
code_edit->add_comment_delimiter("/*", "*/");
|
||||||
|
code_edit->create_code_region();
|
||||||
|
CHECK(code_edit->get_text() == "line1\nline2\nline3");
|
||||||
|
|
||||||
|
// Choose one line comment delimiter.
|
||||||
|
code_edit->set_text("//region region_name\nline2\n//endregion");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("/*", "*/");
|
||||||
|
code_edit->add_comment_delimiter("//", "");
|
||||||
|
CHECK(code_edit->is_line_code_region_start(0));
|
||||||
|
CHECK(code_edit->is_line_code_region_end(2));
|
||||||
|
|
||||||
|
// Update code region delimiter when removing comment delimiter.
|
||||||
|
code_edit->set_text("//region region_name\nline2\n//endregion\n#region region_name\nline2\n#endregion");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("//", "");
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
CHECK(code_edit->is_line_code_region_start(0));
|
||||||
|
CHECK(code_edit->is_line_code_region_end(2));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_start(3));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_end(5));
|
||||||
|
code_edit->remove_comment_delimiter("//");
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_start(0));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_end(2));
|
||||||
|
CHECK(code_edit->is_line_code_region_start(3));
|
||||||
|
CHECK(code_edit->is_line_code_region_end(5));
|
||||||
|
|
||||||
|
// Update code region delimiter when clearing comment delimiters.
|
||||||
|
code_edit->set_text("//region region_name\nline2\n//endregion");
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("//", "");
|
||||||
|
CHECK(code_edit->is_line_code_region_start(0));
|
||||||
|
CHECK(code_edit->is_line_code_region_end(2));
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_start(0));
|
||||||
|
CHECK_FALSE(code_edit->is_line_code_region_end(2));
|
||||||
|
|
||||||
|
// Fold region.
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
code_edit->set_text("#region region_name\nline2\nline3\n#endregion\nvisible line");
|
||||||
|
CHECK(code_edit->can_fold_line(0));
|
||||||
|
for (int i = 1; i < 5; i++) {
|
||||||
|
CHECK_FALSE(code_edit->can_fold_line(i));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
CHECK_FALSE(code_edit->is_line_folded(i));
|
||||||
|
}
|
||||||
|
code_edit->fold_line(0);
|
||||||
|
CHECK(code_edit->is_line_folded(0));
|
||||||
|
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
|
||||||
|
|
||||||
|
// Region with no end can't be folded.
|
||||||
|
ERR_PRINT_OFF;
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
code_edit->set_text("#region region_name\nline2\nline3\n#bad_end_tag\nvisible line");
|
||||||
|
CHECK_FALSE(code_edit->can_fold_line(0));
|
||||||
|
ERR_PRINT_ON;
|
||||||
|
|
||||||
|
// Bad nested region can't be folded.
|
||||||
|
ERR_PRINT_OFF;
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
code_edit->set_text("#region without end\n#region region2\nline3\n#endregion\n#no_end");
|
||||||
|
CHECK_FALSE(code_edit->can_fold_line(0));
|
||||||
|
CHECK(code_edit->can_fold_line(1));
|
||||||
|
ERR_PRINT_ON;
|
||||||
|
|
||||||
|
// Nested region folding.
|
||||||
|
ERR_PRINT_OFF;
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
code_edit->set_text("#region region1\n#region region2\nline3\n#endregion\n#endregion");
|
||||||
|
CHECK(code_edit->can_fold_line(0));
|
||||||
|
CHECK(code_edit->can_fold_line(1));
|
||||||
|
code_edit->fold_line(1);
|
||||||
|
CHECK(code_edit->get_next_visible_line_offset_from(2, 1) == 3);
|
||||||
|
code_edit->fold_line(0);
|
||||||
|
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
|
||||||
|
ERR_PRINT_ON;
|
||||||
|
|
||||||
|
// Unfolding a line inside a region unfold whole region.
|
||||||
|
code_edit->clear_comment_delimiters();
|
||||||
|
code_edit->add_comment_delimiter("#", "");
|
||||||
|
code_edit->set_text("#region region\ninside\nline3\n#endregion\nvisible");
|
||||||
|
code_edit->fold_line(0);
|
||||||
|
CHECK(code_edit->is_line_folded(0));
|
||||||
|
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
|
||||||
|
code_edit->unfold_line(1);
|
||||||
|
CHECK_FALSE(code_edit->is_line_folded(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
memdelete(code_edit);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("[SceneTree][CodeEdit] completion") {
|
TEST_CASE("[SceneTree][CodeEdit] completion") {
|
||||||
CodeEdit *code_edit = memnew(CodeEdit);
|
CodeEdit *code_edit = memnew(CodeEdit);
|
||||||
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
SceneTree::get_singleton()->get_root()->add_child(code_edit);
|
||||||
|
|
Loading…
Reference in New Issue