Skip to content

Commit ff7f1a7

Browse files
lheckerDHowett
authored andcommitted
Fix clear buffer command (#17884)
Without a VT "renderer" there's no implicit output anymore when calling `ClearPseudoConsole`. The fix is trivial, but it works slightly different from before: Previously, we would preserve the line the cursor is on, while this PR doesn't do that. I felt like there's not much merit in preserving the line, because it may be a multi-line prompt which won't work with that. Closes #17867 ## Validation Steps Performed Bind 3 different actions to the 3 variants of "Clear buffer" and test them. They work. ✅ (cherry picked from commit 4259ce5) Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgS3NbU Service-Version: 1.22
1 parent 9b8c060 commit ff7f1a7

File tree

7 files changed

+24
-49
lines changed

7 files changed

+24
-49
lines changed

src/cascadia/TerminalControl/ControlCore.cpp

+18-5
Original file line numberDiff line numberDiff line change
@@ -2199,19 +2199,32 @@ namespace winrt::Microsoft::Terminal::Control::implementation
21992199
// - <none>
22002200
void ControlCore::ClearBuffer(Control::ClearBufferType clearType)
22012201
{
2202-
if (clearType == Control::ClearBufferType::Scrollback || clearType == Control::ClearBufferType::All)
2202+
std::wstring_view command;
2203+
switch (clearType)
2204+
{
2205+
case ClearBufferType::Screen:
2206+
command = L"\x1b[H\x1b[2J";
2207+
break;
2208+
case ClearBufferType::Scrollback:
2209+
command = L"\x1b[3J";
2210+
break;
2211+
case ClearBufferType::All:
2212+
command = L"\x1b[H\x1b[2J\x1b[3J";
2213+
break;
2214+
}
2215+
22032216
{
22042217
const auto lock = _terminal->LockForWriting();
2205-
_terminal->EraseScrollback();
2218+
_terminal->Write(command);
22062219
}
22072220

22082221
if (clearType == Control::ClearBufferType::Screen || clearType == Control::ClearBufferType::All)
22092222
{
2210-
// Send a signal to conpty to clear the buffer.
22112223
if (auto conpty{ _connection.try_as<TerminalConnection::ConptyConnection>() })
22122224
{
2213-
// ConPTY will emit sequences to sync up our buffer with its new
2214-
// contents.
2225+
// Since the clearing of ConPTY occurs asynchronously, this call can result weird issues,
2226+
// where a console application still sees contents that we've already deleted, etc.
2227+
// The correct way would be for ConPTY to emit the appropriate CSI n J sequences.
22152228
conpty.ClearBuffer();
22162229
}
22172230
}

src/cascadia/TerminalCore/Terminal.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,6 @@ void Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
209209
engine.Dispatch().SetCursorStyle(cursorStyle);
210210
}
211211

212-
void Terminal::EraseScrollback()
213-
{
214-
auto& engine = reinterpret_cast<OutputStateMachineEngine&>(_stateMachine->Engine());
215-
engine.Dispatch().EraseInDisplay(DispatchTypes::EraseType::Scrollback);
216-
}
217-
218212
bool Terminal::IsXtermBracketedPasteModeEnabled() const noexcept
219213
{
220214
return _systemMode.test(Mode::BracketedPaste);

src/cascadia/TerminalCore/Terminal.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ class Microsoft::Terminal::Core::Terminal final :
9494
void UpdateAppearance(const winrt::Microsoft::Terminal::Core::ICoreAppearance& appearance);
9595
void SetFontInfo(const FontInfo& fontInfo);
9696
void SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle);
97-
void EraseScrollback();
9897
bool IsXtermBracketedPasteModeEnabled() const noexcept;
9998
std::wstring_view GetWorkingDirectory() noexcept;
10099

src/cascadia/UnitTests_Control/ControlCoreTests.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,9 @@ namespace ControlUnitTests
304304

305305
Log::Comment(L"Check the buffer after the clear");
306306
VERIFY_ARE_EQUAL(20, core->_terminal->GetViewport().Height());
307-
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
307+
VERIFY_ARE_EQUAL(41, core->ScrollOffset());
308308
VERIFY_ARE_EQUAL(20, core->ViewHeight());
309-
VERIFY_ARE_EQUAL(41, core->BufferHeight());
309+
VERIFY_ARE_EQUAL(61, core->BufferHeight());
310310

311311
// In this test, we can't actually check if we cleared the buffer
312312
// contents. ConPTY will handle the actual clearing of the buffer

src/host/PtySignalInputThread.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "output.h"
99
#include "handle.h"
10+
#include "_stream.h"
1011
#include "../interactivity/inc/ServiceLocator.hpp"
1112

1213
using namespace Microsoft::Console;
@@ -197,7 +198,9 @@ void PtySignalInputThread::_DoClearBuffer() const
197198
}
198199

199200
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
200-
THROW_IF_FAILED(gci.GetActiveOutputBuffer().ClearBuffer());
201+
auto& screenInfo = gci.GetActiveOutputBuffer();
202+
auto& stateMachine = screenInfo.GetStateMachine();
203+
stateMachine.ProcessString(L"\x1b[H\x1b[2J");
201204
}
202205

203206
void PtySignalInputThread::_DoShowHide(const ShowHideData& data)

src/host/screenInfo.cpp

-32
Original file line numberDiff line numberDiff line change
@@ -2129,38 +2129,6 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport,
21292129
Tracing::s_TraceWindowViewport(_viewport);
21302130
}
21312131

2132-
// Method Description:
2133-
// - Clear the entire contents of the viewport, except for the cursor's row,
2134-
// which is moved to the top line of the viewport.
2135-
// - This is used exclusively by ConPTY to support GH#1193, GH#1882. This allows
2136-
// a terminal to clear the contents of the ConPTY buffer, which is important
2137-
// if the user would like to be able to clear the terminal-side buffer.
2138-
// Arguments:
2139-
// - <none>
2140-
// Return Value:
2141-
// - S_OK
2142-
[[nodiscard]] HRESULT SCREEN_INFORMATION::ClearBuffer()
2143-
{
2144-
// Rotate the buffer to bring the cursor row to the top of the viewport.
2145-
const auto cursorPos = _textBuffer->GetCursor().GetPosition();
2146-
for (auto i = 0; i < cursorPos.y; i++)
2147-
{
2148-
_textBuffer->IncrementCircularBuffer();
2149-
}
2150-
2151-
// Erase everything below that point.
2152-
RETURN_IF_FAILED(SetCursorPosition({ 0, 1 }, false));
2153-
auto& engine = reinterpret_cast<OutputStateMachineEngine&>(_stateMachine->Engine());
2154-
engine.Dispatch().EraseInDisplay(DispatchTypes::EraseType::ToEnd);
2155-
2156-
// Restore the original cursor x offset, but now on the first row.
2157-
RETURN_IF_FAILED(SetCursorPosition({ cursorPos.x, 0 }, false));
2158-
2159-
_textBuffer->TriggerRedrawAll();
2160-
2161-
return S_OK;
2162-
}
2163-
21642132
// Routine Description:
21652133
// - Writes cells to the output buffer at the cursor position.
21662134
// Arguments:

src/host/screenInfo.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,6 @@ class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console
203203
void SetDefaultAttributes(const TextAttribute& attributes,
204204
const TextAttribute& popupAttributes);
205205

206-
[[nodiscard]] HRESULT ClearBuffer();
207-
208206
void UpdateBottom();
209207

210208
FontInfo& GetCurrentFont() noexcept;

0 commit comments

Comments
 (0)