summaryrefslogtreecommitdiffstats
path: root/tests/scene/test_code_edit.h
diff options
context:
space:
mode:
Diffstat (limited to 'tests/scene/test_code_edit.h')
-rw-r--r--tests/scene/test_code_edit.h2016
1 files changed, 1692 insertions, 324 deletions
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index b0a46b8107..c02830b6df 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -36,6 +36,15 @@
#include "tests/test_macros.h"
namespace TestCodeEdit {
+static inline Array build_array() {
+ return Array();
+}
+template <typename... Targs>
+static inline Array build_array(Variant item, Targs... Fargs) {
+ Array a = build_array(Fargs...);
+ a.push_front(item);
+ return a;
+}
TEST_CASE("[SceneTree][CodeEdit] line gutters") {
CodeEdit *code_edit = memnew(CodeEdit);
@@ -67,10 +76,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
ERR_PRINT_ON;
- Array arg1;
- arg1.push_back(0);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(0));
code_edit->set_line_as_breakpoint(0, true);
CHECK(code_edit->is_line_breakpointed(0));
@@ -86,10 +92,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
code_edit->clear_breakpointed_lines();
SIGNAL_CHECK_FALSE("breakpoint_toggled");
- Array arg1;
- arg1.push_back(0);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(0));
code_edit->set_line_as_breakpoint(0, true);
CHECK(code_edit->is_line_breakpointed(0));
@@ -101,10 +104,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
}
SUBCASE("[CodeEdit] breakpoints and set text") {
- Array arg1;
- arg1.push_back(0);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(0));
code_edit->set_text("test\nline");
code_edit->set_line_as_breakpoint(0, true);
@@ -121,7 +121,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
code_edit->clear_breakpointed_lines();
SIGNAL_DISCARD("breakpoint_toggled")
- ((Array)args[0])[0] = 1;
+ args = build_array(build_array(1));
code_edit->set_text("test\nline");
code_edit->set_line_as_breakpoint(1, true);
CHECK(code_edit->is_line_breakpointed(1));
@@ -137,10 +137,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
}
SUBCASE("[CodeEdit] breakpoints and clear") {
- Array arg1;
- arg1.push_back(0);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(0));
code_edit->set_text("test\nline");
code_edit->set_line_as_breakpoint(0, true);
@@ -157,7 +154,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
code_edit->clear_breakpointed_lines();
SIGNAL_DISCARD("breakpoint_toggled")
- ((Array)args[0])[0] = 1;
+ args = build_array(build_array(1));
code_edit->set_text("test\nline");
code_edit->set_line_as_breakpoint(1, true);
CHECK(code_edit->is_line_breakpointed(1));
@@ -173,21 +170,15 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
}
SUBCASE("[CodeEdit] breakpoints and new lines no text") {
- Array arg1;
- arg1.push_back(0);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(0));
/* No text moves breakpoint. */
code_edit->set_line_as_breakpoint(0, true);
CHECK(code_edit->is_line_breakpointed(0));
SIGNAL_CHECK("breakpoint_toggled", args);
- /* Normal. */
- ((Array)args[0])[0] = 0;
- Array arg2;
- arg2.push_back(1);
- args.push_back(arg2);
+ // Normal.
+ args = build_array(build_array(0), build_array(1));
SEND_GUI_ACTION("ui_text_newline");
CHECK(code_edit->get_line_count() == 2);
@@ -195,18 +186,16 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
CHECK(code_edit->is_line_breakpointed(1));
SIGNAL_CHECK("breakpoint_toggled", args);
- /* Non-Breaking. */
- ((Array)args[0])[0] = 1;
- ((Array)args[1])[0] = 2;
+ // Non-Breaking.
+ args = build_array(build_array(1), build_array(2));
SEND_GUI_ACTION("ui_text_newline_blank");
CHECK(code_edit->get_line_count() == 3);
CHECK_FALSE(code_edit->is_line_breakpointed(1));
CHECK(code_edit->is_line_breakpointed(2));
SIGNAL_CHECK("breakpoint_toggled", args);
- /* Above. */
- ((Array)args[0])[0] = 2;
- ((Array)args[1])[0] = 3;
+ // Above.
+ args = build_array(build_array(2), build_array(3));
SEND_GUI_ACTION("ui_text_newline_above");
CHECK(code_edit->get_line_count() == 4);
CHECK_FALSE(code_edit->is_line_breakpointed(2));
@@ -215,10 +204,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
}
SUBCASE("[CodeEdit] breakpoints and new lines with text") {
- Array arg1;
- arg1.push_back(0);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(0));
/* Having text does not move breakpoint. */
code_edit->insert_text_at_caret("text");
@@ -241,11 +227,8 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
CHECK_FALSE(code_edit->is_line_breakpointed(1));
SIGNAL_CHECK_FALSE("breakpoint_toggled");
- /* Above does move. */
- ((Array)args[0])[0] = 0;
- Array arg2;
- arg2.push_back(1);
- args.push_back(arg2);
+ // Above does move.
+ args = build_array(build_array(0), build_array(1));
code_edit->set_caret_line(0);
SEND_GUI_ACTION("ui_text_newline_above");
@@ -256,10 +239,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
}
SUBCASE("[CodeEdit] breakpoints and backspace") {
- Array arg1;
- arg1.push_back(1);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(1));
code_edit->set_text("\n\n");
code_edit->set_line_as_breakpoint(1, true);
@@ -281,8 +261,8 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
ERR_PRINT_ON;
SIGNAL_CHECK("breakpoint_toggled", args);
- /* Backspace above breakpointed line moves it. */
- ((Array)args[0])[0] = 2;
+ // Backspace above breakpointed line moves it.
+ args = build_array(build_array(2));
code_edit->set_text("\n\n");
code_edit->set_line_as_breakpoint(2, true);
@@ -291,9 +271,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
code_edit->set_caret_line(1);
- Array arg2;
- arg2.push_back(1);
- args.push_back(arg2);
+ args = build_array(build_array(2), build_array(1));
SEND_GUI_ACTION("ui_text_backspace");
ERR_PRINT_OFF;
CHECK_FALSE(code_edit->is_line_breakpointed(2));
@@ -303,10 +281,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
}
SUBCASE("[CodeEdit] breakpoints and delete") {
- Array arg1;
- arg1.push_back(1);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(1));
code_edit->set_text("\n\n");
code_edit->set_line_as_breakpoint(1, true);
@@ -329,8 +304,8 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
ERR_PRINT_ON;
SIGNAL_CHECK("breakpoint_toggled", args);
- /* Delete above breakpointed line moves it. */
- ((Array)args[0])[0] = 2;
+ // Delete above breakpointed line moves it.
+ args = build_array(build_array(2));
code_edit->set_text("\n\n");
code_edit->set_line_as_breakpoint(2, true);
@@ -339,9 +314,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
code_edit->set_caret_line(0);
- Array arg2;
- arg2.push_back(1);
- args.push_back(arg2);
+ args = build_array(build_array(2), build_array(1));
SEND_GUI_ACTION("ui_text_delete");
ERR_PRINT_OFF;
CHECK_FALSE(code_edit->is_line_breakpointed(2));
@@ -351,10 +324,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
}
SUBCASE("[CodeEdit] breakpoints and delete selection") {
- Array arg1;
- arg1.push_back(1);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(1));
code_edit->set_text("\n\n");
code_edit->set_line_as_breakpoint(1, true);
@@ -367,8 +337,8 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
CHECK_FALSE(code_edit->is_line_breakpointed(0));
SIGNAL_CHECK("breakpoint_toggled", args);
- /* Should handle breakpoint move when deleting selection by adding less text then removed. */
- ((Array)args[0])[0] = 9;
+ // Should handle breakpoint move when deleting selection by adding less text then removed.
+ args = build_array(build_array(9));
code_edit->set_text("\n\n\n\n\n\n\n\n\n");
code_edit->set_line_as_breakpoint(9, true);
@@ -377,9 +347,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
code_edit->select(0, 0, 6, 0);
- Array arg2;
- arg2.push_back(4);
- args.push_back(arg2);
+ args = build_array(build_array(9), build_array(4));
SEND_GUI_ACTION("ui_text_newline");
ERR_PRINT_OFF;
CHECK_FALSE(code_edit->is_line_breakpointed(9));
@@ -387,9 +355,8 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
CHECK(code_edit->is_line_breakpointed(4));
SIGNAL_CHECK("breakpoint_toggled", args);
- /* Should handle breakpoint move when deleting selection by adding more text then removed. */
- ((Array)args[0])[0] = 9;
- ((Array)args[1])[0] = 14;
+ // Should handle breakpoint move when deleting selection by adding more text then removed.
+ args = build_array(build_array(9), build_array(14));
code_edit->insert_text_at_caret("\n\n\n\n\n");
MessageQueue::get_singleton()->flush();
@@ -404,10 +371,7 @@ TEST_CASE("[SceneTree][CodeEdit] line gutters") {
}
SUBCASE("[CodeEdit] breakpoints and undo") {
- Array arg1;
- arg1.push_back(1);
- Array args;
- args.push_back(arg1);
+ Array args = build_array(build_array(1));
code_edit->set_text("\n\n");
code_edit->set_line_as_breakpoint(1, true);
@@ -1849,17 +1813,47 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->do_indent();
CHECK(code_edit->get_line(0) == "test\t");
- /* Indent lines does entire line and works without selection. */
+ // Insert in place with multiple carets.
+ code_edit->set_text("test text");
+ code_edit->set_caret_column(5);
+ code_edit->add_caret(0, 7);
+ code_edit->add_caret(0, 2);
+ code_edit->do_indent();
+ CHECK(code_edit->get_line(0) == "te\tst \tte\txt");
+ CHECK(code_edit->get_caret_count() == 3);
+ CHECK(code_edit->get_caret_column(0) == 7);
+ CHECK(code_edit->get_caret_column(1) == 10);
+ CHECK(code_edit->get_caret_column(2) == 3);
+ code_edit->remove_secondary_carets();
+
+ // Indent lines does entire line and works without selection.
code_edit->set_text("");
code_edit->insert_text_at_caret("test");
code_edit->indent_lines();
CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->get_caret_column() == 5);
/* Selection does entire line. */
code_edit->set_text("test");
code_edit->select_all();
code_edit->do_indent();
CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 5);
+
+ // Selection does entire line, right to left selection.
+ code_edit->set_text("test");
+ code_edit->select(0, 4, 0, 0);
+ code_edit->do_indent();
+ CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 5);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
/* Handles multiple lines. */
code_edit->set_text("test\ntext");
@@ -1867,6 +1861,11 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->do_indent();
CHECK(code_edit->get_line(0) == "\ttest");
CHECK(code_edit->get_line(1) == "\ttext");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 5);
/* Do not indent line if last col is zero. */
code_edit->set_text("test\ntext");
@@ -1874,6 +1873,11 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->do_indent();
CHECK(code_edit->get_line(0) == "\ttest");
CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
/* Indent even if last column of first line. */
code_edit->set_text("test\ntext");
@@ -1881,15 +1885,53 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->do_indent();
CHECK(code_edit->get_line(0) == "\ttest");
CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 5);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Indent even if last column of first line, reversed.
+ code_edit->set_text("test\ntext");
+ code_edit->select(1, 0, 0, 4);
+ code_edit->do_indent();
+ CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 5);
/* Check selection is adjusted. */
code_edit->set_text("test");
code_edit->select(0, 1, 0, 2);
code_edit->do_indent();
- CHECK(code_edit->get_selection_from_column() == 2);
- CHECK(code_edit->get_selection_to_column() == 3);
CHECK(code_edit->get_line(0) == "\ttest");
- code_edit->undo();
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 3);
+
+ // Indent once with multiple selections.
+ code_edit->set_text("test");
+ code_edit->select(0, 1, 0, 2);
+ code_edit->add_caret(0, 4);
+ code_edit->select(0, 4, 0, 3, 1);
+ code_edit->do_indent();
+ CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 0);
+ CHECK(code_edit->get_selection_origin_column(0) == 2);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 3);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 0);
+ CHECK(code_edit->get_selection_origin_column(1) == 5);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 4);
}
SUBCASE("[CodeEdit] indent spaces") {
@@ -1922,23 +1964,58 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->do_indent();
CHECK(code_edit->get_line(0) == "test ");
- /* Indent lines does entire line and works without selection. */
+ // Insert in place with multiple carets.
+ code_edit->set_text("test text");
+ code_edit->set_caret_column(5);
+ code_edit->add_caret(0, 7);
+ code_edit->add_caret(0, 2);
+ code_edit->do_indent();
+ CHECK(code_edit->get_line(0) == "te st te xt");
+ CHECK(code_edit->get_caret_count() == 3);
+ CHECK(code_edit->get_caret_column(0) == 10);
+ CHECK(code_edit->get_caret_column(1) == 14);
+ CHECK(code_edit->get_caret_column(2) == 4);
+ code_edit->remove_secondary_carets();
+
+ // Indent lines does entire line and works without selection.
code_edit->set_text("");
code_edit->insert_text_at_caret("test");
code_edit->indent_lines();
CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->get_caret_column() == 8);
/* Selection does entire line. */
code_edit->set_text("test");
code_edit->select_all();
code_edit->do_indent();
CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 8);
+
+ // Selection does entire line, right to left selection.
+ code_edit->set_text("test");
+ code_edit->select(0, 4, 0, 0);
+ code_edit->do_indent();
+ CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
/* single indent only add required spaces. */
code_edit->set_text(" test");
code_edit->select_all();
code_edit->do_indent();
CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 8);
/* Handles multiple lines. */
code_edit->set_text("test\ntext");
@@ -1946,6 +2023,11 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->do_indent();
CHECK(code_edit->get_line(0) == " test");
CHECK(code_edit->get_line(1) == " text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 8);
/* Do not indent line if last col is zero. */
code_edit->set_text("test\ntext");
@@ -1953,6 +2035,11 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->do_indent();
CHECK(code_edit->get_line(0) == " test");
CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
/* Indent even if last column of first line. */
code_edit->set_text("test\ntext");
@@ -1960,14 +2047,53 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->do_indent();
CHECK(code_edit->get_line(0) == " test");
CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Indent even if last column of first line, right to left selection.
+ code_edit->set_text("test\ntext");
+ code_edit->select(1, 0, 0, 4);
+ code_edit->do_indent();
+ CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 8);
/* Check selection is adjusted. */
code_edit->set_text("test");
code_edit->select(0, 1, 0, 2);
code_edit->do_indent();
- CHECK(code_edit->get_selection_from_column() == 5);
- CHECK(code_edit->get_selection_to_column() == 6);
CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 5);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 6);
+
+ // Indent once with multiple selections.
+ code_edit->set_text("test");
+ code_edit->select(0, 1, 0, 2);
+ code_edit->add_caret(0, 4);
+ code_edit->select(0, 4, 0, 3, 1);
+ code_edit->do_indent();
+ CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 0);
+ CHECK(code_edit->get_selection_origin_column(0) == 5);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 6);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 0);
+ CHECK(code_edit->get_selection_origin_column(1) == 8);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 7);
}
SUBCASE("[CodeEdit] unindent tabs") {
@@ -2003,11 +2129,28 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->insert_text_at_caret("\ttest");
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == "test");
+ CHECK(code_edit->get_caret_column() == 4);
+
+ // Unindent lines once with multiple carets.
+ code_edit->set_text("\t\ttest");
+ code_edit->set_caret_column(1);
+ code_edit->add_caret(0, 3);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 2);
+ code_edit->remove_secondary_carets();
/* Caret on col zero unindent line. */
code_edit->set_text("\t\ttest");
+ code_edit->set_caret_column(0);
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->get_caret_column() == 0);
/* Check input action. */
code_edit->set_text("\t\ttest");
@@ -2019,13 +2162,34 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->select_all();
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 5);
- /* Handles multiple lines. */
- code_edit->set_text("\ttest\n\ttext");
+ // Selection does entire line, right to left selection.
+ code_edit->set_text("\t\ttest");
+ code_edit->select(0, 6, 0, 0);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 5);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Handles multiple lines.
+ code_edit->set_text("\t\ttest\n\t\ttext");
code_edit->select_all();
code_edit->unindent_lines();
- CHECK(code_edit->get_line(0) == "test");
- CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->get_line(1) == "\ttext");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 5);
/* Do not unindent line if last col is zero. */
code_edit->set_text("\ttest\n\ttext");
@@ -2033,6 +2197,23 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == "test");
CHECK(code_edit->get_line(1) == "\ttext");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Do not unindent line if last col is zero, right to left selection.
+ code_edit->set_text("\ttest\n\ttext");
+ code_edit->select(1, 0, 0, 0);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == "test");
+ CHECK(code_edit->get_line(1) == "\ttext");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
/* Unindent even if last column of first line. */
code_edit->set_text("\ttest\n\ttext");
@@ -2040,14 +2221,50 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == "test");
CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 4);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
/* Check selection is adjusted. */
code_edit->set_text("\ttest");
code_edit->select(0, 1, 0, 2);
code_edit->unindent_lines();
- CHECK(code_edit->get_selection_from_column() == 0);
- CHECK(code_edit->get_selection_to_column() == 1);
CHECK(code_edit->get_line(0) == "test");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Deselect if only the tab was selected.
+ code_edit->set_text("\ttest");
+ code_edit->select(0, 0, 0, 1);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == "test");
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Unindent once with multiple selections.
+ code_edit->set_text("\t\ttest");
+ code_edit->select(0, 1, 0, 2);
+ code_edit->add_caret(0, 4);
+ code_edit->select(0, 4, 0, 3, 1);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 0);
+ CHECK(code_edit->get_selection_origin_column(0) == 0);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 1);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 0);
+ CHECK(code_edit->get_selection_origin_column(1) == 3);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 2);
}
SUBCASE("[CodeEdit] unindent spaces") {
@@ -2089,11 +2306,28 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->insert_text_at_caret(" test");
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == "test");
+ CHECK(code_edit->get_caret_column() == 4);
+
+ // Unindent lines once with multiple carets.
+ code_edit->set_text(" test");
+ code_edit->set_caret_column(1);
+ code_edit->add_caret(0, 9);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 5);
+ code_edit->remove_secondary_carets();
/* Caret on col zero unindent line. */
code_edit->set_text(" test");
+ code_edit->set_caret_column(0);
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->get_caret_column() == 0);
/* Only as far as needed */
code_edit->set_text(" test");
@@ -2110,13 +2344,34 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->select_all();
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 8);
- /* Handles multiple lines. */
- code_edit->set_text(" test\n text");
+ // Selection does entire line, right to left selection.
+ code_edit->set_text(" test");
+ code_edit->select(0, 12, 0, 0);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Handles multiple lines.
+ code_edit->set_text(" test\n text");
code_edit->select_all();
code_edit->unindent_lines();
- CHECK(code_edit->get_line(0) == "test");
- CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->get_line(1) == " text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 8);
/* Do not unindent line if last col is zero. */
code_edit->set_text(" test\n text");
@@ -2124,6 +2379,23 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == "test");
CHECK(code_edit->get_line(1) == " text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Do not unindent line if last col is zero, right to left selection.
+ code_edit->set_text(" test\n text");
+ code_edit->select(1, 0, 0, 0);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == "test");
+ CHECK(code_edit->get_line(1) == " text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
/* Unindent even if last column of first line. */
code_edit->set_text(" test\n text");
@@ -2131,14 +2403,48 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->unindent_lines();
CHECK(code_edit->get_line(0) == "test");
CHECK(code_edit->get_line(1) == "text");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 1);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
/* Check selection is adjusted. */
code_edit->set_text(" test");
code_edit->select(0, 4, 0, 5);
code_edit->unindent_lines();
- CHECK(code_edit->get_selection_from_column() == 0);
- CHECK(code_edit->get_selection_to_column() == 1);
CHECK(code_edit->get_line(0) == "test");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Deselect if only the tab was selected.
+ code_edit->set_text(" test");
+ code_edit->select(0, 0, 0, 4);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == "test");
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Unindent once with multiple selections.
+ code_edit->set_text(" test");
+ code_edit->select(0, 1, 0, 2);
+ code_edit->add_caret(0, 4);
+ code_edit->select(0, 12, 0, 10, 1);
+ code_edit->unindent_lines();
+ CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK_FALSE(code_edit->has_selection(0));
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 0);
+ CHECK(code_edit->get_selection_origin_column(1) == 8);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 6);
}
SUBCASE("[CodeEdit] auto indent") {
@@ -2153,6 +2459,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline");
CHECK(code_edit->get_line(0) == "test:");
CHECK(code_edit->get_line(1) == "\t");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
/* new blank line should still indent. */
code_edit->set_text("");
@@ -2160,6 +2468,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline_blank");
CHECK(code_edit->get_line(0) == "test:");
CHECK(code_edit->get_line(1) == "\t");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
/* new line above should not indent. */
code_edit->set_text("");
@@ -2167,6 +2477,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline_above");
CHECK(code_edit->get_line(0) == "");
CHECK(code_edit->get_line(1) == "test:");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
/* Whitespace between symbol and caret is okay. */
code_edit->set_text("");
@@ -2174,6 +2486,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline");
CHECK(code_edit->get_line(0) == "test: ");
CHECK(code_edit->get_line(1) == "\t");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
/* Comment between symbol and caret is okay. */
code_edit->add_comment_delimiter("#", "");
@@ -2183,6 +2497,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
CHECK(code_edit->get_line(0) == "test: # comment");
CHECK(code_edit->get_line(1) == "\t");
code_edit->remove_comment_delimiter("#");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
/* Strings between symbol and caret are not okay. */
code_edit->add_string_delimiter("#", "");
@@ -2192,6 +2508,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
CHECK(code_edit->get_line(0) == "test: # string");
CHECK(code_edit->get_line(1) == "");
code_edit->remove_string_delimiter("#");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
/* Non-whitespace prevents auto-indentation. */
code_edit->add_comment_delimiter("#", "");
@@ -2201,6 +2519,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
CHECK(code_edit->get_line(0) == "test := 0 # comment");
CHECK(code_edit->get_line(1) == "");
code_edit->remove_comment_delimiter("#");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
/* Even when there's no comments. */
code_edit->set_text("");
@@ -2208,6 +2528,53 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline");
CHECK(code_edit->get_line(0) == "test := 0");
CHECK(code_edit->get_line(1) == "");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Preserve current indentation.
+ code_edit->set_text("\ttest");
+ code_edit->set_caret_column(3);
+ SEND_GUI_ACTION("ui_text_newline");
+ CHECK(code_edit->get_line(0) == "\tte");
+ CHECK(code_edit->get_line(1) == "\tst");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Preserve current indentation blank.
+ code_edit->set_text("\ttest");
+ code_edit->set_caret_column(3);
+ SEND_GUI_ACTION("ui_text_newline_blank");
+ CHECK(code_edit->get_line(0) == "\ttest");
+ CHECK(code_edit->get_line(1) == "\t");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Preserve current indentation above.
+ code_edit->set_text("\ttest");
+ code_edit->set_caret_column(3);
+ SEND_GUI_ACTION("ui_text_newline_above");
+ CHECK(code_edit->get_line(0) == "\t");
+ CHECK(code_edit->get_line(1) == "\ttest");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Increase existing indentation.
+ code_edit->set_text("\ttest:");
+ code_edit->set_caret_column(6);
+ SEND_GUI_ACTION("ui_text_newline");
+ CHECK(code_edit->get_line(0) == "\ttest:");
+ CHECK(code_edit->get_line(1) == "\t\t");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 2);
+
+ // Increase existing indentation blank.
+ code_edit->set_text("\ttest:");
+ code_edit->set_caret_column(3);
+ SEND_GUI_ACTION("ui_text_newline_blank");
+ CHECK(code_edit->get_line(0) == "\ttest:");
+ CHECK(code_edit->get_line(1) == "\t\t");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 2);
/* If between brace pairs an extra line is added. */
code_edit->set_text("");
@@ -2217,6 +2584,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
CHECK(code_edit->get_line(0) == "test{");
CHECK(code_edit->get_line(1) == "\t");
CHECK(code_edit->get_line(2) == "}");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
/* Except when we are going above. */
code_edit->set_text("");
@@ -2225,6 +2594,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline_above");
CHECK(code_edit->get_line(0) == "");
CHECK(code_edit->get_line(1) == "test{}");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
/* or below. */
code_edit->set_text("");
@@ -2233,6 +2604,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline_blank");
CHECK(code_edit->get_line(0) == "test{}");
CHECK(code_edit->get_line(1) == "");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
}
SUBCASE("[CodeEdit] auto indent spaces") {
@@ -2246,6 +2619,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline");
CHECK(code_edit->get_line(0) == "test:");
CHECK(code_edit->get_line(1) == " ");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 4);
/* new blank line should still indent. */
code_edit->set_text("");
@@ -2253,6 +2628,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline_blank");
CHECK(code_edit->get_line(0) == "test:");
CHECK(code_edit->get_line(1) == " ");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 4);
/* new line above should not indent. */
code_edit->set_text("");
@@ -2260,6 +2637,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline_above");
CHECK(code_edit->get_line(0) == "");
CHECK(code_edit->get_line(1) == "test:");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
/* Whitespace between symbol and caret is okay. */
code_edit->set_text("");
@@ -2267,6 +2646,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline");
CHECK(code_edit->get_line(0) == "test: ");
CHECK(code_edit->get_line(1) == " ");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 4);
/* Comment between symbol and caret is okay. */
code_edit->add_comment_delimiter("#", "");
@@ -2276,6 +2657,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
CHECK(code_edit->get_line(0) == "test: # comment");
CHECK(code_edit->get_line(1) == " ");
code_edit->remove_comment_delimiter("#");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 4);
/* Strings between symbol and caret are not okay. */
code_edit->add_string_delimiter("#", "");
@@ -2285,6 +2668,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
CHECK(code_edit->get_line(0) == "test: # string");
CHECK(code_edit->get_line(1) == "");
code_edit->remove_string_delimiter("#");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
/* Non-whitespace prevents auto-indentation. */
code_edit->add_comment_delimiter("#", "");
@@ -2294,6 +2679,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
CHECK(code_edit->get_line(0) == "test := 0 # comment");
CHECK(code_edit->get_line(1) == "");
code_edit->remove_comment_delimiter("#");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
/* Even when there's no comments. */
code_edit->set_text("");
@@ -2301,6 +2688,53 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline");
CHECK(code_edit->get_line(0) == "test := 0");
CHECK(code_edit->get_line(1) == "");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Preserve current indentation.
+ code_edit->set_text(" test");
+ code_edit->set_caret_column(6);
+ SEND_GUI_ACTION("ui_text_newline");
+ CHECK(code_edit->get_line(0) == " te");
+ CHECK(code_edit->get_line(1) == " st");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 4);
+
+ // Preserve current indentation blank.
+ code_edit->set_text(" test");
+ code_edit->set_caret_column(6);
+ SEND_GUI_ACTION("ui_text_newline_blank");
+ CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->get_line(1) == " ");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 4);
+
+ // Preserve current indentation above.
+ code_edit->set_text(" test");
+ code_edit->set_caret_column(6);
+ SEND_GUI_ACTION("ui_text_newline_above");
+ CHECK(code_edit->get_line(0) == " ");
+ CHECK(code_edit->get_line(1) == " test");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 4);
+
+ // Increase existing indentation.
+ code_edit->set_text(" test:");
+ code_edit->set_caret_column(9);
+ SEND_GUI_ACTION("ui_text_newline");
+ CHECK(code_edit->get_line(0) == " test:");
+ CHECK(code_edit->get_line(1) == " ");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 8);
+
+ // Increase existing indentation blank.
+ code_edit->set_text(" test:");
+ code_edit->set_caret_column(9);
+ SEND_GUI_ACTION("ui_text_newline");
+ CHECK(code_edit->get_line(0) == " test:");
+ CHECK(code_edit->get_line(1) == " ");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 8);
/* If between brace pairs an extra line is added. */
code_edit->set_text("");
@@ -2310,6 +2744,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
CHECK(code_edit->get_line(0) == "test{");
CHECK(code_edit->get_line(1) == " ");
CHECK(code_edit->get_line(2) == "}");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 4);
/* Except when we are going above. */
code_edit->set_text("");
@@ -2318,6 +2754,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline_above");
CHECK(code_edit->get_line(0) == "");
CHECK(code_edit->get_line(1) == "test{}");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
/* or below. */
code_edit->set_text("");
@@ -2326,6 +2764,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
SEND_GUI_ACTION("ui_text_newline_blank");
CHECK(code_edit->get_line(0) == "test{}");
CHECK(code_edit->get_line(1) == "");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
/* If there is something after a colon
and there is a colon in the comment it
@@ -2337,6 +2777,8 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
CHECK(code_edit->get_line(0) == "test:test#:");
CHECK(code_edit->get_line(1) == "");
code_edit->remove_comment_delimiter("#");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
}
}
@@ -2345,64 +2787,50 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->set_indent_using_spaces(false);
// Only line.
- code_edit->insert_text_at_caret(" test");
- code_edit->set_caret_line(0);
- code_edit->set_caret_column(8);
- code_edit->select(0, 8, 0, 9);
+ code_edit->set_text(" test");
+ code_edit->select(0, 9, 0, 8);
code_edit->convert_indent();
CHECK(code_edit->get_line(0) == "\t\ttest");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 3);
CHECK(code_edit->get_caret_column() == 2);
- CHECK(code_edit->get_selection_from_column() == 2);
- CHECK(code_edit->get_selection_to_column() == 3);
// First line.
- code_edit->set_text("");
- code_edit->insert_text_at_caret(" test\n");
- code_edit->set_caret_line(0);
- code_edit->set_caret_column(8);
+ code_edit->set_text(" test\n");
code_edit->select(0, 8, 0, 9);
code_edit->convert_indent();
CHECK(code_edit->get_line(0) == "\t\ttest");
- CHECK(code_edit->get_caret_column() == 2);
- CHECK(code_edit->get_selection_from_column() == 2);
- CHECK(code_edit->get_selection_to_column() == 3);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK(code_edit->get_caret_column() == 3);
// Middle line.
- code_edit->set_text("");
- code_edit->insert_text_at_caret("\n test\n");
- code_edit->set_caret_line(1);
- code_edit->set_caret_column(8);
+ code_edit->set_text("\n test\n");
code_edit->select(1, 8, 1, 9);
code_edit->convert_indent();
CHECK(code_edit->get_line(1) == "\t\ttest");
- CHECK(code_edit->get_caret_column() == 2);
- CHECK(code_edit->get_selection_from_column() == 2);
- CHECK(code_edit->get_selection_to_column() == 3);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK(code_edit->get_caret_column() == 3);
// End line.
- code_edit->set_text("");
- code_edit->insert_text_at_caret("\n test");
- code_edit->set_caret_line(1);
- code_edit->set_caret_column(8);
+ code_edit->set_text("\n test");
code_edit->select(1, 8, 1, 9);
code_edit->convert_indent();
CHECK(code_edit->get_line(1) == "\t\ttest");
- CHECK(code_edit->get_caret_column() == 2);
- CHECK(code_edit->get_selection_from_column() == 2);
- CHECK(code_edit->get_selection_to_column() == 3);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK(code_edit->get_caret_column() == 3);
// Within provided range.
- code_edit->set_text("");
- code_edit->insert_text_at_caret(" test\n test\n");
- code_edit->set_caret_line(1);
- code_edit->set_caret_column(8);
+ code_edit->set_text(" test\n test\n");
code_edit->select(1, 8, 1, 9);
code_edit->convert_indent(1, 1);
CHECK(code_edit->get_line(0) == " test");
CHECK(code_edit->get_line(1) == "\t\ttest");
- CHECK(code_edit->get_caret_column() == 2);
- CHECK(code_edit->get_selection_from_column() == 2);
- CHECK(code_edit->get_selection_to_column() == 3);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK(code_edit->get_caret_column() == 3);
}
SUBCASE("[CodeEdit] convert indent to spaces") {
@@ -2410,64 +2838,50 @@ TEST_CASE("[SceneTree][CodeEdit] indent") {
code_edit->set_indent_using_spaces(true);
// Only line.
- code_edit->insert_text_at_caret("\t\ttest");
- code_edit->set_caret_line(0);
- code_edit->set_caret_column(2);
- code_edit->select(0, 2, 0, 3);
+ code_edit->set_text("\t\ttest");
+ code_edit->select(0, 3, 0, 2);
code_edit->convert_indent();
CHECK(code_edit->get_line(0) == " test");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 9);
CHECK(code_edit->get_caret_column() == 8);
- CHECK(code_edit->get_selection_from_column() == 8);
- CHECK(code_edit->get_selection_to_column() == 9);
// First line.
- code_edit->set_text("");
- code_edit->insert_text_at_caret("\t\ttest\n");
- code_edit->set_caret_line(0);
- code_edit->set_caret_column(2);
+ code_edit->set_text("\t\ttest\n");
code_edit->select(0, 2, 0, 3);
code_edit->convert_indent();
CHECK(code_edit->get_line(0) == " test");
- CHECK(code_edit->get_caret_column() == 8);
- CHECK(code_edit->get_selection_from_column() == 8);
- CHECK(code_edit->get_selection_to_column() == 9);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK(code_edit->get_caret_column() == 9);
// Middle line.
- code_edit->set_text("");
- code_edit->insert_text_at_caret("\n\t\ttest\n");
- code_edit->set_caret_line(1);
- code_edit->set_caret_column(2);
+ code_edit->set_text("\n\t\ttest\n");
code_edit->select(1, 2, 1, 3);
code_edit->convert_indent();
CHECK(code_edit->get_line(1) == " test");
- CHECK(code_edit->get_caret_column() == 8);
- CHECK(code_edit->get_selection_from_column() == 8);
- CHECK(code_edit->get_selection_to_column() == 9);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK(code_edit->get_caret_column() == 9);
// End line.
- code_edit->set_text("");
- code_edit->insert_text_at_caret("\n\t\ttest");
- code_edit->set_caret_line(1);
- code_edit->set_caret_column(2);
+ code_edit->set_text("\n\t\ttest");
code_edit->select(1, 2, 1, 3);
code_edit->convert_indent();
CHECK(code_edit->get_line(1) == " test");
- CHECK(code_edit->get_caret_column() == 8);
- CHECK(code_edit->get_selection_from_column() == 8);
- CHECK(code_edit->get_selection_to_column() == 9);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK(code_edit->get_caret_column() == 9);
// Within provided range.
- code_edit->set_text("");
- code_edit->insert_text_at_caret("\ttest\n\t\ttest\n");
- code_edit->set_caret_line(1);
- code_edit->set_caret_column(2);
+ code_edit->set_text("\ttest\n\t\ttest\n");
code_edit->select(1, 2, 1, 3);
code_edit->convert_indent(1, 1);
CHECK(code_edit->get_line(0) == "\ttest");
CHECK(code_edit->get_line(1) == " test");
- CHECK(code_edit->get_caret_column() == 8);
- CHECK(code_edit->get_selection_from_column() == 8);
- CHECK(code_edit->get_selection_to_column() == 9);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK(code_edit->get_caret_column() == 9);
// Outside of range.
ERR_PRINT_OFF;
@@ -2484,6 +2898,7 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
+ code_edit->set_line_folding_enabled(true);
SUBCASE("[CodeEdit] folding settings") {
code_edit->set_line_folding_enabled(true);
@@ -2494,8 +2909,6 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
}
SUBCASE("[CodeEdit] folding") {
- code_edit->set_line_folding_enabled(true);
-
// No indent.
code_edit->set_text("line1\nline2\nline3");
for (int i = 0; i < 2; i++) {
@@ -2862,6 +3275,100 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
}
+ SUBCASE("[CodeEdit] folding carets") {
+ // Folding a line moves all carets that would be hidden.
+ code_edit->set_text("test\n\tline1\n\t\tline 2\n");
+ code_edit->set_caret_line(1);
+ code_edit->set_caret_column(0);
+ code_edit->add_caret(1, 3);
+ code_edit->add_caret(2, 8);
+ code_edit->add_caret(2, 1);
+ code_edit->select(2, 0, 2, 1, 3);
+
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(1));
+ CHECK(code_edit->get_caret_count() == 1);
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 4);
+
+ // Undoing an action that puts the caret on a folded line unfolds it.
+ code_edit->set_text("test\n\tline1");
+ code_edit->select(1, 1, 1, 2);
+ code_edit->duplicate_selection();
+ CHECK(code_edit->get_text() == "test\n\tlline1");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 3);
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(1));
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 4);
+
+ code_edit->undo();
+ CHECK(code_edit->get_text() == "test\n\tline1");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 2);
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 1);
+ CHECK_FALSE(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(1));
+
+ // Redoing doesn't refold.
+ code_edit->redo();
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 3);
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK_FALSE(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(1));
+ }
+
+ SUBCASE("[CodeEdit] toggle folding carets") {
+ code_edit->set_text("test\n\tline1\ntest2\n\tline2");
+
+ // Fold lines with carets on them.
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(1);
+ code_edit->toggle_foldable_lines_at_carets();
+ CHECK(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(2));
+
+ // Toggle fold on lines with carets.
+ code_edit->add_caret(2, 0);
+ code_edit->toggle_foldable_lines_at_carets();
+ CHECK_FALSE(code_edit->is_line_folded(0));
+ CHECK(code_edit->is_line_folded(2));
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 1);
+ CHECK(code_edit->get_caret_line(1) == 2);
+ CHECK(code_edit->get_caret_column(1) == 0);
+
+ // Multiple carets as part of one fold.
+ code_edit->unfold_all_lines();
+ code_edit->remove_secondary_carets();
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(1);
+ code_edit->add_caret(0, 4);
+ code_edit->add_caret(1, 2);
+ code_edit->toggle_foldable_lines_at_carets();
+ CHECK(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(2));
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 1);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 4);
+ }
+
memdelete(code_edit);
}
@@ -2870,7 +3377,7 @@ TEST_CASE("[SceneTree][CodeEdit] region folding") {
SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
- SUBCASE("[CodeEdit] region folding") {
+ SUBCASE("[CodeEdit] region tags") {
code_edit->set_line_folding_enabled(true);
// Region tag detection.
@@ -2907,16 +3414,51 @@ TEST_CASE("[SceneTree][CodeEdit] region folding") {
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.
+ SUBCASE("[CodeEdit] create code region") {
+ code_edit->set_line_folding_enabled(true);
+
+ // Region creation with selection adds start and close region lines. Region name is selected and the region is folded.
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));
+ CHECK(code_edit->get_text() == "line1\n#region New Code Region\nline2\n#endregion\nline3");
+ CHECK(code_edit->get_caret_count() == 1);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selected_text() == "New Code Region");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 23);
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK(code_edit->is_line_folded(1));
+
+ // Undo region creation. Line get unfolded.
+ code_edit->undo();
+ CHECK(code_edit->get_text() == "line1\nline2\nline3");
+ CHECK(code_edit->get_caret_count() == 1);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 4);
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK_FALSE(code_edit->is_line_folded(1));
+
+ // Redo region creation.
+ code_edit->redo();
+ CHECK(code_edit->get_text() == "line1\n#region New Code Region\nline2\n#endregion\nline3");
+ CHECK(code_edit->get_caret_count() == 1);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selected_text() == "New Code Region");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 23);
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK_FALSE(code_edit->is_line_folded(1));
// Region creation without any selection has no effect.
code_edit->set_text("line1\nline2\nline3");
@@ -2925,7 +3467,7 @@ TEST_CASE("[SceneTree][CodeEdit] region folding") {
code_edit->create_code_region();
CHECK(code_edit->get_text() == "line1\nline2\nline3");
- // Region creation with multiple selections.
+ // Region creation with multiple selections. Secondary carets are removed and the first region name is selected.
code_edit->set_text("line1\nline2\nline3");
code_edit->clear_comment_delimiters();
code_edit->add_comment_delimiter("#", "");
@@ -2934,6 +3476,25 @@ TEST_CASE("[SceneTree][CodeEdit] region folding") {
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");
+ CHECK(code_edit->get_caret_count() == 1);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selected_text() == "New Code Region");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 23);
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 8);
+
+ // Region creation with mixed selection and non-selection carets. Regular carets are ignored.
+ 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->create_code_region();
+ CHECK(code_edit->get_text() == "#region New Code Region\nline1\n#endregion\nline2\nline3");
+ CHECK(code_edit->get_caret_count() == 1);
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selected_text() == "New Code Region");
// Two selections on the same line create only one region.
code_edit->set_text("test line1\ntest line2\ntest line3");
@@ -2960,6 +3521,10 @@ TEST_CASE("[SceneTree][CodeEdit] region folding") {
code_edit->add_comment_delimiter("/*", "*/");
code_edit->create_code_region();
CHECK(code_edit->get_text() == "line1\nline2\nline3");
+ }
+
+ SUBCASE("[CodeEdit] region comment delimiters") {
+ code_edit->set_line_folding_enabled(true);
// Choose one line comment delimiter.
code_edit->set_text("//region region_name\nline2\n//endregion");
@@ -2993,6 +3558,10 @@ TEST_CASE("[SceneTree][CodeEdit] region folding") {
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));
+ }
+
+ SUBCASE("[CodeEdit] fold region") {
+ code_edit->set_line_folding_enabled(true);
// Fold region.
code_edit->clear_comment_delimiters();
@@ -3895,10 +4464,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
SEND_GUI_KEY_EVENT(Key::CTRL);
#endif
- Array signal_args;
- Array arg;
- arg.push_back("some");
- signal_args.push_back(arg);
+ Array signal_args = build_array(build_array("some"));
SIGNAL_CHECK("symbol_validate", signal_args);
SIGNAL_UNWATCH(code_edit, "symbol_validate");
@@ -3928,178 +4494,980 @@ TEST_CASE("[SceneTree][CodeEdit] line length guidelines") {
memdelete(code_edit);
}
-TEST_CASE("[SceneTree][CodeEdit] Backspace delete") {
+TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
CodeEdit *code_edit = memnew(CodeEdit);
SceneTree::get_singleton()->get_root()->add_child(code_edit);
code_edit->grab_focus();
- /* Backspace with selection on first line. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("test backspace");
- code_edit->select(0, 0, 0, 5);
- code_edit->backspace();
- CHECK(code_edit->get_line(0) == "backspace");
-
- /* Backspace with selection on first line and caret at the beginning of file. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("test backspace");
- code_edit->select(0, 0, 0, 5);
- code_edit->set_caret_column(0);
- code_edit->backspace();
- CHECK(code_edit->get_line(0) == "backspace");
-
- /* Move caret up to the previous line on backspace if caret is at the first column. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("line 1\nline 2");
- code_edit->set_caret_line(1);
- code_edit->set_caret_column(0);
- code_edit->backspace();
- CHECK(code_edit->get_line(0) == "line 1line 2");
- CHECK(code_edit->get_caret_line() == 0);
- CHECK(code_edit->get_caret_column() == 6);
-
- /* Backspace delete all text if all text is selected. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("line 1\nline 2\nline 3");
- code_edit->select_all();
- code_edit->backspace();
- CHECK(code_edit->get_text().is_empty());
-
- /* Backspace at the beginning without selection has no effect. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("line 1\nline 2\nline 3");
- code_edit->set_caret_line(0);
- code_edit->set_caret_column(0);
- code_edit->backspace();
- CHECK(code_edit->get_text() == "line 1\nline 2\nline 3");
+ SUBCASE("[SceneTree][CodeEdit] backspace") {
+ // Backspace with selection on first line.
+ code_edit->set_text("test backspace");
+ code_edit->select(0, 0, 0, 5);
+ code_edit->backspace();
+ CHECK(code_edit->get_line(0) == "backspace");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
- memdelete(code_edit);
-}
+ // Backspace with selection on first line and caret at the beginning of file.
+ code_edit->set_text("test backspace");
+ code_edit->select(0, 5, 0, 0);
+ code_edit->backspace();
+ CHECK(code_edit->get_line(0) == "backspace");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
-TEST_CASE("[SceneTree][CodeEdit] New Line") {
- CodeEdit *code_edit = memnew(CodeEdit);
- SceneTree::get_singleton()->get_root()->add_child(code_edit);
- code_edit->grab_focus();
+ // Move caret up to the previous line on backspace if caret is at the first column.
+ code_edit->set_text("line 1\nline 2");
+ code_edit->set_caret_line(1);
+ code_edit->set_caret_column(0);
+ code_edit->backspace();
+ CHECK(code_edit->get_line(0) == "line 1line 2");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 6);
- /* Add a new line. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("test new line");
- code_edit->set_caret_line(0);
- code_edit->set_caret_column(13);
- SEND_GUI_ACTION("ui_text_newline");
- CHECK(code_edit->get_line(0) == "test new line");
- CHECK(code_edit->get_line(1) == "");
-
- /* Split line with new line. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("test new line");
- code_edit->set_caret_line(0);
- code_edit->set_caret_column(5);
- SEND_GUI_ACTION("ui_text_newline");
- CHECK(code_edit->get_line(0) == "test ");
- CHECK(code_edit->get_line(1) == "new line");
-
- /* Delete selection and split with new line. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("test new line");
- code_edit->select(0, 0, 0, 5);
- SEND_GUI_ACTION("ui_text_newline");
- CHECK(code_edit->get_line(0) == "");
- CHECK(code_edit->get_line(1) == "new line");
-
- /* Blank new line below with selection should not split. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("test new line");
- code_edit->select(0, 0, 0, 5);
- SEND_GUI_ACTION("ui_text_newline_blank");
- CHECK(code_edit->get_line(0) == "test new line");
- CHECK(code_edit->get_line(1) == "");
-
- /* Blank new line above with selection should not split. */
- code_edit->set_text("");
- code_edit->insert_text_at_caret("test new line");
- code_edit->select(0, 0, 0, 5);
- SEND_GUI_ACTION("ui_text_newline_above");
- CHECK(code_edit->get_line(0) == "");
- CHECK(code_edit->get_line(1) == "test new line");
+ // Multiple carets with a caret at the first column.
+ code_edit->set_text("line 1\nline 2");
+ code_edit->set_caret_line(1);
+ code_edit->set_caret_column(2);
+ code_edit->add_caret(1, 0);
+ code_edit->add_caret(1, 5);
+ code_edit->backspace();
+ CHECK(code_edit->get_text() == "line 1lne2");
+ CHECK(code_edit->get_caret_count() == 3);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 7);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 6);
+ CHECK(code_edit->get_caret_line(2) == 0);
+ CHECK(code_edit->get_caret_column(2) == 9);
+ code_edit->remove_secondary_carets();
+
+ // Multiple carets close together.
+ code_edit->set_text("line 1\nline 2");
+ code_edit->set_caret_line(1);
+ code_edit->set_caret_column(2);
+ code_edit->add_caret(1, 1);
+ code_edit->backspace();
+ CHECK(code_edit->get_text() == "line 1\nne 2");
+ CHECK(code_edit->get_caret_count() == 1);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
- memdelete(code_edit);
-}
+ // Backspace delete all text if all text is selected.
+ code_edit->set_text("line 1\nline 2\nline 3");
+ code_edit->select_all();
+ code_edit->backspace();
+ CHECK(code_edit->get_text().is_empty());
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
-TEST_CASE("[SceneTree][CodeEdit] Duplicate Lines") {
- CodeEdit *code_edit = memnew(CodeEdit);
- SceneTree::get_singleton()->get_root()->add_child(code_edit);
- code_edit->grab_focus();
+ // Backspace at the beginning without selection has no effect.
+ code_edit->set_text("line 1\nline 2\nline 3");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(0);
+ code_edit->backspace();
+ CHECK(code_edit->get_text() == "line 1\nline 2\nline 3");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+ }
+
+ SUBCASE("[TextEdit] cut") {
+ DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton());
+ code_edit->set_line_folding_enabled(true);
+
+ // Cut without a selection removes the entire line.
+ code_edit->set_text("this is\nsome\n");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(6);
+
+ code_edit->cut();
+ CHECK(DS->clipboard_get() == "this is\n");
+ CHECK(code_edit->get_text() == "some\n");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 3); // In the default font, this is the same position.
+
+ // Undo restores the cut text.
+ code_edit->undo();
+ CHECK(DS->clipboard_get() == "this is\n");
+ CHECK(code_edit->get_text() == "this is\nsome\n");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 6);
+
+ // Redo.
+ code_edit->redo();
+ CHECK(DS->clipboard_get() == "this is\n");
+ CHECK(code_edit->get_text() == "some\n");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 3);
+
+ // Cut unfolds the line.
+ code_edit->set_text("this is\n\tsome\n");
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+
+ code_edit->cut();
+ CHECK_FALSE(code_edit->is_line_folded(0));
+ CHECK(DS->clipboard_get() == "this is\n");
+ CHECK(code_edit->get_text() == "\tsome\n");
+ CHECK(code_edit->get_caret_line() == 0);
+
+ // Cut with a selection removes just the selection.
+ code_edit->set_text("this is\nsome\n");
+ code_edit->select(0, 5, 0, 7);
+
+ SEND_GUI_ACTION("ui_cut");
+ CHECK(code_edit->get_viewport()->is_input_handled());
+ CHECK(DS->clipboard_get() == "is");
+ CHECK(code_edit->get_text() == "this \nsome\n");
+ CHECK_FALSE(code_edit->get_caret_line());
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 5);
+
+ // Cut does not change the text if not editable. Text is still added to clipboard.
+ code_edit->set_text("this is\nsome\n");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(5);
+
+ code_edit->set_editable(false);
+ code_edit->cut();
+ code_edit->set_editable(true);
+ CHECK(DS->clipboard_get() == "this is\n");
+ CHECK(code_edit->get_text() == "this is\nsome\n");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 5);
+
+ // Cut line with multiple carets.
+ code_edit->set_text("this is\nsome\n");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(3);
+ code_edit->add_caret(0, 2);
+ code_edit->add_caret(0, 4);
+ code_edit->add_caret(2, 0);
+
+ code_edit->cut();
+ CHECK(DS->clipboard_get() == "this is\n\n");
+ CHECK(code_edit->get_text() == "some");
+ CHECK(code_edit->get_caret_count() == 3);
+ CHECK_FALSE(code_edit->has_selection(0));
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 2); // In the default font, this is the same position.
+ // The previous caret at index 1 was merged.
+ CHECK_FALSE(code_edit->has_selection(1));
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 3); // In the default font, this is the same position.
+ CHECK_FALSE(code_edit->has_selection(2));
+ CHECK(code_edit->get_caret_line(2) == 0);
+ CHECK(code_edit->get_caret_column(2) == 4);
+ code_edit->remove_secondary_carets();
+
+ // Cut on the only line removes the contents.
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(2);
+
+ code_edit->cut();
+ CHECK(DS->clipboard_get() == "some\n");
+ CHECK(code_edit->get_text() == "");
+ CHECK(code_edit->get_line_count() == 1);
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Cut empty line.
+ code_edit->cut();
+ CHECK(DS->clipboard_get() == "\n");
+ CHECK(code_edit->get_text() == "");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Cut multiple lines, in order.
+ code_edit->set_text("this is\nsome\ntext to\nbe\n\ncut");
+ code_edit->set_caret_line(2);
+ code_edit->set_caret_column(7);
+ code_edit->add_caret(3, 0);
+ code_edit->add_caret(0, 2);
+
+ code_edit->cut();
+ CHECK(DS->clipboard_get() == "this is\ntext to\nbe\n");
+ CHECK(code_edit->get_text() == "some\n\ncut");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->get_caret_line(0) == 1);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 2);
+ code_edit->remove_secondary_carets();
+
+ // Cut multiple selections, in order. Ignores regular carets.
+ code_edit->set_text("this is\nsome\ntext to\nbe\n\ncut");
+ code_edit->add_caret(3, 0);
+ code_edit->add_caret(0, 2);
+ code_edit->add_caret(2, 0);
+ code_edit->select(1, 0, 1, 2, 0);
+ code_edit->select(3, 0, 4, 0, 1);
+ code_edit->select(0, 5, 0, 3, 2);
+
+ code_edit->cut();
+ CHECK(DS->clipboard_get() == "s \nso\nbe\n");
+ CHECK(code_edit->get_text() == "thiis\nme\ntext to\n\ncut");
+ CHECK(code_edit->get_caret_count() == 4);
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line(0) == 1);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->get_caret_line(1) == 3);
+ CHECK(code_edit->get_caret_column(1) == 0);
+ CHECK(code_edit->get_caret_line(2) == 0);
+ CHECK(code_edit->get_caret_column(2) == 3);
+ CHECK(code_edit->get_caret_line(3) == 2);
+ CHECK(code_edit->get_caret_column(3) == 0);
+ }
+
+ SUBCASE("[SceneTree][CodeEdit] new line") {
+ // Add a new line.
+ code_edit->set_text("test new line");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(13);
+ SEND_GUI_ACTION("ui_text_newline");
+ CHECK(code_edit->get_line(0) == "test new line");
+ CHECK(code_edit->get_line(1) == "");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Split line with new line.
+ code_edit->set_text("test new line");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(5);
+ SEND_GUI_ACTION("ui_text_newline");
+ CHECK(code_edit->get_line(0) == "test ");
+ CHECK(code_edit->get_line(1) == "new line");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Delete selection and split with new line.
+ code_edit->set_text("test new line");
+ code_edit->select(0, 0, 0, 5);
+ SEND_GUI_ACTION("ui_text_newline");
+ CHECK(code_edit->get_line(0) == "");
+ CHECK(code_edit->get_line(1) == "new line");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Blank new line below with selection should not split.
+ code_edit->set_text("test new line");
+ code_edit->select(0, 0, 0, 5);
+ SEND_GUI_ACTION("ui_text_newline_blank");
+ CHECK(code_edit->get_line(0) == "test new line");
+ CHECK(code_edit->get_line(1) == "");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Blank new line above with selection should not split.
+ code_edit->set_text("test new line");
+ code_edit->select(0, 0, 0, 5);
+ SEND_GUI_ACTION("ui_text_newline_above");
+ CHECK(code_edit->get_line(0) == "");
+ CHECK(code_edit->get_line(1) == "test new line");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Multiple new lines with multiple carets.
+ code_edit->set_text("test new line");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(5);
+ code_edit->add_caret(0, 8);
+ SEND_GUI_ACTION("ui_text_newline");
+ CHECK(code_edit->get_line(0) == "test ");
+ CHECK(code_edit->get_line(1) == "new");
+ CHECK(code_edit->get_line(2) == " line");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->get_caret_line(0) == 1);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->get_caret_line(1) == 2);
+ CHECK(code_edit->get_caret_column(1) == 0);
+
+ // Multiple blank new lines with multiple carets.
+ code_edit->set_text("test new line");
+ code_edit->remove_secondary_carets();
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(5);
+ code_edit->add_caret(0, 8);
+ SEND_GUI_ACTION("ui_text_newline_blank");
+ CHECK(code_edit->get_line(0) == "test new line");
+ CHECK(code_edit->get_line(1) == "");
+ CHECK(code_edit->get_line(2) == "");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->get_caret_line(0) == 2);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->get_caret_line(1) == 1);
+ CHECK(code_edit->get_caret_column(1) == 0);
+
+ // Multiple new lines above with multiple carets.
+ code_edit->set_text("test new line");
+ code_edit->remove_secondary_carets();
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(5);
+ code_edit->add_caret(0, 8);
+ SEND_GUI_ACTION("ui_text_newline_above");
+ CHECK(code_edit->get_line(0) == "");
+ CHECK(code_edit->get_line(1) == "");
+ CHECK(code_edit->get_line(2) == "test new line");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->get_caret_line(1) == 1);
+ CHECK(code_edit->get_caret_column(1) == 0);
+
+ // See '[CodeEdit] auto indent' tests for tests about new line with indentation.
+ }
+
+ SUBCASE("[SceneTree][CodeEdit] move lines up") {
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+
+ // Move line up with caret on it.
+ code_edit->set_caret_line(2);
+ code_edit->set_caret_column(1);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Undo.
+ code_edit->undo();
+ CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Redo.
+ code_edit->redo();
+ CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Does nothing at the first line.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(1);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Works on empty line.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->set_caret_line(3);
+ code_edit->set_caret_column(0);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "test\nlines\n\nto\nmove\naround");
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Move multiple lines up with selection.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(4, 0, 5, 1);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "test\nlines\nto\nmove\naround\n");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 3);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 4);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Does not affect line with selection end at column 0.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(4, 0, 5, 0);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "test\nlines\nto\nmove\n\naround");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 3);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 4);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Move multiple lines up with selection, right to left selection.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(5, 2, 4, 1);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "test\nlines\nto\nmove\naround\n");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 4);
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK(code_edit->get_caret_line() == 3);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Move multiple lines with multiple carets. A line with multiple carets is only moved once.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(5, 2, 5, 4);
+ code_edit->add_caret(4, 0);
+ code_edit->add_caret(4, 4);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "test\nlines\nto\nmove\naround\n");
+ CHECK(code_edit->get_caret_count() == 3);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 4);
+ CHECK(code_edit->get_selection_origin_column(0) == 2);
+ CHECK(code_edit->get_caret_line(0) == 4);
+ CHECK(code_edit->get_caret_column(0) == 4);
+ CHECK_FALSE(code_edit->has_selection(1));
+ CHECK(code_edit->get_caret_line(1) == 3);
+ CHECK(code_edit->get_caret_column(1) == 0);
+ CHECK_FALSE(code_edit->has_selection(2));
+ CHECK(code_edit->get_caret_line(2) == 3);
+ CHECK(code_edit->get_caret_column(2) == 4);
+
+ // Move multiple separate lines with multiple selections.
+ code_edit->remove_secondary_carets();
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(2, 2, 1, 4);
+ code_edit->add_caret(5, 0);
+ code_edit->select(5, 0, 5, 1, 1);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "lines\nto\ntest\n\naround\nmove");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 1);
+ CHECK(code_edit->get_selection_origin_column(0) == 2);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 4);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 4);
+ CHECK(code_edit->get_selection_origin_column(1) == 0);
+ CHECK(code_edit->get_caret_line(1) == 4);
+ CHECK(code_edit->get_caret_column(1) == 1);
+ }
+
+ SUBCASE("[SceneTree][CodeEdit] move lines down") {
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+
+ // Move line down with caret on it.
+ code_edit->set_caret_line(1);
+ code_edit->set_caret_column(1);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Undo.
+ code_edit->undo();
+ CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Redo.
+ code_edit->redo();
+ CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Does nothing at the last line.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->set_caret_line(5);
+ code_edit->set_caret_column(1);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
+ CHECK(code_edit->get_caret_line() == 5);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Works on empty line.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->set_caret_line(3);
+ code_edit->set_caret_column(0);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "test\nlines\nto\nmove\n\naround");
+ CHECK(code_edit->get_caret_line() == 4);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Move multiple lines down with selection.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(1, 0, 2, 1);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "test\n\nlines\nto\nmove\naround");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 2);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 3);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Does not affect line with selection end at column 0.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(1, 0, 2, 0);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 2);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 3);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Move multiple lines down with selection, right to left selection.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(2, 2, 1, 1);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "test\n\nlines\nto\nmove\naround");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 3);
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Move multiple lines with multiple carets. A line with multiple carets is only moved once.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(1, 2, 1, 4);
+ code_edit->add_caret(0, 0);
+ code_edit->add_caret(0, 1);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "to\ntest\nlines\n\nmove\naround");
+ CHECK(code_edit->get_caret_count() == 3);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 2);
+ CHECK(code_edit->get_selection_origin_column(0) == 2);
+ CHECK(code_edit->get_caret_line(0) == 2);
+ CHECK(code_edit->get_caret_column(0) == 4);
+ CHECK_FALSE(code_edit->has_selection(1));
+ CHECK(code_edit->get_caret_line(1) == 1);
+ CHECK(code_edit->get_caret_column(1) == 0);
+ CHECK_FALSE(code_edit->has_selection(2));
+ CHECK(code_edit->get_caret_line(2) == 1);
+ CHECK(code_edit->get_caret_column(2) == 1);
+
+ // Move multiple separate lines with multiple selections.
+ code_edit->remove_secondary_carets();
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(0, 2, 1, 4);
+ code_edit->add_caret(4, 0);
+ code_edit->select(4, 0, 4, 2, 1);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "to\ntest\nlines\n\naround\nmove");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 1);
+ CHECK(code_edit->get_selection_origin_column(0) == 2);
+ CHECK(code_edit->get_caret_line(0) == 2);
+ CHECK(code_edit->get_caret_column(0) == 4);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 5);
+ CHECK(code_edit->get_selection_origin_column(1) == 0);
+ CHECK(code_edit->get_caret_line(1) == 5);
+ CHECK(code_edit->get_caret_column(1) == 2);
+ }
+
+ SUBCASE("[SceneTree][CodeEdit] delete lines") {
+ code_edit->set_text("test\nlines\nto\n\ndelete");
+
+ // Delete line with caret on it.
+ code_edit->set_caret_line(1);
+ code_edit->set_caret_column(1);
+ code_edit->delete_lines();
+ CHECK(code_edit->get_text() == "test\nto\n\ndelete");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Undo.
+ code_edit->undo();
+ CHECK(code_edit->get_text() == "test\nlines\nto\n\ndelete");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Redo.
+ code_edit->redo();
+ CHECK(code_edit->get_text() == "test\nto\n\ndelete");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Delete empty line.
+ code_edit->set_caret_line(2);
+ code_edit->set_caret_column(0);
+ code_edit->delete_lines();
+ CHECK(code_edit->get_text() == "test\nto\ndelete");
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Deletes only one line when there are multiple carets on it. Carets move down and the column gets clamped.
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(0);
+ code_edit->add_caret(0, 1);
+ code_edit->add_caret(0, 4);
+ code_edit->delete_lines();
+ CHECK(code_edit->get_text() == "to\ndelete");
+ CHECK(code_edit->get_caret_count() == 3);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->get_caret_line(1) == 0);
+ CHECK(code_edit->get_caret_column(1) == 1);
+ CHECK(code_edit->get_caret_line(2) == 0);
+ CHECK(code_edit->get_caret_column(2) == 2);
+
+ // Delete multiple lines with selection.
+ code_edit->remove_secondary_carets();
+ code_edit->set_text("test\nlines\nto\n\ndelete");
+ code_edit->select(0, 1, 2, 1);
+ code_edit->delete_lines();
+ CHECK(code_edit->get_text() == "\ndelete");
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Does not affect line with selection end at column 0.
+ code_edit->set_text("test\nlines\nto\n\ndelete");
+ code_edit->select(0, 1, 1, 0);
+ code_edit->delete_lines();
+ CHECK(code_edit->get_text() == "lines\nto\n\ndelete");
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Delete multiple lines with multiple carets.
+ code_edit->set_text("test\nlines\nto\n\ndelete");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(2);
+ code_edit->add_caret(1, 0);
+ code_edit->add_caret(4, 5);
+ code_edit->delete_lines();
+ CHECK(code_edit->get_text() == "to\n");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->get_caret_line(1) == 1);
+ CHECK(code_edit->get_caret_column(1) == 0);
+
+ // Delete multiple separate lines with multiple selections.
+ code_edit->remove_secondary_carets();
+ code_edit->set_text("test\nlines\nto\n\ndelete");
+ code_edit->add_caret(4, 5);
+ code_edit->select(0, 1, 1, 1);
+ code_edit->select(5, 5, 4, 0, 1);
+ code_edit->delete_lines();
+ CHECK(code_edit->get_text() == "to\n");
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->get_caret_line(0) == 0);
+ CHECK(code_edit->get_caret_column(0) == 1);
+ CHECK(code_edit->get_caret_line(1) == 1);
+ CHECK(code_edit->get_caret_column(1) == 0);
+
+ // Deletes contents when there is only one line.
+ code_edit->remove_secondary_carets();
+ code_edit->set_text("test");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(4);
+ code_edit->delete_lines();
+ CHECK(code_edit->get_text() == "");
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 0);
+ }
+
+ SUBCASE("[SceneTree][CodeEdit] duplicate selection") {
+ code_edit->set_text("test\nlines\nto\n\nduplicate");
+
+ // Duplicate selected text.
+ code_edit->select(0, 1, 1, 2);
+ code_edit->duplicate_selection();
+ CHECK(code_edit->get_text() == "test\nliest\nlines\nto\n\nduplicate");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 2);
+
+ // Undo.
+ code_edit->undo();
+ CHECK(code_edit->get_text() == "test\nlines\nto\n\nduplicate");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 1);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 2);
+
+ // Redo.
+ code_edit->redo();
+ CHECK(code_edit->get_text() == "test\nliest\nlines\nto\n\nduplicate");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 1);
+ CHECK(code_edit->get_selection_origin_column() == 2);
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 2);
+
+ // Duplicate selected text, right to left selection.
+ code_edit->set_text("test\nlines\nto\n\nduplicate");
+ code_edit->select(1, 1, 0, 2);
+ code_edit->duplicate_selection();
+ CHECK(code_edit->get_text() == "test\nlst\nlines\nto\n\nduplicate");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 2);
+ CHECK(code_edit->get_selection_origin_column() == 1);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 1);
+
+ // Duplicate line if there is no selection.
+ code_edit->deselect();
+ code_edit->set_text("test\nlines\nto\n\nduplicate");
+ code_edit->set_caret_line(1);
+ code_edit->set_caret_column(2);
+ code_edit->duplicate_selection();
+ CHECK(code_edit->get_text() == "test\nlines\nlines\nto\n\nduplicate");
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 2);
+
+ // Duplicate multiple lines.
+ code_edit->deselect();
+ code_edit->set_text("test\nlines\nto\n\nduplicate");
+ code_edit->set_caret_line(1);
+ code_edit->set_caret_column(2);
+ code_edit->add_caret(5, 0);
+ code_edit->add_caret(0, 4);
+ code_edit->duplicate_selection();
+ CHECK(code_edit->get_text() == "test\ntest\nlines\nlines\nto\n\nduplicate\nduplicate");
+ CHECK(code_edit->get_caret_count() == 3);
+ CHECK_FALSE(code_edit->has_selection());
+ CHECK(code_edit->get_caret_line(0) == 3);
+ CHECK(code_edit->get_caret_column(0) == 2);
+ CHECK(code_edit->get_caret_line(1) == 7);
+ CHECK(code_edit->get_caret_column(1) == 0);
+ CHECK(code_edit->get_caret_line(2) == 1);
+ CHECK(code_edit->get_caret_column(2) == 4);
+
+ // Duplicate multiple separate selections.
+ code_edit->remove_secondary_carets();
+ code_edit->set_text("test\nlines\nto\n\nduplicate");
+ code_edit->add_caret(4, 4);
+ code_edit->add_caret(0, 1);
+ code_edit->add_caret(0, 4);
+ code_edit->select(2, 0, 2, 1, 0);
+ code_edit->select(3, 0, 4, 4, 1);
+ code_edit->select(0, 1, 0, 0, 2);
+ code_edit->select(0, 2, 0, 4, 3);
+ code_edit->duplicate_selection();
+ CHECK(code_edit->get_text() == "ttestst\nlines\ntto\n\ndupl\nduplicate");
+ CHECK(code_edit->get_caret_count() == 4);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 2);
+ CHECK(code_edit->get_selection_origin_column(0) == 1);
+ CHECK(code_edit->get_caret_line(0) == 2);
+ CHECK(code_edit->get_caret_column(0) == 2);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 4);
+ CHECK(code_edit->get_selection_origin_column(1) == 4);
+ CHECK(code_edit->get_caret_line(1) == 5);
+ CHECK(code_edit->get_caret_column(1) == 4);
+ CHECK(code_edit->has_selection(2));
+ CHECK(code_edit->get_selection_origin_line(2) == 0);
+ CHECK(code_edit->get_selection_origin_column(2) == 2);
+ CHECK(code_edit->get_caret_line(2) == 0);
+ CHECK(code_edit->get_caret_column(2) == 1);
+ CHECK(code_edit->has_selection(3));
+ CHECK(code_edit->get_selection_origin_line(3) == 0);
+ CHECK(code_edit->get_selection_origin_column(3) == 5);
+ CHECK(code_edit->get_caret_line(3) == 0);
+ CHECK(code_edit->get_caret_column(3) == 7);
+
+ // Duplicate adjacent selections.
+ code_edit->remove_secondary_carets();
+ code_edit->set_text("test\nlines\nto\n\nduplicate");
+ code_edit->add_caret(1, 2);
+ code_edit->select(1, 0, 1, 1, 0);
+ code_edit->select(1, 1, 1, 4, 1);
+ code_edit->duplicate_selection();
+ CHECK(code_edit->get_text() == "test\nllineines\nto\n\nduplicate");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 1);
+ CHECK(code_edit->get_selection_origin_column(0) == 1);
+ CHECK(code_edit->get_caret_line(0) == 1);
+ CHECK(code_edit->get_caret_column(0) == 2);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 1);
+ CHECK(code_edit->get_selection_origin_column(1) == 5);
+ CHECK(code_edit->get_caret_line(1) == 1);
+ CHECK(code_edit->get_caret_column(1) == 8);
+
+ // Duplicate lines then duplicate selections when there are both selections and non-selections.
+ code_edit->remove_secondary_carets();
+ code_edit->set_text("test duplicate");
+ code_edit->select(0, 14, 0, 13, 0);
+ code_edit->add_caret(0, 8);
+ code_edit->add_caret(0, 4);
+ code_edit->select(0, 2, 0, 4, 2);
+ code_edit->duplicate_selection();
+ CHECK(code_edit->get_text() == "test duplicate\ntestst duplicatee");
+ CHECK(code_edit->get_caret_count() == 3);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 1);
+ CHECK(code_edit->get_selection_origin_column(0) == 17);
+ CHECK(code_edit->get_caret_line(0) == 1);
+ CHECK(code_edit->get_caret_column(0) == 16);
+ CHECK_FALSE(code_edit->has_selection(1));
+ CHECK(code_edit->get_caret_line(1) == 1);
+ CHECK(code_edit->get_caret_column(1) == 10);
+ CHECK(code_edit->has_selection(2));
+ CHECK(code_edit->get_selection_origin_line(2) == 1);
+ CHECK(code_edit->get_selection_origin_column(2) == 4);
+ CHECK(code_edit->get_caret_line(2) == 1);
+ CHECK(code_edit->get_caret_column(2) == 6);
+ }
+
+ SUBCASE("[SceneTree][CodeEdit] duplicate lines") {
+ String reset_text = R"(extends Node
+
+func _ready():
+ var a := len(OS.get_cmdline_args())
+ var b := get_child_count()
+ var c := a + b
+ for i in range(c):
+ print("This is the solution: ", sin(i))
+ var pos = get_index() - 1
+ print("Make sure this exits: %b" % pos)
+)";
+
+ code_edit->set_text(reset_text);
- code_edit->set_text(R"(extends Node
+ // Duplicate a single line without selection.
+ code_edit->set_caret_line(0);
+ code_edit->duplicate_lines();
+ CHECK(code_edit->get_line(0) == "extends Node");
+ CHECK(code_edit->get_line(1) == "extends Node");
+ CHECK(code_edit->get_line(2) == "");
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
+ // Duplicate multiple lines with selection.
+ code_edit->set_text(reset_text);
+ code_edit->select(4, 8, 6, 15);
+ code_edit->duplicate_lines();
+ CHECK(code_edit->get_text() == R"(extends Node
+
+func _ready():
+ var a := len(OS.get_cmdline_args())
+ var b := get_child_count()
+ var c := a + b
+ for i in range(c):
+ var b := get_child_count()
+ var c := a + b
+ for i in range(c):
+ print("This is the solution: ", sin(i))
+ var pos = get_index() - 1
+ print("Make sure this exits: %b" % pos)
+)");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 7);
+ CHECK(code_edit->get_selection_origin_column() == 8);
+ CHECK(code_edit->get_caret_line() == 9);
+ CHECK(code_edit->get_caret_column() == 15);
+
+ // Duplicate multiple lines with right to left selection.
+ code_edit->set_text(reset_text);
+ code_edit->select(6, 15, 4, 8);
+ code_edit->duplicate_lines();
+ CHECK(code_edit->get_text() == R"(extends Node
func _ready():
var a := len(OS.get_cmdline_args())
var b := get_child_count()
var c := a + b
for i in range(c):
+ var b := get_child_count()
+ var c := a + b
+ for i in range(c):
print("This is the solution: ", sin(i))
var pos = get_index() - 1
print("Make sure this exits: %b" % pos)
)");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 9);
+ CHECK(code_edit->get_selection_origin_column() == 15);
+ CHECK(code_edit->get_caret_line() == 7);
+ CHECK(code_edit->get_caret_column() == 8);
+
+ // Duplicate single lines with multiple carets. Multiple carets on a single line only duplicate once.
+ code_edit->remove_secondary_carets();
+ code_edit->deselect();
+ code_edit->set_text(reset_text);
+ code_edit->set_caret_line(3);
+ code_edit->set_caret_column(1);
+ code_edit->add_caret(5, 1);
+ code_edit->add_caret(5, 5);
+ code_edit->add_caret(4, 2);
+ code_edit->duplicate_lines();
+ CHECK(code_edit->get_text() == R"(extends Node
- /* Duplicate a single line without selection. */
- code_edit->set_caret_line(0);
- code_edit->duplicate_lines();
- CHECK(code_edit->get_line(0) == "extends Node");
- CHECK(code_edit->get_line(1) == "extends Node");
- CHECK(code_edit->get_line(2) == "");
-
- /* Duplicate multiple lines with selection. */
- code_edit->set_caret_line(6);
- code_edit->set_caret_column(15);
- code_edit->select(4, 8, 6, 15);
- code_edit->duplicate_lines();
- CHECK(code_edit->get_line(6) == "\tvar c := a + b");
- CHECK(code_edit->get_line(7) == "\tvar a := len(OS.get_cmdline_args())");
- CHECK(code_edit->get_line(8) == "\tvar b := get_child_count()");
- CHECK(code_edit->get_line(9) == "\tvar c := a + b");
- CHECK(code_edit->get_line(10) == "\tfor i in range(c):");
-
- /* Duplicate single lines with multiple carets. */
- code_edit->deselect();
- code_edit->set_caret_line(10);
- code_edit->set_caret_column(1);
- code_edit->add_caret(11, 2);
- code_edit->add_caret(12, 1);
- code_edit->duplicate_lines();
- CHECK(code_edit->get_line(9) == "\tvar c := a + b");
- CHECK(code_edit->get_line(10) == "\tfor i in range(c):");
- CHECK(code_edit->get_line(11) == "\tfor i in range(c):");
- CHECK(code_edit->get_line(12) == "\t\tprint(\"This is the solution: \", sin(i))");
- CHECK(code_edit->get_line(13) == "\t\tprint(\"This is the solution: \", sin(i))");
- CHECK(code_edit->get_line(14) == "\tvar pos = get_index() - 1");
- CHECK(code_edit->get_line(15) == "\tvar pos = get_index() - 1");
- CHECK(code_edit->get_line(16) == "\tprint(\"Make sure this exits: %b\" % pos)");
-
- /* Duplicate multiple lines with multiple carets. */
- code_edit->select(0, 0, 1, 2, 0);
- code_edit->select(3, 0, 4, 2, 1);
- code_edit->select(16, 0, 17, 0, 2);
- code_edit->set_caret_line(1, false, true, 0, 0);
- code_edit->set_caret_column(2, false, 0);
- code_edit->set_caret_line(4, false, true, 0, 1);
- code_edit->set_caret_column(2, false, 1);
- code_edit->set_caret_line(17, false, true, 0, 2);
- code_edit->set_caret_column(0, false, 2);
- code_edit->duplicate_lines();
- CHECK(code_edit->get_line(1) == "extends Node");
- CHECK(code_edit->get_line(2) == "extends Node");
- CHECK(code_edit->get_line(3) == "extends Node");
- CHECK(code_edit->get_line(4) == "");
- CHECK(code_edit->get_line(6) == "\tvar a := len(OS.get_cmdline_args())");
- CHECK(code_edit->get_line(7) == "func _ready():");
- CHECK(code_edit->get_line(8) == "\tvar a := len(OS.get_cmdline_args())");
- CHECK(code_edit->get_line(9) == "\tvar b := get_child_count()");
- CHECK(code_edit->get_line(20) == "\tprint(\"Make sure this exits: %b\" % pos)");
- CHECK(code_edit->get_line(21) == "");
- CHECK(code_edit->get_line(22) == "\tprint(\"Make sure this exits: %b\" % pos)");
- CHECK(code_edit->get_line(23) == "");
+func _ready():
+ var a := len(OS.get_cmdline_args())
+ var a := len(OS.get_cmdline_args())
+ var b := get_child_count()
+ var b := get_child_count()
+ var c := a + b
+ var c := a + b
+ for i in range(c):
+ print("This is the solution: ", sin(i))
+ var pos = get_index() - 1
+ print("Make sure this exits: %b" % pos)
+)");
+ CHECK(code_edit->get_caret_count() == 4);
+ CHECK_FALSE(code_edit->has_selection(0));
+ CHECK(code_edit->get_caret_line(0) == 4);
+ CHECK(code_edit->get_caret_column(0) == 1);
+ CHECK_FALSE(code_edit->has_selection(1));
+ CHECK(code_edit->get_caret_line(1) == 8);
+ CHECK(code_edit->get_caret_column(1) == 1);
+ CHECK_FALSE(code_edit->has_selection(2));
+ CHECK(code_edit->get_caret_line(2) == 8);
+ CHECK(code_edit->get_caret_column(2) == 5);
+ CHECK_FALSE(code_edit->has_selection(3));
+ CHECK(code_edit->get_caret_line(3) == 6);
+ CHECK(code_edit->get_caret_column(3) == 2);
+
+ // Duplicate multiple lines with multiple selections.
+ code_edit->remove_secondary_carets();
+ code_edit->set_text(reset_text);
+ code_edit->add_caret(4, 2);
+ code_edit->add_caret(6, 0);
+ code_edit->add_caret(7, 8);
+ code_edit->select(0, 0, 2, 5, 0);
+ code_edit->select(3, 0, 4, 2, 1);
+ code_edit->select(7, 1, 6, 0, 2);
+ code_edit->select(7, 3, 7, 8, 3);
+ code_edit->duplicate_lines();
+ CHECK(code_edit->get_text() == R"(extends Node
+
+func _ready():
+extends Node
+
+func _ready():
+ var a := len(OS.get_cmdline_args())
+ var b := get_child_count()
+ var a := len(OS.get_cmdline_args())
+ var b := get_child_count()
+ var c := a + b
+ for i in range(c):
+ print("This is the solution: ", sin(i))
+ for i in range(c):
+ print("This is the solution: ", sin(i))
+ var pos = get_index() - 1
+ print("Make sure this exits: %b" % pos)
+)");
+ CHECK(code_edit->get_caret_count() == 4);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 3);
+ CHECK(code_edit->get_selection_origin_column(0) == 0);
+ CHECK(code_edit->get_caret_line(0) == 5);
+ CHECK(code_edit->get_caret_column(0) == 5);
+
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 8);
+ CHECK(code_edit->get_selection_origin_column(1) == 0);
+ CHECK(code_edit->get_caret_line(1) == 9);
+ CHECK(code_edit->get_caret_column(1) == 2);
+
+ CHECK(code_edit->has_selection(2));
+ CHECK(code_edit->get_selection_origin_line(2) == 14);
+ CHECK(code_edit->get_selection_origin_column(2) == 1);
+ CHECK(code_edit->get_caret_line(2) == 13);
+ CHECK(code_edit->get_caret_column(2) == 0);
+
+ CHECK(code_edit->has_selection(3));
+ CHECK(code_edit->get_selection_origin_line(3) == 14);
+ CHECK(code_edit->get_selection_origin_column(3) == 3);
+ CHECK(code_edit->get_caret_line(3) == 14);
+ CHECK(code_edit->get_caret_column(3) == 8);
+ }
memdelete(code_edit);
}