MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections;5using System.Collections.Generic;6using System.Management.Automation.Internal;7 8namespace System.Management.Automation9{10 #region OutputRendering11 /// <summary>12 /// Defines the options for output rendering.13 /// </summary>14 public enum OutputRendering15 {16 /// <summary>Render ANSI only to host.</summary>17 Host = 0,18 19 /// <summary>Render as plaintext.</summary>20 PlainText = 1,21 22 /// <summary>Render as ANSI.</summary>23 Ansi = 2,24 }25 #endregion OutputRendering26 27 /// <summary>28 /// Defines the options for views of progress rendering.29 /// </summary>30 public enum ProgressView31 {32 /// <summary>Render progress using minimal space.</summary>33 Minimal = 0,34 35 /// <summary>Classic rendering of progress.</summary>36 Classic = 1,37 }38 39 #region PSStyle40 /// <summary>41 /// Contains configuration for how PowerShell renders text.42 /// </summary>43 public sealed class PSStyle44 {45 /// <summary>46 /// Contains foreground colors.47 /// </summary>48 public sealed class ForegroundColor49 {50 /// <summary>51 /// Gets the color black.52 /// </summary>53 public string Black { get; } = "\x1b[30m";54 55 /// <summary>56 /// Gets the color red.57 /// </summary>58 public string Red { get; } = "\x1b[31m";59 60 /// <summary>61 /// Gets the color green.62 /// </summary>63 public string Green { get; } = "\x1b[32m";64 65 /// <summary>66 /// Gets the color yellow.67 /// </summary>68 public string Yellow { get; } = "\x1b[33m";69 70 /// <summary>71 /// Gets the color blue.72 /// </summary>73 public string Blue { get; } = "\x1b[34m";74 75 /// <summary>76 /// Gets the color magenta.77 /// </summary>78 public string Magenta { get; } = "\x1b[35m";79 80 /// <summary>81 /// Gets the color cyan.82 /// </summary>83 public string Cyan { get; } = "\x1b[36m";84 85 /// <summary>86 /// Gets the color white.87 /// </summary>88 public string White { get; } = "\x1b[37m";89 90 /// <summary>91 /// Gets the color bright black.92 /// </summary>93 public string BrightBlack { get; } = "\x1b[90m";94 95 /// <summary>96 /// Gets the color bright red.97 /// </summary>98 public string BrightRed { get; } = "\x1b[91m";99 100 /// <summary>101 /// Gets the color bright green.102 /// </summary>103 public string BrightGreen { get; } = "\x1b[92m";104 105 /// <summary>106 /// Gets the color bright yellow.107 /// </summary>108 public string BrightYellow { get; } = "\x1b[93m";109 110 /// <summary>111 /// Gets the color bright blue.112 /// </summary>113 public string BrightBlue { get; } = "\x1b[94m";114 115 /// <summary>116 /// Gets the color bright magenta.117 /// </summary>118 public string BrightMagenta { get; } = "\x1b[95m";119 120 /// <summary>121 /// Gets the color bright cyan.122 /// </summary>123 public string BrightCyan { get; } = "\x1b[96m";124 125 /// <summary>126 /// Gets the color bright white.127 /// </summary>128 public string BrightWhite { get; } = "\x1b[97m";129 130 /// <summary>131 /// Set as RGB (Red, Green, Blue).132 /// </summary>133 /// <param name="red">Byte value representing red.</param>134 /// <param name="green">Byte value representing green.</param>135 /// <param name="blue">Byte value representing blue.</param>136 /// <returns>String representing ANSI code for RGB value.</returns>137 public string FromRgb(byte red, byte green, byte blue)138 {139 return $"\x1b[38;2;{red};{green};{blue}m";140 }141 142 /// <summary>143 /// The color set as RGB as a single number.144 /// </summary>145 /// <param name="rgb">RGB value specified as an integer.</param>146 /// <returns>String representing ANSI code for RGB value.</returns>147 public string FromRgb(int rgb)148 {149 byte red, green, blue;150 blue = (byte)(rgb & 0xFF);151 rgb >>= 8;152 green = (byte)(rgb & 0xFF);153 rgb >>= 8;154 red = (byte)(rgb & 0xFF);155 156 return FromRgb(red, green, blue);157 }158 159 /// <summary>160 /// Return the VT escape sequence for a foreground color.161 /// </summary>162 /// <param name="color">The foreground color to be mapped from.</param>163 /// <returns>The VT escape sequence representing the foreground color.</returns>164 public string FromConsoleColor(ConsoleColor color)165 {166 return MapForegroundColorToEscapeSequence(color);167 }168 }169 170 /// <summary>171 /// Contains background colors.172 /// </summary>173 public sealed class BackgroundColor174 {175 /// <summary>176 /// Gets the color black.177 /// </summary>178 public string Black { get; } = "\x1b[40m";179 180 /// <summary>181 /// Gets the color red.182 /// </summary>183 public string Red { get; } = "\x1b[41m";184 185 /// <summary>186 /// Gets the color green.187 /// </summary>188 public string Green { get; } = "\x1b[42m";189 190 /// <summary>191 /// Gets the color yellow.192 /// </summary>193 public string Yellow { get; } = "\x1b[43m";194 195 /// <summary>196 /// Gets the color blue.197 /// </summary>198 public string Blue { get; } = "\x1b[44m";199 200 /// <summary>201 /// Gets the color magenta.202 /// </summary>203 public string Magenta { get; } = "\x1b[45m";204 205 /// <summary>206 /// Gets the color cyan.207 /// </summary>208 public string Cyan { get; } = "\x1b[46m";209 210 /// <summary>211 /// Gets the color white.212 /// </summary>213 public string White { get; } = "\x1b[47m";214 215 /// <summary>216 /// Gets the color bright black.217 /// </summary>218 public string BrightBlack { get; } = "\x1b[100m";219 220 /// <summary>221 /// Gets the color bright red.222 /// </summary>223 public string BrightRed { get; } = "\x1b[101m";224 225 /// <summary>226 /// Gets the color bright green.227 /// </summary>228 public string BrightGreen { get; } = "\x1b[102m";229 230 /// <summary>231 /// Gets the color bright yellow.232 /// </summary>233 public string BrightYellow { get; } = "\x1b[103m";234 235 /// <summary>236 /// Gets the color bright blue.237 /// </summary>238 public string BrightBlue { get; } = "\x1b[104m";239 240 /// <summary>241 /// Gets the color bright magenta.242 /// </summary>243 public string BrightMagenta { get; } = "\x1b[105m";244 245 /// <summary>246 /// Gets the color bright cyan.247 /// </summary>248 public string BrightCyan { get; } = "\x1b[106m";249 250 /// <summary>251 /// Gets the color bright white.252 /// </summary>253 public string BrightWhite { get; } = "\x1b[107m";254 255 /// <summary>256 /// The color set as RGB (Red, Green, Blue).257 /// </summary>258 /// <param name="red">Byte value representing red.</param>259 /// <param name="green">Byte value representing green.</param>260 /// <param name="blue">Byte value representing blue.</param>261 /// <returns>String representing ANSI code for RGB value.</returns>262 public string FromRgb(byte red, byte green, byte blue)263 {264 return $"\x1b[48;2;{red};{green};{blue}m";265 }266 267 /// <summary>268 /// The color set as RGB as a single number.269 /// </summary>270 /// <param name="rgb">RGB value specified as an integer.</param>271 /// <returns>String representing ANSI code for RGB value.</returns>272 public string FromRgb(int rgb)273 {274 byte red, green, blue;275 blue = (byte)(rgb & 0xFF);276 rgb >>= 8;277 green = (byte)(rgb & 0xFF);278 rgb >>= 8;279 red = (byte)(rgb & 0xFF);280 281 return FromRgb(red, green, blue);282 }283 284 /// <summary>285 /// Return the VT escape sequence for a background color.286 /// </summary>287 /// <param name="color">The background color to be mapped from.</param>288 /// <returns>The VT escape sequence representing the background color.</returns>289 public string FromConsoleColor(ConsoleColor color)290 {291 return MapBackgroundColorToEscapeSequence(color);292 }293 }294 295 /// <summary>296 /// Contains configuration for the progress bar visualization.297 /// </summary>298 public sealed class ProgressConfiguration299 {300 /// <summary>301 /// Gets or sets the style for progress bar.302 /// </summary>303 public string Style304 {305 get => _style;306 set => _style = ValidateNoContent(value);307 }308 309 private string _style = "\x1b[33;1m";310 311 /// <summary>312 /// Gets or sets the max width of the progress bar.313 /// </summary>314 public int MaxWidth315 {316 get => _maxWidth;317 set318 {319 // Width less than 18 does not render correctly due to the different parts of the progress bar.320 if (value < 18)321 {322 throw new ArgumentOutOfRangeException(nameof(MaxWidth), PSStyleStrings.ProgressWidthTooSmall);323 }324 325 _maxWidth = value;326 }327 }328 329 private int _maxWidth = 120;330 331 /// <summary>332 /// Gets or sets the view for progress bar.333 /// </summary>334 public ProgressView View { get; set; } = ProgressView.Minimal;335 336 /// <summary>337 /// Gets or sets a value indicating whether to use Operating System Command (OSC) control sequences 'ESC ]9;4;' to show indicator in terminal.338 /// </summary>339 public bool UseOSCIndicator { get; set; } = false;340 }341 342 /// <summary>343 /// Contains formatting styles for steams and objects.344 /// </summary>345 public sealed class FormattingData346 {347 /// <summary>348 /// Gets or sets the accent style for formatting.349 /// </summary>350 public string FormatAccent351 {352 get => _formatAccent;353 set => _formatAccent = ValidateNoContent(value);354 }355 356 private string _formatAccent = "\x1b[32;1m";357 358 /// <summary>359 /// Gets or sets the style for table headers.360 /// </summary>361 public string TableHeader362 {363 get => _tableHeader;364 set => _tableHeader = ValidateNoContent(value);365 }366 367 private string _tableHeader = "\x1b[32;1m";368 369 /// <summary>370 /// Gets or sets the style for custom table headers.371 /// </summary>372 public string CustomTableHeaderLabel373 {374 get => _customTableHeaderLabel;375 set => _customTableHeaderLabel = ValidateNoContent(value);376 }377 378 private string _customTableHeaderLabel = "\x1b[32;1;3m";379 380 /// <summary>381 /// Gets or sets the accent style for errors.382 /// </summary>383 public string ErrorAccent384 {385 get => _errorAccent;386 set => _errorAccent = ValidateNoContent(value);387 }388 389 private string _errorAccent = "\x1b[36;1m";390 391 /// <summary>392 /// Gets or sets the style for error messages.393 /// </summary>394 public string Error395 {396 get => _error;397 set => _error = ValidateNoContent(value);398 }399 400 private string _error = "\x1b[31;1m";401 402 /// <summary>403 /// Gets or sets the style for warning messages.404 /// </summary>405 public string Warning406 {407 get => _warning;408 set => _warning = ValidateNoContent(value);409 }410 411 private string _warning = "\x1b[33;1m";412 413 /// <summary>414 /// Gets or sets the style for verbose messages.415 /// </summary>416 public string Verbose417 {418 get => _verbose;419 set => _verbose = ValidateNoContent(value);420 }421 422 private string _verbose = "\x1b[33;1m";423 424 /// <summary>425 /// Gets or sets the style for debug messages.426 /// </summary>427 public string Debug428 {429 get => _debug;430 set => _debug = ValidateNoContent(value);431 }432 433 private string _debug = "\x1b[33;1m";434 435 /// <summary>436 /// Gets or sets the style for rendering feedback provider names.437 /// </summary>438 public string FeedbackName439 {440 get => _feedbackName;441 set => _feedbackName = ValidateNoContent(value);442 }443 444 // Yellow by default.445 private string _feedbackName = "\x1b[33m";446 447 /// <summary>448 /// Gets or sets the style for rendering feedback message.449 /// </summary>450 public string FeedbackText451 {452 get => _feedbackText;453 set => _feedbackText = ValidateNoContent(value);454 }455 456 // BrightCyan by default.457 private string _feedbackText = "\x1b[96m";458 459 /// <summary>460 /// Gets or sets the style for rendering feedback actions.461 /// </summary>462 public string FeedbackAction463 {464 get => _feedbackAction;465 set => _feedbackAction = ValidateNoContent(value);466 }467 468 // BrightWhite by default.469 private string _feedbackAction = "\x1b[97m";470 }471 472 /// <summary>473 /// Contains formatting styles for FileInfo objects.474 /// </summary>475 public sealed class FileInfoFormatting476 {477 /// <summary>478 /// Gets or sets the style for directories.479 /// </summary>480 public string Directory481 {482 get => _directory;483 set => _directory = ValidateNoContent(value);484 }485 486 private string _directory = "\x1b[44;1m";487 488 /// <summary>489 /// Gets or sets the style for symbolic links.490 /// </summary>491 public string SymbolicLink492 {493 get => _symbolicLink;494 set => _symbolicLink = ValidateNoContent(value);495 }496 497 private string _symbolicLink = "\x1b[36;1m";498 499 /// <summary>500 /// Gets or sets the style for executables.501 /// </summary>502 public string Executable503 {504 get => _executable;505 set => _executable = ValidateNoContent(value);506 }507 508 private string _executable = "\x1b[32;1m";509 510 /// <summary>511 /// Custom dictionary handling validation of extension and content.512 /// </summary>513 public sealed class FileExtensionDictionary514 {515 private static string ValidateExtension(string extension)516 {517 if (!extension.StartsWith('.'))518 {519 throw new ArgumentException(PSStyleStrings.ExtensionNotStartingWithPeriod);520 }521 522 return extension;523 }524 525 private readonly Dictionary<string, string> _extensionDictionary = new(StringComparer.OrdinalIgnoreCase);526 527 /// <summary>528 /// Add new extension and decoration to dictionary.529 /// </summary>530 /// <param name="extension">Extension to add.</param>531 /// <param name="decoration">ANSI string value to add.</param>532 public void Add(string extension, string decoration)533 {534 _extensionDictionary.Add(ValidateExtension(extension), ValidateNoContent(decoration));535 }536 537 /// <summary>538 /// Add new extension and decoration to dictionary without validation.539 /// </summary>540 /// <param name="extension">Extension to add.</param>541 /// <param name="decoration">ANSI string value to add.</param>542 internal void AddWithoutValidation(string extension, string decoration)543 {544 _extensionDictionary.Add(extension, decoration);545 }546 547 /// <summary>548 /// Remove an extension from dictionary.549 /// </summary>550 /// <param name="extension">Extension to remove.</param>551 public void Remove(string extension)552 {553 _extensionDictionary.Remove(ValidateExtension(extension));554 }555 556 /// <summary>557 /// Clear the dictionary.558 /// </summary>559 public void Clear()560 {561 _extensionDictionary.Clear();562 }563 564 /// <summary>565 /// Gets or sets the decoration by specified extension.566 /// </summary>567 /// <param name="extension">Extension to get decoration for.</param>568 /// <returns>The decoration for specified extension.</returns>569 public string this[string extension]570 {571 get572 {573 return _extensionDictionary[ValidateExtension(extension)];574 }575 576 set577 {578 _extensionDictionary[ValidateExtension(extension)] = ValidateNoContent(value);579 }580 }581 582 /// <summary>583 /// Gets whether the dictionary contains the specified extension.584 /// </summary>585 /// <param name="extension">Extension to check for.</param>586 /// <returns>True if the dictionary contains the specified extension, otherwise false.</returns>587 public bool ContainsKey(string extension)588 {589 if (string.IsNullOrEmpty(extension))590 {591 return false;592 }593 594 return _extensionDictionary.ContainsKey(ValidateExtension(extension));595 }596 597 /// <summary>598 /// Gets the extensions for the dictionary.599 /// </summary>600 /// <returns>The extensions for the dictionary.</returns>601 public IEnumerable<string> Keys602 {603 get604 {605 return _extensionDictionary.Keys;606 }607 }608 }609 610 /// <summary>611 /// Gets the style for archive.612 /// </summary>613 public FileExtensionDictionary Extension { get; }614 615 /// <summary>616 /// Initializes a new instance of the <see cref="FileInfoFormatting"/> class.617 /// </summary>618 public FileInfoFormatting()619 {620 Extension = new FileExtensionDictionary();621 622 // archives623 Extension.AddWithoutValidation(".zip", "\x1b[31;1m");624 Extension.AddWithoutValidation(".tgz", "\x1b[31;1m");625 Extension.AddWithoutValidation(".gz", "\x1b[31;1m");626 Extension.AddWithoutValidation(".tar", "\x1b[31;1m");627 Extension.AddWithoutValidation(".nupkg", "\x1b[31;1m");628 Extension.AddWithoutValidation(".cab", "\x1b[31;1m");629 Extension.AddWithoutValidation(".7z", "\x1b[31;1m");630 631 // powershell632 Extension.AddWithoutValidation(".ps1", "\x1b[33;1m");633 Extension.AddWithoutValidation(".psd1", "\x1b[33;1m");634 Extension.AddWithoutValidation(".psm1", "\x1b[33;1m");635 Extension.AddWithoutValidation(".ps1xml", "\x1b[33;1m");636 }637 }638 639 /// <summary>640 /// Gets or sets the rendering mode for output.641 /// </summary>642 public OutputRendering OutputRendering { get; set; } = OutputRendering.Host;643 644 /// <summary>645 /// Gets value to turn off all attributes.646 /// </summary>647 public string Reset { get; } = "\x1b[0m";648 649 /// <summary>650 /// Gets value to turn off blink.651 /// </summary>652 public string BlinkOff { get; } = "\x1b[25m";653 654 /// <summary>655 /// Gets value to turn on blink.656 /// </summary>657 public string Blink { get; } = "\x1b[5m";658 659 /// <summary>660 /// Gets value to turn off bold.661 /// </summary>662 public string BoldOff { get; } = "\x1b[22m";663 664 /// <summary>665 /// Gets value to turn on blink.666 /// </summary>667 public string Bold { get; } = "\x1b[1m";668 669 /// <summary>670 /// Gets value to turn off dim.671 /// </summary>672 public string DimOff { get; } = "\x1b[22m";673 674 /// <summary>675 /// Gets value to turn on dim.676 /// </summary>677 public string Dim { get; } = "\x1b[2m";678 679 /// <summary>680 /// Gets value to turn on hidden.681 /// </summary>682 public string Hidden { get; } = "\x1b[8m";683 684 /// <summary>685 /// Gets value to turn off hidden.686 /// </summary>687 public string HiddenOff { get; } = "\x1b[28m";688 689 /// <summary>690 /// Gets value to turn on reverse.691 /// </summary>692 public string Reverse { get; } = "\x1b[7m";693 694 /// <summary>695 /// Gets value to turn off reverse.696 /// </summary>697 public string ReverseOff { get; } = "\x1b[27m";698 699 /// <summary>700 /// Gets value to turn off standout.701 /// </summary>702 public string ItalicOff { get; } = "\x1b[23m";703 704 /// <summary>705 /// Gets value to turn on standout.706 /// </summary>707 public string Italic { get; } = "\x1b[3m";708 709 /// <summary>710 /// Gets value to turn off underlined.711 /// </summary>712 public string UnderlineOff { get; } = "\x1b[24m";713 714 /// <summary>715 /// Gets value to turn on underlined.716 /// </summary>717 public string Underline { get; } = "\x1b[4m";718 719 /// <summary>720 /// Gets value to turn off strikethrough.721 /// </summary>722 public string StrikethroughOff { get; } = "\x1b[29m";723 724 /// <summary>725 /// Gets value to turn on strikethrough.726 /// </summary>727 public string Strikethrough { get; } = "\x1b[9m";728 729 /// <summary>730 /// Gets ANSI representation of a hyperlink.731 /// </summary>732 /// <param name="text">Text describing the link.</param>733 /// <param name="link">A valid hyperlink.</param>734 /// <returns>String representing ANSI code for the hyperlink.</returns>735 public string FormatHyperlink(string text, Uri link)736 {737 return $"\x1b]8;;{link}\x1b\\{text}\x1b]8;;\x1b\\";738 }739 740 /// <summary>741 /// Gets the formatting rendering settings.742 /// </summary>743 public FormattingData Formatting { get; }744 745 /// <summary>746 /// Gets the configuration for progress rendering.747 /// </summary>748 public ProgressConfiguration Progress { get; }749 750 /// <summary>751 /// Gets foreground colors.752 /// </summary>753 public ForegroundColor Foreground { get; }754 755 /// <summary>756 /// Gets background colors.757 /// </summary>758 public BackgroundColor Background { get; }759 760 /// <summary>761 /// Gets FileInfo colors.762 /// </summary>763 public FileInfoFormatting FileInfo { get; }764 765 private static readonly PSStyle s_psstyle = new PSStyle();766 767 private PSStyle()768 {769 Formatting = new FormattingData();770 Progress = new ProgressConfiguration();771 Foreground = new ForegroundColor();772 Background = new BackgroundColor();773 FileInfo = new FileInfoFormatting();774 }775 776 private static string ValidateNoContent(string text)777 {778 ArgumentNullException.ThrowIfNull(text);779 780 var decorartedString = new ValueStringDecorated(text);781 if (decorartedString.ContentLength > 0)782 {783 throw new ArgumentException(string.Format(PSStyleStrings.TextContainsContent, decorartedString.ToString(OutputRendering.PlainText)));784 }785 786 return text;787 }788 789 /// <summary>790 /// Gets singleton instance.791 /// </summary>792 public static PSStyle Instance793 {794 get795 {796 return s_psstyle;797 }798 }799 800 /// <summary>801 /// The map of background console colors to escape sequences.802 /// </summary>803 private static readonly string[] BackgroundColorMap =804 {805 "\x1b[40m", // Black806 "\x1b[44m", // DarkBlue807 "\x1b[42m", // DarkGreen808 "\x1b[46m", // DarkCyan809 "\x1b[41m", // DarkRed810 "\x1b[45m", // DarkMagenta811 "\x1b[43m", // DarkYellow812 "\x1b[47m", // Gray813 "\x1b[100m", // DarkGray814 "\x1b[104m", // Blue815 "\x1b[102m", // Green816 "\x1b[106m", // Cyan817 "\x1b[101m", // Red818 "\x1b[105m", // Magenta819 "\x1b[103m", // Yellow820 "\x1b[107m", // White821 };822 823 /// <summary>824 /// The map of foreground console colors to escape sequences.825 /// </summary>826 private static readonly string[] ForegroundColorMap =827 {828 "\x1b[30m", // Black829 "\x1b[34m", // DarkBlue830 "\x1b[32m", // DarkGreen831 "\x1b[36m", // DarkCyan832 "\x1b[31m", // DarkRed833 "\x1b[35m", // DarkMagenta834 "\x1b[33m", // DarkYellow835 "\x1b[37m", // Gray836 "\x1b[90m", // DarkGray837 "\x1b[94m", // Blue838 "\x1b[92m", // Green839 "\x1b[96m", // Cyan840 "\x1b[91m", // Red841 "\x1b[95m", // Magenta842 "\x1b[93m", // Yellow843 "\x1b[97m", // White844 };845 846 /// <summary>847 /// Return the VT escape sequence for a ConsoleColor.848 /// </summary>849 /// <param name="color">The <see cref="ConsoleColor"/> to be mapped from.</param>850 /// <param name="isBackground">Whether or not it's a background color.</param>851 /// <returns>The VT escape sequence representing the color.</returns>852 internal static string MapColorToEscapeSequence(ConsoleColor color, bool isBackground)853 {854 int index = (int)color;855 if (index < 0 || index >= ForegroundColorMap.Length)856 {857 throw new ArgumentOutOfRangeException(paramName: nameof(color));858 }859 860 return (isBackground ? BackgroundColorMap : ForegroundColorMap)[index];861 }862 863 /// <summary>864 /// Return the VT escape sequence for a foreground color.865 /// </summary>866 /// <param name="foregroundColor">The foreground color to be mapped from.</param>867 /// <returns>The VT escape sequence representing the foreground color.</returns>868 public static string MapForegroundColorToEscapeSequence(ConsoleColor foregroundColor)869 => MapColorToEscapeSequence(foregroundColor, isBackground: false);870 871 /// <summary>872 /// Return the VT escape sequence for a background color.873 /// </summary>874 /// <param name="backgroundColor">The background color to be mapped from.</param>875 /// <returns>The VT escape sequence representing the background color.</returns>876 public static string MapBackgroundColorToEscapeSequence(ConsoleColor backgroundColor)877 => MapColorToEscapeSequence(backgroundColor, isBackground: true);878 879 /// <summary>880 /// Return the VT escape sequence for a pair of foreground and background colors.881 /// </summary>882 /// <param name="foregroundColor">The foreground color of the color pair.</param>883 /// <param name="backgroundColor">The background color of the color pair.</param>884 /// <returns>The VT escape sequence representing the foreground and background color pair.</returns>885 public static string MapColorPairToEscapeSequence(ConsoleColor foregroundColor, ConsoleColor backgroundColor)886 {887 int foreIndex = (int)foregroundColor;888 int backIndex = (int)backgroundColor;889 890 if (foreIndex < 0 || foreIndex >= ForegroundColorMap.Length)891 {892 throw new ArgumentOutOfRangeException(paramName: nameof(foregroundColor));893 }894 895 if (backIndex < 0 || backIndex >= BackgroundColorMap.Length)896 {897 throw new ArgumentOutOfRangeException(paramName: nameof(backgroundColor));898 }899 900 string foreground = ForegroundColorMap[foreIndex];901 string background = BackgroundColorMap[backIndex];902 903 return string.Concat(904 foreground.AsSpan(start: 0, length: foreground.Length - 1),905 ";".AsSpan(),906 background.AsSpan(start: 2));907 }908 }909 910 #endregion PSStyle911}912 