mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-01 01:25:27 +08:00 
			
		
		
		
	Initial commit
This commit is contained in:
		
							
								
								
									
										77
									
								
								src/.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/.editorconfig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| root = false | ||||
|  | ||||
| [*.cs] | ||||
| # IDE0055: Fix formatting | ||||
| dotnet_diagnostic.IDE0055.severity = warning | ||||
|  | ||||
| # SA1101: Prefix local calls with this | ||||
| dotnet_diagnostic.SA1101.severity = none | ||||
|  | ||||
| # SA1633: File should have header | ||||
| dotnet_diagnostic.SA1633.severity = none | ||||
|  | ||||
| # SA1201: Elements should appear in the correct order | ||||
| dotnet_diagnostic.SA1201.severity = none | ||||
|  | ||||
| # SA1202: Public members should come before private members | ||||
| dotnet_diagnostic.SA1202.severity = none | ||||
|  | ||||
| # SA1309: Field names should not begin with underscore | ||||
| dotnet_diagnostic.SA1309.severity = none | ||||
|  | ||||
| # SA1404: Code analysis suppressions should have justification | ||||
| dotnet_diagnostic.SA1404.severity = none | ||||
|  | ||||
| # SA1516: Elements should be separated by a blank line | ||||
| dotnet_diagnostic.SA1516.severity = none | ||||
|  | ||||
| # CA1303: Do not pass literals as localized parameters | ||||
| dotnet_diagnostic.CA1303.severity = none | ||||
|  | ||||
| # CSA1204: Static members should appear before non-static members | ||||
| dotnet_diagnostic.SA1204.severity = none | ||||
|  | ||||
| # IDE0052: Remove unread private members | ||||
| dotnet_diagnostic.IDE0052.severity = warning | ||||
|  | ||||
| # IDE0063: Use simple 'using' statement | ||||
| csharp_prefer_simple_using_statement = false:suggestion | ||||
|  | ||||
| # IDE0018: Variable declaration can be inlined | ||||
| dotnet_diagnostic.IDE0018.severity = warning | ||||
|  | ||||
| # SA1625: Element documenation should not be copied and pasted | ||||
| dotnet_diagnostic.SA1625.severity = none | ||||
|  | ||||
| # IDE0005: Using directive is unnecessary | ||||
| dotnet_diagnostic.IDE0005.severity = warning | ||||
|  | ||||
| # SA1117: Parameters should be on same line or separate lines | ||||
| dotnet_diagnostic.SA1117.severity = none | ||||
|  | ||||
| # SA1404: Code analysis suppression should have justification | ||||
| dotnet_diagnostic.SA1404.severity = none | ||||
|  | ||||
| # SA1101: Prefix local calls with this | ||||
| dotnet_diagnostic.SA1101.severity = none | ||||
|  | ||||
| # SA1633: File should have header | ||||
| dotnet_diagnostic.SA1633.severity = none | ||||
|  | ||||
| # SA1649: File name should match first type name | ||||
| dotnet_diagnostic.SA1649.severity = none | ||||
|  | ||||
| # SA1402: File may only contain a single type | ||||
| dotnet_diagnostic.SA1402.severity = none | ||||
|  | ||||
| # CA1814: Prefer jagged arrays over multidimensional | ||||
| dotnet_diagnostic.CA1814.severity = none | ||||
|  | ||||
| # RCS1194: Implement exception constructors. | ||||
| dotnet_diagnostic.RCS1194.severity = none | ||||
|  | ||||
| # CA1032: Implement standard exception constructors | ||||
| dotnet_diagnostic.CA1032.severity = none | ||||
|  | ||||
| # CA1826: Do not use Enumerable methods on indexable collections. Instead use the collection directly | ||||
| dotnet_diagnostic.CA1826.severity = none | ||||
							
								
								
									
										47
									
								
								src/Directory.Build.props
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/Directory.Build.props
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| <Project> | ||||
|   <PropertyGroup Label="Settings"> | ||||
|     <Deterministic>true</Deterministic> | ||||
|     <LangVersion>8.0</LangVersion> | ||||
|     <IncludeSymbols>true</IncludeSymbols> | ||||
|     <MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip> | ||||
|     <GenerateDocumentationFile>true</GenerateDocumentationFile> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <PropertyGroup Label="Deterministic Build" Condition="'$(GITHUB_ACTIONS)' == 'true'"> | ||||
|     <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <PropertyGroup Label="Package Information"> | ||||
|     <Description>A library that makes it easier to create beautiful console applications.</Description> | ||||
|     <Company>Spectre Systems AB</Company> | ||||
|     <Copyright>Spectre Systems AB</Copyright> | ||||
|     <Authors>Patrik Svensson</Authors> | ||||
|     <RepositoryType>git</RepositoryType> | ||||
|     <RepositoryUrl>https://github.com/spectresystems/spectre.console</RepositoryUrl> | ||||
|     <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance> | ||||
|     <PackageProjectUrl>https://github.com/spectresystems/spectre.console</PackageProjectUrl> | ||||
|     <PackageLicenseExpression>MIT</PackageLicenseExpression> | ||||
|     <PackageReleaseNotes>https://github.com/spectresystems/spectre.console/releases</PackageReleaseNotes> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <PropertyGroup Label="Source Link"> | ||||
|     <PublishRepositoryUrl>true</PublishRepositoryUrl> | ||||
|     <EmbedUntrackedSources>true</EmbedUntrackedSources> | ||||
|     <AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder> | ||||
|   </PropertyGroup> | ||||
|    | ||||
|   <ItemGroup Label="Package References"> | ||||
|     <PackageReference Include="MinVer" PrivateAssets="All" Version="2.3.0" /> | ||||
|     <PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" Version="1.0.0" /> | ||||
|     <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8"> | ||||
|       <PrivateAssets>all</PrivateAssets> | ||||
|       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||
|     </PackageReference> | ||||
|     <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.113"> | ||||
|       <PrivateAssets>All</PrivateAssets> | ||||
|     </PackageReference> | ||||
|     <PackageReference Include="Roslynator.Analyzers" Version="2.3.0"> | ||||
|       <PrivateAssets>All</PrivateAssets> | ||||
|     </PackageReference> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
							
								
								
									
										8
									
								
								src/Directory.Build.targets
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/Directory.Build.targets
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| <Project> | ||||
|   <Target Name="Versioning" BeforeTargets="MinVer"> | ||||
|     <PropertyGroup Label="Build"> | ||||
|       <MinVerDefaultPreReleasePhase>preview</MinVerDefaultPreReleasePhase> | ||||
|       <MinVerVerbosity>normal</MinVerVerbosity> | ||||
|     </PropertyGroup> | ||||
|   </Target> | ||||
| </Project> | ||||
							
								
								
									
										8
									
								
								src/Sample/.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/Sample/.editorconfig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| root = false | ||||
| [*.cs] | ||||
|  | ||||
| # Default severity for all analyzer diagnostics | ||||
| dotnet_analyzer_diagnostic.severity = none | ||||
|  | ||||
| # CS1591: Missing XML comment for publicly visible type or member | ||||
| dotnet_diagnostic.CS1591.severity = none | ||||
							
								
								
									
										53
									
								
								src/Sample/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/Sample/Program.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Reflection; | ||||
| using System.Runtime.InteropServices; | ||||
| using Spectre.Console; | ||||
|  | ||||
| namespace Sample | ||||
| { | ||||
|     public static class Program | ||||
|     { | ||||
|         public static void Main(string[] args) | ||||
|         { | ||||
|             // Use the static API to write some things to the console. | ||||
|             AnsiConsole.Foreground = Color.Chartreuse2; | ||||
|             AnsiConsole.Style = Styles.Underline | Styles.Bold; | ||||
|             AnsiConsole.WriteLine("Hello World!"); | ||||
|             AnsiConsole.Reset(); | ||||
|             AnsiConsole.WriteLine($"Capabilities: {AnsiConsole.Capabilities}"); | ||||
|             AnsiConsole.WriteLine($"Width={AnsiConsole.Width}, Height={AnsiConsole.Height}"); | ||||
|             AnsiConsole.WriteLine("Good bye!"); | ||||
|             AnsiConsole.WriteLine(); | ||||
|  | ||||
|             // We can get the default console via the static API. | ||||
|             var console = AnsiConsole.Console; | ||||
|  | ||||
|             // Or you can build it yourself the old fashion way. | ||||
|             console = AnsiConsole.Create( | ||||
|                 new AnsiConsoleSettings() | ||||
|                 { | ||||
|                     Ansi = AnsiSupport.Yes, | ||||
|                     ColorSystem = ColorSystemSupport.Standard, | ||||
|                     Out = Console.Out, | ||||
|                 }); | ||||
|  | ||||
|             // In this case, we will find the closest colors | ||||
|             // and downgrade them to the specified color system. | ||||
|             console.Foreground = Color.Chartreuse2; | ||||
|             console.Style = Styles.Underline | Styles.Bold; | ||||
|             console.WriteLine("Hello World!"); | ||||
|             console.ResetColors(); | ||||
|             console.ResetStyle(); | ||||
|             console.WriteLine($"Capabilities: {console.Capabilities}"); | ||||
|             console.WriteLine($"Width={AnsiConsole.Width}, Height={AnsiConsole.Height}"); | ||||
|             console.WriteLine("Good bye!"); | ||||
|             console.WriteLine(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										14
									
								
								src/Sample/Sample.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/Sample/Sample.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <OutputType>Exe</OutputType> | ||||
|     <TargetFramework>netcoreapp3.1</TargetFramework> | ||||
|     <RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild> | ||||
|     <IsPackable>false</IsPackable> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\Spectre.Console\Spectre.Console.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
							
								
								
									
										23
									
								
								src/Spectre.Console.Tests/.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/Spectre.Console.Tests/.editorconfig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| root = false | ||||
| [*.cs] | ||||
|  | ||||
| # Default severity for analyzer diagnostics with category 'StyleCop.CSharp.DocumentationRules' | ||||
| dotnet_analyzer_diagnostic.category-StyleCop.CSharp.DocumentationRules.severity = none | ||||
|  | ||||
| # CA1707: Identifiers should not contain underscores | ||||
| dotnet_diagnostic.CA1707.severity = none | ||||
|  | ||||
| # SA1200: Using directives should be placed correctly | ||||
| dotnet_diagnostic.SA1200.severity = none | ||||
|  | ||||
| # CS1591: Missing XML comment for publicly visible type or member | ||||
| dotnet_diagnostic.CS1591.severity = none | ||||
|  | ||||
| # SA1210: Using directives should be ordered alphabetically by namespace | ||||
| dotnet_diagnostic.SA1210.severity = none | ||||
|  | ||||
| # CA1034: Nested types should not be visible | ||||
| dotnet_diagnostic.CA1034.severity = none | ||||
|  | ||||
| # CA2000: Dispose objects before losing scope | ||||
| dotnet_diagnostic.CA2000.severity = none | ||||
							
								
								
									
										31
									
								
								src/Spectre.Console.Tests/AnsiConsoleFixture.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/Spectre.Console.Tests/AnsiConsoleFixture.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| using System; | ||||
| using System.IO; | ||||
|  | ||||
| namespace Spectre.Console.Tests | ||||
| { | ||||
|     public sealed class AnsiConsoleFixture : IDisposable | ||||
|     { | ||||
|         private readonly StringWriter _writer; | ||||
|  | ||||
|         public IAnsiConsole Console { get; } | ||||
|  | ||||
|         public string Output => _writer.ToString(); | ||||
|  | ||||
|         public AnsiConsoleFixture(ColorSystem system) | ||||
|         { | ||||
|             _writer = new StringWriter(); | ||||
|  | ||||
|             Console = AnsiConsole.Create(new AnsiConsoleSettings | ||||
|             { | ||||
|                 Ansi = AnsiSupport.Yes, | ||||
|                 ColorSystem = (ColorSystemSupport)system, | ||||
|                 Out = _writer, | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         public void Dispose() | ||||
|         { | ||||
|             _writer?.Dispose(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										216
									
								
								src/Spectre.Console.Tests/AnsiConsoleTests.Colors.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								src/Spectre.Console.Tests/AnsiConsoleTests.Colors.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,216 @@ | ||||
| using Shouldly; | ||||
| using Xunit; | ||||
|  | ||||
| namespace Spectre.Console.Tests | ||||
| { | ||||
|     public partial class AnsiConsoleTests | ||||
|     { | ||||
|         public sealed class TrueColor | ||||
|         { | ||||
|             [Theory] | ||||
|             [InlineData(true, "\u001b[38;2;128;0;128mHello\u001b[0m")] | ||||
|             [InlineData(false, "\u001b[48;2;128;0;128mHello\u001b[0m")] | ||||
|             public void Should_Return_Correct_Code(bool foreground, string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor); | ||||
|                 fixture.Console.SetColor(new Color(128, 0, 128), foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|  | ||||
|             [Theory] | ||||
|             [InlineData(true, "\u001b[38;5;5mHello\u001b[0m")] | ||||
|             [InlineData(false, "\u001b[48;5;5mHello\u001b[0m")] | ||||
|             public void Should_Return_Eight_Bit_Ansi_Code_For_Known_Colors(bool foreground, string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor); | ||||
|                 fixture.Console.SetColor(Color.Purple, foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public sealed class EightBit | ||||
|         { | ||||
|             [Theory] | ||||
|             [InlineData(true, "\u001b[38;5;3mHello\u001b[0m")] | ||||
|             [InlineData(false, "\u001b[48;5;3mHello\u001b[0m")] | ||||
|             public void Should_Return_Correct_Code_For_Known_Color(bool foreground, string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.EightBit); | ||||
|                 fixture.Console.SetColor(Color.Olive, foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|  | ||||
|             [Theory] | ||||
|             [InlineData(true, "\u001b[38;5;3mHello\u001b[0m")] | ||||
|             [InlineData(false, "\u001b[48;5;3mHello\u001b[0m")] | ||||
|             public void Should_Map_TrueColor_To_Nearest_Eight_Bit_Color_If_Possible(bool foreground, string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.EightBit); | ||||
|                 fixture.Console.SetColor(new Color(128, 128, 0), foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|  | ||||
|             [Theory] | ||||
|             [InlineData(true, "\u001b[38;5;3mHello\u001b[0m")] | ||||
|             [InlineData(false, "\u001b[48;5;3mHello\u001b[0m")] | ||||
|             public void Should_Estimate_TrueColor_To_Nearest_Eight_Bit_Color(bool foreground, string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.EightBit); | ||||
|                 fixture.Console.SetColor(new Color(126, 127, 0), foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public sealed class Standard | ||||
|         { | ||||
|             [Theory] | ||||
|             [InlineData(true, "\u001b[33mHello\u001b[0m")] | ||||
|             [InlineData(false, "\u001b[43mHello\u001b[0m")] | ||||
|             public void Should_Return_Correct_Code_For_Known_Color(bool foreground, string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.Standard); | ||||
|                 fixture.Console.SetColor(Color.Olive, foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|  | ||||
|             [Theory] | ||||
|             [InlineData(true, 128, 128, 128, "\u001b[90mHello\u001b[0m")] | ||||
|             [InlineData(false, 128, 128, 128, "\u001b[100mHello\u001b[0m")] | ||||
|             [InlineData(true, 0, 128, 0, "\u001b[32mHello\u001b[0m")] | ||||
|             [InlineData(false, 0, 128, 0, "\u001b[42mHello\u001b[0m")] | ||||
|             public void Should_Map_TrueColor_To_Nearest_Four_Bit_Color_If_Possible( | ||||
|                 bool foreground, | ||||
|                 byte r, byte g, byte b, | ||||
|                 string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.Standard); | ||||
|                 fixture.Console.SetColor(new Color(r, g, b), foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|  | ||||
|             [Theory] | ||||
|             [InlineData(true, 112, 120, 128, "\u001b[90mHello\u001b[0m")] | ||||
|             [InlineData(false, 112, 120, 128, "\u001b[100mHello\u001b[0m")] | ||||
|             [InlineData(true, 0, 120, 12, "\u001b[32mHello\u001b[0m")] | ||||
|             [InlineData(false, 0, 120, 12, "\u001b[42mHello\u001b[0m")] | ||||
|             public void Should_Estimate_TrueColor_To_Nearest_Four_Bit_Color( | ||||
|                 bool foreground, | ||||
|                 byte r, byte g, byte b, | ||||
|                 string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.Standard); | ||||
|                 fixture.Console.SetColor(new Color(r, g, b), foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public sealed class Legacy | ||||
|         { | ||||
|             [Theory] | ||||
|             [InlineData(true, "\u001b[33mHello\u001b[0m")] | ||||
|             [InlineData(false, "\u001b[43mHello\u001b[0m")] | ||||
|             public void Should_Return_Correct_Code_For_Known_Color(bool foreground, string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.Legacy); | ||||
|                 fixture.Console.SetColor(Color.Olive, foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|  | ||||
|             [Theory] | ||||
|             [InlineData(true, 128, 128, 128, "\u001b[37mHello\u001b[0m")] | ||||
|             [InlineData(false, 128, 128, 128, "\u001b[47mHello\u001b[0m")] | ||||
|             [InlineData(true, 0, 128, 0, "\u001b[32mHello\u001b[0m")] | ||||
|             [InlineData(false, 0, 128, 0, "\u001b[42mHello\u001b[0m")] | ||||
|             public void Should_Map_TrueColor_To_Nearest_Three_Bit_Color_If_Possible( | ||||
|                 bool foreground, | ||||
|                 byte r, byte g, byte b, | ||||
|                 string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.Legacy); | ||||
|                 fixture.Console.SetColor(new Color(r, g, b), foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|  | ||||
|             [Theory] | ||||
|             [InlineData(true, 112, 120, 128, "\u001b[36mHello\u001b[0m")] | ||||
|             [InlineData(false, 112, 120, 128, "\u001b[46mHello\u001b[0m")] | ||||
|             [InlineData(true, 0, 120, 12, "\u001b[32mHello\u001b[0m")] | ||||
|             [InlineData(false, 0, 120, 12, "\u001b[42mHello\u001b[0m")] | ||||
|             public void Should_Estimate_TrueColor_To_Nearest_Three_Bit_Color( | ||||
|                 bool foreground, | ||||
|                 byte r, byte g, byte b, | ||||
|                 string expected) | ||||
|             { | ||||
|                 // Given | ||||
|                 var fixture = new AnsiConsoleFixture(ColorSystem.Legacy); | ||||
|                 fixture.Console.SetColor(new Color(r, g, b), foreground); | ||||
|  | ||||
|                 // When | ||||
|                 fixture.Console.Write("Hello"); | ||||
|  | ||||
|                 // Then | ||||
|                 fixture.Output.ShouldBe(expected); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										47
									
								
								src/Spectre.Console.Tests/AnsiConsoleTests.Style.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/Spectre.Console.Tests/AnsiConsoleTests.Style.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| using Shouldly; | ||||
| using Xunit; | ||||
|  | ||||
| namespace Spectre.Console.Tests | ||||
| { | ||||
|     public partial class AnsiConsoleTests | ||||
|     { | ||||
|         [Theory] | ||||
|         [InlineData(Styles.Bold, "\u001b[1mHello World[0m")] | ||||
|         [InlineData(Styles.Dim, "\u001b[2mHello World[0m")] | ||||
|         [InlineData(Styles.Italic, "\u001b[3mHello World[0m")] | ||||
|         [InlineData(Styles.Underline, "\u001b[4mHello World[0m")] | ||||
|         [InlineData(Styles.Invert, "\u001b[7mHello World[0m")] | ||||
|         [InlineData(Styles.Conceal, "\u001b[8mHello World[0m")] | ||||
|         [InlineData(Styles.SlowBlink, "\u001b[5mHello World[0m")] | ||||
|         [InlineData(Styles.RapidBlink, "\u001b[6mHello World[0m")] | ||||
|         [InlineData(Styles.Strikethrough, "\u001b[9mHello World[0m")] | ||||
|         public void Should_Write_Style_Correctly(Styles style, string expected) | ||||
|         { | ||||
|             // Given | ||||
|             var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor); | ||||
|             fixture.Console.Style = style; | ||||
|  | ||||
|             // When | ||||
|             fixture.Console.Write("Hello World"); | ||||
|  | ||||
|             // Then | ||||
|             fixture.Output.ShouldBe(expected); | ||||
|         } | ||||
|  | ||||
|         [Theory] | ||||
|         [InlineData(Styles.Bold | Styles.Underline, "\u001b[1;4mHello World[0m")] | ||||
|         [InlineData(Styles.Bold | Styles.Underline | Styles.Conceal, "\u001b[1;4;8mHello World[0m")] | ||||
|         public void Should_Write_Combined_Styles_Correctly(Styles style, string expected) | ||||
|         { | ||||
|             // Given | ||||
|             var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor); | ||||
|             fixture.Console.Style = style; | ||||
|  | ||||
|             // When | ||||
|             fixture.Console.Write("Hello World"); | ||||
|  | ||||
|             // Then | ||||
|             fixture.Output.ShouldBe(expected); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										72
									
								
								src/Spectre.Console.Tests/AnsiConsoleTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/Spectre.Console.Tests/AnsiConsoleTests.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| using Shouldly; | ||||
| using Xunit; | ||||
|  | ||||
| namespace Spectre.Console.Tests | ||||
| { | ||||
|     public partial class AnsiConsoleTests | ||||
|     { | ||||
|         [Fact] | ||||
|         public void Should_Combine_Style_And_Colors() | ||||
|         { | ||||
|             // Given | ||||
|             var fixture = new AnsiConsoleFixture(ColorSystem.Standard); | ||||
|             fixture.Console.Foreground = Color.RoyalBlue1; | ||||
|             fixture.Console.Background = Color.NavajoWhite1; | ||||
|             fixture.Console.Style = Styles.Italic; | ||||
|  | ||||
|             // When | ||||
|             fixture.Console.Write("Hello"); | ||||
|  | ||||
|             // Then | ||||
|             fixture.Output.ShouldBe("\u001b[3;90;47mHello\u001b[0m"); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void Should_Not_Include_Foreground_If_Set_To_Default_Color() | ||||
|         { | ||||
|             // Given | ||||
|             var fixture = new AnsiConsoleFixture(ColorSystem.Standard); | ||||
|             fixture.Console.Foreground = Color.Default; | ||||
|             fixture.Console.Background = Color.NavajoWhite1; | ||||
|             fixture.Console.Style = Styles.Italic; | ||||
|  | ||||
|             // When | ||||
|             fixture.Console.Write("Hello"); | ||||
|  | ||||
|             // Then | ||||
|             fixture.Output.ShouldBe("\u001b[3;47mHello\u001b[0m"); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void Should_Not_Include_Background_If_Set_To_Default_Color() | ||||
|         { | ||||
|             // Given | ||||
|             var fixture = new AnsiConsoleFixture(ColorSystem.Standard); | ||||
|             fixture.Console.Foreground = Color.RoyalBlue1; | ||||
|             fixture.Console.Background = Color.Default; | ||||
|             fixture.Console.Style = Styles.Italic; | ||||
|  | ||||
|             // When | ||||
|             fixture.Console.Write("Hello"); | ||||
|  | ||||
|             // Then | ||||
|             fixture.Output.ShouldBe("\u001b[3;90mHello\u001b[0m"); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void Should_Not_Include_Style_If_Set_To_None() | ||||
|         { | ||||
|             // Given | ||||
|             var fixture = new AnsiConsoleFixture(ColorSystem.Standard); | ||||
|             fixture.Console.Foreground = Color.RoyalBlue1; | ||||
|             fixture.Console.Background = Color.NavajoWhite1; | ||||
|             fixture.Console.Style = Styles.None; | ||||
|  | ||||
|             // When | ||||
|             fixture.Console.Write("Hello"); | ||||
|  | ||||
|             // Then | ||||
|             fixture.Output.ShouldBe("\u001b[90;47mHello\u001b[0m"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/Spectre.Console.Tests/Extensions/ConsoleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/Spectre.Console.Tests/Extensions/ConsoleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| using System; | ||||
|  | ||||
| namespace Spectre.Console.Tests | ||||
| { | ||||
|     public static class ConsoleExtensions | ||||
|     { | ||||
|         public static void SetColor(this IAnsiConsole console, Color color, bool foreground) | ||||
|         { | ||||
|             if (console is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(console)); | ||||
|             } | ||||
|  | ||||
|             if (foreground) | ||||
|             { | ||||
|                 console.Foreground = color; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 console.Background = color; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										21
									
								
								src/Spectre.Console.Tests/Spectre.Console.Tests.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/Spectre.Console.Tests/Spectre.Console.Tests.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>netcoreapp3.1</TargetFramework> | ||||
|  | ||||
|     <IsPackable>false</IsPackable> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> | ||||
|     <PackageReference Include="Shouldly" Version="4.0.0-beta0002" /> | ||||
|     <PackageReference Include="xunit" Version="2.4.0" /> | ||||
|     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | ||||
|     <PackageReference Include="coverlet.collector" Version="1.2.0" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\Spectre.Console\Spectre.Console.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
							
								
								
									
										73
									
								
								src/Spectre.Console.sln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/Spectre.Console.sln
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
|  | ||||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
| # Visual Studio Version 16 | ||||
| VisualStudioVersion = 16.0.30225.117 | ||||
| MinimumVisualStudioVersion = 15.0.26124.0 | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console", "Spectre.Console\Spectre.Console.csproj", "{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectre.Console.Tests", "Spectre.Console.Tests\Spectre.Console.Tests.csproj", "{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample", "Sample\Sample.csproj", "{272E6092-BD31-4EB6-A9FF-F4179F91958F}" | ||||
| EndProject | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{20595AD4-8D75-4AF8-B6BC-9C38C160423F}" | ||||
| 	ProjectSection(SolutionItems) = preProject | ||||
| 		.editorconfig = .editorconfig | ||||
| 		Directory.Build.props = Directory.Build.props | ||||
| 		Directory.Build.targets = Directory.Build.targets | ||||
| 		stylecop.json = stylecop.json | ||||
| 	EndProjectSection | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		Debug|Any CPU = Debug|Any CPU | ||||
| 		Debug|x64 = Debug|x64 | ||||
| 		Debug|x86 = Debug|x86 | ||||
| 		Release|Any CPU = Release|Any CPU | ||||
| 		Release|x64 = Release|x64 | ||||
| 		Release|x86 = Release|x86 | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Debug|x64.ActiveCfg = Debug|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Debug|x64.Build.0 = Debug|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Debug|x86.ActiveCfg = Debug|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Debug|x86.Build.0 = Debug|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Release|x64.ActiveCfg = Release|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Release|x64.Build.0 = Release|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Release|x86.ActiveCfg = Release|Any CPU | ||||
| 		{80DCBEF3-99D6-46C0-9C5B-42B4534D9113}.Release|x86.Build.0 = Release|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|x64.ActiveCfg = Debug|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|x64.Build.0 = Debug|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|x86.ActiveCfg = Debug|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Debug|x86.Build.0 = Debug|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|x64.ActiveCfg = Release|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|x64.Build.0 = Release|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|x86.ActiveCfg = Release|Any CPU | ||||
| 		{9F1AC4C1-766E-4421-8A78-B28F5BCDD94F}.Release|x86.Build.0 = Release|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Debug|x64.ActiveCfg = Debug|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Debug|x64.Build.0 = Debug|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Debug|x86.ActiveCfg = Debug|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Debug|x86.Build.0 = Debug|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Release|x64.ActiveCfg = Release|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Release|x64.Build.0 = Release|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Release|x86.ActiveCfg = Release|Any CPU | ||||
| 		{272E6092-BD31-4EB6-A9FF-F4179F91958F}.Release|x86.Build.0 = Release|Any CPU | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(ExtensibilityGlobals) = postSolution | ||||
| 		SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C} | ||||
| 	EndGlobalSection | ||||
| EndGlobal | ||||
							
								
								
									
										135
									
								
								src/Spectre.Console/AnsiConsole.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								src/Spectre.Console/AnsiConsole.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| using System; | ||||
| using Spectre.Console.Internal; | ||||
|  | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// A console capable of writing ANSI escape sequences. | ||||
|     /// </summary> | ||||
|     public static class AnsiConsole | ||||
|     { | ||||
|         private static readonly Lazy<IAnsiConsole> _console = new Lazy<IAnsiConsole>(() => | ||||
|         { | ||||
|             return Create(new AnsiConsoleSettings | ||||
|             { | ||||
|                 Ansi = AnsiSupport.Detect, | ||||
|                 ColorSystem = ColorSystemSupport.Detect, | ||||
|                 Out = System.Console.Out, | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the current renderer. | ||||
|         /// </summary> | ||||
|         public static IAnsiConsole Console => _console.Value; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the console's capabilities. | ||||
|         /// </summary> | ||||
|         public static AnsiConsoleCapabilities Capabilities => Console.Capabilities; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the buffer width of the console. | ||||
|         /// </summary> | ||||
|         public static int Width | ||||
|         { | ||||
|             get => Console.Width; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the buffer height of the console. | ||||
|         /// </summary> | ||||
|         public static int Height | ||||
|         { | ||||
|             get => Console.Height; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets or sets the foreground color. | ||||
|         /// </summary> | ||||
|         public static Color Foreground | ||||
|         { | ||||
|             get => Console.Foreground; | ||||
|             set => Console.SetColor(value, true); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets or sets the background color. | ||||
|         /// </summary> | ||||
|         public static Color Background | ||||
|         { | ||||
|             get => Console.Background; | ||||
|             set => Console.SetColor(value, false); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets or sets the style. | ||||
|         /// </summary> | ||||
|         public static Styles Style | ||||
|         { | ||||
|             get => Console.Style; | ||||
|             set => Console.Style = value; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Creates a new <see cref="IAnsiConsole"/> instance | ||||
|         /// from the provided settings. | ||||
|         /// </summary> | ||||
|         /// <param name="settings">The settings to use.</param> | ||||
|         /// <returns>An <see cref="IAnsiConsole"/> instance.</returns> | ||||
|         public static IAnsiConsole Create(AnsiConsoleSettings settings) | ||||
|         { | ||||
|             return ConsoleBuilder.Build(settings); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Resets colors and styles to the default ones. | ||||
|         /// </summary> | ||||
|         public static void Reset() | ||||
|         { | ||||
|             Console.Reset(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Resets the current style back to the default one. | ||||
|         /// </summary> | ||||
|         public static void ResetStyle() | ||||
|         { | ||||
|             Console.ResetStyle(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Resets the foreground and background colors to the default ones. | ||||
|         /// </summary> | ||||
|         public static void ResetColors() | ||||
|         { | ||||
|             Console.ResetColors(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Writes the content to the console. | ||||
|         /// </summary> | ||||
|         /// <param name="content">The content to write.</param> | ||||
|         public static void Write(string content) | ||||
|         { | ||||
|             Console.Write(content); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Writes an empty line to the console. | ||||
|         /// </summary> | ||||
|         public static void WriteLine() | ||||
|         { | ||||
|             Console.WriteLine(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Writes a line to the console. | ||||
|         /// </summary> | ||||
|         /// <param name="content">The content to write.</param> | ||||
|         public static void WriteLine(string content) | ||||
|         { | ||||
|             Console.WriteLine(content); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										42
									
								
								src/Spectre.Console/AnsiConsoleCapabilities.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/Spectre.Console/AnsiConsoleCapabilities.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Represents console capabilities. | ||||
|     /// </summary> | ||||
|     public sealed class AnsiConsoleCapabilities | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Gets a value indicating whether or not | ||||
|         /// the console supports Ansi. | ||||
|         /// </summary> | ||||
|         public bool SupportsAnsi { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the color system. | ||||
|         /// </summary> | ||||
|         public ColorSystem ColorSystem { get; } | ||||
|  | ||||
|         internal AnsiConsoleCapabilities(bool supportsAnsi, ColorSystem colorSystem) | ||||
|         { | ||||
|             SupportsAnsi = supportsAnsi; | ||||
|             ColorSystem = colorSystem; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public override string ToString() | ||||
|         { | ||||
|             var supportsAnsi = SupportsAnsi ? "Yes" : "No"; | ||||
|             var bits = ColorSystem switch | ||||
|             { | ||||
|                 ColorSystem.NoColors => "1 bit", | ||||
|                 ColorSystem.Legacy => "3 bits", | ||||
|                 ColorSystem.Standard => "4 bits", | ||||
|                 ColorSystem.EightBit => "8 bits", | ||||
|                 ColorSystem.TrueColor => "24 bits", | ||||
|                 _ => "?" | ||||
|             }; | ||||
|  | ||||
|             return $"ANSI={supportsAnsi}, Colors={ColorSystem} ({bits})"; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										27
									
								
								src/Spectre.Console/AnsiConsoleSettings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/Spectre.Console/AnsiConsoleSettings.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| using System.IO; | ||||
|  | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Settings used by <see cref="ConsoleBuilder"/> | ||||
|     /// when building a <see cref="IAnsiConsole"/>. | ||||
|     /// </summary> | ||||
|     public sealed class AnsiConsoleSettings | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Gets or sets a value indicating whether or | ||||
|         /// not ANSI escape sequences are supported. | ||||
|         /// </summary> | ||||
|         public AnsiSupport Ansi { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets or sets the color system to use. | ||||
|         /// </summary> | ||||
|         public ColorSystemSupport ColorSystem { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets or sets the out buffer. | ||||
|         /// </summary> | ||||
|         public TextWriter Out { get; set; } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/Spectre.Console/AnsiSupport.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/Spectre.Console/AnsiSupport.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Determines ANSI escape sequence support. | ||||
|     /// </summary> | ||||
|     public enum AnsiSupport | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// ANSI escape sequence support should | ||||
|         /// be detected by the system. | ||||
|         /// </summary> | ||||
|         Detect = 0, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// ANSI escape sequences are supported. | ||||
|         /// </summary> | ||||
|         Yes = 1, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// ANSI escape sequences are not supported. | ||||
|         /// </summary> | ||||
|         No = 2, | ||||
|     } | ||||
| } | ||||
							
								
								
									
										1352
									
								
								src/Spectre.Console/Color.Known.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1352
									
								
								src/Spectre.Console/Color.Known.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										211
									
								
								src/Spectre.Console/Color.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								src/Spectre.Console/Color.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,211 @@ | ||||
| using System; | ||||
| using System.Diagnostics; | ||||
| using System.Linq; | ||||
| using Spectre.Console.Internal; | ||||
|  | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Represents a color. | ||||
|     /// </summary> | ||||
|     public partial struct Color : IEquatable<Color> | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Gets the default color. | ||||
|         /// </summary> | ||||
|         public static Color Default { get; } | ||||
|  | ||||
|         static Color() | ||||
|         { | ||||
|             Default = new Color(0, "default", 0, 0, 0, true); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the red component. | ||||
|         /// </summary> | ||||
|         public byte R { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the green component. | ||||
|         /// </summary> | ||||
|         public byte G { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the blue component. | ||||
|         /// </summary> | ||||
|         public byte B { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the name of the color, if any. | ||||
|         /// </summary> | ||||
|         public string Name { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the number of the color, if any. | ||||
|         /// </summary> | ||||
|         internal byte? Number { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets a value indicating whether or not this is the default color. | ||||
|         /// </summary> | ||||
|         internal bool IsDefault { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes a new instance of the <see cref="Color"/> struct. | ||||
|         /// </summary> | ||||
|         /// <param name="red">The red component.</param> | ||||
|         /// <param name="green">The green component.</param> | ||||
|         /// <param name="blue">The blue component.</param> | ||||
|         public Color(byte red, byte green, byte blue) | ||||
|         { | ||||
|             R = red; | ||||
|             G = green; | ||||
|             B = blue; | ||||
|             IsDefault = false; | ||||
|             Name = null; | ||||
|             Number = null; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public override int GetHashCode() | ||||
|         { | ||||
|             unchecked | ||||
|             { | ||||
|                 var hash = (int)2166136261; | ||||
|                 hash = (hash * 16777619) ^ R.GetHashCode(); | ||||
|                 hash = (hash * 16777619) ^ G.GetHashCode(); | ||||
|                 hash = (hash * 16777619) ^ B.GetHashCode(); | ||||
|                 return hash; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public override bool Equals(object obj) | ||||
|         { | ||||
|             return obj is Color color && Equals(color); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public bool Equals(Color other) | ||||
|         { | ||||
|             return Number == other.Number || (R == other.R && G == other.G && B == other.B); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Checks if two <see cref="Color"/> instances are equal. | ||||
|         /// </summary> | ||||
|         /// <param name="left">The first color instance to compare.</param> | ||||
|         /// <param name="right">The second color instance to compare.</param> | ||||
|         /// <returns><c>true</c> if the two colors are equal, otherwise <c>false</c>.</returns> | ||||
|         public static bool operator ==(Color left, Color right) | ||||
|         { | ||||
|             return left.Equals(right); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Checks if two <see cref="Color"/> instances are not equal. | ||||
|         /// </summary> | ||||
|         /// <param name="left">The first color instance to compare.</param> | ||||
|         /// <param name="right">The second color instance to compare.</param> | ||||
|         /// <returns><c>true</c> if the two colors are not equal, otherwise <c>false</c>.</returns> | ||||
|         public static bool operator !=(Color left, Color right) | ||||
|         { | ||||
|             return !(left == right); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Convers a <see cref="ConsoleColor"/> to a <see cref="Color"/>. | ||||
|         /// </summary> | ||||
|         /// <param name="color">The color to convert.</param> | ||||
|         public static implicit operator Color(ConsoleColor color) | ||||
|         { | ||||
|             return FromConsoleColor(color); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Convers a color number into a <see cref="Color"/>. | ||||
|         /// </summary> | ||||
|         /// <param name="number">The color number.</param> | ||||
|         /// <returns>The color representing the specified color number.</returns> | ||||
|         public static Color FromColorNumber(int number) | ||||
|         { | ||||
|             if (number < 0 || number > 255) | ||||
|             { | ||||
|                 throw new InvalidOperationException("Color number must be between 0 and 255"); | ||||
|             } | ||||
|  | ||||
|             return ColorPalette.EightBit.First(x => x.Number == number); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Convers a <see cref="Color"/> to a <see cref="ConsoleColor"/>. | ||||
|         /// </summary> | ||||
|         /// <param name="color">The color to convert.</param> | ||||
|         /// <returns>A <see cref="ConsoleColor"/> representing the <see cref="Color"/>.</returns> | ||||
|         public static ConsoleColor ToConsoleColor(Color color) | ||||
|         { | ||||
|             if (color.IsDefault) | ||||
|             { | ||||
|                 return (ConsoleColor)(-1); | ||||
|             } | ||||
|  | ||||
|             if (color.Number == null || color.Number.Value >= 16) | ||||
|             { | ||||
|                 color = ColorPalette.ExactOrClosest(ColorSystem.Standard, color); | ||||
|             } | ||||
|  | ||||
|             // Should not happen, but this will make things easier if we mess things up... | ||||
|             Debug.Assert(color.Number >= 0 && color.Number < 16, "Color does not fall inside the standard palette range."); | ||||
|  | ||||
|             return color.Number.Value switch | ||||
|             { | ||||
|                 0 => ConsoleColor.Black, | ||||
|                 1 => ConsoleColor.DarkRed, | ||||
|                 2 => ConsoleColor.DarkGreen, | ||||
|                 3 => ConsoleColor.DarkYellow, | ||||
|                 4 => ConsoleColor.DarkBlue, | ||||
|                 5 => ConsoleColor.DarkMagenta, | ||||
|                 6 => ConsoleColor.DarkCyan, | ||||
|                 7 => ConsoleColor.Gray, | ||||
|                 8 => ConsoleColor.DarkGray, | ||||
|                 9 => ConsoleColor.Red, | ||||
|                 10 => ConsoleColor.Green, | ||||
|                 11 => ConsoleColor.Yellow, | ||||
|                 12 => ConsoleColor.Blue, | ||||
|                 13 => ConsoleColor.Magenta, | ||||
|                 14 => ConsoleColor.Cyan, | ||||
|                 15 => ConsoleColor.White, | ||||
|                 _ => throw new InvalidOperationException("Cannot convert color to console color."), | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Convers a <see cref="ConsoleColor"/> to a <see cref="Color"/>. | ||||
|         /// </summary> | ||||
|         /// <param name="color">The color to convert.</param> | ||||
|         /// <returns>A <see cref="Color"/> representing the <see cref="ConsoleColor"/>.</returns> | ||||
|         public static Color FromConsoleColor(ConsoleColor color) | ||||
|         { | ||||
|             return color switch | ||||
|             { | ||||
|                 ConsoleColor.Black => Black, | ||||
|                 ConsoleColor.Blue => Blue, | ||||
|                 ConsoleColor.Cyan => Aqua, | ||||
|                 ConsoleColor.DarkBlue => Navy, | ||||
|                 ConsoleColor.DarkCyan => Teal, | ||||
|                 ConsoleColor.DarkGray => Grey, | ||||
|                 ConsoleColor.DarkGreen => Green, | ||||
|                 ConsoleColor.DarkMagenta => Purple, | ||||
|                 ConsoleColor.DarkRed => Maroon, | ||||
|                 ConsoleColor.DarkYellow => Olive, | ||||
|                 ConsoleColor.Gray => Silver, | ||||
|                 ConsoleColor.Green => Lime, | ||||
|                 ConsoleColor.Magenta => Fuchsia, | ||||
|                 ConsoleColor.Red => Red, | ||||
|                 ConsoleColor.White => White, | ||||
|                 ConsoleColor.Yellow => Yellow, | ||||
|                 _ => Default, | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										33
									
								
								src/Spectre.Console/ColorSystem.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/Spectre.Console/ColorSystem.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Represents a color system. | ||||
|     /// </summary> | ||||
|     public enum ColorSystem | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// No colors. | ||||
|         /// </summary> | ||||
|         NoColors = 0, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Legacy, 3-bit mode. | ||||
|         /// </summary> | ||||
|         Legacy = 1, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Standard, 4-bit mode. | ||||
|         /// </summary> | ||||
|         Standard = 2, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 8-bit mode. | ||||
|         /// </summary> | ||||
|         EightBit = 3, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 24-bit mode. | ||||
|         /// </summary> | ||||
|         TrueColor = 4, | ||||
|     } | ||||
| } | ||||
							
								
								
									
										38
									
								
								src/Spectre.Console/ColorSystemSupport.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/Spectre.Console/ColorSystemSupport.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Determines what color system should be used. | ||||
|     /// </summary> | ||||
|     public enum ColorSystemSupport | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Try to detect the color system. | ||||
|         /// </summary> | ||||
|         Detect = -1, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// No colors. | ||||
|         /// </summary> | ||||
|         NoColors = 0, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Legacy, 3-bit mode. | ||||
|         /// </summary> | ||||
|         Legacy = 1, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Standard, 4-bit mode. | ||||
|         /// </summary> | ||||
|         Standard = 2, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 8-bit mode. | ||||
|         /// </summary> | ||||
|         EightBit = 3, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 24-bit mode. | ||||
|         /// </summary> | ||||
|         TrueColor = 4, | ||||
|     } | ||||
| } | ||||
							
								
								
									
										83
									
								
								src/Spectre.Console/ConsoleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/Spectre.Console/ConsoleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| using System; | ||||
|  | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Contains extension methods for <see cref="IAnsiConsole"/>. | ||||
|     /// </summary> | ||||
|     public static class ConsoleExtensions | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Resets both colors and style for the console. | ||||
|         /// </summary> | ||||
|         /// <param name="console">The console to reset.</param> | ||||
|         public static void Reset(this IAnsiConsole console) | ||||
|         { | ||||
|             if (console is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(console)); | ||||
|             } | ||||
|  | ||||
|             console.ResetColors(); | ||||
|             console.ResetStyle(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Resets the current style back to the default one. | ||||
|         /// </summary> | ||||
|         /// <param name="console">The console to reset the style for.</param> | ||||
|         public static void ResetStyle(this IAnsiConsole console) | ||||
|         { | ||||
|             if (console is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(console)); | ||||
|             } | ||||
|  | ||||
|             console.Style = Styles.None; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Resets the foreground and background colors to the default ones. | ||||
|         /// </summary> | ||||
|         /// <param name="console">The console to reset colors for.</param> | ||||
|         public static void ResetColors(this IAnsiConsole console) | ||||
|         { | ||||
|             if (console is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(console)); | ||||
|             } | ||||
|  | ||||
|             console.Foreground = Color.Default; | ||||
|             console.Background = Color.Default; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Writes an empty line to the console. | ||||
|         /// </summary> | ||||
|         /// <param name="console">The console to write to.</param> | ||||
|         public static void WriteLine(this IAnsiConsole console) | ||||
|         { | ||||
|             if (console is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(console)); | ||||
|             } | ||||
|  | ||||
|             console.WriteLine(null); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Writes a line to the console. | ||||
|         /// </summary> | ||||
|         /// <param name="console">The console to write to.</param> | ||||
|         /// <param name="content">The content to write.</param> | ||||
|         public static void WriteLine(this IAnsiConsole console, string content) | ||||
|         { | ||||
|             if (console is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(console)); | ||||
|             } | ||||
|  | ||||
|             console.WriteLine(content); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										52
									
								
								src/Spectre.Console/IAnsiConsole.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/Spectre.Console/IAnsiConsole.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Represents a console. | ||||
|     /// </summary> | ||||
|     public interface IAnsiConsole | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Gets the console's capabilities. | ||||
|         /// </summary> | ||||
|         public AnsiConsoleCapabilities Capabilities { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the buffer width of the console. | ||||
|         /// </summary> | ||||
|         public int Width { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets the buffer height of the console. | ||||
|         /// </summary> | ||||
|         public int Height { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets or sets the current style. | ||||
|         /// </summary> | ||||
|         Styles Style { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets or sets the current foreground. | ||||
|         /// </summary> | ||||
|         Color Foreground { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Gets or sets the current background. | ||||
|         /// </summary> | ||||
|         Color Background { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Writes a string followed by a line terminator to the console. | ||||
|         /// </summary> | ||||
|         /// <param name="text">The string to write.</param> | ||||
|         void Write(string text); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Writes a string followed by a line terminator to the console. | ||||
|         /// </summary> | ||||
|         /// <param name="text"> | ||||
|         /// The string to write. If value is null, only the line terminator is written. | ||||
|         /// </param> | ||||
|         void WriteLine(string text); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										44
									
								
								src/Spectre.Console/Internal/Ansi/AnsiBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/Spectre.Console/Internal/Ansi/AnsiBuilder.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| using System.Linq; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal static class AnsiBuilder | ||||
|     { | ||||
|         public static string GetAnsi( | ||||
|             ColorSystem system, | ||||
|             string text, | ||||
|             Styles style, | ||||
|             Color foreground, | ||||
|             Color background) | ||||
|         { | ||||
|             var codes = AnsiStyleBuilder.GetAnsiCodes(style); | ||||
|  | ||||
|             // Got foreground? | ||||
|             if (foreground != Color.Default) | ||||
|             { | ||||
|                 codes = codes.Concat(AnsiColorBuilder.GetAnsiCodes(system, foreground, foreground: true)); | ||||
|             } | ||||
|  | ||||
|             // Got background? | ||||
|             if (background != Color.Default) | ||||
|             { | ||||
|                 codes = codes.Concat(AnsiColorBuilder.GetAnsiCodes(system, background, foreground: false)); | ||||
|             } | ||||
|  | ||||
|             var result = codes.ToArray(); | ||||
|             if (result.Length == 0) | ||||
|             { | ||||
|                 return text; | ||||
|             } | ||||
|  | ||||
|             var lol = string.Concat( | ||||
|                 "\u001b[", | ||||
|                 string.Join(";", result), | ||||
|                 "m", | ||||
|                 text, | ||||
|                 "\u001b[0m"); | ||||
|  | ||||
|             return lol; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										70
									
								
								src/Spectre.Console/Internal/Ansi/AnsiColorBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/Spectre.Console/Internal/Ansi/AnsiColorBuilder.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal static class AnsiColorBuilder | ||||
|     { | ||||
|         public static IEnumerable<byte> GetAnsiCodes(ColorSystem system, Color color, bool foreground) | ||||
|         { | ||||
|             return system switch | ||||
|             { | ||||
|                 ColorSystem.NoColors => Array.Empty<byte>(), // No colors | ||||
|                 ColorSystem.TrueColor => GetTrueColor(color, foreground), // 24-bit | ||||
|                 ColorSystem.EightBit => GetEightBit(color, foreground), // 8-bit | ||||
|                 ColorSystem.Standard => GetFourBit(color, foreground), // 4-bit | ||||
|                 ColorSystem.Legacy => GetThreeBit(color, foreground), // 3-bit | ||||
|                 _ => throw new InvalidOperationException("Could not determine ANSI color."), | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         private static IEnumerable<byte> GetThreeBit(Color color, bool foreground) | ||||
|         { | ||||
|             var number = color.Number; | ||||
|             if (number == null || color.Number >= 8) | ||||
|             { | ||||
|                 number = ColorPalette.ExactOrClosest(ColorSystem.Legacy, color).Number; | ||||
|             } | ||||
|  | ||||
|             Debug.Assert(number >= 0 && number < 8, "Invalid range for 4-bit color"); | ||||
|  | ||||
|             var mod = foreground ? 30 : 40; | ||||
|             return new byte[] { (byte)(number.Value + mod) }; | ||||
|         } | ||||
|  | ||||
|         private static IEnumerable<byte> GetFourBit(Color color, bool foreground) | ||||
|         { | ||||
|             var number = color.Number; | ||||
|             if (number == null || color.Number >= 16) | ||||
|             { | ||||
|                 number = ColorPalette.ExactOrClosest(ColorSystem.Standard, color).Number; | ||||
|             } | ||||
|  | ||||
|             Debug.Assert(number >= 0 && number < 16, "Invalid range for 4-bit color"); | ||||
|  | ||||
|             var mod = number < 8 ? (foreground ? 30 : 40) : (foreground ? 82 : 92); | ||||
|             return new byte[] { (byte)(number.Value + mod) }; | ||||
|         } | ||||
|  | ||||
|         private static IEnumerable<byte> GetEightBit(Color color, bool foreground) | ||||
|         { | ||||
|             var number = color.Number ?? ColorPalette.ExactOrClosest(ColorSystem.EightBit, color).Number; | ||||
|             Debug.Assert(number >= 0 && number <= 255, "Invalid range for 8-bit color"); | ||||
|  | ||||
|             var mod = foreground ? (byte)38 : (byte)48; | ||||
|             return new byte[] { mod, 5, (byte)number }; | ||||
|         } | ||||
|  | ||||
|         private static IEnumerable<byte> GetTrueColor(Color color, bool foreground) | ||||
|         { | ||||
|             if (color.Number != null) | ||||
|             { | ||||
|                 return GetEightBit(color, foreground); | ||||
|             } | ||||
|  | ||||
|             var mod = foreground ? (byte)38 : (byte)48; | ||||
|             return new byte[] { mod, 2, color.R, color.G, color.B }; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										129
									
								
								src/Spectre.Console/Internal/Ansi/AnsiDetector.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/Spectre.Console/Internal/Ansi/AnsiDetector.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using System.Linq; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Text.RegularExpressions; | ||||
|  | ||||
| ///////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // Portions of this code was ported from the supports-ansi project by Qingrong Ke | ||||
| // https://github.com/keqingrong/supports-ansi/blob/master/index.js | ||||
| ///////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal static class AnsiDetector | ||||
|     { | ||||
|         private static readonly Regex[] Regexes = new[] | ||||
|         { | ||||
|             new Regex("^xterm"), // xterm, PuTTY, Mintty | ||||
|             new Regex("^rxvt"), // RXVT | ||||
|             new Regex("^eterm"), // Eterm | ||||
|             new Regex("^screen"), // GNU screen, tmux | ||||
|             new Regex("tmux"), // tmux | ||||
|             new Regex("^vt100"), // DEC VT series | ||||
|             new Regex("^vt102"), // DEC VT series | ||||
|             new Regex("^vt220"), // DEC VT series | ||||
|             new Regex("^vt320"), // DEC VT series | ||||
|             new Regex("ansi"), // ANSI | ||||
|             new Regex("scoansi"), // SCO ANSI | ||||
|             new Regex("cygwin"), // Cygwin, MinGW | ||||
|             new Regex("linux"), // Linux console | ||||
|             new Regex("konsole"), // Konsole | ||||
|             new Regex("bvterm"), // Bitvise SSH Client | ||||
|         }; | ||||
|  | ||||
|         public static bool SupportsAnsi(bool upgrade) | ||||
|         { | ||||
|             // Github action doesn't setup a correct PTY but supports ANSI. | ||||
|             if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("GITHUB_ACTION"))) | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // Running on Windows? | ||||
|             if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||||
|             { | ||||
|                 // Running under ConEmu? | ||||
|                 var conEmu = Environment.GetEnvironmentVariable("ConEmuANSI"); | ||||
|                 if (!string.IsNullOrEmpty(conEmu) && conEmu.Equals("On", StringComparison.OrdinalIgnoreCase)) | ||||
|                 { | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 return Windows.SupportsAnsi(upgrade); | ||||
|             } | ||||
|  | ||||
|             // Check if the terminal is of type ANSI/VT100/xterm compatible. | ||||
|             var term = Environment.GetEnvironmentVariable("TERM"); | ||||
|             if (!string.IsNullOrWhiteSpace(term)) | ||||
|             { | ||||
|                 if (Regexes.Any(regex => regex.IsMatch(term))) | ||||
|                 { | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         [SuppressMessage("Design", "CA1060:Move pinvokes to native methods class")] | ||||
|         internal static class Windows | ||||
|         { | ||||
|             [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore")] | ||||
|             private const int STD_OUTPUT_HANDLE = -11; | ||||
|             [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore")] | ||||
|             private const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004; | ||||
|             [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore")] | ||||
|             private const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008; | ||||
|  | ||||
|             [DllImport("kernel32.dll")] | ||||
|             private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); | ||||
|  | ||||
|             [DllImport("kernel32.dll")] | ||||
|             private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); | ||||
|  | ||||
|             [DllImport("kernel32.dll", SetLastError = true)] | ||||
|             private static extern IntPtr GetStdHandle(int nStdHandle); | ||||
|  | ||||
|             [DllImport("kernel32.dll")] | ||||
|             public static extern uint GetLastError(); | ||||
|  | ||||
|             [SuppressMessage("Design", "CA1031:Do not catch general exception types")] | ||||
|             public static bool SupportsAnsi(bool upgrade) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     var @out = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
|                     if (!GetConsoleMode(@out, out uint mode)) | ||||
|                     { | ||||
|                         // Could not get console mode. | ||||
|                         return false; | ||||
|                     } | ||||
|  | ||||
|                     if ((mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0) | ||||
|                     { | ||||
|                         if (!upgrade) | ||||
|                         { | ||||
|                             return false; | ||||
|                         } | ||||
|  | ||||
|                         // Try enable ANSI support. | ||||
|                         mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN; | ||||
|                         if (!SetConsoleMode(@out, mode)) | ||||
|                         { | ||||
|                             // Enabling failed. | ||||
|                             return false; | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     return true; | ||||
|                 } | ||||
|                 catch | ||||
|                 { | ||||
|                     // All we know here is that we don't support ANSI. | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										56
									
								
								src/Spectre.Console/Internal/Ansi/AnsiStyleBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/Spectre.Console/Internal/Ansi/AnsiStyleBuilder.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| using System.Collections.Generic; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal static class AnsiStyleBuilder | ||||
|     { | ||||
|         // TODO: Rewrite this to not yield | ||||
|         public static IEnumerable<byte> GetAnsiCodes(Styles style) | ||||
|         { | ||||
|             if ((style & Styles.Bold) != 0) | ||||
|             { | ||||
|                 yield return 1; | ||||
|             } | ||||
|  | ||||
|             if ((style & Styles.Dim) != 0) | ||||
|             { | ||||
|                 yield return 2; | ||||
|             } | ||||
|  | ||||
|             if ((style & Styles.Italic) != 0) | ||||
|             { | ||||
|                 yield return 3; | ||||
|             } | ||||
|  | ||||
|             if ((style & Styles.Underline) != 0) | ||||
|             { | ||||
|                 yield return 4; | ||||
|             } | ||||
|  | ||||
|             if ((style & Styles.SlowBlink) != 0) | ||||
|             { | ||||
|                 yield return 5; | ||||
|             } | ||||
|  | ||||
|             if ((style & Styles.RapidBlink) != 0) | ||||
|             { | ||||
|                 yield return 6; | ||||
|             } | ||||
|  | ||||
|             if ((style & Styles.Invert) != 0) | ||||
|             { | ||||
|                 yield return 7; | ||||
|             } | ||||
|  | ||||
|             if ((style & Styles.Conceal) != 0) | ||||
|             { | ||||
|                 yield return 8; | ||||
|             } | ||||
|  | ||||
|             if ((style & Styles.Strikethrough) != 0) | ||||
|             { | ||||
|                 yield return 9; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										158
									
								
								src/Spectre.Console/Internal/Colors/ColorPalette.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/Spectre.Console/Internal/Colors/ColorPalette.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal static class ColorPalette | ||||
|     { | ||||
|         public static IReadOnlyList<Color> Legacy { get; } | ||||
|         public static IReadOnlyList<Color> Standard { get; } | ||||
|         public static IReadOnlyList<Color> EightBit { get; } | ||||
|  | ||||
|         static ColorPalette() | ||||
|         { | ||||
|             Legacy = new List<Color> | ||||
|             { | ||||
|                 Color.Black, Color.Maroon, Color.Green, Color.Olive, | ||||
|                 Color.Navy, Color.Purple, Color.Teal, Color.Silver, | ||||
|             }; | ||||
|  | ||||
|             Standard = new List<Color>(Legacy) | ||||
|             { | ||||
|                 Color.Grey, Color.Red, Color.Lime, Color.Yellow, | ||||
|                 Color.Blue, Color.Fuchsia, Color.Aqua, Color.White, | ||||
|             }; | ||||
|  | ||||
|             EightBit = new List<Color>(Standard) | ||||
|             { | ||||
|                 Color.Grey0, Color.NavyBlue, Color.DarkBlue, Color.Blue3, | ||||
|                 Color.Blue3_1, Color.Blue1, Color.DarkGreen, Color.DeepSkyBlue4, | ||||
|                 Color.DeepSkyBlue4_1, Color.DeepSkyBlue4_2, Color.DodgerBlue3, Color.DodgerBlue2, | ||||
|                 Color.Green4, Color.SpringGreen4, Color.Turquoise4, Color.DeepSkyBlue3, | ||||
|                 Color.DeepSkyBlue3_1, Color.DodgerBlue1, Color.Green3, Color.SpringGreen3, | ||||
|                 Color.DarkCyan, Color.LightSeaGreen, Color.DeepSkyBlue2, Color.DeepSkyBlue1, | ||||
|                 Color.Green3_1, Color.SpringGreen3_1, Color.SpringGreen2, Color.Cyan3, | ||||
|                 Color.DarkTurquoise, Color.Turquoise2, Color.Green1, Color.SpringGreen2_1, | ||||
|                 Color.SpringGreen1, Color.MediumSpringGreen, Color.Cyan2, Color.Cyan1, | ||||
|                 Color.DarkRed, Color.DeepPink4, Color.Purple4, Color.Purple4_1, | ||||
|                 Color.Purple3, Color.BlueViolet, Color.Orange4, Color.Grey37, | ||||
|                 Color.MediumPurple4, Color.SlateBlue3, Color.SlateBlue3_1, Color.RoyalBlue1, | ||||
|                 Color.Chartreuse4, Color.DarkSeaGreen4, Color.PaleTurquoise4, Color.SteelBlue, | ||||
|                 Color.SteelBlue3, Color.CornflowerBlue, Color.Chartreuse3, Color.DarkSeaGreen4_1, | ||||
|                 Color.CadetBlue, Color.CadetBlue_1, Color.SkyBlue3, Color.SteelBlue1, | ||||
|                 Color.Chartreuse3_1, Color.PaleGreen3, Color.SeaGreen3, Color.Aquamarine3, | ||||
|                 Color.MediumTurquoise, Color.SteelBlue1_1, Color.Chartreuse2, Color.SeaGreen2, | ||||
|                 Color.SeaGreen1, Color.SeaGreen1_1, Color.Aquamarine1, Color.DarkSlateGray2, | ||||
|                 Color.DarkRed_1, Color.DeepPink4_1, Color.DarkMagenta, Color.DarkMagenta_1, | ||||
|                 Color.DarkViolet, Color.Purple_1, Color.Orange4_1, Color.LightPink4, | ||||
|                 Color.Plum4, Color.MediumPurple3, Color.MediumPurple3_1, Color.SlateBlue1, | ||||
|                 Color.Yellow4, Color.Wheat4, Color.Grey53, Color.LightSlateGrey, | ||||
|                 Color.MediumPurple, Color.LightSlateBlue, Color.Yellow4_1, Color.DarkOliveGreen3, | ||||
|                 Color.DarkSeaGreen, Color.LightSkyBlue3, Color.LightSkyBlue3_1, Color.SkyBlue2, | ||||
|                 Color.Chartreuse2_1, Color.DarkOliveGreen3_1, Color.PaleGreen3_1, Color.DarkSeaGreen3, | ||||
|                 Color.DarkSlateGray3, Color.SkyBlue1, Color.Chartreuse1, Color.LightGreen, | ||||
|                 Color.LightGreen_1, Color.PaleGreen1, Color.Aquamarine1_1, Color.DarkSlateGray1, | ||||
|                 Color.Red3, Color.DeepPink4_2, Color.MediumVioletRed, Color.Magenta3, | ||||
|                 Color.DarkViolet_1, Color.Purple_2, Color.DarkOrange3, Color.IndianRed, | ||||
|                 Color.HotPink3, Color.MediumOrchid3, Color.MediumOrchid, Color.MediumPurple2, | ||||
|                 Color.DarkGoldenrod, Color.LightSalmon3, Color.RosyBrown, Color.Grey63, | ||||
|                 Color.MediumPurple2_1, Color.MediumPurple1, Color.Gold3, Color.DarkKhaki, | ||||
|                 Color.NavajoWhite3, Color.Grey69, Color.LightSteelBlue3, Color.LightSteelBlue, | ||||
|                 Color.Yellow3, Color.DarkOliveGreen3_2, Color.DarkSeaGreen3_1, Color.DarkSeaGreen2, | ||||
|                 Color.LightCyan3, Color.LightSkyBlue1, Color.GreenYellow, Color.DarkOliveGreen2, | ||||
|                 Color.PaleGreen1_1, Color.DarkSeaGreen2_1, Color.DarkSeaGreen1, Color.PaleTurquoise1, | ||||
|                 Color.Red3_1, Color.DeepPink3, Color.DeepPink3_1, Color.Magenta3_1, | ||||
|                 Color.Magenta3_2, Color.Magenta2, Color.DarkOrange3_1, Color.IndianRed_1, | ||||
|                 Color.HotPink3_1, Color.HotPink2, Color.Orchid, Color.MediumOrchid1, | ||||
|                 Color.Orange3, Color.LightSalmon3_1, Color.LightPink3, Color.Pink3, | ||||
|                 Color.Plum3, Color.Violet, Color.Gold3_1, Color.LightGoldenrod3, | ||||
|                 Color.Tan, Color.MistyRose3, Color.Thistle3, Color.Plum2, | ||||
|                 Color.Yellow3_1, Color.Khaki3, Color.LightGoldenrod2, Color.LightYellow3, | ||||
|                 Color.Grey84, Color.LightSteelBlue1, Color.Yellow2, Color.DarkOliveGreen1, | ||||
|                 Color.DarkOliveGreen1_1, Color.DarkSeaGreen1_1, Color.Honeydew2, Color.LightCyan1, | ||||
|                 Color.Red1, Color.DeepPink2, Color.DeepPink1, Color.DeepPink1_1, | ||||
|                 Color.Magenta2_1, Color.Magenta1, Color.OrangeRed1, Color.IndianRed1, | ||||
|                 Color.IndianRed1_1, Color.HotPink, Color.HotPink_1, Color.MediumOrchid1_1, | ||||
|                 Color.DarkOrange, Color.Salmon1, Color.LightCoral, Color.PaleVioletRed1, | ||||
|                 Color.Orchid2, Color.Orchid1, Color.Orange1, Color.SandyBrown, | ||||
|                 Color.LightSalmon1, Color.LightPink1, Color.Pink1, Color.Plum1, | ||||
|                 Color.Gold1, Color.LightGoldenrod2_1, Color.LightGoldenrod2_2, Color.NavajoWhite1, | ||||
|                 Color.MistyRose1, Color.Thistle1, Color.Yellow1, Color.LightGoldenrod1, | ||||
|                 Color.Khaki1, Color.Wheat1, Color.Cornsilk1, Color.Grey100, | ||||
|                 Color.Grey3, Color.Grey7, Color.Grey11, Color.Grey15, | ||||
|                 Color.Grey19, Color.Grey23, Color.Grey27, Color.Grey30, | ||||
|                 Color.Grey35, Color.Grey39, Color.Grey42, Color.Grey46, | ||||
|                 Color.Grey50, Color.Grey54, Color.Grey58, Color.Grey62, | ||||
|                 Color.Grey66, Color.Grey70, Color.Grey74, Color.Grey78, | ||||
|                 Color.Grey82, Color.Grey85, Color.Grey89, Color.Grey93, | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         internal static Color ExactOrClosest(ColorSystem system, Color color) | ||||
|         { | ||||
|             var exact = Exact(system, color); | ||||
|             if (exact != null) | ||||
|             { | ||||
|                 return exact.Value; | ||||
|             } | ||||
|  | ||||
|             return Closest(system, color); | ||||
|         } | ||||
|  | ||||
|         private static Color? Exact(ColorSystem system, Color color) | ||||
|         { | ||||
|             if (system == ColorSystem.TrueColor) | ||||
|             { | ||||
|                 return color; | ||||
|             } | ||||
|  | ||||
|             var palette = system switch | ||||
|             { | ||||
|                 ColorSystem.Legacy => Legacy, | ||||
|                 ColorSystem.Standard => Standard, | ||||
|                 ColorSystem.EightBit => EightBit, | ||||
|                 _ => throw new NotSupportedException(), | ||||
|             }; | ||||
|  | ||||
|             return palette | ||||
|                 .Where(c => c.Equals(color)) | ||||
|                 .Cast<Color?>() | ||||
|                 .FirstOrDefault(); | ||||
|         } | ||||
|  | ||||
|         private static Color Closest(ColorSystem system, Color color) | ||||
|         { | ||||
|             if (system == ColorSystem.TrueColor) | ||||
|             { | ||||
|                 return color; | ||||
|             } | ||||
|  | ||||
|             var palette = system switch | ||||
|             { | ||||
|                 ColorSystem.Legacy => Legacy, | ||||
|                 ColorSystem.Standard => Standard, | ||||
|                 ColorSystem.EightBit => EightBit, | ||||
|                 _ => throw new NotSupportedException(), | ||||
|             }; | ||||
|  | ||||
|             // https://stackoverflow.com/a/9085524 | ||||
|             static double Distance(Color first, Color second) | ||||
|             { | ||||
|                 var rmean = ((float)first.R + second.R) / 2; | ||||
|                 var r = first.R - second.R; | ||||
|                 var g = first.G - second.G; | ||||
|                 var b = first.B - second.B; | ||||
|                 return Math.Sqrt( | ||||
|                     ((int)((512 + rmean) * r * r) >> 8) | ||||
|                     + (4 * g * g) | ||||
|                     + ((int)((767 - rmean) * b * b) >> 8)); | ||||
|             } | ||||
|  | ||||
|             return Enumerable.Range(0, int.MaxValue) | ||||
|                 .Zip(palette, (id, other) => (Distance: Distance(other, color), Id: id, Color: other)) | ||||
|                 .OrderBy(x => x.Distance) | ||||
|                 .FirstOrDefault().Color; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/Spectre.Console/Internal/Colors/ColorSystemDetector.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/Spectre.Console/Internal/Colors/ColorSystemDetector.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| using System; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Text.RegularExpressions; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal static class ColorSystemDetector | ||||
|     { | ||||
|         // Adapted from https://github.com/willmcgugan/rich/blob/f0c29052c22d1e49579956a9207324d9072beed7/rich/console.py#L391 | ||||
|         // which I think is battletested enough to trust. | ||||
|         public static ColorSystem Detect(bool supportsAnsi) | ||||
|         { | ||||
|             if (Environment.GetEnvironmentVariables().Contains("NO_COLOR")) | ||||
|             { | ||||
|                 // No colors supported | ||||
|                 return ColorSystem.NoColors; | ||||
|             } | ||||
|             else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||||
|             { | ||||
|                 if (supportsAnsi) | ||||
|                 { | ||||
|                     var regex = new Regex("^Microsoft Windows (?'major'[0-9]*).(?'minor'[0-9]*).(?'build'[0-9]*)$"); | ||||
|                     var match = regex.Match(RuntimeInformation.OSDescription); | ||||
|                     if (match.Success && int.TryParse(match.Groups["major"].Value, out var major)) | ||||
|                     { | ||||
|                         if (major > 10) | ||||
|                         { | ||||
|                             // Future Patrik will thank me. | ||||
|                             return ColorSystem.TrueColor; | ||||
|                         } | ||||
|  | ||||
|                         if (major == 10 && int.TryParse(match.Groups["build"].Value, out var build) && build >= 15063) | ||||
|                         { | ||||
|                             return ColorSystem.TrueColor; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 var colorTerm = Environment.GetEnvironmentVariable("COLORTERM"); | ||||
|                 if (!string.IsNullOrWhiteSpace(colorTerm)) | ||||
|                 { | ||||
|                     if (colorTerm.Equals("truecolor", StringComparison.OrdinalIgnoreCase) || | ||||
|                        colorTerm.Equals("24bit", StringComparison.OrdinalIgnoreCase)) | ||||
|                     { | ||||
|                         return ColorSystem.TrueColor; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return ColorSystem.EightBit; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										73
									
								
								src/Spectre.Console/Internal/Composition/Composer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/Spectre.Console/Internal/Composition/Composer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| using System; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal sealed class Composer : IRenderable | ||||
|     { | ||||
|         private readonly BlockElement _root; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public int Length => _root.Length; | ||||
|  | ||||
|         public Composer() | ||||
|         { | ||||
|             _root = new BlockElement(); | ||||
|         } | ||||
|  | ||||
|         public static Composer New() | ||||
|         { | ||||
|             return new Composer(); | ||||
|         } | ||||
|  | ||||
|         public Composer Text(string text) | ||||
|         { | ||||
|             _root.Append(new TextElement(text)); | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public Composer Foreground(Color color, Action<Composer> action) | ||||
|         { | ||||
|             if (action is null) | ||||
|             { | ||||
|                 return this; | ||||
|             } | ||||
|  | ||||
|             var content = new Composer(); | ||||
|             action(content); | ||||
|             _root.Append(new ForegroundElement(color, content)); | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public Composer Background(Color color, Action<Composer> action) | ||||
|         { | ||||
|             if (action is null) | ||||
|             { | ||||
|                 return this; | ||||
|             } | ||||
|  | ||||
|             var content = new Composer(); | ||||
|             action(content); | ||||
|             _root.Append(new BackgroundElement(color, content)); | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public Composer Style(Styles style, Action<Composer> action) | ||||
|         { | ||||
|             if (action is null) | ||||
|             { | ||||
|                 return this; | ||||
|             } | ||||
|  | ||||
|             var content = new Composer(); | ||||
|             action(content); | ||||
|             _root.Append(new StyleElement(style, content)); | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public void Render(IAnsiConsole renderer) | ||||
|         { | ||||
|             _root.Render(renderer); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,35 @@ | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     [SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Not used (yet)")] | ||||
|     internal sealed class BackgroundElement : IRenderable | ||||
|     { | ||||
|         private readonly Color _color; | ||||
|         private readonly IRenderable _element; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public int Length => _element.Length; | ||||
|  | ||||
|         public BackgroundElement(Color color, IRenderable element) | ||||
|         { | ||||
|             _color = color; | ||||
|             _element = element ?? throw new ArgumentNullException(nameof(element)); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public void Render(IAnsiConsole renderer) | ||||
|         { | ||||
|             if (renderer is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(renderer)); | ||||
|             } | ||||
|  | ||||
|             using (renderer.PushColor(_color, foreground: false)) | ||||
|             { | ||||
|                 _element.Render(renderer); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,41 @@ | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     [SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Not used (yet)")] | ||||
|     internal sealed class BlockElement : IRenderable | ||||
|     { | ||||
|         private readonly List<IRenderable> _elements; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public int Length { get; private set; } | ||||
|  | ||||
|         public IReadOnlyList<IRenderable> Elements => _elements; | ||||
|  | ||||
|         public BlockElement() | ||||
|         { | ||||
|             _elements = new List<IRenderable>(); | ||||
|         } | ||||
|  | ||||
|         public BlockElement Append(IRenderable element) | ||||
|         { | ||||
|             if (element != null) | ||||
|             { | ||||
|                 _elements.Add(element); | ||||
|                 Length += element.Length; | ||||
|             } | ||||
|  | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public void Render(IAnsiConsole renderer) | ||||
|         { | ||||
|             foreach (var element in _elements) | ||||
|             { | ||||
|                 element.Render(renderer); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,35 @@ | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     [SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Not used (yet)")] | ||||
|     internal sealed class ForegroundElement : IRenderable | ||||
|     { | ||||
|         private readonly Color _color; | ||||
|         private readonly IRenderable _element; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public int Length => _element.Length; | ||||
|  | ||||
|         public ForegroundElement(Color color, IRenderable element) | ||||
|         { | ||||
|             _color = color; | ||||
|             _element = element ?? throw new ArgumentNullException(nameof(element)); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public void Render(IAnsiConsole renderer) | ||||
|         { | ||||
|             if (renderer is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(renderer)); | ||||
|             } | ||||
|  | ||||
|             using (renderer.PushColor(_color, foreground: true)) | ||||
|             { | ||||
|                 _element.Render(renderer); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,18 @@ | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     [SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Not used (yet)")] | ||||
|     internal sealed class LineBreakElement : IRenderable | ||||
|     { | ||||
|         /// <inheritdoc/> | ||||
|         public int Length => 0; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public void Render(IAnsiConsole renderer) | ||||
|         { | ||||
|             renderer.Write(Environment.NewLine); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,35 @@ | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     [SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Not used (yet)")] | ||||
|     internal sealed class StyleElement : IRenderable | ||||
|     { | ||||
|         private readonly Styles _style; | ||||
|         private readonly IRenderable _element; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public int Length => _element.Length; | ||||
|  | ||||
|         public StyleElement(Styles style, IRenderable element) | ||||
|         { | ||||
|             _style = style; | ||||
|             _element = element ?? throw new ArgumentNullException(nameof(element)); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public void Render(IAnsiConsole renderer) | ||||
|         { | ||||
|             if (renderer is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(renderer)); | ||||
|             } | ||||
|  | ||||
|             using (renderer.PushStyle(_style)) | ||||
|             { | ||||
|                 _element.Render(renderer); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,24 @@ | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     [SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Not used (yet)")] | ||||
|     internal sealed class TextElement : IRenderable | ||||
|     { | ||||
|         private readonly string _text; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public int Length => _text.Length; | ||||
|  | ||||
|         public TextElement(string text) | ||||
|         { | ||||
|             _text = text ?? throw new System.ArgumentNullException(nameof(text)); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public void Render(IAnsiConsole renderer) | ||||
|         { | ||||
|             renderer.Write(_text); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										19
									
								
								src/Spectre.Console/Internal/Composition/IRenderable.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/Spectre.Console/Internal/Composition/IRenderable.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Represents something that can be rendered to a console. | ||||
|     /// </summary> | ||||
|     internal interface IRenderable | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Gets the length of the element. | ||||
|         /// </summary> | ||||
|         int Length { get; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Renders the element using the specified renderer. | ||||
|         /// </summary> | ||||
|         /// <param name="console">The renderer to use.</param> | ||||
|         void Render(IAnsiConsole console); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										36
									
								
								src/Spectre.Console/Internal/ConsoleBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/Spectre.Console/Internal/ConsoleBuilder.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| using System; | ||||
| using Spectre.Console.Internal; | ||||
|  | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     internal static class ConsoleBuilder | ||||
|     { | ||||
|         public static IAnsiConsole Build(AnsiConsoleSettings settings) | ||||
|         { | ||||
|             if (settings is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(settings)); | ||||
|             } | ||||
|  | ||||
|             var buffer = settings.Out ?? System.Console.Out; | ||||
|  | ||||
|             var supportsAnsi = settings.Ansi == AnsiSupport.Detect | ||||
|                 ? AnsiDetector.SupportsAnsi(true) | ||||
|                 : settings.Ansi == AnsiSupport.Yes; | ||||
|  | ||||
|             var colorSystem = settings.ColorSystem == ColorSystemSupport.Detect | ||||
|                 ? ColorSystemDetector.Detect(supportsAnsi) | ||||
|                 : (ColorSystem)settings.ColorSystem; | ||||
|  | ||||
|             if (supportsAnsi) | ||||
|             { | ||||
|                 return new AnsiConsoleRenderer(buffer, colorSystem) | ||||
|                 { | ||||
|                     Style = Styles.None, | ||||
|                 }; | ||||
|             } | ||||
|  | ||||
|             return new FallbackConsoleRenderer(buffer, colorSystem); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										8
									
								
								src/Spectre.Console/Internal/Constants.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/Spectre.Console/Internal/Constants.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal static class Constants | ||||
|     { | ||||
|         public const int DefaultBufferWidth = 80; | ||||
|         public const int DefaultBufferHeight = 9001; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										101
									
								
								src/Spectre.Console/Internal/Extensions/ConsoleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/Spectre.Console/Internal/Extensions/ConsoleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal static class ConsoleExtensions | ||||
|     { | ||||
|         public static IDisposable PushColor(this IAnsiConsole console, Color color, bool foreground) | ||||
|         { | ||||
|             if (console is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(console)); | ||||
|             } | ||||
|  | ||||
|             var current = console.Foreground; | ||||
|             console.SetColor(color, foreground); | ||||
|             return new ColorScope(console, current, foreground); | ||||
|         } | ||||
|  | ||||
|         public static IDisposable PushStyle(this IAnsiConsole console, Styles style) | ||||
|         { | ||||
|             if (console is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(console)); | ||||
|             } | ||||
|  | ||||
|             var current = console.Style; | ||||
|             console.Style = style; | ||||
|             return new StyleScope(console, current); | ||||
|         } | ||||
|  | ||||
|         public static void SetColor(this IAnsiConsole console, Color color, bool foreground) | ||||
|         { | ||||
|             if (console is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(console)); | ||||
|             } | ||||
|  | ||||
|             if (foreground) | ||||
|             { | ||||
|                 console.Foreground = color; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 console.Background = color; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     internal sealed class ColorScope : IDisposable | ||||
|     { | ||||
|         private readonly IAnsiConsole _console; | ||||
|         private readonly Color _color; | ||||
|         private readonly bool _foreground; | ||||
|  | ||||
|         public ColorScope(IAnsiConsole console, Color color, bool foreground) | ||||
|         { | ||||
|             _console = console ?? throw new ArgumentNullException(nameof(console)); | ||||
|             _color = color; | ||||
|             _foreground = foreground; | ||||
|         } | ||||
|  | ||||
|         [SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations")] | ||||
|         [SuppressMessage("Performance", "CA1821:Remove empty Finalizers")] | ||||
|         ~ColorScope() | ||||
|         { | ||||
|             throw new InvalidOperationException("Color scope was not disposed."); | ||||
|         } | ||||
|  | ||||
|         public void Dispose() | ||||
|         { | ||||
|             GC.SuppressFinalize(this); | ||||
|             _console.SetColor(_color, _foreground); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     internal sealed class StyleScope : IDisposable | ||||
|     { | ||||
|         private readonly IAnsiConsole _console; | ||||
|         private readonly Styles _style; | ||||
|  | ||||
|         public StyleScope(IAnsiConsole console, Styles color) | ||||
|         { | ||||
|             _console = console ?? throw new ArgumentNullException(nameof(console)); | ||||
|             _style = color; | ||||
|         } | ||||
|  | ||||
|         [SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations")] | ||||
|         [SuppressMessage("Performance", "CA1821:Remove empty Finalizers")] | ||||
|         ~StyleScope() | ||||
|         { | ||||
|             throw new InvalidOperationException("Style scope was not disposed."); | ||||
|         } | ||||
|  | ||||
|         public void Dispose() | ||||
|         { | ||||
|             GC.SuppressFinalize(this); | ||||
|             _console.Style = _style; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,21 @@ | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using System.IO; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal static class TextWriterExtensions | ||||
|     { | ||||
|         [SuppressMessage("Design", "CA1031:Do not catch general exception types")] | ||||
|         public static bool IsStandardOut(this TextWriter writer) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 return writer == System.Console.Out; | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										100
									
								
								src/Spectre.Console/Internal/Rendering/AnsiConsoleRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/Spectre.Console/Internal/Rendering/AnsiConsoleRenderer.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| using System; | ||||
| using System.IO; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal sealed class AnsiConsoleRenderer : IAnsiConsole | ||||
|     { | ||||
|         private readonly TextWriter _out; | ||||
|         private readonly ColorSystem _system; | ||||
|  | ||||
|         public AnsiConsoleCapabilities Capabilities { get; } | ||||
|         public Styles Style { get; set; } | ||||
|         public Color Foreground { get; set; } | ||||
|         public Color Background { get; set; } | ||||
|  | ||||
|         public int Width | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (_out.IsStandardOut()) | ||||
|                 { | ||||
|                     return System.Console.BufferWidth; | ||||
|                 } | ||||
|  | ||||
|                 return Constants.DefaultBufferWidth; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public int Height | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (_out.IsStandardOut()) | ||||
|                 { | ||||
|                     return System.Console.BufferHeight; | ||||
|                 } | ||||
|  | ||||
|                 return Constants.DefaultBufferHeight; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public AnsiConsoleRenderer(TextWriter @out, ColorSystem system) | ||||
|         { | ||||
|             _out = @out ?? throw new ArgumentNullException(nameof(@out)); | ||||
|             _system = system; | ||||
|  | ||||
|             Capabilities = new AnsiConsoleCapabilities(true, system); | ||||
|             Foreground = Color.Default; | ||||
|             Background = Color.Default; | ||||
|             Style = Styles.None; | ||||
|         } | ||||
|  | ||||
|         public void Reset(bool colors, bool styles) | ||||
|         { | ||||
|             if (colors) | ||||
|             { | ||||
|                 Foreground = Color.Default; | ||||
|                 Background = Color.Default; | ||||
|             } | ||||
|  | ||||
|             if (styles) | ||||
|             { | ||||
|                 Style = Styles.None; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void Write(string text) | ||||
|         { | ||||
|             if (string.IsNullOrEmpty(text)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             _out.Write(AnsiBuilder.GetAnsi( | ||||
|                 _system, | ||||
|                 text, | ||||
|                 Style, | ||||
|                 Foreground, | ||||
|                 Background)); | ||||
|         } | ||||
|  | ||||
|         public void WriteLine(string text) | ||||
|         { | ||||
|             if (text == null) | ||||
|             { | ||||
|                 _out.WriteLine(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 _out.WriteLine( | ||||
|                     AnsiBuilder.GetAnsi( | ||||
|                         _system, | ||||
|                         text, | ||||
|                         Style, | ||||
|                         Foreground, | ||||
|                         Background)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,121 @@ | ||||
| using System; | ||||
| using System.IO; | ||||
|  | ||||
| namespace Spectre.Console.Internal | ||||
| { | ||||
|     internal sealed class FallbackConsoleRenderer : IAnsiConsole | ||||
|     { | ||||
|         private readonly ConsoleColor _defaultForeground; | ||||
|         private readonly ConsoleColor _defaultBackground; | ||||
|  | ||||
|         private readonly TextWriter _out; | ||||
|         private readonly ColorSystem _system; | ||||
|         private ConsoleColor _foreground; | ||||
|         private ConsoleColor _background; | ||||
|  | ||||
|         public AnsiConsoleCapabilities Capabilities { get; } | ||||
|  | ||||
|         public int Width | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (_out.IsStandardOut()) | ||||
|                 { | ||||
|                     return System.Console.BufferWidth; | ||||
|                 } | ||||
|  | ||||
|                 return Constants.DefaultBufferWidth; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public int Height | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (_out.IsStandardOut()) | ||||
|                 { | ||||
|                     return System.Console.BufferHeight; | ||||
|                 } | ||||
|  | ||||
|                 return Constants.DefaultBufferHeight; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public Styles Style { get; set; } | ||||
|  | ||||
|         public Color Foreground | ||||
|         { | ||||
|             get => _foreground; | ||||
|             set | ||||
|             { | ||||
|                 _foreground = Color.ToConsoleColor(value); | ||||
|                 if (_system != ColorSystem.NoColors && _out.IsStandardOut()) | ||||
|                 { | ||||
|                     if ((int)_foreground == -1) | ||||
|                     { | ||||
|                         _foreground = _defaultForeground; | ||||
|                     } | ||||
|  | ||||
|                     System.Console.ForegroundColor = _foreground; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public Color Background | ||||
|         { | ||||
|             get => _background; | ||||
|             set | ||||
|             { | ||||
|                 _background = Color.ToConsoleColor(value); | ||||
|                 if (_system != ColorSystem.NoColors && _out.IsStandardOut()) | ||||
|                 { | ||||
|                     if ((int)_background == -1) | ||||
|                     { | ||||
|                         _background = _defaultBackground; | ||||
|                     } | ||||
|  | ||||
|                     if (_system != ColorSystem.NoColors) | ||||
|                     { | ||||
|                         System.Console.BackgroundColor = _background; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public FallbackConsoleRenderer(TextWriter @out, ColorSystem system) | ||||
|         { | ||||
|             _out = @out; | ||||
|             _system = system; | ||||
|  | ||||
|             Capabilities = new AnsiConsoleCapabilities(false, _system); | ||||
|  | ||||
|             if (_out.IsStandardOut()) | ||||
|             { | ||||
|                 _defaultForeground = System.Console.ForegroundColor; | ||||
|                 _defaultBackground = System.Console.BackgroundColor; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 _defaultForeground = ConsoleColor.Gray; | ||||
|                 _defaultBackground = ConsoleColor.Black; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public void Write(string text) | ||||
|         { | ||||
|             _out.Write(text); | ||||
|         } | ||||
|  | ||||
|         public void WriteLine(string text) | ||||
|         { | ||||
|             if (text == null) | ||||
|             { | ||||
|                 _out.WriteLine(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 _out.WriteLine(text); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										21
									
								
								src/Spectre.Console/Spectre.Console.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/Spectre.Console/Spectre.Console.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>netstandard2.0</TargetFramework> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <AdditionalFiles Include="..\stylecop.json" Link="stylecop.json" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <Compile Update="Color.*.cs"> | ||||
|       <DependentUpon>Color.cs</DependentUpon> | ||||
|     </Compile> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="System.Memory" Version="4.5.4" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
							
								
								
									
										75
									
								
								src/Spectre.Console/Styles.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/Spectre.Console/Styles.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| using System; | ||||
|  | ||||
| namespace Spectre.Console | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Represents a style. | ||||
|     /// </summary> | ||||
|     /// <remarks> | ||||
|     /// Support for different styles is up to the terminal. | ||||
|     /// </remarks> | ||||
|     [Flags] | ||||
|     public enum Styles | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// No style. | ||||
|         /// </summary> | ||||
|         None = 0, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Bold text. | ||||
|         /// Not supported in every environment. | ||||
|         /// </summary> | ||||
|         Bold = 1 << 0, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Dim or faint text. | ||||
|         /// Not supported in every environment. | ||||
|         /// </summary> | ||||
|         Dim = 1 << 1, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Italic text. | ||||
|         /// Not supported in every environment. | ||||
|         /// </summary> | ||||
|         Italic = 1 << 2, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Underlined text. | ||||
|         /// Not supported in every environment. | ||||
|         /// </summary> | ||||
|         Underline = 1 << 3, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Swaps the foreground and background colors. | ||||
|         /// Not supported in every environment. | ||||
|         /// </summary> | ||||
|         Invert = 1 << 4, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Hides the text. | ||||
|         /// Not supported in every environment. | ||||
|         /// </summary> | ||||
|         Conceal = 1 << 5, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Makes text blink. | ||||
|         /// Normally less than 150 blinks per minute. | ||||
|         /// Not supported in every environment. | ||||
|         /// </summary> | ||||
|         SlowBlink = 1 << 6, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Makes text blink. | ||||
|         /// Normally more than 150 blinks per minute. | ||||
|         /// Not supported in every environment. | ||||
|         /// </summary> | ||||
|         RapidBlink = 1 << 7, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Shows text with a horizontal line through the center. | ||||
|         /// Not supported in every environment. | ||||
|         /// </summary> | ||||
|         Strikethrough = 1 << 8, | ||||
|     } | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/stylecop.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/stylecop.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| { | ||||
|   "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", | ||||
|   "settings": { | ||||
|     "documentationRules": { | ||||
|       "documentExposedElements": true, | ||||
|       "documentInternalElements": false, | ||||
|       "documentPrivateElements": false, | ||||
|       "documentPrivateFields": false | ||||
|     }, | ||||
|     "layoutRules": { | ||||
|       "newlineAtEndOfFile": "allow", | ||||
|       "allowConsecutiveUsings": true | ||||
|     }, | ||||
|     "orderingRules": { | ||||
|       "usingDirectivesPlacement": "outsideNamespace", | ||||
|       "systemUsingDirectivesFirst": true, | ||||
|       "elementOrder": [ | ||||
|         "kind", | ||||
|         "accessibility", | ||||
|         "constant", | ||||
|         "static", | ||||
|         "readonly" | ||||
|       ] | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Patrik Svensson
					Patrik Svensson