CLS in CMD and PowerShell #9507

Closed
opened 2026-01-31 01:56:12 +00:00 by claunia · 7 comments
Owner

Originally created by @vefatica on GitHub (Jul 8, 2020).

I found a couple threads, about a year old, complaining about CLS not clearing the whole screen buffer (including what Terminal calls the "history" (scrollback)). That's no longer the case, and since I doubt that CMD and PowerShell have changed, I wonder how an app clears everything (visible window and above) in Terminal using the console API. This (just below), which I have used does not work; it clears only the visible window.

CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hScreenBuf, &csbi);
COORD cdZero = {0,0};
DWORD dwWritten, dwSize = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputAttribute(hScreenBuf, csbi.wAttributes, dwSize, cdZero, &dwWritten);
FillConsoleOutputCharacter(hScreenBuf, L' ', dwSize, cdZero, &dwWritten);
SetConsoleCursorPosition(hScreenBuf, cdZero);

More generally, are there any guidelines in how much of the (C) console API works in Terminal as it did in ConHost? Surprisingly, at least some ways of clearing the whole screen buffer don't work, while (even more surprisingly) creating alternate console screen buffers and switching to them does work. Again ... are there any guidelines on what works and what doesn't work?

Thanks.

  • Vince
Originally created by @vefatica on GitHub (Jul 8, 2020). I found a couple threads, about a year old, complaining about CLS not clearing the whole screen buffer (including what Terminal calls the "history" (scrollback)). That's no longer the case, and since I doubt that CMD and PowerShell have changed, I wonder how an app clears everything (visible window and above) in Terminal using the console API. This (just below), which I have used does not work; it clears only the visible window. ``` CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo(hScreenBuf, &csbi); COORD cdZero = {0,0}; DWORD dwWritten, dwSize = csbi.dwSize.X * csbi.dwSize.Y; FillConsoleOutputAttribute(hScreenBuf, csbi.wAttributes, dwSize, cdZero, &dwWritten); FillConsoleOutputCharacter(hScreenBuf, L' ', dwSize, cdZero, &dwWritten); SetConsoleCursorPosition(hScreenBuf, cdZero); ``` More generally, are there any guidelines in how much of the (C) console API works in Terminal as it did in ConHost? Surprisingly, at least some ways of clearing the whole screen buffer don't work, while (even more surprisingly) creating alternate console screen buffers and switching to them does work. Again ... are there any guidelines on what works and what doesn't work? Thanks. - Vince
claunia added the Issue-QuestionNeeds-Tag-FixResolution-Answered labels 2026-01-31 01:56:12 +00:00
Author
Owner

@eryksun commented on GitHub (Jul 8, 2020):

CMD's cls command is based on ScrollConsoleScreenBuffer. In the source you can see a shim was added in ScrollConsoleScreenBufferWImpl if the client process is cmd.exe (i.e. enableCmdShim is true) and the call matches the parameters that cls uses, i.e. sourceIsWholeBuffer and targetIsNegativeBufferHeight and noClipProvided and fillIsBlank. Ultimately this writes "\x1b[3J" to clear the screen and scrollback, which is a sequence that's supported by other terminals as well.

@eryksun commented on GitHub (Jul 8, 2020): CMD's `cls` command is based on [`ScrollConsoleScreenBuffer`](https://docs.microsoft.com/en-us/windows/console/scrollconsolescreenbuffer). In the source you can see a shim was added in [`ScrollConsoleScreenBufferWImpl`](https://github.com/microsoft/terminal/blob/f0df154ba97ad54f26412b70cc7dbac1a9c0cb49/src/host/getset.cpp#L831) if the client process is cmd.exe (i.e. `enableCmdShim` is true) and the call matches the parameters that `cls` uses, i.e. `sourceIsWholeBuffer` and `targetIsNegativeBufferHeight` and `noClipProvided` and `fillIsBlank`. Ultimately this writes [`"\x1b[3J"`](https://github.com/microsoft/terminal/blob/70a7ccc120d5d5a096e82aff16da299ec6c2ed06/src/renderer/vt/VtSequences.cpp#L112) to clear the screen and scrollback, which is a sequence that's supported by other terminals as well.
Author
Owner

@vefatica commented on GitHub (Jul 8, 2020):

Are you sure about that? I tried "echo ^e[3J" in the "TCC" command processor (JPSoft) and also "wprintf(L"\x1b[3J");" in my own EXE and it cleared only the scrollback. I need both [3J and [2J to clear the scrollback and the visible window.

@vefatica commented on GitHub (Jul 8, 2020): Are you sure about that? I tried "echo ^e[3J" in the "TCC" command processor (JPSoft) and also "wprintf(L"\x1b[3J");" in my own EXE and it cleared only the scrollback. I need both <ESC>[3J and <ESC>[2J to clear the scrollback and the visible window.
Author
Owner

@DHowett commented on GitHub (Jul 8, 2020):

That shim creates a [3J in addition to its existing effect (which blanks the entire buffer with spaces). That existing effect mimics the [2J and [H that are necessary for a non-WinAPI application to clear the active buffer and home the cursor.

When I’m not on my phone I’ll go into a bit more detail about what APIs are supported or expected to work. In short: there’s an entire conhost in the background between your app and the Terminal, running doing normal conhost things. The terminal is treated as another screen to which that console host can render.

@DHowett commented on GitHub (Jul 8, 2020): That shim _creates_ a `[3J` in addition to its existing effect (which blanks the entire buffer with spaces). That existing effect mimics the `[2J` and `[H` that are necessary for a non-WinAPI application to clear the active buffer and home the cursor. When I’m not on my phone I’ll go into a bit more detail about what APIs are supported or expected to work. In short: there’s an entire conhost in the background between your app and the Terminal, running doing normal conhost things. The terminal is treated as another _screen_ to which that console host can render.
Author
Owner

@vefatica commented on GitHub (Jul 8, 2020):

Interesting! Thanks! I look forward to your further comments. That's exactly what I've changed my routine to.
wprintf(L"\x1b[2J\x1b[3J\x1b[H");

@vefatica commented on GitHub (Jul 8, 2020): Interesting! Thanks! I look forward to your further comments. That's exactly what I've changed my routine to. `wprintf(L"\x1b[2J\x1b[3J\x1b[H");`
Author
Owner

@eryksun commented on GitHub (Jul 8, 2020):

That existing effect mimics the [2J and [H that are necessary for a non-WinAPI application to clear the active buffer and home the cursor.

To clarify, the existing effect of the ScrollConsoleScreenBuffer call is the [2J that clears the screen. CMD's cls calls SetConsoleCursorPosition to home the cursor like [H.

@eryksun commented on GitHub (Jul 8, 2020): > That existing effect mimics the `[2J` and `[H` that are necessary for a non-WinAPI application to clear the active buffer and home the cursor. To clarify, the existing effect of the `ScrollConsoleScreenBuffer` call is the `[2J` that clears the screen. CMD's `cls` calls `SetConsoleCursorPosition` to home the cursor like `[H`.
Author
Owner

@DHowett commented on GitHub (Jul 8, 2020):

Yes, I was speaking about the whole set of operations that CMD performs 😄

So, @vefatica, here's a rough and incomplete list of things that will/won't work as expected in Terminal.

For the most part, a pseudoconsole hosted session acts like a traditional console session with the buffer size locked to the viewport size.

  • Works
    • All output, all VT output
    • All console output modes
    • All keyboard input (as of Terminal 1.1/Windows 10.0.20000+, these can be passed through with high fidelity)
      • (aliases, history: this should not have been in conhost to begin with, but here we are living with mistakes made in 1901)
      • Ctrl events
    • All VT input
    • Alternate screen buffers
    • Anything that addresses the visible part of the screen
    • Title manipulation through SetConsoleTitle
    • Job management, process list APIs
  • Works, but no well-behaved application should do this
    • Anything regarding reading back the contents of the buffer
  • Won't work
    • The console selection APIs (unplanned)
    • WriteConsole[AW] pausing on selection, halting the client application (unplanned)
    • Anything font-related (unplanned; fonts are not inherently remotable, imagine your SSH server caring what font you had set!)
    • Anything that expects the buffer to be taller than the viewport (unplanned; terminals do not have this)
      • Anything that addresses the scrollback with a read/write operation
    • Anything that attempts to change the window size (tracked: #5094)
    • Anything that directly manipulates the HWND of the console window (as returned by GetConsoleWindow) (unplanned; well-behaved apps don't do this; Terminal hosts multiple consoles per HWND anyway, so it would really generally wreak havoc)
    • Specific types of input
      • Win32 mouse events (tracked: #376)
      • Win32 focus events (unplanned; low-value)

The Terminal's scrollback is the natural result of lines being pushed up out of the viewport, and it is immutable. All that an application can do is send the well-known VT sequence to destroy it.
Clearing the screen by scrolling it off the viewport is a case of addressing the scrollback buffer, or anything above the "viewport", which doesn't exist.

@DHowett commented on GitHub (Jul 8, 2020): Yes, I was speaking about the whole set of operations that CMD performs :smile: So, @vefatica, here's a rough and incomplete list of things that will/won't work as expected in Terminal. For the most part, a pseudoconsole hosted session acts like a traditional console session _with the buffer size locked to the viewport size_. * Works * All output, all VT output * All console output modes * All keyboard input (as of Terminal 1.1/Windows 10.0.20000+, these can be passed through with high fidelity) * (aliases, history: this should not have been in conhost to begin with, but here we are living with mistakes made in 1901) * <kbd>Ctrl</kbd> events * All VT input * Alternate screen buffers * Anything that addresses the visible part of the screen * Title manipulation through SetConsoleTitle * Job management, process list APIs * Works, but no well-behaved application should do this * Anything regarding reading back the contents of the buffer * Won't work * The console selection APIs (unplanned) * `WriteConsole[AW]` pausing on selection, halting the client application (unplanned) * Anything font-related (unplanned; fonts are not inherently remotable, imagine your SSH server caring what font you had set!) * Anything that expects the buffer to be taller than the viewport (unplanned; terminals do not have this) * Anything that addresses the scrollback with a read/write operation * Anything that attempts to change the window size (tracked: #5094) * Anything that directly manipulates the HWND of the console window (as returned by `GetConsoleWindow`) (unplanned; well-behaved apps don't do this; Terminal hosts multiple consoles per HWND anyway, so it would really generally wreak havoc) * Specific types of input * Win32 mouse events (tracked: #376) * Win32 focus events (unplanned; low-value) The Terminal's scrollback is the natural result of lines being pushed up out of the viewport, and it is immutable. All that an application can do is send the well-known VT sequence to destroy it. Clearing the screen by scrolling it off the viewport is a case of addressing the scrollback buffer, or anything above the "viewport", which doesn't exist.
Author
Owner

@DHowett commented on GitHub (Jul 10, 2020):

Marking as answered question. Thanks 😄

Happy to continue the discussion! Closed doesn't mean dead/ignored.

@DHowett commented on GitHub (Jul 10, 2020): Marking as answered question. Thanks :smile: Happy to continue the discussion! Closed doesn't mean dead/ignored.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#9507