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 mod insert {
let curr = contents.get_char(pos).unwrap_or(' '); let curr = contents.get_char(pos).unwrap_or(' ');
let current_line = text.char_to_line(pos); let current_line = text.char_to_line(pos);
let line_is_only_whitespace = text let line_start = text.line_to_char(current_line);
.line(current_line)
.chars()
.all(|char| char.is_ascii_whitespace());
let mut new_text = String::new(); let mut new_text = String::new();
@ -3973,15 +3970,10 @@ pub mod insert {
.and_then(|config| config.comment_tokens.as_ref()) .and_then(|config| config.comment_tokens.as_ref())
.and_then(|tokens| comment::get_comment_token(text, tokens, current_line)); .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 let (from, to, local_offs) = if let Some(idx) =
// the current line. This makes the current line empty and the new line contain the text.slice(line_start..pos).last_non_whitespace_char()
// indentation of the old line. {
let (from, to, local_offs) = if line_is_only_whitespace { let first_trailing_whitespace_char = (line_start + idx + 1).min(pos);
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 line = text.line(current_line); let line = text.line(current_line);
let indent = match line.first_non_whitespace_char() { let indent = match line.first_non_whitespace_char() {
@ -4034,20 +4026,34 @@ pub mod insert {
new_text.chars().count() 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 { let new_range = if range.cursor(text) > range.anchor {
// when appending, extend the range by local_offs // when appending, extend the range by local_offs
Range::new( Range::new(
range.anchor + global_offs, range.anchor + global_offs,
range.head + local_offs + global_offs, (range.head as isize + local_offs) as usize + global_offs,
) )
} else { } else {
// when inserting, slide the range by local_offs // when inserting, slide the range by local_offs
Range::new( Range::new(
range.anchor + local_offs + global_offs, (range.anchor as isize + local_offs) as usize + global_offs,
range.head + local_offs + global_offs, (range.head as isize + local_offs) as usize + global_offs,
) )
}; };

View file

@ -2,6 +2,7 @@ use helix_term::application::Application;
use super::*; use super::*;
mod insert;
mod movement; mod movement;
mod write; 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>", "i<ret>",
indoc! {"\ indoc! {"\
foo: foo:
#[|b]#ar #[|b]#ar
"}, "},
), ),