From ef6f355f5078a25531ba655cbbec09c190a1805f Mon Sep 17 00:00:00 2001 From: BDisp Date: Mon, 22 May 2023 05:18:18 +0100 Subject: [PATCH] Fixes #2653. TextField is using the UTF8 encoding to handle substring not compatible with string. (#2654) --- Terminal.Gui/Views/TextField.cs | 24 ++++++++++++------------ UnitTests/Views/TextFieldTests.cs | 14 +++++++++++++- UnitTests/Views/TextViewTests.cs | 17 ++++++++++++++--- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 680e572f6..37354b37e 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -1129,8 +1129,8 @@ namespace Terminal.Gui { length = Math.Abs (x + direction <= text.Count ? x + direction - selectedStart : text.Count - selectedStart); SetSelectedStartSelectedLength (); if (start > -1 && length > 0) { - selectedText = length > 0 ? StringExtensions.ToString (text).Substring ( - start < 0 ? 0 : start, length > text.Count ? text.Count : length) : ""; + selectedText = length > 0 ? StringExtensions.ToString (text.GetRange ( + start < 0 ? 0 : start, length > text.Count ? text.Count : length)) : ""; if (first > start) { first = start; } @@ -1198,11 +1198,11 @@ namespace Terminal.Gui { string actualText = Text; SetSelectedStartSelectedLength (); int selStart = SelectedStart > -1 ? start : point; - (var _, var len) = TextModel.DisplaySize (text, 0, selStart, false); - (var _, var len2) = TextModel.DisplaySize (text, selStart, selStart + length, false); - (var _, var len3) = TextModel.DisplaySize (text, selStart + length, actualText.GetRuneCount (), false); - var newText = actualText [..len] + - actualText.Substring (len + len2, len3); + (var size, var _) = TextModel.DisplaySize (text, 0, selStart, false); + (var size2, var _) = TextModel.DisplaySize (text, selStart, selStart + length, false); + (var size3, var _) = TextModel.DisplaySize (text, selStart + length, actualText.GetRuneCount (), false); + var newText = actualText [..size] + + actualText.Substring (size + size2, size3); ClearAllSelection (); point = selStart >= newText.GetRuneCount () ? newText.GetRuneCount () : selStart; return newText.ToRuneList (); @@ -1220,13 +1220,13 @@ namespace Terminal.Gui { SetSelectedStartSelectedLength (); int selStart = start == -1 ? CursorPosition : start; string actualText = Text; - (int _, int len) = TextModel.DisplaySize (text, 0, selStart, false); - (var _, var len2) = TextModel.DisplaySize (text, selStart, selStart + length, false); - (var _, var len3) = TextModel.DisplaySize (text, selStart + length, actualText.GetRuneCount (), false); + (int size, int _) = TextModel.DisplaySize (text, 0, selStart, false); + (var size2, var _) = TextModel.DisplaySize (text, selStart, selStart + length, false); + (var size3, var _) = TextModel.DisplaySize (text, selStart + length, actualText.GetRuneCount (), false); string cbTxt = Clipboard.Contents.Split ("\n") [0] ?? ""; - Text = actualText [..len] + + Text = actualText [..size] + cbTxt + - actualText.Substring (len + len2, len3); + actualText.Substring (size + size2, size3); point = selStart + cbTxt.GetRuneCount (); ClearAllSelection (); SetNeedsDisplay (); diff --git a/UnitTests/Views/TextFieldTests.cs b/UnitTests/Views/TextFieldTests.cs index b6d91b6a3..2dba68658 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/UnitTests/Views/TextFieldTests.cs @@ -914,7 +914,7 @@ namespace Terminal.Gui.ViewsTests { } [Fact] - [AutoInitShutdown(useFakeClipboard:true)] + [AutoInitShutdown (useFakeClipboard: true)] public void KeyBindings_Command () { var tf = new TextField ("This is a test.") { Width = 20 }; @@ -1598,5 +1598,17 @@ Les Miล›erables", output); Assert.Null (_textField.SelectedText); Assert.Equal ("TAB to jump between text fields.", _textField.Text); } + + [Fact, TextFieldTestsAutoInitShutdown] + public void Copy_Paste_Surrogate_Pairs () + { + _textField.Text = "TextField with some more test text. Unicode shouldn't ๐”นAโ„๐”ฝ!"; + _textField.SelectAll (); + _textField.Cut (); + Assert.Equal ("TextField with some more test text. Unicode shouldn't ๐”นAโ„๐”ฝ!", Application.Driver.Clipboard.GetClipboardData ()); + Assert.Equal (string.Empty, _textField.Text); + _textField.Paste (); + Assert.Equal ("TextField with some more test text. Unicode shouldn't ๐”นAโ„๐”ฝ!", _textField.Text); + } } } \ No newline at end of file diff --git a/UnitTests/Views/TextViewTests.cs b/UnitTests/Views/TextViewTests.cs index 6214b2d6b..08f319c44 100644 --- a/UnitTests/Views/TextViewTests.cs +++ b/UnitTests/Views/TextViewTests.cs @@ -33,7 +33,7 @@ namespace Terminal.Gui.ViewsTests { // 1 2 3 // 01234567890123456789012345678901=32 (Length) - var buff = Encoding.Unicode.GetBytes(txt); + var buff = Encoding.Unicode.GetBytes (txt); var ms = new System.IO.MemoryStream (buff).ToArray (); _textView = new TextView () { Width = 30, Height = 10 }; _textView.Text = Encoding.Unicode.GetString (ms); @@ -2527,7 +2527,7 @@ line. } [Fact] - [AutoInitShutdown (useFakeClipboard:true)] + [AutoInitShutdown (useFakeClipboard: true)] public void KeyBindings_Command () { var text = "This is the first line.\nThis is the second line.\nThis is the third line."; @@ -4657,7 +4657,7 @@ line. } [Fact] - [AutoInitShutdown (useFakeClipboard:true)] + [AutoInitShutdown (useFakeClipboard: true)] public void HistoryText_Undo_Redo_Copy_Without_Selection_Multi_Line_Paste () { var text = "This is the first line.\nThis is the second line.\nThis is the third line."; @@ -6947,5 +6947,16 @@ This is the second line. Assert.Equal ("TAB to jump between text fields.", _textView.Text); } + [Fact, TextViewTestsAutoInitShutdown] + public void Copy_Paste_Surrogate_Pairs () + { + _textView.Text = "TextView with some more test text. Unicode shouldn't ๐”นAโ„๐”ฝ!"; + _textView.SelectAll (); + _textView.Cut (); + Assert.Equal ("TextView with some more test text. Unicode shouldn't ๐”นAโ„๐”ฝ!", Application.Driver.Clipboard.GetClipboardData ()); + Assert.Equal (string.Empty, _textView.Text); + _textView.Paste (); + Assert.Equal ("TextView with some more test text. Unicode shouldn't ๐”นAโ„๐”ฝ!", _textView.Text); + } } } \ No newline at end of file