From 1194331a0221b6343c9b8848342597b301098825 Mon Sep 17 00:00:00 2001 From: rhysd Date: Sat, 18 Nov 2023 16:46:41 +0900 Subject: [PATCH] fix `TextArea::set_yank_text` doesn't support CRLF (`\r\n`) for newline --- src/textarea.rs | 16 +++++++++++----- tests/textarea.rs | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/textarea.rs b/src/textarea.rs index 0579565..d2822a6 100644 --- a/src/textarea.rs +++ b/src/textarea.rs @@ -2042,7 +2042,7 @@ impl<'a> TextArea<'a> { /// Get the yanked text. Text is automatically yanked when deleting strings by [`TextArea::delete_line_by_head`], /// [`TextArea::delete_line_by_end`], [`TextArea::delete_word`], [`TextArea::delete_next_word`], /// [`TextArea::delete_str`], [`TextArea::copy`], and [`TextArea::cut`]. When multiple lines were yanked, they are - /// joined with `\n`. + /// always joined with `\n`. /// ``` /// use tui_textarea::TextArea; /// @@ -2059,18 +2059,24 @@ impl<'a> TextArea<'a> { self.yank.to_string() } - /// Set a yanked text. The text can be inserted by [`TextArea::paste`]. + /// Set a yanked text. The text can be inserted by [`TextArea::paste`]. `\n` and `\r\n` are recognized as newline + /// but `\r` isn't. /// ``` /// use tui_textarea::TextArea; /// /// let mut textarea = TextArea::default(); /// - /// textarea.set_yank_text("hello, world"); + /// textarea.set_yank_text("hello\nworld"); /// textarea.paste(); - /// assert_eq!(textarea.lines(), ["hello, world"]); + /// assert_eq!(textarea.lines(), ["hello", "world"]); /// ``` pub fn set_yank_text(&mut self, text: impl Into) { - let lines: Vec<_> = text.into().split('\n').map(str::to_string).collect(); + // `str::lines` is not available since it strips a newline at end + let lines: Vec<_> = text + .into() + .split('\n') + .map(|s| s.strip_suffix('\r').unwrap_or(s).to_string()) + .collect(); self.yank = lines.into(); } diff --git a/tests/textarea.rs b/tests/textarea.rs index 701bbf2..868ca3f 100644 --- a/tests/textarea.rs +++ b/tests/textarea.rs @@ -1420,6 +1420,24 @@ fn test_set_yank_paste_text() { } } +#[test] +fn test_set_yank_crlf() { + let tests = [ + ("\r\n", &["", ""][..], "\n"), + ("\r\n\r\n", &["", "", ""][..], "\n\n"), + ("a\r\nb", &["a", "b"][..], "a\nb"), + ("a\r\nb\r\n", &["a", "b", ""][..], "a\nb\n"), + ]; + for test in tests { + let (pasted, lines, yanked) = test; + let mut t = TextArea::default(); + t.set_yank_text(pasted); + t.paste(); + assert_eq!(t.lines(), lines, "{test:?}"); + assert_eq!(t.yank_text(), yanked, "{test:?}"); + } +} + #[test] fn test_select_all() { let mut t = TextArea::from(["aaa", "bbb", "ccc"]);