diff --git a/examples/Links/Links.csproj b/examples/Links/Links.csproj
new file mode 100644
index 0000000..5b35d6f
--- /dev/null
+++ b/examples/Links/Links.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ netcoreapp3.1
+ false
+ Demonstrates how to render links in a console.
+
+
+
+
+
+
+
diff --git a/examples/Links/Program.cs b/examples/Links/Program.cs
new file mode 100644
index 0000000..6ceaa6a
--- /dev/null
+++ b/examples/Links/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using Spectre.Console;
+
+namespace Links
+{
+ public static class Program
+ {
+ public static void Main()
+ {
+ if (AnsiConsole.Capabilities.SupportLinks)
+ {
+ AnsiConsole.MarkupLine("[link=https://patriksvensson.se]Click to visit my blog[/]!");
+ }
+ else
+ {
+ AnsiConsole.MarkupLine("[red]It looks like your terminal doesn't support links[/]");
+ AnsiConsole.WriteLine();
+ AnsiConsole.MarkupLine("[yellow](╯°□°)╯[/]︵ [blue]┻━┻[/]");
+ }
+ }
+ }
+}
diff --git a/src/Spectre.Console.Tests/Extensions/ConsoleExtensions.cs b/src/Spectre.Console.Tests/Extensions/ConsoleExtensions.cs
deleted file mode 100644
index 01282ee..0000000
--- a/src/Spectre.Console.Tests/Extensions/ConsoleExtensions.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-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;
- }
- }
- }
-}
diff --git a/src/Spectre.Console.Tests/Extensions/StyleExtensions.cs b/src/Spectre.Console.Tests/Extensions/StyleExtensions.cs
new file mode 100644
index 0000000..92af879
--- /dev/null
+++ b/src/Spectre.Console.Tests/Extensions/StyleExtensions.cs
@@ -0,0 +1,15 @@
+namespace Spectre.Console.Tests
+{
+ internal static class StyleExtensions
+ {
+ public static Style SetColor(this Style style, Color color, bool foreground)
+ {
+ if (foreground)
+ {
+ return style.WithForeground(color);
+ }
+
+ return style.WithBackground(color);
+ }
+ }
+}
diff --git a/src/Spectre.Console.Tests/Fixtures/ConsoleWithWidth.cs b/src/Spectre.Console.Tests/Fixtures/ConsoleWithWidth.cs
index dde146c..4ba1bda 100644
--- a/src/Spectre.Console.Tests/Fixtures/ConsoleWithWidth.cs
+++ b/src/Spectre.Console.Tests/Fixtures/ConsoleWithWidth.cs
@@ -1,4 +1,4 @@
-using System.Text;
+using System.Text;
namespace Spectre.Console.Tests
{
@@ -13,19 +13,15 @@ namespace Spectre.Console.Tests
public Encoding Encoding => _console.Encoding;
- public Decoration Decoration { get => _console.Decoration; set => _console.Decoration = value; }
- public Color Foreground { get => _console.Foreground; set => _console.Foreground = value; }
- public Color Background { get => _console.Background; set => _console.Background = value; }
-
public ConsoleWithWidth(IAnsiConsole console, int width)
{
_console = console;
Width = width;
}
- public void Write(string text)
+ public void Write(string text, Style style)
{
- _console.Write(text);
+ _console.Write(text, style);
}
}
}
diff --git a/src/Spectre.Console.Tests/Fixtures/PlainConsole.cs b/src/Spectre.Console.Tests/Fixtures/PlainConsole.cs
index 887d983..af2f169 100644
--- a/src/Spectre.Console.Tests/Fixtures/PlainConsole.cs
+++ b/src/Spectre.Console.Tests/Fixtures/PlainConsole.cs
@@ -16,6 +16,7 @@ namespace Spectre.Console.Tests
public Decoration Decoration { get; set; }
public Color Foreground { get; set; }
public Color Background { get; set; }
+ public string Link { get; set; }
public StringWriter Writer { get; }
public string RawOutput => Writer.ToString();
@@ -39,7 +40,7 @@ namespace Spectre.Console.Tests
Writer.Dispose();
}
- public void Write(string text)
+ public void Write(string text, Style style)
{
Writer.Write(text);
}
diff --git a/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Colors.cs b/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Colors.cs
index d476ee0..161e58f 100644
--- a/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Colors.cs
+++ b/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Colors.cs
@@ -14,10 +14,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor);
- fixture.Console.SetColor(new Color(128, 0, 128), foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(new Color(128, 0, 128), foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -30,10 +29,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor);
- fixture.Console.SetColor(Color.Purple, foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(Color.Purple, foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -49,10 +47,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.EightBit);
- fixture.Console.SetColor(Color.Olive, foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(Color.Olive, foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -65,10 +62,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.EightBit);
- fixture.Console.SetColor(new Color(128, 128, 0), foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(new Color(128, 128, 0), foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -81,10 +77,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.EightBit);
- fixture.Console.SetColor(new Color(126, 127, 0), foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(new Color(126, 127, 0), foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -100,10 +95,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
- fixture.Console.SetColor(Color.Olive, foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(Color.Olive, foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -121,10 +115,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
- fixture.Console.SetColor(new Color(r, g, b), foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(new Color(r, g, b), foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -142,10 +135,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
- fixture.Console.SetColor(new Color(r, g, b), foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(new Color(r, g, b), foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -161,10 +153,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Legacy);
- fixture.Console.SetColor(Color.Olive, foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(Color.Olive, foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -182,10 +173,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Legacy);
- fixture.Console.SetColor(new Color(r, g, b), foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(new Color(r, g, b), foreground));
// Then
fixture.Output.ShouldBe(expected);
@@ -203,10 +193,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Legacy);
- fixture.Console.SetColor(new Color(r, g, b), foreground);
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write("Hello", new Style().SetColor(new Color(r, g, b), foreground));
// Then
fixture.Output.ShouldBe(expected);
diff --git a/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Markup.cs b/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Markup.cs
index 1303104..5f0136e 100644
--- a/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Markup.cs
+++ b/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Markup.cs
@@ -13,6 +13,8 @@ namespace Spectre.Console.Tests.Unit
[Theory]
[InlineData("[yellow]Hello[/]", "[93mHello[0m")]
[InlineData("[yellow]Hello [italic]World[/]![/]", "[93mHello [0m[3;93mWorld[0m[93m![0m")]
+ [InlineData("[link=https://patriksvensson.se]Click to visit my blog[/]", "]8;id=2026695893;https://patriksvensson.se\\Click to visit my blog]8;;\\")]
+ [InlineData("[link]https://patriksvensson.se[/]", "]8;id=2026695893;https://patriksvensson.se\\https://patriksvensson.se]8;;\\")]
public void Should_Output_Expected_Ansi_For_Markup(string markup, string expected)
{
// Given
diff --git a/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Style.cs b/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Style.cs
index ced16e6..5c3fb53 100644
--- a/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Style.cs
+++ b/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.Style.cs
@@ -19,10 +19,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor);
- fixture.Console.Decoration = decoration;
// When
- fixture.Console.Write("Hello World");
+ fixture.Console.Write("Hello World", Style.WithDecoration(decoration));
// Then
fixture.Output.ShouldBe(expected);
@@ -35,10 +34,9 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor);
- fixture.Console.Decoration = decoration;
// When
- fixture.Console.Write("Hello World");
+ fixture.Console.Write("Hello World", Style.WithDecoration(decoration));
// Then
fixture.Output.ShouldBe(expected);
diff --git a/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.cs b/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.cs
index d8f0fee..ebfe152 100644
--- a/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.cs
+++ b/src/Spectre.Console.Tests/Unit/AnsiConsoleTests.cs
@@ -1,5 +1,4 @@
using System;
-using System.Globalization;
using Shouldly;
using Xunit;
@@ -12,12 +11,13 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
- fixture.Console.Foreground = Color.RoyalBlue1;
- fixture.Console.Background = Color.NavajoWhite1;
- fixture.Console.Decoration = Decoration.Italic;
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write(
+ "Hello",
+ Style.WithForeground(Color.RoyalBlue1)
+ .WithBackground(Color.NavajoWhite1)
+ .WithDecoration(Decoration.Italic));
// Then
fixture.Output.ShouldBe("\u001b[3;90;47mHello\u001b[0m");
@@ -28,12 +28,13 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
- fixture.Console.Foreground = Color.Default;
- fixture.Console.Background = Color.NavajoWhite1;
- fixture.Console.Decoration = Decoration.Italic;
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write(
+ "Hello",
+ Style.WithForeground(Color.Default)
+ .WithBackground(Color.NavajoWhite1)
+ .WithDecoration(Decoration.Italic));
// Then
fixture.Output.ShouldBe("\u001b[3;47mHello\u001b[0m");
@@ -44,12 +45,13 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
- fixture.Console.Foreground = Color.RoyalBlue1;
- fixture.Console.Background = Color.Default;
- fixture.Console.Decoration = Decoration.Italic;
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write(
+ "Hello",
+ Style.WithForeground(Color.RoyalBlue1)
+ .WithBackground(Color.Default)
+ .WithDecoration(Decoration.Italic));
// Then
fixture.Output.ShouldBe("\u001b[3;90mHello\u001b[0m");
@@ -60,190 +62,18 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
- fixture.Console.Foreground = Color.RoyalBlue1;
- fixture.Console.Background = Color.NavajoWhite1;
- fixture.Console.Decoration = Decoration.None;
// When
- fixture.Console.Write("Hello");
+ fixture.Console.Write(
+ "Hello",
+ Style.WithForeground(Color.RoyalBlue1)
+ .WithBackground(Color.NavajoWhite1)
+ .WithDecoration(Decoration.None));
// Then
fixture.Output.ShouldBe("\u001b[90;47mHello\u001b[0m");
}
- public sealed class Write
- {
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Int32_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(CultureInfo.InvariantCulture, 32);
-
- // Then
- fixture.Output.ShouldBe("32");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_UInt32_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(CultureInfo.InvariantCulture, 32U);
-
- // Then
- fixture.Output.ShouldBe("32");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Int64_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(CultureInfo.InvariantCulture, 32L);
-
- // Then
- fixture.Output.ShouldBe("32");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_UInt64_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(CultureInfo.InvariantCulture, 32UL);
-
- // Then
- fixture.Output.ShouldBe("32");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Single_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(CultureInfo.InvariantCulture, 32.432F);
-
- // Then
- fixture.Output.ShouldBe("32.432");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Double_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(CultureInfo.InvariantCulture, (double)32.432);
-
- // Then
- fixture.Output.ShouldBe("32.432");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Decimal_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(CultureInfo.InvariantCulture, 32.432M);
-
- // Then
- fixture.Output.ShouldBe("32.432");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Boolean_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(CultureInfo.InvariantCulture, true);
-
- // Then
- fixture.Output.ShouldBe("True");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Char_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(CultureInfo.InvariantCulture, 'P');
-
- // Then
- fixture.Output.ShouldBe("P");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Char_Array_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(
- CultureInfo.InvariantCulture,
- new[] { 'P', 'a', 't', 'r', 'i', 'k' });
-
- // Then
- fixture.Output.ShouldBe("Patrik");
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Formatted_String_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.Write(
- CultureInfo.InvariantCulture,
- "Hello {0}! {1}",
- "World", 32);
-
- // Then
- fixture.Output.ShouldBe("Hello World! 32");
- }
- }
-
public sealed class WriteLine
{
[Fact]
@@ -253,10 +83,8 @@ namespace Spectre.Console.Tests.Unit
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, AnsiSupport.Yes);
// When
- fixture.Console.Background = ConsoleColor.Red;
- fixture.Console.WriteLine("Hello");
- fixture.Console.Background = ConsoleColor.Green;
- fixture.Console.WriteLine("World");
+ fixture.Console.WriteLine("Hello", Style.WithBackground(ConsoleColor.Red));
+ fixture.Console.WriteLine("World", Style.WithBackground(ConsoleColor.Green));
// Then
fixture.Output.NormalizeLineEndings()
@@ -270,183 +98,12 @@ namespace Spectre.Console.Tests.Unit
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, AnsiSupport.Yes);
// When
- fixture.Console.Background = ConsoleColor.Red;
- fixture.Console.WriteLine("Hello\nWorld");
+ fixture.Console.WriteLine("Hello\nWorld", Style.WithBackground(ConsoleColor.Red));
// Then
fixture.Output.NormalizeLineEndings()
.ShouldBe("[101mHello[0m\n[101mWorld[0m\n");
}
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Int32_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32);
-
- // Then
- fixture.Output.ShouldBe("32" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_UInt32_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32U);
-
- // Then
- fixture.Output.ShouldBe("32" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Int64_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32L);
-
- // Then
- fixture.Output.ShouldBe("32" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_UInt64_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32UL);
-
- // Then
- fixture.Output.ShouldBe("32" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Single_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32.432F);
-
- // Then
- fixture.Output.ShouldBe("32.432" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Double_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(CultureInfo.InvariantCulture, (double)32.432);
-
- // Then
- fixture.Output.ShouldBe("32.432" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Decimal_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32.432M);
-
- // Then
- fixture.Output.ShouldBe("32.432" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Boolean_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(CultureInfo.InvariantCulture, true);
-
- // Then
- fixture.Output.ShouldBe("True" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Char_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(CultureInfo.InvariantCulture, 'P');
-
- // Then
- fixture.Output.ShouldBe("P" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Char_Array_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(
- CultureInfo.InvariantCulture,
- new[] { 'P', 'a', 't', 'r', 'i', 'k' });
-
- // Then
- fixture.Output.ShouldBe("Patrik" + Environment.NewLine);
- }
-
- [Theory]
- [InlineData(AnsiSupport.Yes)]
- [InlineData(AnsiSupport.No)]
- public void Should_Write_Formatted_String_With_Format_Provider(AnsiSupport ansi)
- {
- // Given
- var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
-
- // When
- fixture.Console.WriteLine(
- CultureInfo.InvariantCulture,
- "Hello {0}! {1}",
- "World", 32);
-
- // Then
- fixture.Output.ShouldBe("Hello World! 32" + Environment.NewLine);
- }
}
}
}
diff --git a/src/Spectre.Console.Tests/Unit/StyleTests.cs b/src/Spectre.Console.Tests/Unit/StyleTests.cs
index dda6994..9b246ac 100644
--- a/src/Spectre.Console.Tests/Unit/StyleTests.cs
+++ b/src/Spectre.Console.Tests/Unit/StyleTests.cs
@@ -11,7 +11,7 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic);
- var other = new Style(Color.Green, Color.Silver, Decoration.Underline);
+ var other = new Style(Color.Green, Color.Silver, Decoration.Underline, "https://example.com");
// When
var result = first.Combine(other);
@@ -20,6 +20,77 @@ namespace Spectre.Console.Tests.Unit
result.Foreground.ShouldBe(Color.Green);
result.Background.ShouldBe(Color.Silver);
result.Decoration.ShouldBe(Decoration.Bold | Decoration.Italic | Decoration.Underline);
+ result.Link.ShouldBe("https://example.com");
+ }
+
+ [Fact]
+ public void Should_Consider_Two_Identical_Styles_Equal()
+ {
+ // Given
+ var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
+ var second = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
+
+ // When
+ var result = first.Equals(second);
+
+ // Then
+ result.ShouldBeTrue();
+ }
+
+ [Fact]
+ public void Should_Not_Consider_Two_Styles_With_Different_Foreground_Colors_Equal()
+ {
+ // Given
+ var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
+ var second = new Style(Color.Blue, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
+
+ // When
+ var result = first.Equals(second);
+
+ // Then
+ result.ShouldBeFalse();
+ }
+
+ [Fact]
+ public void Should_Not_Consider_Two_Styles_With_Different_Background_Colors_Equal()
+ {
+ // Given
+ var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
+ var second = new Style(Color.White, Color.Blue, Decoration.Bold | Decoration.Italic, "http://example.com");
+
+ // When
+ var result = first.Equals(second);
+
+ // Then
+ result.ShouldBeFalse();
+ }
+
+ [Fact]
+ public void Should_Not_Consider_Two_Styles_With_Different_Decorations_Equal()
+ {
+ // Given
+ var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
+ var second = new Style(Color.White, Color.Yellow, Decoration.Bold, "http://example.com");
+
+ // When
+ var result = first.Equals(second);
+
+ // Then
+ result.ShouldBeFalse();
+ }
+
+ [Fact]
+ public void Should_Not_Consider_Two_Styles_With_Different_Links_Equal()
+ {
+ // Given
+ var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
+ var second = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://foo.com");
+
+ // When
+ var result = first.Equals(second);
+
+ // Then
+ result.ShouldBeFalse();
}
public sealed class TheParseMethod
@@ -62,16 +133,36 @@ namespace Spectre.Console.Tests.Unit
}
[Fact]
- public void Should_Parse_Text_And_Decoration()
+ public void Should_Parse_Link_Without_Address()
{
// Given, When
- var result = Style.Parse("bold underline blue on green");
+ var result = Style.Parse("link");
// Then
result.ShouldNotBeNull();
- result.Decoration.ShouldBe(Decoration.Bold | Decoration.Underline);
- result.Foreground.ShouldBe(Color.Blue);
- result.Background.ShouldBe(Color.Green);
+ result.Link.ShouldBe("https://emptylink");
+ }
+
+ [Fact]
+ public void Should_Parse_Link()
+ {
+ // Given, When
+ var result = Style.Parse("link=https://example.com");
+
+ // Then
+ result.ShouldNotBeNull();
+ result.Link.ShouldBe("https://example.com");
+ }
+
+ [Fact]
+ public void Should_Throw_If_Link_Is_Set_Twice()
+ {
+ // Given, When
+ var result = Record.Exception(() => Style.Parse("link=https://example.com link=https://example.com"));
+
+ // Then
+ result.ShouldBeOfType();
+ result.Message.ShouldBe("A link has already been set.");
}
[Fact]
@@ -131,6 +222,20 @@ namespace Spectre.Console.Tests.Unit
result.Message.ShouldBe("Could not find color 'lol'.");
}
+ [Fact]
+ public void Should_Parse_Colors_And_Decoration_And_Link()
+ {
+ // Given, When
+ var result = Style.Parse("link=https://example.com bold underline blue on green");
+
+ // Then
+ result.ShouldNotBeNull();
+ result.Decoration.ShouldBe(Decoration.Bold | Decoration.Underline);
+ result.Foreground.ShouldBe(Color.Blue);
+ result.Background.ShouldBe(Color.Green);
+ result.Link.ShouldBe("https://example.com");
+ }
+
[Theory]
[InlineData("#FF0000 on #0000FF")]
[InlineData("#F00 on #00F")]
diff --git a/src/Spectre.Console.sln b/src/Spectre.Console.sln
index 1341d73..5b115ac 100644
--- a/src/Spectre.Console.sln
+++ b/src/Spectre.Console.sln
@@ -29,7 +29,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Columns", "..\examples\Colu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Info", "..\examples\Info\Info.csproj", "{225CE0D4-06AB-411A-8D29-707504FE53B3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borders", "..\examples\Borders\Borders.csproj", "{094245E6-4C94-485D-B5AC-3153E878B112}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Borders", "..\examples\Borders\Borders.csproj", "{094245E6-4C94-485D-B5AC-3153E878B112}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Links", "..\examples\Links\Links.csproj", "{6AF8C93B-AA41-4F44-8B1B-B8D166576174}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -149,6 +151,18 @@ Global
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x64.Build.0 = Release|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.ActiveCfg = Release|Any CPU
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.Build.0 = Release|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x64.Build.0 = Debug|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x86.Build.0 = Debug|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x64.ActiveCfg = Release|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x64.Build.0 = Release|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x86.ActiveCfg = Release|Any CPU
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -161,6 +175,7 @@ Global
{33357599-C79D-4299-888F-634E2C3EACEF} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{225CE0D4-06AB-411A-8D29-707504FE53B3} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{094245E6-4C94-485D-B5AC-3153E878B112} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
+ {6AF8C93B-AA41-4F44-8B1B-B8D166576174} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C}
diff --git a/src/Spectre.Console/AnsiConsole.State.cs b/src/Spectre.Console/AnsiConsole.State.cs
new file mode 100644
index 0000000..31e0503
--- /dev/null
+++ b/src/Spectre.Console/AnsiConsole.State.cs
@@ -0,0 +1,85 @@
+using System;
+using System.IO;
+using Spectre.Console.Internal;
+
+namespace Spectre.Console
+{
+ ///
+ /// A console capable of writing ANSI escape sequences.
+ ///
+ public static partial class AnsiConsole
+ {
+ private static ConsoleColor _defaultForeground;
+ private static ConsoleColor _defaultBackground;
+
+ internal static Style CurrentStyle { get; private set; } = Style.Plain;
+ internal static bool Created { get; private set; }
+
+ ///
+ /// Gets or sets the foreground color.
+ ///
+ public static Color Foreground
+ {
+ get => CurrentStyle.Foreground;
+ set => CurrentStyle = CurrentStyle.WithForeground(value);
+ }
+
+ ///
+ /// Gets or sets the background color.
+ ///
+ public static Color Background
+ {
+ get => CurrentStyle.Background;
+ set => CurrentStyle = CurrentStyle.WithBackground(value);
+ }
+
+ ///
+ /// Gets or sets the text decoration.
+ ///
+ public static Decoration Decoration
+ {
+ get => CurrentStyle.Decoration;
+ set => CurrentStyle = CurrentStyle.WithDecoration(value);
+ }
+
+ internal static void Initialize(TextWriter? @out)
+ {
+ if (@out?.IsStandardOut() ?? false)
+ {
+ Foreground = _defaultForeground = System.Console.ForegroundColor;
+ Background = _defaultBackground = System.Console.BackgroundColor;
+ }
+ else
+ {
+ Foreground = _defaultForeground = Color.Silver;
+ Background = _defaultBackground = Color.Black;
+ }
+ }
+
+ ///
+ /// Resets colors and text decorations.
+ ///
+ public static void Reset()
+ {
+ ResetColors();
+ ResetDecoration();
+ }
+
+ ///
+ /// Resets the current applied text decorations.
+ ///
+ public static void ResetDecoration()
+ {
+ Decoration = Decoration.None;
+ }
+
+ ///
+ /// Resets the current applied foreground and background colors.
+ ///
+ public static void ResetColors()
+ {
+ Foreground = _defaultForeground;
+ Background = _defaultBackground;
+ }
+ }
+}
diff --git a/src/Spectre.Console/AnsiConsole.Write.cs b/src/Spectre.Console/AnsiConsole.Write.cs
index aa9cdb6..f974cb5 100644
--- a/src/Spectre.Console/AnsiConsole.Write.cs
+++ b/src/Spectre.Console/AnsiConsole.Write.cs
@@ -14,7 +14,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(string value)
{
- Console.Write(value);
+ Console.Write(value, CurrentStyle);
}
///
@@ -24,7 +24,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(int value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -35,7 +35,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, int value)
{
- Console.Write(value.ToString(provider));
+ Console.Write(value.ToString(provider), CurrentStyle);
}
///
@@ -45,7 +45,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(uint value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -56,7 +56,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, uint value)
{
- Console.Write(value.ToString(provider));
+ Console.Write(value.ToString(provider), CurrentStyle);
}
///
@@ -66,7 +66,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(long value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -77,7 +77,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, long value)
{
- Console.Write(value.ToString(provider));
+ Console.Write(value.ToString(provider), CurrentStyle);
}
///
@@ -87,7 +87,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(ulong value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -98,7 +98,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, ulong value)
{
- Console.Write(value.ToString(provider));
+ Console.Write(value.ToString(provider), CurrentStyle);
}
///
@@ -108,7 +108,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(float value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -119,7 +119,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, float value)
{
- Console.Write(value.ToString(provider));
+ Console.Write(value.ToString(provider), CurrentStyle);
}
///
@@ -129,7 +129,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(double value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -140,7 +140,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, double value)
{
- Console.Write(value.ToString(provider));
+ Console.Write(value.ToString(provider), CurrentStyle);
}
///
@@ -149,7 +149,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(decimal value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -159,7 +159,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, decimal value)
{
- Console.Write(value.ToString(provider));
+ Console.Write(value.ToString(provider), CurrentStyle);
}
///
@@ -168,7 +168,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(bool value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -178,7 +178,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, bool value)
{
- Console.Write(value.ToString(provider));
+ Console.Write(value.ToString(provider), CurrentStyle);
}
///
@@ -187,7 +187,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(char value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -197,7 +197,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, char value)
{
- Console.Write(value.ToString(provider));
+ Console.Write(value.ToString(provider), CurrentStyle);
}
///
@@ -206,7 +206,7 @@ namespace Spectre.Console
/// The value to write.
public static void Write(char[] value)
{
- Console.Write(CultureInfo.CurrentCulture, value);
+ Write(CultureInfo.CurrentCulture, value);
}
///
@@ -216,7 +216,15 @@ namespace Spectre.Console
/// The value to write.
public static void Write(IFormatProvider provider, char[] value)
{
- Console.Write(provider, value);
+ if (value is null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ for (var index = 0; index < value.Length; index++)
+ {
+ Console.Write(value[index].ToString(provider), CurrentStyle);
+ }
}
///
@@ -227,7 +235,7 @@ namespace Spectre.Console
/// An array of objects to write.
public static void Write(string format, params object[] args)
{
- Console.Write(CultureInfo.CurrentCulture, format, args);
+ Write(CultureInfo.CurrentCulture, format, args);
}
///
@@ -239,7 +247,7 @@ namespace Spectre.Console
/// An array of objects to write.
public static void Write(IFormatProvider provider, string format, params object[] args)
{
- Console.Write(string.Format(provider, format, args));
+ Console.Write(string.Format(provider, format, args), CurrentStyle);
}
}
}
diff --git a/src/Spectre.Console/AnsiConsole.WriteLine.cs b/src/Spectre.Console/AnsiConsole.WriteLine.cs
index a00f183..90075b5 100644
--- a/src/Spectre.Console/AnsiConsole.WriteLine.cs
+++ b/src/Spectre.Console/AnsiConsole.WriteLine.cs
@@ -22,7 +22,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(string value)
{
- Console.WriteLine(value);
+ Console.WriteLine(value, CurrentStyle);
}
///
@@ -32,7 +32,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(int value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -43,7 +43,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, int value)
{
- Console.WriteLine(value.ToString(provider));
+ Console.WriteLine(value.ToString(provider), CurrentStyle);
}
///
@@ -53,7 +53,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(uint value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -64,7 +64,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, uint value)
{
- Console.WriteLine(value.ToString(provider));
+ Console.WriteLine(value.ToString(provider), CurrentStyle);
}
///
@@ -74,7 +74,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(long value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -85,7 +85,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, long value)
{
- Console.WriteLine(value.ToString(provider));
+ Console.WriteLine(value.ToString(provider), CurrentStyle);
}
///
@@ -95,7 +95,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(ulong value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -106,7 +106,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, ulong value)
{
- Console.WriteLine(value.ToString(provider));
+ Console.WriteLine(value.ToString(provider), CurrentStyle);
}
///
@@ -116,7 +116,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(float value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -127,7 +127,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, float value)
{
- Console.WriteLine(value.ToString(provider));
+ Console.WriteLine(value.ToString(provider), CurrentStyle);
}
///
@@ -137,7 +137,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(double value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -148,7 +148,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, double value)
{
- Console.WriteLine(value.ToString(provider));
+ Console.WriteLine(value.ToString(provider), CurrentStyle);
}
///
@@ -158,7 +158,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(decimal value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -169,7 +169,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, decimal value)
{
- Console.WriteLine(value.ToString(provider));
+ Console.WriteLine(value.ToString(provider), CurrentStyle);
}
///
@@ -179,7 +179,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(bool value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -190,7 +190,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, bool value)
{
- Console.WriteLine(value.ToString(provider));
+ Console.WriteLine(value.ToString(provider), CurrentStyle);
}
///
@@ -200,7 +200,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(char value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -211,7 +211,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, char value)
{
- Console.WriteLine(value.ToString(provider));
+ Console.WriteLine(value.ToString(provider), CurrentStyle);
}
///
@@ -221,7 +221,7 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(char[] value)
{
- Console.WriteLine(CultureInfo.CurrentCulture, value);
+ WriteLine(CultureInfo.CurrentCulture, value);
}
///
@@ -232,7 +232,17 @@ namespace Spectre.Console
/// The value to write.
public static void WriteLine(IFormatProvider provider, char[] value)
{
- Console.WriteLine(provider, value);
+ if (value is null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ for (var index = 0; index < value.Length; index++)
+ {
+ Console.Write(value[index].ToString(provider), CurrentStyle);
+ }
+
+ Console.WriteLine();
}
///
@@ -244,7 +254,7 @@ namespace Spectre.Console
/// An array of objects to write.
public static void WriteLine(string format, params object[] args)
{
- Console.WriteLine(CultureInfo.CurrentCulture, format, args);
+ WriteLine(CultureInfo.CurrentCulture, format, args);
}
///
@@ -257,7 +267,7 @@ namespace Spectre.Console
/// An array of objects to write.
public static void WriteLine(IFormatProvider provider, string format, params object[] args)
{
- Console.WriteLine(string.Format(provider, format, args));
+ Console.WriteLine(string.Format(provider, format, args), CurrentStyle);
}
}
}
diff --git a/src/Spectre.Console/AnsiConsole.cs b/src/Spectre.Console/AnsiConsole.cs
index e88b67e..b2c607b 100644
--- a/src/Spectre.Console/AnsiConsole.cs
+++ b/src/Spectre.Console/AnsiConsole.cs
@@ -16,12 +16,13 @@ namespace Spectre.Console
ColorSystem = ColorSystemSupport.Detect,
Out = System.Console.Out,
});
+ Initialize(System.Console.Out);
Created = true;
return console;
});
///
- /// Gets the current renderer.
+ /// Gets the underlying .
///
public static IAnsiConsole Console => _console.Value;
@@ -30,8 +31,6 @@ namespace Spectre.Console
///
public static Capabilities Capabilities => Console.Capabilities;
- internal static bool Created { get; private set; }
-
///
/// Gets the buffer width of the console.
///
@@ -48,33 +47,6 @@ namespace Spectre.Console
get => Console.Height;
}
- ///
- /// Gets or sets the foreground color.
- ///
- public static Color Foreground
- {
- get => Console.Foreground;
- set => Console.SetColor(value, true);
- }
-
- ///
- /// Gets or sets the background color.
- ///
- public static Color Background
- {
- get => Console.Background;
- set => Console.SetColor(value, false);
- }
-
- ///
- /// Gets or sets the text decoration.
- ///
- public static Decoration Decoration
- {
- get => Console.Decoration;
- set => Console.Decoration = value;
- }
-
///
/// Creates a new instance
/// from the provided settings.
@@ -85,29 +57,5 @@ namespace Spectre.Console
{
return ConsoleBuilder.Build(settings);
}
-
- ///
- /// Resets colors and text decorations.
- ///
- public static void Reset()
- {
- Console.Reset();
- }
-
- ///
- /// Resets the current applied text decorations.
- ///
- public static void ResetDecoration()
- {
- Console.ResetDecoration();
- }
-
- ///
- /// Resets the current applied foreground and background colors.
- ///
- public static void ResetColors()
- {
- Console.ResetColors();
- }
}
}
diff --git a/src/Spectre.Console/Capabilities.cs b/src/Spectre.Console/Capabilities.cs
index 7de2932..284999c 100644
--- a/src/Spectre.Console/Capabilities.cs
+++ b/src/Spectre.Console/Capabilities.cs
@@ -11,6 +11,17 @@ namespace Spectre.Console
///
public bool SupportsAnsi { get; }
+ ///
+ /// Gets a value indicating whether or not
+ /// the console support links.
+ ///
+ ///
+ /// There is probably a lot of room for improvement here
+ /// once we have more information about the terminal
+ /// we're running inside.
+ ///
+ public bool SupportLinks => SupportsAnsi && !LegacyConsole;
+
///
/// Gets the color system.
///
diff --git a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Rendering.cs b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Rendering.cs
index 59ec1e1..dec7b3c 100644
--- a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Rendering.cs
+++ b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Rendering.cs
@@ -1,6 +1,5 @@
using System;
using System.Linq;
-using Spectre.Console.Internal;
using Spectre.Console.Rendering;
namespace Spectre.Console
@@ -28,30 +27,18 @@ namespace Spectre.Console
}
var options = new RenderContext(console.Encoding, console.Capabilities.LegacyConsole);
+ var segments = renderable.Render(options, console.Width).Where(x => !(x.Text.Length == 0 && !x.IsLineBreak)).ToArray();
+ segments = Segment.Merge(segments).ToArray();
- using (console.PushStyle(Style.Plain))
+ var current = Style.Plain;
+ foreach (var segment in segments)
{
- var segments = renderable.Render(options, console.Width).Where(x => !(x.Text.Length == 0 && !x.IsLineBreak)).ToArray();
- segments = Segment.Merge(segments).ToArray();
-
- var current = Style.Plain;
- foreach (var segment in segments)
+ if (string.IsNullOrEmpty(segment.Text))
{
- if (string.IsNullOrEmpty(segment.Text))
- {
- continue;
- }
-
- if (!segment.Style.Equals(current))
- {
- console.Foreground = segment.Style.Foreground;
- console.Background = segment.Style.Background;
- console.Decoration = segment.Style.Decoration;
- current = segment.Style;
- }
-
- console.Write(segment.Text);
+ continue;
}
+
+ console.Write(segment.Text, segment.Style);
}
}
}
diff --git a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Write.cs b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Write.cs
deleted file mode 100644
index e93ccfc..0000000
--- a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Write.cs
+++ /dev/null
@@ -1,339 +0,0 @@
-using System;
-using System.Globalization;
-
-namespace Spectre.Console
-{
- ///
- /// Contains extension methods for .
- ///
- public static partial class AnsiConsoleExtensions
- {
- ///
- /// Writes the specified string value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, string value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- if (value != null)
- {
- console.Write(value);
- }
- }
-
- ///
- /// Writes the text representation of the specified 32-bit
- /// signed integer value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, int value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified 32-bit
- /// signed integer value to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, int value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.Write(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified 32-bit
- /// unsigned integer value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, uint value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified 32-bit
- /// unsigned integer value to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, uint value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.Write(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified 64-bit
- /// signed integer value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, long value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified 64-bit
- /// signed integer value to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, long value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.Write(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified 64-bit
- /// unsigned integer value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, ulong value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified 64-bit
- /// unsigned integer value to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, ulong value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.Write(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified single-precision
- /// floating-point value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, float value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified single-precision
- /// floating-point value to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, float value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.Write(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified double-precision
- /// floating-point value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, double value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified double-precision
- /// floating-point value to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, double value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.Write(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified decimal value, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, decimal value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified decimal value, to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, decimal value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- Write(console, value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified boolean value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, bool value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified boolean value to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, bool value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- Write(console, value.ToString(provider));
- }
-
- ///
- /// Writes the specified Unicode character to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, char value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the specified Unicode character to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, char value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- Write(console, value.ToString(provider));
- }
-
- ///
- /// Writes the specified array of Unicode characters to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void Write(this IAnsiConsole console, char[] value)
- {
- Write(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the specified array of Unicode characters to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, char[] value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- if (value is null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- for (var index = 0; index < value.Length; index++)
- {
- console.Write(value[index].ToString(provider));
- }
- }
-
- ///
- /// Writes the text representation of the specified array of objects,
- /// to the console using the specified format information.
- ///
- /// The console to write to.
- /// A composite format string.
- /// An array of objects to write.
- public static void Write(this IAnsiConsole console, string format, params object[] args)
- {
- Write(console, CultureInfo.CurrentCulture, format, args);
- }
-
- ///
- /// Writes the text representation of the specified array of objects,
- /// to the console using the specified format information.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// A composite format string.
- /// An array of objects to write.
- public static void Write(this IAnsiConsole console, IFormatProvider provider, string format, params object[] args)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- Write(console, string.Format(provider, format, args));
- }
- }
-}
diff --git a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.WriteLine.cs b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.WriteLine.cs
deleted file mode 100644
index 8a003b2..0000000
--- a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.WriteLine.cs
+++ /dev/null
@@ -1,368 +0,0 @@
-using System;
-using System.Globalization;
-
-namespace Spectre.Console
-{
- ///
- /// Contains extension methods for .
- ///
- public static partial class AnsiConsoleExtensions
- {
- ///
- /// Writes an empty line to the console.
- ///
- /// The console to write to.
- public static void WriteLine(this IAnsiConsole console)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.Write(Environment.NewLine);
- }
-
- ///
- /// Writes the specified string value, followed by the
- /// current line terminator, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, string value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- if (value != null)
- {
- console.Write(value);
- }
-
- console.WriteLine();
- }
-
- ///
- /// Writes the text representation of the specified 32-bit signed integer value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, int value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified 32-bit signed integer value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, int value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.WriteLine(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified 32-bit unsigned integer value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, uint value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified 32-bit unsigned integer value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, uint value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.WriteLine(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified 64-bit signed integer value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, long value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified 64-bit signed integer value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, long value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.WriteLine(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified 64-bit unsigned integer value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, ulong value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified 64-bit unsigned integer value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, ulong value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.WriteLine(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified single-precision floating-point
- /// value, followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, float value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified single-precision floating-point
- /// value, followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, float value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.WriteLine(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified double-precision floating-point
- /// value, followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, double value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified double-precision floating-point
- /// value, followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, double value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.WriteLine(value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified decimal value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, decimal value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified decimal value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, decimal value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- WriteLine(console, value.ToString(provider));
- }
-
- ///
- /// Writes the text representation of the specified boolean value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, bool value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the text representation of the specified boolean value,
- /// followed by the current line terminator, to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, bool value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- WriteLine(console, value.ToString(provider));
- }
-
- ///
- /// Writes the specified Unicode character, followed by the current
- /// line terminator, value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, char value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the specified Unicode character, followed by the current
- /// line terminator, value to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, char value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- WriteLine(console, value.ToString(provider));
- }
-
- ///
- /// Writes the specified array of Unicode characters, followed by the current
- /// line terminator, value to the console.
- ///
- /// The console to write to.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, char[] value)
- {
- WriteLine(console, CultureInfo.CurrentCulture, value);
- }
-
- ///
- /// Writes the specified array of Unicode characters, followed by the current
- /// line terminator, value to the console.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// The value to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, char[] value)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- if (value is null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- for (var index = 0; index < value.Length; index++)
- {
- console.Write(value[index].ToString(provider));
- }
-
- console.WriteLine();
- }
-
- ///
- /// Writes the text representation of the specified array of objects,
- /// followed by the current line terminator, to the console
- /// using the specified format information.
- ///
- /// The console to write to.
- /// A composite format string.
- /// An array of objects to write.
- public static void WriteLine(this IAnsiConsole console, string format, params object[] args)
- {
- WriteLine(console, CultureInfo.CurrentCulture, format, args);
- }
-
- ///
- /// Writes the text representation of the specified array of objects,
- /// followed by the current line terminator, to the console
- /// using the specified format information.
- ///
- /// The console to write to.
- /// An object that supplies culture-specific formatting information.
- /// A composite format string.
- /// An array of objects to write.
- public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, string format, params object[] args)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- WriteLine(console, string.Format(provider, format, args));
- }
- }
-}
diff --git a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.cs b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.cs
index 3614320..b8f659a 100644
--- a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.cs
+++ b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.cs
@@ -8,47 +8,34 @@ namespace Spectre.Console
public static partial class AnsiConsoleExtensions
{
///
- /// Resets colors and text decorations.
+ /// Writes an empty line to the console.
///
- /// The console to reset.
- public static void Reset(this IAnsiConsole console)
+ /// The console to write to.
+ public static void WriteLine(this IAnsiConsole console)
{
if (console is null)
{
throw new ArgumentNullException(nameof(console));
}
- console.ResetColors();
- console.ResetDecoration();
+ console.Write(Environment.NewLine, Style.Plain);
}
///
- /// Resets the current applied text decorations.
+ /// Writes the specified string value, followed by the current line terminator, to the console.
///
- /// The console to reset the text decorations for.
- public static void ResetDecoration(this IAnsiConsole console)
+ /// The console to write to.
+ /// The text to write.
+ /// The text style.
+ public static void WriteLine(this IAnsiConsole console, string text, Style style)
{
if (console is null)
{
throw new ArgumentNullException(nameof(console));
}
- console.Decoration = Decoration.None;
- }
-
- ///
- /// Resets the current applied foreground and background colors.
- ///
- /// The console to reset colors for.
- public static void ResetColors(this IAnsiConsole console)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- console.Foreground = Color.Default;
- console.Background = Color.Default;
+ console.Write(text, style);
+ console.WriteLine();
}
}
}
diff --git a/src/Spectre.Console/Extensions/StyleExtensions.cs b/src/Spectre.Console/Extensions/StyleExtensions.cs
index e11df9b..13cf29b 100644
--- a/src/Spectre.Console/Extensions/StyleExtensions.cs
+++ b/src/Spectre.Console/Extensions/StyleExtensions.cs
@@ -66,5 +66,26 @@ namespace Spectre.Console
background: style.Background,
decoration: decoration);
}
+
+ ///
+ /// Creates a new style from the specified one with
+ /// the specified link.
+ ///
+ /// The style.
+ /// The link.
+ /// The same instance so that multiple calls can be chained.
+ public static Style WithLink(this Style style, string link)
+ {
+ if (style is null)
+ {
+ throw new ArgumentNullException(nameof(style));
+ }
+
+ return new Style(
+ foreground: style.Foreground,
+ background: style.Background,
+ decoration: style.Decoration,
+ link: link);
+ }
}
}
diff --git a/src/Spectre.Console/IAnsiConsole.cs b/src/Spectre.Console/IAnsiConsole.cs
index 14e97b1..2b6e064 100644
--- a/src/Spectre.Console/IAnsiConsole.cs
+++ b/src/Spectre.Console/IAnsiConsole.cs
@@ -27,25 +27,11 @@ namespace Spectre.Console
///
Encoding Encoding { get; }
- ///
- /// Gets or sets the current text decoration.
- ///
- Decoration Decoration { get; set; }
-
- ///
- /// Gets or sets the current foreground.
- ///
- Color Foreground { get; set; }
-
- ///
- /// Gets or sets the current background.
- ///
- Color Background { get; set; }
-
///
/// Writes a string followed by a line terminator to the console.
///
/// The string to write.
- void Write(string text);
+ /// The style to use.
+ void Write(string text, Style style);
}
}
diff --git a/src/Spectre.Console/Internal/Ansi/AnsiBuilder.cs b/src/Spectre.Console/Internal/Ansi/AnsiBuilder.cs
index abdf13f..b38c92a 100644
--- a/src/Spectre.Console/Internal/Ansi/AnsiBuilder.cs
+++ b/src/Spectre.Console/Internal/Ansi/AnsiBuilder.cs
@@ -1,3 +1,4 @@
+using System;
using System.Linq;
namespace Spectre.Console.Internal
@@ -5,40 +6,59 @@ namespace Spectre.Console.Internal
internal static class AnsiBuilder
{
public static string GetAnsi(
- ColorSystem system,
+ Capabilities capabilities,
string text,
Decoration decoration,
Color foreground,
- Color background)
+ Color background,
+ string? link)
{
var codes = AnsiDecorationBuilder.GetAnsiCodes(decoration);
// Got foreground?
if (foreground != Color.Default)
{
- codes = codes.Concat(AnsiColorBuilder.GetAnsiCodes(system, foreground, foreground: true));
+ codes = codes.Concat(
+ AnsiColorBuilder.GetAnsiCodes(
+ capabilities.ColorSystem,
+ foreground,
+ true));
}
// Got background?
if (background != Color.Default)
{
- codes = codes.Concat(AnsiColorBuilder.GetAnsiCodes(system, background, foreground: false));
+ codes = codes.Concat(
+ AnsiColorBuilder.GetAnsiCodes(
+ capabilities.ColorSystem,
+ background,
+ false));
}
var result = codes.ToArray();
- if (result.Length == 0)
+ if (result.Length == 0 && link == null)
{
return text;
}
- var lol = string.Concat(
- "\u001b[",
- string.Join(";", result),
- "m",
- text,
- "\u001b[0m");
+ var ansiCodes = string.Join(";", result);
+ var ansi = result.Length > 0
+ ? $"\u001b[{ansiCodes}m{text}\u001b[0m"
+ : text;
- return lol;
+ if (link != null && !capabilities.LegacyConsole)
+ {
+ // Empty links means we should take the URL from the text.
+ if (link.Equals(Constants.EmptyLink, StringComparison.Ordinal))
+ {
+ link = text;
+ }
+
+ var linkId = Math.Abs(link.GetDeterministicHashCode());
+ ansi = $"\u001b]8;id={linkId};{link}\u001b\\{ansi}\u001b]8;;\u001b\\";
+ }
+
+ return ansi;
}
}
}
diff --git a/src/Spectre.Console/Internal/AnsiConsoleRenderer.cs b/src/Spectre.Console/Internal/AnsiConsoleRenderer.cs
index 840a9c7..792d57b 100644
--- a/src/Spectre.Console/Internal/AnsiConsoleRenderer.cs
+++ b/src/Spectre.Console/Internal/AnsiConsoleRenderer.cs
@@ -7,13 +7,9 @@ namespace Spectre.Console.Internal
internal sealed class AnsiConsoleRenderer : IAnsiConsole
{
private readonly TextWriter _out;
- private readonly ColorSystem _system;
public Capabilities Capabilities { get; }
public Encoding Encoding { get; }
- public Decoration Decoration { get; set; }
- public Color Foreground { get; set; }
- public Color Background { get; set; }
public int Width
{
@@ -44,28 +40,26 @@ namespace Spectre.Console.Internal
public AnsiConsoleRenderer(TextWriter @out, ColorSystem system, bool legacyConsole)
{
_out = @out ?? throw new ArgumentNullException(nameof(@out));
- _system = system;
Capabilities = new Capabilities(true, system, legacyConsole);
Encoding = @out.IsStandardOut() ? System.Console.OutputEncoding : Encoding.UTF8;
- Foreground = Color.Default;
- Background = Color.Default;
- Decoration = Decoration.None;
}
- public void Write(string text)
+ public void Write(string text, Style style)
{
if (string.IsNullOrEmpty(text))
{
return;
}
+ style ??= Style.Plain;
+
var parts = text.NormalizeLineEndings().Split(new[] { '\n' });
foreach (var (_, _, last, part) in parts.Enumerate())
{
if (!string.IsNullOrEmpty(part))
{
- _out.Write(AnsiBuilder.GetAnsi(_system, part, Decoration, Foreground, Background));
+ _out.Write(AnsiBuilder.GetAnsi(Capabilities, part, style.Decoration, style.Foreground, style.Background, style.Link));
}
if (!last)
diff --git a/src/Spectre.Console/Internal/ConsoleBuilder.cs b/src/Spectre.Console/Internal/ConsoleBuilder.cs
index 453f2ac..a076717 100644
--- a/src/Spectre.Console/Internal/ConsoleBuilder.cs
+++ b/src/Spectre.Console/Internal/ConsoleBuilder.cs
@@ -56,10 +56,7 @@ namespace Spectre.Console.Internal
if (supportsAnsi)
{
- return new AnsiConsoleRenderer(buffer, colorSystem, legacyConsole)
- {
- Decoration = Decoration.None,
- };
+ return new AnsiConsoleRenderer(buffer, colorSystem, legacyConsole);
}
return new FallbackConsoleRenderer(buffer, colorSystem, legacyConsole);
diff --git a/src/Spectre.Console/Internal/Constants.cs b/src/Spectre.Console/Internal/Constants.cs
index 76a2cf0..309a8ea 100644
--- a/src/Spectre.Console/Internal/Constants.cs
+++ b/src/Spectre.Console/Internal/Constants.cs
@@ -4,5 +4,7 @@ namespace Spectre.Console.Internal
{
public const int DefaultBufferWidth = 80;
public const int DefaultBufferHeight = 9001;
+
+ public const string EmptyLink = "https://emptylink";
}
}
diff --git a/src/Spectre.Console/Internal/Extensions/AnsiConsoleExtensions.cs b/src/Spectre.Console/Internal/Extensions/AnsiConsoleExtensions.cs
deleted file mode 100644
index 05bf631..0000000
--- a/src/Spectre.Console/Internal/Extensions/AnsiConsoleExtensions.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-
-namespace Spectre.Console.Internal
-{
- internal static class AnsiConsoleExtensions
- {
- public static IDisposable PushStyle(this IAnsiConsole console, Style style)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- if (style is null)
- {
- throw new ArgumentNullException(nameof(style));
- }
-
- var current = new Style(console.Foreground, console.Background, console.Decoration);
- console.SetColor(style.Foreground, true);
- console.SetColor(style.Background, false);
- console.Decoration = style.Decoration;
- return new StyleScope(console, current);
- }
-
- public static IDisposable PushColor(this IAnsiConsole console, Color color, bool foreground)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- var current = foreground ? console.Foreground : console.Background;
- console.SetColor(color, foreground);
- return new ColorScope(console, current, foreground);
- }
-
- public static IDisposable PushDecoration(this IAnsiConsole console, Decoration decoration)
- {
- if (console is null)
- {
- throw new ArgumentNullException(nameof(console));
- }
-
- var current = console.Decoration;
- console.Decoration = decoration;
- return new DecorationScope(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 StyleScope : IDisposable
- {
- private readonly IAnsiConsole _console;
- private readonly Style _style;
-
- public StyleScope(IAnsiConsole console, Style style)
- {
- _console = console ?? throw new ArgumentNullException(nameof(console));
- _style = style ?? throw new ArgumentNullException(nameof(style));
- }
-
- [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.SetColor(_style.Foreground, true);
- _console.SetColor(_style.Background, false);
- _console.Decoration = _style.Decoration;
- }
- }
-
- 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 DecorationScope : IDisposable
- {
- private readonly IAnsiConsole _console;
- private readonly Decoration _decoration;
-
- public DecorationScope(IAnsiConsole console, Decoration decoration)
- {
- _console = console ?? throw new ArgumentNullException(nameof(console));
- _decoration = decoration;
- }
-
- [SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations")]
- [SuppressMessage("Performance", "CA1821:Remove empty Finalizers")]
- ~DecorationScope()
- {
- throw new InvalidOperationException("Decoration scope was not disposed.");
- }
-
- public void Dispose()
- {
- GC.SuppressFinalize(this);
- _console.Decoration = _decoration;
- }
- }
-}
diff --git a/src/Spectre.Console/Internal/Extensions/StringExtensions.cs b/src/Spectre.Console/Internal/Extensions/StringExtensions.cs
index 0b4a495..567be83 100644
--- a/src/Spectre.Console/Internal/Extensions/StringExtensions.cs
+++ b/src/Spectre.Console/Internal/Extensions/StringExtensions.cs
@@ -78,5 +78,28 @@ namespace Spectre.Console.Internal
return result.ToArray();
}
+
+ // https://andrewlock.net/why-is-string-gethashcode-different-each-time-i-run-my-program-in-net-core/
+ public static int GetDeterministicHashCode(this string str)
+ {
+ unchecked
+ {
+ var hash1 = (5381 << 16) + 5381;
+ var hash2 = hash1;
+
+ for (var i = 0; i < str.Length; i += 2)
+ {
+ hash1 = ((hash1 << 5) + hash1) ^ str[i];
+ if (i == str.Length - 1)
+ {
+ break;
+ }
+
+ hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
+ }
+
+ return hash1 + (hash2 * 1566083941);
+ }
+ }
}
}
diff --git a/src/Spectre.Console/Internal/FallbackConsoleRenderer.cs b/src/Spectre.Console/Internal/FallbackConsoleRenderer.cs
index 1775744..a5ac093 100644
--- a/src/Spectre.Console/Internal/FallbackConsoleRenderer.cs
+++ b/src/Spectre.Console/Internal/FallbackConsoleRenderer.cs
@@ -1,4 +1,3 @@
-using System;
using System.IO;
using System.Text;
@@ -6,16 +5,11 @@ 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;
+ private Style? _lastStyle;
public Capabilities Capabilities { get; }
-
public Encoding Encoding { get; }
public int Width
@@ -44,47 +38,6 @@ namespace Spectre.Console.Internal
}
}
- public Decoration Decoration { 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, bool legacyConsole)
{
_out = @out;
@@ -92,25 +45,46 @@ namespace Spectre.Console.Internal
if (_out.IsStandardOut())
{
- _defaultForeground = System.Console.ForegroundColor;
- _defaultBackground = System.Console.BackgroundColor;
-
Encoding = System.Console.OutputEncoding;
}
else
{
- _defaultForeground = ConsoleColor.Gray;
- _defaultBackground = ConsoleColor.Black;
-
Encoding = Encoding.UTF8;
}
Capabilities = new Capabilities(false, _system, legacyConsole);
}
- public void Write(string text)
+ public void Write(string text, Style style)
{
+ if (_lastStyle?.Equals(style) != true)
+ {
+ SetStyle(style);
+ }
+
_out.Write(text.NormalizeLineEndings(native: true));
}
+
+ private void SetStyle(Style style)
+ {
+ _lastStyle = style;
+
+ if (_out.IsStandardOut())
+ {
+ System.Console.ResetColor();
+
+ var background = Color.ToConsoleColor(style.Background);
+ if (_system != ColorSystem.NoColors && _out.IsStandardOut() && (int)background != -1)
+ {
+ System.Console.BackgroundColor = background;
+ }
+
+ var foreground = Color.ToConsoleColor(style.Foreground);
+ if (_system != ColorSystem.NoColors && _out.IsStandardOut() && (int)foreground != -1)
+ {
+ System.Console.ForegroundColor = foreground;
+ }
+ }
+ }
}
}
diff --git a/src/Spectre.Console/Internal/Text/StyleParser.cs b/src/Spectre.Console/Internal/Text/StyleParser.cs
index 184880b..2be1e53 100644
--- a/src/Spectre.Console/Internal/Text/StyleParser.cs
+++ b/src/Spectre.Console/Internal/Text/StyleParser.cs
@@ -35,6 +35,7 @@ namespace Spectre.Console.Internal
var effectiveDecoration = (Decoration?)null;
var effectiveForeground = (Color?)null;
var effectiveBackground = (Color?)null;
+ var effectiveLink = (string?)null;
var parts = text.Split(new[] { ' ' });
var foreground = true;
@@ -51,6 +52,23 @@ namespace Spectre.Console.Internal
continue;
}
+ if (part.StartsWith("link=", StringComparison.OrdinalIgnoreCase))
+ {
+ if (effectiveLink != null)
+ {
+ error = "A link has already been set.";
+ return null;
+ }
+
+ effectiveLink = part.Substring(5);
+ continue;
+ }
+ else if (part.StartsWith("link", StringComparison.OrdinalIgnoreCase))
+ {
+ effectiveLink = Constants.EmptyLink;
+ continue;
+ }
+
var decoration = DecorationTable.GetDecoration(part);
if (decoration != null)
{
@@ -116,7 +134,11 @@ namespace Spectre.Console.Internal
}
error = null;
- return new Style(effectiveForeground, effectiveBackground, effectiveDecoration);
+ return new Style(
+ effectiveForeground,
+ effectiveBackground,
+ effectiveDecoration,
+ effectiveLink);
}
[SuppressMessage("Design", "CA1031:Do not catch general exception types")]
diff --git a/src/Spectre.Console/Spectre.Console.csproj b/src/Spectre.Console/Spectre.Console.csproj
index 140c0f2..2464963 100644
--- a/src/Spectre.Console/Spectre.Console.csproj
+++ b/src/Spectre.Console/Spectre.Console.csproj
@@ -41,12 +41,6 @@
AnsiConsoleExtensions.cs
-
- AnsiConsoleExtensions.cs
-
-
- AnsiConsoleExtensions.cs
-
3.0.0
diff --git a/src/Spectre.Console/Style.cs b/src/Spectre.Console/Style.cs
index 9cc10be..4eb7bad 100644
--- a/src/Spectre.Console/Style.cs
+++ b/src/Spectre.Console/Style.cs
@@ -24,6 +24,11 @@ namespace Spectre.Console
///
public Decoration Decoration { get; }
+ ///
+ /// Gets the link.
+ ///
+ public string? Link { get; }
+
///
/// Gets an with the
/// default colors and without text decoration.
@@ -31,7 +36,7 @@ namespace Spectre.Console
public static Style Plain { get; } = new Style();
private Style()
- : this(null, null, null)
+ : this(null, null, null, null)
{
}
@@ -41,11 +46,13 @@ namespace Spectre.Console
/// The foreground color.
/// The background color.
/// The text decoration.
- public Style(Color? foreground = null, Color? background = null, Decoration? decoration = null)
+ /// The link.
+ public Style(Color? foreground = null, Color? background = null, Decoration? decoration = null, string? link = null)
{
Foreground = foreground ?? Color.Default;
Background = background ?? Color.Default;
Decoration = decoration ?? Decoration.None;
+ Link = link;
}
///
@@ -78,13 +85,23 @@ namespace Spectre.Console
return new Style(decoration: decoration);
}
+ ///
+ /// Creates a new style from the specified link.
+ ///
+ /// The link.
+ /// A new with the specified link.
+ public static Style WithLink(string link)
+ {
+ return new Style(link: link);
+ }
+
///
/// Creates a copy of the current .
///
/// A copy of the current .
public Style Clone()
{
- return new Style(Foreground, Background, Decoration);
+ return new Style(Foreground, Background, Decoration, Link);
}
///
@@ -111,7 +128,13 @@ namespace Spectre.Console
background = other.Background;
}
- return new Style(foreground, background, Decoration | other.Decoration);
+ var link = Link;
+ if (!string.IsNullOrWhiteSpace(other.Link))
+ {
+ link = other.Link;
+ }
+
+ return new Style(foreground, background, Decoration | other.Decoration, link);
}
///
@@ -158,6 +181,12 @@ namespace Spectre.Console
hash = (hash * 16777619) ^ Foreground.GetHashCode();
hash = (hash * 16777619) ^ Background.GetHashCode();
hash = (hash * 16777619) ^ Decoration.GetHashCode();
+
+ if (Link != null)
+ {
+ hash = (hash * 16777619) ^ Link?.GetHashCode() ?? 0;
+ }
+
return hash;
}
}
@@ -178,7 +207,8 @@ namespace Spectre.Console
return Foreground.Equals(other.Foreground) &&
Background.Equals(other.Background) &&
- Decoration == other.Decoration;
+ Decoration == other.Decoration &&
+ string.Equals(Link, other.Link, StringComparison.Ordinal);
}
}
}