Fix code folding when end of block is unindented delimiter

This commit is contained in:
ator-dev 2021-11-24 22:36:04 +00:00 committed by ator-dev
parent 70d530029a
commit bac0a035c9
2 changed files with 78 additions and 27 deletions

View file

@ -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) {
if (get_line(i).strip_edges().size() == 0) {
continue;
}
if (get_indent_level(i) > start_indent) {
end_line = i;
continue;
}
if (i == line_count) {
/* Do not fold empty last line of script if any */
end_line = i;
if (get_line(i).strip_edges().size() == 0) {
end_line--;
}
break;
}
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;
}
}

View file

@ -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&");
@ -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));