From 1a2654d291e530a189c376702d6f47ecc05c84bc Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 13 Jan 2020 17:07:43 -0600 Subject: [PATCH] Try to wrap the line properly with conpty This confusingly doesn't always work --- src/renderer/vt/XtermEngine.cpp | 13 +++++++++++-- src/renderer/vt/paint.cpp | 15 +++++++++++++++ src/renderer/vt/vtrenderer.hpp | 2 ++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/renderer/vt/XtermEngine.cpp b/src/renderer/vt/XtermEngine.cpp index 2c1d8a08ed1..556381c5661 100644 --- a/src/renderer/vt/XtermEngine.cpp +++ b/src/renderer/vt/XtermEngine.cpp @@ -19,7 +19,7 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, _ColorTable(ColorTable), _cColorTable(cColorTable), _fUseAsciiOnly(fUseAsciiOnly), - _previousLineWrapped(false), + // _previousLineWrapped(false), _usingUnderLine(false), _needToDisableCursor(false), _lastCursorIsVisible(false), @@ -248,7 +248,13 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, // If the previous line wrapped, then the cursor is already at this // position, we just don't know it yet. Don't emit anything. - if (_previousLineWrapped) + bool previousLineWrapped = false; + if (_wrappedRow.has_value()) + { + previousLineWrapped = coord.Y == _wrappedRow.value() + 1; + } + + if (previousLineWrapped) { hr = S_OK; } @@ -298,6 +304,9 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, _newBottomLine = false; } _deferredCursorPos = INVALID_COORDS; + + _wrappedRow = std::nullopt; + return hr; } diff --git a/src/renderer/vt/paint.cpp b/src/renderer/vt/paint.cpp index 920dc86aeb2..02b35895968 100644 --- a/src/renderer/vt/paint.cpp +++ b/src/renderer/vt/paint.cpp @@ -449,6 +449,21 @@ using namespace Microsoft::Console::Types; std::wstring wstr = std::wstring(unclusteredString.data(), cchActual); RETURN_IF_FAILED(VtEngine::_WriteTerminalUtf8(wstr)); + // If we've written text to the last column of the viewport, then mark + // that we've wrapped this line. The next time we attempt to move the + // cursor, if we're trying to move it to the start of the next line, + // we'll remember that this line was wrapped, and not manually break the + // line. + // Don't do this is the last character we're writing is a space - The last + // char will always be a space, but if we see that, we shouldn't wrap. + + // TODO: This seems to be off by one char. Resizing cmd.exe, the '.' at the + // end of the initial message sometimes gets cut off weirdly. + if ((_lastText.X + (totalWidth - numSpaces)) > _lastViewport.RightInclusive()) + { + _wrappedRow = coord.Y; + } + // Update our internal tracker of the cursor's position. // See MSFT:20266233 // If the cursor is at the rightmost column of the terminal, and we write a diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index 5adf1cd1d9c..3b180e5e7c7 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -136,6 +136,8 @@ namespace Microsoft::Console::Render Microsoft::Console::VirtualTerminal::RenderTracing _trace; bool _inResizeRequest{ false }; + std::optional _wrappedRow{ std::nullopt }; + [[nodiscard]] HRESULT _Write(std::string_view const str) noexcept; [[nodiscard]] HRESULT _WriteFormattedString(const std::string* const pFormat, ...) noexcept; [[nodiscard]] HRESULT _Flush() noexcept;