Z 1618/extend comments (#2585)
Fixes Z-1618. In the current state, this only works for line comments such as `//` (and whatever's set in `{language}.toml` as a line_comment). Release Notes: - Comments are now extended on new line.
This commit is contained in:
parent
d5441ba386
commit
e94129446d
2 changed files with 88 additions and 29 deletions
|
@ -2179,40 +2179,72 @@ impl Editor {
|
|||
indent.len = cmp::min(indent.len, start_point.column);
|
||||
let start = selection.start;
|
||||
let end = selection.end;
|
||||
let is_cursor = start == end;
|
||||
let language_scope = buffer.language_scope_at(start);
|
||||
let (comment_delimiter, insert_extra_newline) =
|
||||
if let Some(language) = &language_scope {
|
||||
let leading_whitespace_len = buffer
|
||||
.reversed_chars_at(start)
|
||||
.take_while(|c| c.is_whitespace() && *c != '\n')
|
||||
.map(|c| c.len_utf8())
|
||||
.sum::<usize>();
|
||||
|
||||
let mut insert_extra_newline = false;
|
||||
if let Some(language) = buffer.language_scope_at(start) {
|
||||
let leading_whitespace_len = buffer
|
||||
.reversed_chars_at(start)
|
||||
.take_while(|c| c.is_whitespace() && *c != '\n')
|
||||
.map(|c| c.len_utf8())
|
||||
.sum::<usize>();
|
||||
let trailing_whitespace_len = buffer
|
||||
.chars_at(end)
|
||||
.take_while(|c| c.is_whitespace() && *c != '\n')
|
||||
.map(|c| c.len_utf8())
|
||||
.sum::<usize>();
|
||||
|
||||
let trailing_whitespace_len = buffer
|
||||
.chars_at(end)
|
||||
.take_while(|c| c.is_whitespace() && *c != '\n')
|
||||
.map(|c| c.len_utf8())
|
||||
.sum::<usize>();
|
||||
let insert_extra_newline =
|
||||
language.brackets().any(|(pair, enabled)| {
|
||||
let pair_start = pair.start.trim_end();
|
||||
let pair_end = pair.end.trim_start();
|
||||
|
||||
insert_extra_newline = language.brackets().any(|(pair, enabled)| {
|
||||
let pair_start = pair.start.trim_end();
|
||||
let pair_end = pair.end.trim_start();
|
||||
enabled
|
||||
&& pair.newline
|
||||
&& buffer.contains_str_at(
|
||||
end + trailing_whitespace_len,
|
||||
pair_end,
|
||||
)
|
||||
&& buffer.contains_str_at(
|
||||
(start - leading_whitespace_len)
|
||||
.saturating_sub(pair_start.len()),
|
||||
pair_start,
|
||||
)
|
||||
});
|
||||
// Comment extension on newline is allowed only for cursor selections
|
||||
let comment_delimiter =
|
||||
language.line_comment_prefix().filter(|_| is_cursor);
|
||||
let comment_delimiter = if let Some(delimiter) = comment_delimiter {
|
||||
buffer
|
||||
.buffer_line_for_row(start_point.row)
|
||||
.is_some_and(|(snapshot, range)| {
|
||||
snapshot
|
||||
.chars_for_range(range)
|
||||
.skip_while(|c| c.is_whitespace())
|
||||
.take(delimiter.len())
|
||||
.eq(delimiter.chars())
|
||||
})
|
||||
.then(|| delimiter.clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
(comment_delimiter, insert_extra_newline)
|
||||
} else {
|
||||
(None, false)
|
||||
};
|
||||
|
||||
enabled
|
||||
&& pair.newline
|
||||
&& buffer
|
||||
.contains_str_at(end + trailing_whitespace_len, pair_end)
|
||||
&& buffer.contains_str_at(
|
||||
(start - leading_whitespace_len)
|
||||
.saturating_sub(pair_start.len()),
|
||||
pair_start,
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
let mut new_text = String::with_capacity(1 + indent.len as usize);
|
||||
new_text.push('\n');
|
||||
let capacity_for_delimiter = comment_delimiter
|
||||
.as_deref()
|
||||
.map(str::len)
|
||||
.unwrap_or_default();
|
||||
let mut new_text =
|
||||
String::with_capacity(1 + capacity_for_delimiter + indent.len as usize);
|
||||
new_text.push_str("\n");
|
||||
new_text.extend(indent.chars());
|
||||
if let Some(delimiter) = &comment_delimiter {
|
||||
new_text.push_str(&delimiter);
|
||||
}
|
||||
if insert_extra_newline {
|
||||
new_text = new_text.repeat(2);
|
||||
}
|
||||
|
|
|
@ -1719,6 +1719,33 @@ async fn test_newline_below(cx: &mut gpui::TestAppContext) {
|
|||
"});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_newline_comments(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx, |settings| {
|
||||
settings.defaults.tab_size = NonZeroU32::new(4)
|
||||
});
|
||||
|
||||
let language = Arc::new(Language::new(
|
||||
LanguageConfig {
|
||||
line_comment: Some("//".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! {"
|
||||
// Fooˇ
|
||||
"});
|
||||
|
||||
cx.update_editor(|e, cx| e.newline(&Newline, cx));
|
||||
cx.assert_editor_state(indoc! {"
|
||||
// Foo
|
||||
//ˇ
|
||||
"});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_insert_with_old_selections(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue