Skip to content

Commit 509cd9a

Browse files
committed
Span.ToString(OutputMode)
1 parent fdd89a1 commit 509cd9a

File tree

13 files changed

+175
-92
lines changed

13 files changed

+175
-92
lines changed

src/System.CommandLine.Rendering.Tests/FormatSpanTests.cs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ public class FormatSpanTests
1111
[Fact]
1212
public void ForegroundColorSpans_with_equivalent_content_have_the_same_hash_code()
1313
{
14-
var one = new ForegroundColorSpan("green");
15-
var two = new ForegroundColorSpan("green");
14+
var one = new ForegroundColorSpan("green", Ansi.Color.Foreground.Green);
15+
var two = new ForegroundColorSpan("green", Ansi.Color.Foreground.Green);
1616

1717
one.GetHashCode().Should().Be(two.GetHashCode());
1818
}
1919

2020
[Fact]
2121
public void ForegroundColorSpans_with_the_same_name_are_equal()
2222
{
23-
var one = new ForegroundColorSpan("green");
24-
var two = new ForegroundColorSpan("green");
23+
var one = new ForegroundColorSpan("green", Ansi.Color.Foreground.Green);
24+
var two = new ForegroundColorSpan("green", Ansi.Color.Foreground.Green);
2525

2626
one.Equals(two)
2727
.Should()
@@ -35,8 +35,8 @@ public void ForegroundColorSpans_with_the_same_name_are_equal()
3535
[Fact]
3636
public void ForegroundColorSpans_with_different_names_are_not_equal()
3737
{
38-
var one = new ForegroundColorSpan("red");
39-
var two = new ForegroundColorSpan("green");
38+
var one = new ForegroundColorSpan("red", Ansi.Color.Foreground.Green);
39+
var two = new ForegroundColorSpan("green", Ansi.Color.Foreground.Green);
4040

4141
one.Equals(two)
4242
.Should()
@@ -46,17 +46,17 @@ public void ForegroundColorSpans_with_different_names_are_not_equal()
4646
[Fact]
4747
public void BackgroundColorSpans_with_equivalent_content_have_the_same_hash_code()
4848
{
49-
var one = new BackgroundColorSpan("green");
50-
var two = new BackgroundColorSpan("green");
49+
var one = new BackgroundColorSpan("green", Ansi.Color.Foreground.Green);
50+
var two = new BackgroundColorSpan("green", Ansi.Color.Foreground.Green);
5151

5252
one.GetHashCode().Should().Be(two.GetHashCode());
5353
}
5454

5555
[Fact]
5656
public void BackgroundColorSpans_with_the_same_name_are_equal()
5757
{
58-
var one = new BackgroundColorSpan("green");
59-
var two = new BackgroundColorSpan("green");
58+
var one = new BackgroundColorSpan("green", Ansi.Color.Foreground.Green);
59+
var two = new BackgroundColorSpan("green", Ansi.Color.Foreground.Green);
6060

6161
one.Equals(two)
6262
.Should()
@@ -70,8 +70,8 @@ public void BackgroundColorSpans_with_the_same_name_are_equal()
7070
[Fact]
7171
public void BackgroundColorSpans_with_different_names_are_not_equal()
7272
{
73-
var one = new BackgroundColorSpan("red");
74-
var two = new BackgroundColorSpan("green");
73+
var one = new BackgroundColorSpan("red", Ansi.Color.Foreground.Red);
74+
var two = new BackgroundColorSpan("green", Ansi.Color.Foreground.Green);
7575

7676
one.Equals(two)
7777
.Should()
@@ -81,8 +81,8 @@ public void BackgroundColorSpans_with_different_names_are_not_equal()
8181
[Fact]
8282
public void A_ForegroundColorSpan_and_a_BackgroundColorSpan_having_the_same_name_are_not_equal()
8383
{
84-
var one = new ForegroundColorSpan("green");
85-
var two = new BackgroundColorSpan("green");
84+
var one = new ForegroundColorSpan("green", Ansi.Color.Foreground.Green);
85+
var two = new BackgroundColorSpan("green", Ansi.Color.Foreground.Green);
8686

8787
one.Equals(two)
8888
.Should()
@@ -92,26 +92,26 @@ public void A_ForegroundColorSpan_and_a_BackgroundColorSpan_having_the_same_name
9292
[Fact]
9393
public void A_ForegroundColorSpan_and_a_BackgroundColorSpan_having_the_same_name_do_not_have_the_same_hash_code()
9494
{
95-
var one = new ForegroundColorSpan("green");
96-
var two = new BackgroundColorSpan("green");
95+
var one = new ForegroundColorSpan("green", Ansi.Color.Foreground.Green);
96+
var two = new BackgroundColorSpan("green", Ansi.Color.Foreground.Green);
9797

9898
one.GetHashCode().Should().NotBe(two.GetHashCode());
9999
}
100100

101101
[Fact]
102102
public void StyleSpans_with_equivalent_content_have_the_same_hash_code()
103103
{
104-
var one = new StyleSpan("green");
105-
var two = new StyleSpan("green");
104+
var one = new StyleSpan("green", Ansi.Color.Foreground.Green);
105+
var two = new StyleSpan("green", Ansi.Color.Foreground.Green);
106106

107107
one.GetHashCode().Should().Be(two.GetHashCode());
108108
}
109109

110110
[Fact]
111111
public void StyleSpans_with_the_same_name_are_equal()
112112
{
113-
var one = new StyleSpan("green");
114-
var two = new StyleSpan("green");
113+
var one = new StyleSpan("green", Ansi.Color.Foreground.Green);
114+
var two = new StyleSpan("green", Ansi.Color.Foreground.Green);
115115

116116
one.Equals(two)
117117
.Should()
@@ -125,8 +125,8 @@ public void StyleSpans_with_the_same_name_are_equal()
125125
[Fact]
126126
public void StyleSpans_with_different_names_are_not_equal()
127127
{
128-
var one = new StyleSpan("red");
129-
var two = new StyleSpan("green");
128+
var one = new StyleSpan("red", Ansi.Color.Foreground.Green);
129+
var two = new StyleSpan("green", Ansi.Color.Foreground.Green);
130130

131131
one.Equals(two)
132132
.Should()

src/System.CommandLine.Rendering.Tests/SpanTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,27 @@ public void Span_starts_update_when_parent_is_added_to_another_parent_span()
8282
innerContainerSpan[3].Start.Should().Be("firstsecond".Length);
8383
innerContainerSpan[4].Start.Should().Be("firstsecondthird".Length);
8484
}
85+
86+
[Fact]
87+
public void ToString_with_non_ansi_omits_ANSI_codes()
88+
{
89+
var span = new SpanFormatter()
90+
.ParseToSpan($"one{ForegroundColorSpan.Red()}two{ForegroundColorSpan.Reset()}three");
91+
92+
span.ToString(OutputMode.NonAnsi)
93+
.Should()
94+
.Be("onetwothree");
95+
}
96+
97+
[Fact]
98+
public void ToString_with_ansi_includes_ANSI_codes()
99+
{
100+
var span = new SpanFormatter()
101+
.ParseToSpan($"one{ForegroundColorSpan.Red()}two{ForegroundColorSpan.Reset()}three");
102+
103+
span.ToString(OutputMode.Ansi)
104+
.Should()
105+
.Be($"one{Ansi.Color.Foreground.Red.EscapeSequence}two{Ansi.Color.Foreground.Default.EscapeSequence}three");
106+
}
85107
}
86108
}

src/System.CommandLine.Rendering.Tests/ViewRenderingTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ public void Views_can_be_appended_to_output(OutputMode outputMode)
6868
_terminal.RenderOperations()
6969
.Should()
7070
.BeEquivalentSequenceTo(
71-
new TextRendered("1", new Point(0, 2)),
72-
new TextRendered("2", new Point(0, 3)),
73-
new TextRendered("3" + Environment.NewLine, new Point(0, 4)));
71+
new TextRendered("1", new Point(0, 0)),
72+
new TextRendered("2", new Point(0, 1)),
73+
new TextRendered("3" + Environment.NewLine, new Point(0, 2)));
7474
}
7575

7676
[Theory]

src/System.CommandLine.Rendering/BackgroundColorSpan.cs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,58 @@ namespace System.CommandLine.Rendering
55
{
66
public class BackgroundColorSpan : ColorSpan
77
{
8-
public BackgroundColorSpan(string name) : base(name)
8+
public BackgroundColorSpan(string name, AnsiControlCode ansiControlCode)
9+
: base(name, ansiControlCode)
910
{
1011
}
1112

12-
public BackgroundColorSpan(RgbColor rgbColor) : base(rgbColor)
13+
public BackgroundColorSpan(RgbColor rgbColor)
14+
: base(rgbColor,
15+
Ansi.Color.Foreground.Rgb(
16+
rgbColor.Red,
17+
rgbColor.Green,
18+
rgbColor.Blue))
1319
{
1420
}
1521

16-
public BackgroundColorSpan(byte r, byte g, byte b) : this(new RgbColor(r, g, b))
22+
public BackgroundColorSpan(byte r, byte g, byte b)
23+
: this(new RgbColor(r, g, b))
1724
{
1825
}
1926

20-
public static BackgroundColorSpan Reset() => new BackgroundColorSpan(nameof(Reset));
27+
public static BackgroundColorSpan Reset() => new BackgroundColorSpan(nameof(Reset), Ansi.Color.Background.Default);
2128

22-
public static BackgroundColorSpan Black() => new BackgroundColorSpan(nameof(Black));
29+
public static BackgroundColorSpan Black() => new BackgroundColorSpan(nameof(Black), Ansi.Color.Background.Black);
2330

24-
public static BackgroundColorSpan Red() => new BackgroundColorSpan(nameof(Red));
31+
public static BackgroundColorSpan Red() => new BackgroundColorSpan(nameof(Red), Ansi.Color.Background.Red);
2532

26-
public static BackgroundColorSpan Green() => new BackgroundColorSpan(nameof(Green));
33+
public static BackgroundColorSpan Green() => new BackgroundColorSpan(nameof(Green), Ansi.Color.Background.Green);
2734

28-
public static BackgroundColorSpan Yellow() => new BackgroundColorSpan(nameof(Yellow));
35+
public static BackgroundColorSpan Yellow() => new BackgroundColorSpan(nameof(Yellow), Ansi.Color.Background.Yellow);
2936

30-
public static BackgroundColorSpan Blue() => new BackgroundColorSpan(nameof(Blue));
37+
public static BackgroundColorSpan Blue() => new BackgroundColorSpan(nameof(Blue), Ansi.Color.Background.Blue);
3138

32-
public static BackgroundColorSpan Magenta() => new BackgroundColorSpan(nameof(Magenta));
39+
public static BackgroundColorSpan Magenta() => new BackgroundColorSpan(nameof(Magenta), Ansi.Color.Background.Magenta);
3340

34-
public static BackgroundColorSpan Cyan() => new BackgroundColorSpan(nameof(Cyan));
41+
public static BackgroundColorSpan Cyan() => new BackgroundColorSpan(nameof(Cyan), Ansi.Color.Background.Cyan);
3542

36-
public static BackgroundColorSpan White() => new BackgroundColorSpan(nameof(White));
43+
public static BackgroundColorSpan White() => new BackgroundColorSpan(nameof(White), Ansi.Color.Background.White);
3744

38-
public static BackgroundColorSpan DarkGray() => new BackgroundColorSpan(nameof(DarkGray));
45+
public static BackgroundColorSpan DarkGray() => new BackgroundColorSpan(nameof(DarkGray), Ansi.Color.Background.DarkGray);
3946

40-
public static BackgroundColorSpan LightRed() => new BackgroundColorSpan(nameof(LightRed));
47+
public static BackgroundColorSpan LightRed() => new BackgroundColorSpan(nameof(LightRed), Ansi.Color.Background.LightRed);
4148

42-
public static BackgroundColorSpan LightGreen() => new BackgroundColorSpan(nameof(LightGreen));
49+
public static BackgroundColorSpan LightGreen() => new BackgroundColorSpan(nameof(LightGreen), Ansi.Color.Background.LightGreen);
4350

44-
public static BackgroundColorSpan LightYellow() => new BackgroundColorSpan(nameof(LightYellow));
51+
public static BackgroundColorSpan LightYellow() => new BackgroundColorSpan(nameof(LightYellow), Ansi.Color.Background.LightYellow);
4552

46-
public static BackgroundColorSpan LightBlue() => new BackgroundColorSpan(nameof(LightBlue));
53+
public static BackgroundColorSpan LightBlue() => new BackgroundColorSpan(nameof(LightBlue), Ansi.Color.Background.LightBlue);
4754

48-
public static BackgroundColorSpan LightMagenta() => new BackgroundColorSpan(nameof(LightMagenta));
55+
public static BackgroundColorSpan LightMagenta() => new BackgroundColorSpan(nameof(LightMagenta), Ansi.Color.Background.LightMagenta);
4956

50-
public static BackgroundColorSpan LightCyan() => new BackgroundColorSpan(nameof(LightCyan));
57+
public static BackgroundColorSpan LightCyan() => new BackgroundColorSpan(nameof(LightCyan), Ansi.Color.Background.LightCyan);
5158

52-
public static BackgroundColorSpan LightGray() => new BackgroundColorSpan(nameof(LightGray));
59+
public static BackgroundColorSpan LightGray() => new BackgroundColorSpan(nameof(LightGray), Ansi.Color.Background.LightGray);
5360

5461
public static BackgroundColorSpan Rgb(byte r, byte g, byte b) => new BackgroundColorSpan(r, g, b);
5562
}

src/System.CommandLine.Rendering/ColorSpan.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ namespace System.CommandLine.Rendering
55
{
66
public abstract class ColorSpan : FormatSpan
77
{
8-
protected ColorSpan(string name) : base(name)
8+
protected ColorSpan(string name, AnsiControlCode ansiControlCode)
9+
: base(name, ansiControlCode)
910
{
1011
}
1112

12-
protected ColorSpan(RgbColor rgbColor) :
13-
base(GetName(rgbColor) ?? throw new ArgumentNullException(nameof(rgbColor)))
13+
protected ColorSpan(RgbColor rgbColor, AnsiControlCode ansiControlCode)
14+
: base(
15+
GetName(rgbColor) ?? throw new ArgumentNullException(nameof(rgbColor)),
16+
ansiControlCode)
1417
{
1518
RgbColor = rgbColor;
1619
}
@@ -22,4 +25,4 @@ protected static string GetName(RgbColor rgbColor)
2225
return rgbColor?.ToString();
2326
}
2427
}
25-
}
28+
}

src/System.CommandLine.Rendering/ContainerSpan.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections;
55
using System.Collections.Generic;
6+
using System.IO;
67
using System.Linq;
78

89
namespace System.CommandLine.Rendering
@@ -52,6 +53,12 @@ private void RecalculateChildPositions()
5253
}
5354
}
5455

55-
public override string ToString() => string.Join("", _children);
56+
public override void WriteTo(TextWriter writer, OutputMode outputMode)
57+
{
58+
for (var i = 0; i < _children.Count; i++)
59+
{
60+
_children[i].WriteTo(writer, outputMode);
61+
}
62+
}
5663
}
5764
}

src/System.CommandLine.Rendering/ForegroundColorSpan.cs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,59 @@ namespace System.CommandLine.Rendering
55
{
66
public class ForegroundColorSpan : ColorSpan
77
{
8-
public ForegroundColorSpan(string name) : base(name)
8+
public ForegroundColorSpan(string name, AnsiControlCode ansiControlCode)
9+
: base(name, ansiControlCode)
910
{
1011
}
1112

12-
public ForegroundColorSpan(RgbColor rgbColor) : base(rgbColor)
13+
public ForegroundColorSpan(RgbColor rgbColor)
14+
: base(rgbColor,
15+
Ansi.Color.Foreground.Rgb(
16+
rgbColor.Red,
17+
rgbColor.Green,
18+
rgbColor.Blue))
1319
{
1420
}
1521

16-
public ForegroundColorSpan(byte r, byte g, byte b) : this(new RgbColor(r, g, b))
22+
public ForegroundColorSpan(byte r, byte g, byte b)
23+
: this(new RgbColor(r, g, b))
1724
{
1825
}
1926

20-
public static ForegroundColorSpan Reset() => new ForegroundColorSpan(nameof(Reset));
27+
public static ForegroundColorSpan Reset() => new ForegroundColorSpan(nameof(Reset), Ansi.Color.Foreground.Default);
2128

22-
public static ForegroundColorSpan Black() => new ForegroundColorSpan(nameof(Black));
29+
public static ForegroundColorSpan Black() => new ForegroundColorSpan(nameof(Black), Ansi.Color.Foreground.Black);
2330

24-
public static ForegroundColorSpan Red() => new ForegroundColorSpan(nameof(Red));
31+
public static ForegroundColorSpan Red() => new ForegroundColorSpan(nameof(Red), Ansi.Color.Foreground.Red);
2532

26-
public static ForegroundColorSpan Green() => new ForegroundColorSpan(nameof(Green));
33+
public static ForegroundColorSpan Green() => new ForegroundColorSpan(nameof(Green), Ansi.Color.Foreground.Green);
2734

28-
public static ForegroundColorSpan Yellow() => new ForegroundColorSpan(nameof(Yellow));
35+
public static ForegroundColorSpan Yellow() => new ForegroundColorSpan(nameof(Yellow), Ansi.Color.Foreground.Yellow);
2936

30-
public static ForegroundColorSpan Blue() => new ForegroundColorSpan(nameof(Blue));
37+
public static ForegroundColorSpan Blue() => new ForegroundColorSpan(nameof(Blue), Ansi.Color.Foreground.Blue);
3138

32-
public static ForegroundColorSpan Magenta() => new ForegroundColorSpan(nameof(Magenta));
39+
public static ForegroundColorSpan Magenta() => new ForegroundColorSpan(nameof(Magenta), Ansi.Color.Foreground.Magenta);
3340

34-
public static ForegroundColorSpan Cyan() => new ForegroundColorSpan(nameof(Cyan));
41+
public static ForegroundColorSpan Cyan() => new ForegroundColorSpan(nameof(Cyan), Ansi.Color.Foreground.Cyan);
3542

36-
public static ForegroundColorSpan White() => new ForegroundColorSpan(nameof(White));
43+
public static ForegroundColorSpan White() => new ForegroundColorSpan(nameof(White), Ansi.Color.Foreground.White);
3744

38-
public static ForegroundColorSpan DarkGray() => new ForegroundColorSpan(nameof(DarkGray));
45+
public static ForegroundColorSpan DarkGray() => new ForegroundColorSpan(nameof(DarkGray), Ansi.Color.Foreground.DarkGray);
3946

40-
public static ForegroundColorSpan LightRed() => new ForegroundColorSpan(nameof(LightRed));
47+
public static ForegroundColorSpan LightRed() => new ForegroundColorSpan(nameof(LightRed), Ansi.Color.Foreground.LightRed);
4148

42-
public static ForegroundColorSpan LightGreen() => new ForegroundColorSpan(nameof(LightGreen));
49+
public static ForegroundColorSpan LightGreen() => new ForegroundColorSpan(nameof(LightGreen), Ansi.Color.Foreground.LightGreen);
4350

44-
public static ForegroundColorSpan LightYellow() => new ForegroundColorSpan(nameof(LightYellow));
51+
public static ForegroundColorSpan LightYellow() => new ForegroundColorSpan(nameof(LightYellow), Ansi.Color.Foreground.LightYellow);
4552

46-
public static ForegroundColorSpan LightBlue() => new ForegroundColorSpan(nameof(LightBlue));
53+
public static ForegroundColorSpan LightBlue() => new ForegroundColorSpan(nameof(LightBlue), Ansi.Color.Foreground.LightBlue);
4754

48-
public static ForegroundColorSpan LightMagenta() => new ForegroundColorSpan(nameof(LightMagenta));
55+
public static ForegroundColorSpan LightMagenta() => new ForegroundColorSpan(nameof(LightMagenta), Ansi.Color.Foreground.LightMagenta);
4956

50-
public static ForegroundColorSpan LightCyan() => new ForegroundColorSpan(nameof(LightCyan));
57+
public static ForegroundColorSpan LightCyan() => new ForegroundColorSpan(nameof(LightCyan), Ansi.Color.Foreground.LightCyan);
5158

52-
public static ForegroundColorSpan LightGray() => new ForegroundColorSpan(nameof(LightGray));
59+
public static ForegroundColorSpan LightGray() => new ForegroundColorSpan(nameof(LightGray), Ansi.Color.Foreground.LightGray);
5360

5461
public static ForegroundColorSpan Rgb(byte r, byte g, byte b) => new ForegroundColorSpan(r, g, b);
5562
}
56-
}
63+
}

0 commit comments

Comments
 (0)