editor: Fix regression causing incorrect delimiter on newline in case of multiple comment prefixes (#31129)

smit created

Closes #31115

This fixes regression caused by
https://github.com/zed-industries/zed/pull/30824 while keeping that fix.

- [x] Test

Release Notes:

- Fixed the issue where adding a newline after the `///` comment would
extend it with `//` instead of `///` in Rust and other similar
languages.

Change summary

crates/editor/src/editor.rs       | 15 ++++++++-----
crates/editor/src/editor_tests.rs | 36 +++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 6 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -3964,15 +3964,18 @@ impl Editor {
                                     .skip(num_of_whitespaces)
                                     .take(max_len_of_delimiter)
                                     .collect::<String>();
-                                let (delimiter, trimmed_len) =
-                                    delimiters.iter().find_map(|delimiter| {
-                                        let trimmed = delimiter.trim_end();
-                                        if comment_candidate.starts_with(trimmed) {
-                                            Some((delimiter, trimmed.len()))
+                                let (delimiter, trimmed_len) = delimiters
+                                    .iter()
+                                    .filter_map(|delimiter| {
+                                        let prefix = delimiter.trim_end();
+                                        if comment_candidate.starts_with(prefix) {
+                                            Some((delimiter, prefix.len()))
                                         } else {
                                             None
                                         }
-                                    })?;
+                                    })
+                                    .max_by_key(|(_, len)| *len)?;
+
                                 let cursor_is_placed_after_comment_marker =
                                     num_of_whitespaces + trimmed_len <= start_point.column as usize;
                                 if cursor_is_placed_after_comment_marker {

crates/editor/src/editor_tests.rs 🔗

@@ -2820,6 +2820,42 @@ async fn test_newline_comments(cx: &mut TestAppContext) {
     "});
 }
 
+#[gpui::test]
+async fn test_newline_comments_with_multiple_delimiters(cx: &mut TestAppContext) {
+    init_test(cx, |settings| {
+        settings.defaults.tab_size = NonZeroU32::new(4)
+    });
+
+    let language = Arc::new(Language::new(
+        LanguageConfig {
+            line_comments: vec!["// ".into(), "/// ".into()],
+            ..LanguageConfig::default()
+        },
+        None,
+    ));
+    {
+        let mut cx = EditorTestContext::new(cx).await;
+        cx.update_buffer(|buffer, cx| buffer.set_language(Some(language), cx));
+        cx.set_state(indoc! {"
+        //ˇ
+    "});
+        cx.update_editor(|e, window, cx| e.newline(&Newline, window, cx));
+        cx.assert_editor_state(indoc! {"
+        //
+        // ˇ
+    "});
+
+        cx.set_state(indoc! {"
+        ///ˇ
+    "});
+        cx.update_editor(|e, window, cx| e.newline(&Newline, window, cx));
+        cx.assert_editor_state(indoc! {"
+        ///
+        /// ˇ
+    "});
+    }
+}
+
 #[gpui::test]
 async fn test_newline_documentation_comments(cx: &mut TestAppContext) {
     init_test(cx, |settings| {