add anchor to selection fixup info in newline

This commit is contained in:
Keith Simmons 2022-04-28 13:10:31 -07:00
parent 4c860dc82f
commit 42b900774e

View file

@ -1861,69 +1861,63 @@ impl Editor {
pub fn newline(&mut self, _: &Newline, cx: &mut ViewContext<Self>) { pub fn newline(&mut self, _: &Newline, cx: &mut ViewContext<Self>) {
self.transact(cx, |this, cx| { self.transact(cx, |this, cx| {
let mut old_selections = SmallVec::<[_; 32]>::new(); let (edits, selection_fixup_info): (Vec<_>, Vec<_>) = {
{
let selections = this.local_selections::<usize>(cx); let selections = this.local_selections::<usize>(cx);
let buffer = this.buffer.read(cx).snapshot(cx); let buffer = this.buffer.read(cx).snapshot(cx);
for selection in selections.iter() { selections
let start_point = selection.start.to_point(&buffer); .iter()
let indent = buffer .map(|selection| {
.indent_column_for_line(start_point.row) let start_point = selection.start.to_point(&buffer);
.min(start_point.column); let indent = buffer
let start = selection.start; .indent_column_for_line(start_point.row)
let end = selection.end; .min(start_point.column);
let start = selection.start;
let end = selection.end;
let mut insert_extra_newline = false; let mut insert_extra_newline = false;
if let Some(language) = buffer.language() { if let Some(language) = buffer.language() {
let leading_whitespace_len = buffer let leading_whitespace_len = buffer
.reversed_chars_at(start) .reversed_chars_at(start)
.take_while(|c| c.is_whitespace() && *c != '\n') .take_while(|c| c.is_whitespace() && *c != '\n')
.map(|c| c.len_utf8()) .map(|c| c.len_utf8())
.sum::<usize>(); .sum::<usize>();
let trailing_whitespace_len = buffer let trailing_whitespace_len = buffer
.chars_at(end) .chars_at(end)
.take_while(|c| c.is_whitespace() && *c != '\n') .take_while(|c| c.is_whitespace() && *c != '\n')
.map(|c| c.len_utf8()) .map(|c| c.len_utf8())
.sum::<usize>(); .sum::<usize>();
insert_extra_newline = language.brackets().iter().any(|pair| { insert_extra_newline = language.brackets().iter().any(|pair| {
let pair_start = pair.start.trim_end(); let pair_start = pair.start.trim_end();
let pair_end = pair.end.trim_start(); let pair_end = pair.end.trim_start();
pair.newline pair.newline
&& buffer.contains_str_at(end + trailing_whitespace_len, pair_end) && buffer
&& buffer.contains_str_at( .contains_str_at(end + trailing_whitespace_len, pair_end)
(start - leading_whitespace_len) && buffer.contains_str_at(
.saturating_sub(pair_start.len()), (start - leading_whitespace_len)
pair_start, .saturating_sub(pair_start.len()),
) pair_start,
}); )
} });
}
old_selections.push(( let mut new_text = String::with_capacity(1 + indent as usize);
selection.id, new_text.push('\n');
buffer.anchor_after(end), new_text.extend(iter::repeat(' ').take(indent as usize));
start..end, if insert_extra_newline {
indent, new_text = new_text.repeat(2);
insert_extra_newline, }
)); (
} (start..end, new_text),
} (insert_extra_newline, buffer.anchor_after(end)),
)
})
.unzip()
};
this.buffer.update(cx, |buffer, cx| { this.buffer.update(cx, |buffer, cx| {
let edits =
old_selections
.iter()
.map(|(_, _, range, indent, insert_extra_newline)| {
let mut new_text = String::with_capacity(1 + *indent as usize);
new_text.push('\n');
new_text.extend(iter::repeat(' ').take(*indent as usize));
if *insert_extra_newline {
new_text = new_text.repeat(2);
}
(range.clone(), new_text)
});
buffer.edit_with_autoindent_batched(edits, cx); buffer.edit_with_autoindent_batched(edits, cx);
let buffer = buffer.read(cx); let buffer = buffer.read(cx);
@ -1931,20 +1925,18 @@ impl Editor {
.selections .selections
.iter() .iter()
.cloned() .cloned()
.zip(old_selections) .zip(selection_fixup_info)
.map( .map(|(mut new_selection, (extra_newline_inserted, end))| {
|(mut new_selection, (_, end_anchor, _, _, insert_extra_newline))| { let mut cursor = end.to_point(&buffer);
let mut cursor = end_anchor.to_point(&buffer); if extra_newline_inserted {
if insert_extra_newline { cursor.row -= 1;
cursor.row -= 1; cursor.column = buffer.line_len(cursor.row);
cursor.column = buffer.line_len(cursor.row); }
} let anchor = buffer.anchor_after(cursor);
let anchor = buffer.anchor_after(cursor); new_selection.start = anchor.clone();
new_selection.start = anchor.clone(); new_selection.end = anchor;
new_selection.end = anchor; new_selection
new_selection })
},
)
.collect(); .collect();
}); });