diff --git a/src/Spectre.Console.Tests/Unit/TextTests.cs b/src/Spectre.Console.Tests/Unit/TextTests.cs index ca1c495..da30d54 100644 --- a/src/Spectre.Console.Tests/Unit/TextTests.cs +++ b/src/Spectre.Console.Tests/Unit/TextTests.cs @@ -48,26 +48,14 @@ namespace Spectre.Console.Tests.Unit .ShouldBe("Hello World"); } - [Fact] - public void Should_Write_Line_Breaks() + [Theory] + [InlineData("Hello\n\nWorld\n\n")] + [InlineData("Hello\r\n\r\nWorld\r\n\r\n")] + public void Should_Write_Line_Breaks(string input) { // Given var fixture = new PlainConsole(width: 5); - var text = new Text("Hello\n\nWorld"); - - // When - fixture.Render(text); - - // Then - fixture.RawOutput.ShouldBe("Hello\n\nWorld"); - } - - [Fact] - public void Should_Write_Line_Breaks_At_End() - { - // Given - var fixture = new PlainConsole(width: 5); - var text = new Text("Hello\n\nWorld\n\n"); + var text = new Text(input); // When fixture.Render(text); diff --git a/src/Spectre.Console/Composition/Segment.cs b/src/Spectre.Console/Composition/Segment.cs index e270105..c9a02e0 100644 --- a/src/Spectre.Console/Composition/Segment.cs +++ b/src/Spectre.Console/Composition/Segment.cs @@ -39,7 +39,7 @@ namespace Spectre.Console.Composition /// /// Gets a segment representing a line break. /// - public static Segment LineBreak { get; } = new Segment("\n", Style.Plain, true); + public static Segment LineBreak { get; } = new Segment(Environment.NewLine, Style.Plain, true); /// /// Gets an empty segment. @@ -95,7 +95,7 @@ namespace Spectre.Console.Composition /// A new segment without any trailing line endings. public Segment StripLineEndings() { - return new Segment(Text.TrimEnd('\n'), Style); + return new Segment(Text.TrimEnd('\n').TrimEnd('\r'), Style); } /// diff --git a/src/Spectre.Console/Composition/Widgets/Panel.cs b/src/Spectre.Console/Composition/Widgets/Panel.cs index a53445f..175bd2f 100644 --- a/src/Spectre.Console/Composition/Widgets/Panel.cs +++ b/src/Spectre.Console/Composition/Widgets/Panel.cs @@ -80,7 +80,7 @@ namespace Spectre.Console new Segment(border.GetPart(BorderPart.HeaderTopLeft)), new Segment(border.GetPart(BorderPart.HeaderTop, panelWidth)), new Segment(border.GetPart(BorderPart.HeaderTopRight)), - new Segment("\n"), + Segment.LineBreak, }; // Render the child. @@ -118,14 +118,14 @@ namespace Spectre.Console } result.Add(new Segment(border.GetPart(BorderPart.CellRight))); - result.Add(new Segment("\n")); + result.Add(Segment.LineBreak); } // Panel bottom result.Add(new Segment(border.GetPart(BorderPart.FooterBottomLeft))); result.Add(new Segment(border.GetPart(BorderPart.FooterBottom, panelWidth))); result.Add(new Segment(border.GetPart(BorderPart.FooterBottomRight))); - result.Add(new Segment("\n")); + result.Add(Segment.LineBreak); return result; } diff --git a/src/Spectre.Console/Composition/Widgets/Text.cs b/src/Spectre.Console/Composition/Widgets/Text.cs index 93d0828..afc5b2c 100644 --- a/src/Spectre.Console/Composition/Widgets/Text.cs +++ b/src/Spectre.Console/Composition/Widgets/Text.cs @@ -92,7 +92,7 @@ namespace Spectre.Console var justification = context.Justification ?? Alignment; foreach (var (_, _, last, line) in lines.Enumerate()) { - var length = line.Sum(l => l.CellLength(context.Encoding)); + var length = line.Sum(l => l.StripLineEndings().CellLength(context.Encoding)); if (length < maxWidth) { // Justify right side diff --git a/src/Spectre.Console/Internal/Text/Cell.cs b/src/Spectre.Console/Internal/Text/Cell.cs index aeec84d..89ef993 100644 --- a/src/Spectre.Console/Internal/Text/Cell.cs +++ b/src/Spectre.Console/Internal/Text/Cell.cs @@ -70,6 +70,11 @@ namespace Spectre.Console.Internal public static int GetCellLength(Encoding encoding, char rune) { + if (rune == '\r' || rune == '\n') + { + return 0; + } + // Is it represented by a single byte? // In that case we don't have to calculate the // actual cell width.