editor: Fix line comments not extending when adding new line immediately after slash (#30824)

This PR fixes a bug where comments don't extend when cursor is right
next to the second slash. We added `// ` as a prefix character to
correctly position the cursor after a new line, but this broke comment
validation by including that trailing space, which it shouldn't.

Now both line comments and block comments (already handled in JSDoc PR)
can extend right after the prefix without needing an additional space.

Before:


https://github.com/user-attachments/assets/ca4d4c1b-b9b9-4f1b-b47a-56ae35776f41

After:


https://github.com/user-attachments/assets/b3408e1e-3efe-4787-ba68-d33cd2ea8563

Release Notes:

- Fixed issue where comments weren't extending when adding new line
immediately after comment prefix (`//`).
This commit is contained in:
Smit Barmase 2025-05-16 19:11:37 +05:30 committed by GitHub
parent 6bec76cd5d
commit 0355b9dfab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 15 deletions

View file

@ -3954,26 +3954,28 @@ impl Editor {
let (snapshot, range) =
buffer.buffer_line_for_row(MultiBufferRow(start_point.row))?;
let mut index_of_first_non_whitespace = 0;
let num_of_whitespaces = snapshot
.chars_for_range(range.clone())
.take_while(|c| c.is_whitespace())
.count();
let comment_candidate = snapshot
.chars_for_range(range)
.skip_while(|c| {
let should_skip = c.is_whitespace();
if should_skip {
index_of_first_non_whitespace += 1;
}
should_skip
})
.skip(num_of_whitespaces)
.take(max_len_of_delimiter)
.collect::<String>();
let comment_prefix = delimiters.iter().find(|comment_prefix| {
comment_candidate.starts_with(comment_prefix.as_ref())
})?;
let (delimiter, trimmed_len) =
delimiters.iter().find_map(|delimiter| {
let trimmed = delimiter.trim_end();
if comment_candidate.starts_with(trimmed) {
Some((delimiter, trimmed.len()))
} else {
None
}
})?;
let cursor_is_placed_after_comment_marker =
index_of_first_non_whitespace + comment_prefix.len()
<= start_point.column as usize;
num_of_whitespaces + trimmed_len <= start_point.column as usize;
if cursor_is_placed_after_comment_marker {
Some(comment_prefix.clone())
Some(delimiter.clone())
} else {
None
}

View file

@ -2755,7 +2755,7 @@ async fn test_newline_comments(cx: &mut TestAppContext) {
let language = Arc::new(Language::new(
LanguageConfig {
line_comments: vec!["//".into()],
line_comments: vec!["// ".into()],
..LanguageConfig::default()
},
None,
@ -2770,7 +2770,29 @@ async fn test_newline_comments(cx: &mut TestAppContext) {
cx.update_editor(|e, window, cx| e.newline(&Newline, window, cx));
cx.assert_editor_state(indoc! {"
// Foo
// ˇ
"});
// Ensure that we add comment prefix when existing line contains space
cx.update_editor(|e, window, cx| e.newline(&Newline, window, cx));
cx.assert_editor_state(
indoc! {"
// Foo
//s
// ˇ
"}
.replace("s", " ") // s is used as space placeholder to prevent format on save
.as_str(),
);
// Ensure that we add comment prefix when existing line does not contain space
cx.set_state(indoc! {"
// Foo
//ˇ
"});
cx.update_editor(|e, window, cx| e.newline(&Newline, window, cx));
cx.assert_editor_state(indoc! {"
// Foo
//
// ˇ
"});
// Ensure that if cursor is before the comment start, we do not actually insert a comment prefix.
cx.set_state(indoc! {"