Unnamed repository; edit this file 'description' to name the repository.
Fix `try_restore_indent` on non-LF documents
On Windows for example the behavior of this function typically diverges from the usual behavior on Unix. Instead of checking that the inserted string starts with `'\n'` (untrue for for CRLF line endings) we need to check that the first grapheme cluster in the string is a line ending. (All line endings are single grapheme clusters.)
Michael Davis 9 months ago
parent 1023e8f · commit 702a961
-rw-r--r--helix-term/tests/test/commands/insert.rs22
-rw-r--r--helix-view/src/editor.rs10
2 files changed, 29 insertions, 3 deletions
diff --git a/helix-term/tests/test/commands/insert.rs b/helix-term/tests/test/commands/insert.rs
index a3da5fb2..d83dda84 100644
--- a/helix-term/tests/test/commands/insert.rs
+++ b/helix-term/tests/test/commands/insert.rs
@@ -512,3 +512,25 @@ async fn test_open_above_with_comments() -> anyhow::Result<()> {
Ok(())
}
+
+#[tokio::test(flavor = "multi_thread")]
+async fn try_restore_indent() -> anyhow::Result<()> {
+ // Assert that `helix_view::editor::try_restore_indent` handles line endings correctly
+ // endings.
+ test((
+ indoc! {"\
+ if true #[|{]#
+ }
+ "},
+ // `try_restore_indent` should remove the indentation when adding a blank line.
+ ":lang rust<ret>o<esc>",
+ indoc! {"\
+ if true {
+ #[
+ |]#}
+ "},
+ ))
+ .await?;
+
+ Ok(())
+}
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 9aa073fc..0ecddd87 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -2262,16 +2262,20 @@ impl Editor {
fn try_restore_indent(doc: &mut Document, view: &mut View) {
use helix_core::{
- chars::char_is_whitespace, line_ending::line_end_char_index, Operation, Transaction,
+ chars::char_is_whitespace,
+ line_ending::{line_end_char_index, str_is_line_ending},
+ unicode::segmentation::UnicodeSegmentation,
+ Operation, Transaction,
};
fn inserted_a_new_blank_line(changes: &[Operation], pos: usize, line_end_pos: usize) -> bool {
if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] =
changes
{
+ let mut graphemes = inserted_str.graphemes(true);
move_pos + inserted_str.len() == pos
- && inserted_str.starts_with('\n')
- && inserted_str.chars().skip(1).all(char_is_whitespace)
+ && graphemes.next().is_some_and(str_is_line_ending)
+ && graphemes.all(|g| g.chars().all(char_is_whitespace))
&& pos == line_end_pos // ensure no characters exists after current position
} else {
false