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 ());
}
}