using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Terminal.Gui; /// /// Extensions to to support TUI text manipulation. /// public static class StringExtensions { /// /// Repeats the string times. /// /// /// This is a Terminal.Gui extension method to to support TUI text manipulation. /// /// The text to repeat. /// Number of times to repeat the text. /// /// The text repeated if is greater than zero, /// otherwise . /// public static string Repeat (this string str, int n) { if (n <= 0) { return null; } if (string.IsNullOrEmpty (str) || n == 1) { return str; } return new StringBuilder (str.Length * n) .Insert (0, str, n) .ToString (); } /// /// Gets the number of columns the string occupies in the terminal. /// /// /// This is a Terminal.Gui extension method to to support TUI text manipulation. /// /// The string to measure. /// public static int GetColumns (this string str) { return str == null ? 0 : str.EnumerateRunes ().Sum (r => Math.Max (r.GetColumns (), 0)); } /// /// Gets the number of runes in the string. /// /// /// This is a Terminal.Gui extension method to to support TUI text manipulation. /// /// The string to count. /// public static int GetRuneCount (this string str) => str.EnumerateRunes ().Count (); /// /// Converts the string into a array. /// /// /// This is a Terminal.Gui extension method to to support TUI text manipulation. /// /// The string to convert. /// public static Rune [] ToRunes (this string str) => str.EnumerateRunes ().ToArray (); /// /// Converts the string into a . /// /// /// This is a Terminal.Gui extension method to to support TUI text manipulation. /// /// The string to convert. /// public static List ToRuneList (this string str) => str.EnumerateRunes ().ToList (); /// /// Unpacks the first UTF-8 encoding in the string and returns the rune and its width in bytes. /// /// /// This is a Terminal.Gui extension method to to support TUI text manipulation. /// /// The string to decode. /// Starting offset. /// Number of bytes in the buffer, or -1 to make it the length of the buffer. /// public static (Rune Rune, int Size) DecodeRune (this string str, int start = 0, int count = -1) { var rune = str.EnumerateRunes ().ToArray () [start]; var bytes = Encoding.UTF8.GetBytes (rune.ToString ()); if (count == -1) { count = bytes.Length; } var operationStatus = Rune.DecodeFromUtf8 (bytes, out rune, out int bytesConsumed); if (operationStatus == System.Buffers.OperationStatus.Done && bytesConsumed >= count) { return (rune, bytesConsumed); } return (Rune.ReplacementChar, 1); } /// /// Unpacks the last UTF-8 encoding in the string. /// /// /// This is a Terminal.Gui extension method to to support TUI text manipulation. /// /// The string to decode. /// Index in string to stop at; if -1, use the buffer length. /// public static (Rune rune, int size) DecodeLastRune (this string str, int end = -1) { var rune = str.EnumerateRunes ().ToArray () [end == -1 ? ^1 : end]; var bytes = Encoding.UTF8.GetBytes (rune.ToString ()); var operationStatus = Rune.DecodeFromUtf8 (bytes, out rune, out int bytesConsumed); if (operationStatus == System.Buffers.OperationStatus.Done) { return (rune, bytesConsumed); } return (Rune.ReplacementChar, 1); } /// /// Converts a generic collection into a string. /// /// The enumerable rune to convert. /// public static string ToString (IEnumerable runes) { var str = string.Empty; foreach (var rune in runes) { str += rune.ToString (); } return str; } /// /// Converts a byte generic collection into a string in the provided encoding (default is UTF8) /// /// The enumerable byte to convert. /// The encoding to be used. /// public static string ToString (IEnumerable bytes, Encoding encoding = null) { if (encoding == null) { encoding = Encoding.UTF8; } return encoding.GetString (bytes.ToArray ()); } }