From dd4e8b9e66b4ec816514b457a014dff46904d16e Mon Sep 17 00:00:00 2001 From: smit Date: Thu, 22 May 2025 23:27:03 +0530 Subject: [PATCH] editor: Fix block comment incorrectly continues to next line in some cases (#31204) Closes #31138 Fix edge case where adding newline if there is text afterwards end delimiter of multiline comment, would continue the comment prefix. This is fixed by checking for end delimiter on whole line instead of just assuming it would always be at end. - [x] Tests Release Notes: - Fixed the issue where in some cases the block comment continues to the next line even though the comment block is already closed. --- crates/editor/src/editor.rs | 36 +++++++++++++++---------------- crates/editor/src/editor_tests.rs | 26 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 1f39f9ed7b7bcce6caad62f208aab71db732bd68..5835529fa6a74f11a68bdfb49081d8483dde75b9 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -4044,31 +4044,29 @@ impl Editor { }; let cursor_is_before_end_tag_if_exists = { - let num_of_whitespaces_rev = snapshot - .reversed_chars_for_range(range.clone()) - .take_while(|c| c.is_whitespace()) - .count(); - let mut line_iter = snapshot - .reversed_chars_for_range(range) - .skip(num_of_whitespaces_rev); - let end_tag_exists = end_tag - .chars() - .rev() - .all(|char| line_iter.next() == Some(char)); - if end_tag_exists { - let max_point = snapshot.line_len(start_point.row) as usize; - let ordering = (num_of_whitespaces_rev - + end_tag.len() - + start_point.column as usize) - .cmp(&max_point); + let mut char_position = 0u32; + let mut end_tag_offset = None; + + 'outer: for chunk in snapshot.text_for_range(range.clone()) { + if let Some(byte_pos) = chunk.find(&**end_tag) { + let chars_before_match = + chunk[..byte_pos].chars().count() as u32; + end_tag_offset = + Some(char_position + chars_before_match); + break 'outer; + } + char_position += chunk.chars().count() as u32; + } + + if let Some(end_tag_offset) = end_tag_offset { let cursor_is_before_end_tag = - ordering != Ordering::Greater; + start_point.column <= end_tag_offset; if cursor_is_after_start_tag { if cursor_is_before_end_tag { insert_extra_newline = true; } let cursor_is_at_start_of_end_tag = - ordering == Ordering::Equal; + start_point.column == end_tag_offset; if cursor_is_at_start_of_end_tag { indent_on_extra_newline.len = (*len).into(); } diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index d1ad72234a671a71efd46e712919b6aae82cc385..d0af01f884b2cc16436d149634e2d086180f6d15 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -3012,6 +3012,32 @@ async fn test_newline_documentation_comments(cx: &mut TestAppContext) { */ ˇ "}); + + // Ensure that inline comment followed by code + // doesn't add comment prefix on newline + cx.set_state(indoc! {" + /** */ textˇ + "}); + cx.update_editor(|e, window, cx| e.newline(&Newline, window, cx)); + cx.assert_editor_state(indoc! {" + /** */ text + ˇ + "}); + + // Ensure that text after comment end tag + // doesn't add comment prefix on newline + cx.set_state(indoc! {" + /** + * + */ˇtext + "}); + cx.update_editor(|e, window, cx| e.newline(&Newline, window, cx)); + cx.assert_editor_state(indoc! {" + /** + * + */ + ˇtext + "}); } // Ensure that comment continuations can be disabled. update_test_language_settings(cx, |settings| {