Trim all trailing whitespace on insert_newline

This commit is contained in:
Michael Davis 2024-10-07 11:20:33 -04:00 committed by Blaž Hrastnik
parent 4c8175ca04
commit 1e6fe00001
4 changed files with 78 additions and 18 deletions

View File

@ -3961,10 +3961,7 @@ pub fn insert_newline(cx: &mut Context) {
let curr = contents.get_char(pos).unwrap_or(' ');
let current_line = text.char_to_line(pos);
let line_is_only_whitespace = text
.line(current_line)
.chars()
.all(|char| char.is_ascii_whitespace());
let line_start = text.line_to_char(current_line);
let mut new_text = String::new();
@ -3973,15 +3970,10 @@ pub fn insert_newline(cx: &mut Context) {
.and_then(|config| config.comment_tokens.as_ref())
.and_then(|tokens| comment::get_comment_token(text, tokens, current_line));
// If the current line is all whitespace, insert a line ending at the beginning of
// the current line. This makes the current line empty and the new line contain the
// indentation of the old line.
let (from, to, local_offs) = if line_is_only_whitespace {
let line_start = text.line_to_char(current_line);
new_text.push_str(doc.line_ending.as_str());
(line_start, line_start, new_text.chars().count())
} else {
let (from, to, local_offs) = if let Some(idx) =
text.slice(line_start..pos).last_non_whitespace_char()
{
let first_trailing_whitespace_char = (line_start + idx + 1).min(pos);
let line = text.line(current_line);
let indent = match line.first_non_whitespace_char() {
@ -4034,20 +4026,34 @@ pub fn insert_newline(cx: &mut Context) {
new_text.chars().count()
};
(pos, pos, local_offs)
(
first_trailing_whitespace_char,
pos,
// Note that `first_trailing_whitespace_char` is at least `pos` so the
// unsigned subtraction (`pos - first_trailing_whitespace_char`) cannot
// underflow.
local_offs as isize - (pos - first_trailing_whitespace_char) as isize,
)
} else {
// If the current line is all whitespace, insert a line ending at the beginning of
// the current line. This makes the current line empty and the new line contain the
// indentation of the old line.
new_text.push_str(doc.line_ending.as_str());
(line_start, line_start, new_text.chars().count() as isize)
};
let new_range = if range.cursor(text) > range.anchor {
// when appending, extend the range by local_offs
Range::new(
range.anchor + global_offs,
range.head + local_offs + global_offs,
(range.head as isize + local_offs) as usize + global_offs,
)
} else {
// when inserting, slide the range by local_offs
Range::new(
range.anchor + local_offs + global_offs,
range.head + local_offs + global_offs,
(range.anchor as isize + local_offs) as usize + global_offs,
(range.head as isize + local_offs) as usize + global_offs,
)
};

View File

@ -2,6 +2,7 @@
use super::*;
mod insert;
mod movement;
mod write;

View File

@ -0,0 +1,53 @@
use super::*;
#[tokio::test(flavor = "multi_thread")]
async fn insert_newline_trim_trailing_whitespace() -> anyhow::Result<()> {
// Trailing whitespace is trimmed.
test((
indoc! {"\
hello·······#[|
]#world
"}
.replace('·', " "),
"i<ret>",
indoc! {"\
hello
#[|
]#world
"}
.replace('·', " "),
))
.await?;
// Whitespace that would become trailing is trimmed too.
test((
indoc! {"\
hello········#[|w]#orld
"}
.replace('·', " "),
"i<ret>",
indoc! {"\
hello
#[|w]#orld
"}
.replace('·', " "),
))
.await?;
// Only whitespace before the cursor is trimmed.
test((
indoc! {"\
hello········#[]#····world
"}
.replace('·', " "),
"i<ret>",
indoc! {"\
hello
#[]#····world
"}
.replace('·', " "),
))
.await?;
Ok(())
}

View File

@ -795,7 +795,7 @@ async fn auto_indent() -> anyhow::Result<()> {
"##},
"i<ret>",
indoc! {"\
foo:
foo:
#[|b]#ar
"},
),