Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
PSStyle.cs912 linesDownload Raw Back to common
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