From 40b7931279936f220088785145dc2cd3a4dcb04b Mon Sep 17 00:00:00 2001 From: Aziroshin Date: Fri, 4 Apr 2025 09:45:09 +0200 Subject: [PATCH] [CodeEdit] Fix folding for comments mixed with code region tags. Co-authored-by: Kit Bishop --- scene/gui/code_edit.cpp | 8 +++++-- tests/scene/test_code_edit.h | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 9722b5e2eef..870c5bbf842 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -1645,12 +1645,12 @@ bool CodeEdit::can_fold_line(int p_line) const { if (delimiter_end_line == p_line) { /* Check we are the start of the block. */ if (p_line - 1 >= 0) { - if ((in_string != -1 && is_in_string(p_line - 1) != -1) || (in_comment != -1 && is_in_comment(p_line - 1) != -1)) { + if ((in_string != -1 && is_in_string(p_line - 1) != -1) || (in_comment != -1 && is_in_comment(p_line - 1) != -1 && !is_line_code_region_start(p_line - 1) && !is_line_code_region_end(p_line - 1))) { return false; } } /* Check it continues for at least one line. */ - return ((in_string != -1 && is_in_string(p_line + 1) != -1) || (in_comment != -1 && is_in_comment(p_line + 1) != -1)); + return ((in_string != -1 && is_in_string(p_line + 1) != -1) || (in_comment != -1 && is_in_comment(p_line + 1) != -1 && !is_line_code_region_start(p_line + 1) && !is_line_code_region_end(p_line + 1))); } return ((in_string != -1 && is_in_string(delimiter_end_line) != -1) || (in_comment != -1 && is_in_comment(delimiter_end_line) != -1)); } @@ -1705,6 +1705,10 @@ void CodeEdit::fold_line(int p_line) { if ((in_string != -1 && is_in_string(i) == -1) || (in_comment != -1 && is_in_comment(i) == -1)) { break; } + if (in_comment != -1 && (is_line_code_region_start(i) || is_line_code_region_end(i))) { + // A code region tag should split a comment block, ending it early. + break; + } end_line = i; } } diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h index 6938b16bc7d..22336542565 100644 --- a/tests/scene/test_code_edit.h +++ b/tests/scene/test_code_edit.h @@ -3269,6 +3269,47 @@ TEST_CASE("[SceneTree][CodeEdit] folding") { CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4); } + SUBCASE("[CodeEdit] folding comments including and/or adjacent to code regions") { + code_edit->add_comment_delimiter("#", "", true); + + // Single line comment directly above a code region tag is not foldable. + code_edit->set_text("#line0\n#region a\nnothing\n#line3\n#endregion"); + CHECK_FALSE(code_edit->can_fold_line(0)); + CHECK_FALSE(code_edit->can_fold_line(3)); + + // Comment blocks. + // Foldable even when directly below a code region start tag. + code_edit->set_text("#line0\n#line1\n#region a\n#line3\n#line4\nnothing\n#endregion"); + CHECK(code_edit->can_fold_line(3)); + + // Doesn't fold beyond region start tag. + code_edit->fold_line(0); + CHECK(code_edit->is_line_folded(0)); + CHECK_EQ(code_edit->get_visible_line_count_in_range(0, 1), 1); + CHECK_EQ(code_edit->get_visible_line_count_in_range(2, 2), 1); + + // Foldable even when directly below a code region end tag. + code_edit->set_text("#region a\nnothing\n#line2\n#line3\n#endregion\n#line5\n#line6"); + CHECK(code_edit->can_fold_line(5)); + + // Doesn't fold beyond region end tag. + code_edit->fold_line(2); + CHECK(code_edit->is_line_folded(2)); + CHECK_EQ(code_edit->get_visible_line_count_in_range(2, 3), 1); + CHECK_EQ(code_edit->get_visible_line_count_in_range(4, 4), 1); + + code_edit->add_comment_delimiter("/*", "*/", false); + + // Multiline comments. + // Folds a region tag inside it. + code_edit->set_text("/*\nnothing\n#region a\n*/\n#endregion"); + CHECK(code_edit->can_fold_line(0)); + code_edit->fold_line(0); + CHECK(code_edit->is_line_folded(0)); + CHECK_EQ(code_edit->get_visible_line_count_in_range(0, 3), 1); + CHECK_EQ(code_edit->get_visible_line_count_in_range(4, 4), 1); + } + 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");