Procházet zdrojové kódy

Merge pull request #55227 from ator-dev/fix-code-folding

Rémi Verschelde před 3 roky
rodič
revize
1b89296fad
2 změnil soubory, kde provedl 77 přidání a 26 odebrání
  1. 5 22
      scene/gui/code_edit.cpp
  2. 72 4
      tests/scene/test_code_edit.h

+ 5 - 22
scene/gui/code_edit.cpp

@@ -1419,40 +1419,23 @@ void CodeEdit::fold_line(int p_line) {
 		/* End line is the same therefore we have a block of single line delimiters. */
 		if (end_line == p_line) {
 			for (int i = p_line + 1; i <= line_count; i++) {
-				if (i == line_count) {
-					end_line = line_count;
-					break;
-				}
-
 				if ((in_string != -1 && is_in_string(i) == -1) || (in_comment != -1 && is_in_comment(i) == -1)) {
-					end_line = i - 1;
 					break;
 				}
+				end_line = i;
 			}
 		}
 	} else {
 		int start_indent = get_indent_level(p_line);
 		for (int i = p_line + 1; i <= line_count; i++) {
-			if (get_line(p_line).strip_edges().size() == 0 || is_in_string(i) != -1 || is_in_comment(i) != -1) {
-				end_line = i;
+			if (get_line(i).strip_edges().size() == 0) {
 				continue;
 			}
-
-			if (i == line_count) {
-				/* Do not fold empty last line of script if any */
+			if (get_indent_level(i) > start_indent) {
 				end_line = i;
-				if (get_line(i).strip_edges().size() == 0) {
-					end_line--;
-				}
-				break;
+				continue;
 			}
-
-			if ((get_indent_level(i) <= start_indent && get_line(i).strip_edges().size() != 0)) {
-				/* Keep an empty line unfolded if any */
-				end_line = i - 1;
-				if (get_line(i - 1).strip_edges().size() == 0 && i - 2 > p_line) {
-					end_line = i - 2;
-				}
+			if (is_in_string(i) == -1 && is_in_comment(i) == -1) {
 				break;
 			}
 		}

+ 72 - 4
tests/scene/test_code_edit.h

@@ -2332,6 +2332,20 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
 		CHECK_FALSE(code_edit->is_line_folded(2));
 		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
 
+		// Indent with blank lines.
+		code_edit->set_text("line1\n\tline2\n\n\nline3");
+		CHECK(code_edit->can_fold_line(0));
+		for (int i = 1; i < 2; i++) {
+			CHECK_FALSE(code_edit->can_fold_line(i));
+			code_edit->fold_line(i);
+			CHECK_FALSE(code_edit->is_line_folded(i));
+		}
+		code_edit->fold_line(0);
+		CHECK(code_edit->is_line_folded(0));
+		CHECK_FALSE(code_edit->is_line_folded(1));
+		CHECK_FALSE(code_edit->is_line_folded(2));
+		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
+
 		// Nested indents.
 		code_edit->set_text("line1\n\tline2\n\t\tline3\nline4");
 		CHECK(code_edit->can_fold_line(0));
@@ -2408,7 +2422,7 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
 		for (int i = 1; i < code_edit->get_line_count(); i++) {
 			CHECK_FALSE(code_edit->is_line_folded(i));
 		}
-		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 6);
+		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 5);
 
 		// End of file.
 		code_edit->set_text("line1\n\tline2");
@@ -2490,7 +2504,7 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
 
 		// Multiline blocks.
 		code_edit->add_comment_delimiter("&", "&", false);
-		code_edit->set_text("&line1\n\tline2&");
+		code_edit->set_text("&line1\n\tline2&\nline3");
 		CHECK(code_edit->can_fold_line(0));
 		CHECK_FALSE(code_edit->can_fold_line(1));
 		code_edit->fold_line(1);
@@ -2498,7 +2512,17 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
 		code_edit->fold_line(0);
 		CHECK(code_edit->is_line_folded(0));
 		CHECK_FALSE(code_edit->is_line_folded(1));
-		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
+		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
+
+		// Multiline comment before last line.
+		code_edit->set_text("&line1\nline2&\ntest");
+		CHECK(code_edit->can_fold_line(0));
+		CHECK_FALSE(code_edit->can_fold_line(2));
+		code_edit->fold_line(1);
+		CHECK_FALSE(code_edit->is_line_folded(1));
+		code_edit->fold_line(0);
+		CHECK(code_edit->is_line_folded(0));
+		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
 
 		// Has to be full line.
 		code_edit->set_text("test &line1\n\tline2&");
@@ -2554,7 +2578,7 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
 		CHECK_FALSE(code_edit->is_line_folded(1));
 		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
 
-		// Non-indented comments/ strings.
+		// Non-indented comments/strings.
 		// Single line
 		code_edit->set_text("test\n\tline1\n#line1\n#line2\n\ttest");
 		CHECK(code_edit->can_fold_line(0));
@@ -2576,6 +2600,50 @@ TEST_CASE("[SceneTree][CodeEdit] folding") {
 		CHECK_FALSE(code_edit->is_line_folded(1));
 		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
 
+		// Indent level 0->1, comment after lines
+		code_edit->set_text("line1\n\tline2\n#test");
+		CHECK(code_edit->can_fold_line(0));
+		CHECK_FALSE(code_edit->can_fold_line(1));
+		code_edit->fold_line(1);
+		CHECK_FALSE(code_edit->is_line_folded(1));
+		code_edit->fold_line(0);
+		CHECK(code_edit->is_line_folded(0));
+		CHECK_FALSE(code_edit->is_line_folded(1));
+		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
+
+		// Indent level 0->1, comment between lines
+		code_edit->set_text("line1\n#test\n\tline2\nline3");
+		CHECK(code_edit->can_fold_line(0));
+		CHECK_FALSE(code_edit->can_fold_line(2));
+		code_edit->fold_line(2);
+		CHECK_FALSE(code_edit->is_line_folded(2));
+		code_edit->fold_line(0);
+		CHECK(code_edit->is_line_folded(0));
+		CHECK_FALSE(code_edit->is_line_folded(2));
+		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 3);
+
+		// Indent level 1->2, comment after lines
+		code_edit->set_text("\tline1\n\t\tline2\n#test");
+		CHECK(code_edit->can_fold_line(0));
+		CHECK_FALSE(code_edit->can_fold_line(1));
+		code_edit->fold_line(1);
+		CHECK_FALSE(code_edit->is_line_folded(1));
+		code_edit->fold_line(0);
+		CHECK(code_edit->is_line_folded(0));
+		CHECK_FALSE(code_edit->is_line_folded(1));
+		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
+
+		// Indent level 1->2, comment between lines
+		code_edit->set_text("\tline1\n#test\n\t\tline2\nline3");
+		CHECK(code_edit->can_fold_line(0));
+		CHECK_FALSE(code_edit->can_fold_line(2));
+		code_edit->fold_line(2);
+		CHECK_FALSE(code_edit->is_line_folded(2));
+		code_edit->fold_line(0);
+		CHECK(code_edit->is_line_folded(0));
+		CHECK_FALSE(code_edit->is_line_folded(2));
+		CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 3);
+
 		// Multiline
 		code_edit->set_text("test\n\tline1\n&line1\nline2&\n\ttest");
 		CHECK(code_edit->can_fold_line(0));