/// <summary> /// Writes a long piece of text to the console such that each new line is left-aligned /// to the same indent. /// </summary> /// <param name="text">The text to write.</param> /// <param name="indent">The indent to left align the text.</param> /// <param name="indentFirstLine"> /// Whether the first line should be indented or just written from the current cursor /// position. /// </param> public static void PrintIndented(ColorString text, int indent, bool indentFirstLine = false) { if (text is null) { throw new ArgumentNullException(nameof(text)); } var indentStr = new string(c : ' ', indent); int lineWidth = Console.WindowWidth - indent - 1; if (indentFirstLine) { Console.Write(indentStr); } // Tracks the length of the strings printed on the current line. // Once the length crosses the line width, it is reset and we move to the next line. int length = 0; foreach (ColorStringBlock block in text) { string[] parts = block.Text.Split(new[] { ' ' }, StringSplitOptions.None); for (int i = 0; i < parts.Length; i++) { // If the current length of the printed line plus the length of the next part if greater // than the line width, we need to start the next part on the next line. // Write a new line and the indent. Reset length to 0; if (length + parts[i].Length > lineWidth) { Console.WriteLine(); Console.Write(indentStr); length = 0; } // Write the part to console and increment length by its length. SetupColorsForBlockPrinting(block); Print(parts[i]); length += parts[i].Length; // Except for the last part, write the separating space character as well. // Increment length by 1. if (i < parts.Length - 1) { SetupColorsForBlockPrinting(block); Console.Write(" "); length++; } } } Console.WriteLine(); }
/// <summary> /// Creates an instance of a <see cref="ColorString" /> from the specified color string. /// </summary> /// <param name="cstr">The color string to parse.</param> /// <param name="colorStr"> /// The new <see cref="ColorString" /> instance created from the color string. /// </param> /// <returns> /// True, if the color string could be parsed and a <see cref="ColorString" /> instance /// created; otherwise false. /// </returns> public static bool TryParse(string cstr, out ColorString colorStr) { if (cstr is null) { colorStr = new ColorString(string.Empty); return(true); } // Search the string for color blocks. If none are found, just return the string. MatchCollection matches = ColorStringPattern.Matches(cstr); if (matches.Count == 0) { colorStr = new ColorString(cstr); return(true); } colorStr = new ColorString(cstr.Substring(0, matches[0].Index)); for (var i = 0; i < matches.Count; i++) { Match match = matches[i]; string[] colorParts = match.Groups[1].Value.Split('.'); CColor? foregroundColor = null; CColor? backgroundColor = null; foreach (string colorPart in colorParts) { bool isBackground = colorPart.StartsWith("Bg", StringComparison.OrdinalIgnoreCase); string actualColorStr = isBackground ? colorPart.Substring(2) : colorPart; var color = (CColor)Enum.Parse(typeof(CColor), actualColorStr, ignoreCase: true); if (isBackground) { backgroundColor = color; } else { foregroundColor = color; } } int startIndex = match.Index + match.Length; int endIndex = i < matches.Count - 1 ? matches[i + 1].Index : cstr.Length; colorStr.Text(cstr.Substring(startIndex, endIndex - startIndex), foregroundColor, backgroundColor); } return(true); }
/// <summary> /// Writes a <see cref="ColorString" /> object to the console. /// </summary> /// <param name="message">The <see cref="ColorString" /> object to write.</param> public static void Print(ColorString message) { foreach (ColorStringBlock block in message) { SetupColorsForBlockPrinting(block); Console.Write(block.Text); if (Settings.ColorReset == ColorResetOption.ResetAfterColor) { Console.ResetColor(); } } if (Settings.ColorReset == ColorResetOption.ResetAfterCommand) { Console.ResetColor(); } }
/// <summary> /// Displays a text prompt, and then reads a stream of characters from standard output, /// but obscures the entered characters with a mask character. /// </summary> /// <param name="prompt">The text prompt to display.</param> /// <param name="hideCursor">If <c>true</c>, hides the cursor while the characters are being input.</param> /// <param name="hideMask">If <c>true</c>, prevents the mask character from being shown.</param> /// <param name="needValue">If <c>true</c>, at least one character must be entered.</param> /// <returns>The entered stream of characters as a <see cref="SecureString"/>.</returns> public static SecureString ReadSecretSecure(ColorString prompt, bool hideCursor = false, bool hideMask = false, bool needValue = false) { Print(prompt); return(ReadSecretSecure(hideCursor, hideMask, needValue)); }
public static string Prompt(ColorString message, Func <string, bool> validator) { Print(message); return(Prompt(validator)); }
/// <summary> /// Displays a message and waits for user input. /// </summary> /// <param name="message">A string or color string representing the message to be displayed.</param> /// <returns>The input entered by the user.</returns> public static string Prompt(ColorString message) { Print(message); return(Console.ReadLine()); }