From bdbd9dca16fe9696cec47dcdef702cab8c3d5db8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:29:17 +0000 Subject: [PATCH 1/3] Initial plan From 3ff28223fc18170e251100e54261c360b28e66f0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:32:07 +0000 Subject: [PATCH 2/3] Preserve empty output lines from telnet events --- src/SharpMUTerm.Core/Session/WorldSession.cs | 7 +++++++ .../Session/WorldSessionTests.cs | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/SharpMUTerm.Core/Session/WorldSession.cs b/src/SharpMUTerm.Core/Session/WorldSession.cs index 2135679..87f7a92 100644 --- a/src/SharpMUTerm.Core/Session/WorldSession.cs +++ b/src/SharpMUTerm.Core/Session/WorldSession.cs @@ -312,15 +312,22 @@ private void OnOutputReceived(object? sender, TelnetOutputEventArgs e) return; } + var emitted = false; foreach (var completed in _parser.Feed(e.Text)) { ProcessOutputLine(completed); + emitted = true; } var tail = _parser.Flush(); if (tail is not null) { ProcessOutputLine(tail); + emitted = true; + } + else if (!emitted) + { + ProcessOutputLine(StyledLine.Empty); } } diff --git a/tests/SharpMUTerm.Core.Tests/Session/WorldSessionTests.cs b/tests/SharpMUTerm.Core.Tests/Session/WorldSessionTests.cs index 8cffdaa..364b7c2 100644 --- a/tests/SharpMUTerm.Core.Tests/Session/WorldSessionTests.cs +++ b/tests/SharpMUTerm.Core.Tests/Session/WorldSessionTests.cs @@ -34,6 +34,20 @@ public async Task OutputLine_IsAppendedToScrollbackAndRaisesEvent() await Assert.That(printed).IsNotNull(); } + [Test] + public async Task EmptyOutputLine_IsAppendedAsBlankLine() + { + var (session, telnet) = Create(World()); + await session.ConnectAsync(); + var before = session.Scrollback.Snapshot().Count; + + telnet.EmitLine(string.Empty); + + var after = session.Scrollback.Snapshot(); + await Assert.That(after.Count).IsEqualTo(before + 1); + await Assert.That(after[^1].IsEmpty).IsTrue(); + } + [Test] public async Task AnsiColor_InOutput_IsParsedIntoStyledSpans() { From 44bfbf8f202bd9abe7db0d767a3be6ea90e88b08 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:40:23 +0000 Subject: [PATCH 3/3] Add same-frame blank-line regression test --- .../Session/WorldSessionTests.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/SharpMUTerm.Core.Tests/Session/WorldSessionTests.cs b/tests/SharpMUTerm.Core.Tests/Session/WorldSessionTests.cs index 364b7c2..4efdc8f 100644 --- a/tests/SharpMUTerm.Core.Tests/Session/WorldSessionTests.cs +++ b/tests/SharpMUTerm.Core.Tests/Session/WorldSessionTests.cs @@ -48,6 +48,22 @@ public async Task EmptyOutputLine_IsAppendedAsBlankLine() await Assert.That(after[^1].IsEmpty).IsTrue(); } + [Test] + public async Task SameFrame_OutputPreservesAnEmptyMiddleLine() + { + var (session, telnet) = Create(World()); + await session.ConnectAsync(); + var before = session.Scrollback.Snapshot().Count; + + telnet.EmitLine("Line one\n\nThis line three, previous line was empty, this is valid output. It came from the same received frame."); + + var after = session.Scrollback.Snapshot(); + await Assert.That(after.Count).IsEqualTo(before + 3); + await Assert.That(after[before].Text).IsEqualTo("Line one"); + await Assert.That(after[before + 1].IsEmpty).IsTrue(); + await Assert.That(after[before + 2].Text).IsEqualTo("This line three, previous line was empty, this is valid output. It came from the same received frame."); + } + [Test] public async Task AnsiColor_InOutput_IsParsedIntoStyledSpans() {