terminal: `cls` in PowerShell and cmd.exe doesn't fully clear the Terminal scroll-back history
I feel like this problem should have been reported already, but I couldn’t find it in GitHub issue search.
Environment
Windows build number: Microsoft Windows [Version 10.0.18362.205] - Win10 ver. 1903 with Microsoft-internal test build for monthly quality update
Windows Terminal version: 8dd2e795abb5ef7288ad8f08aece6ff581ec1609 - Azure DevOps CI build for AMD64
Steps to reproduce
- Start Terminal, with either a Command Prompt (cmd.exe) tab or a PowerShell tab.
- Run this command:
type C:\Windows\System32\OEMDefaultAssociations.xml - Observe a long XML file appear on screen.
- Run this command:
cls
Expected behavior
The visible area of the window is cleared of everything except the cmd/PS prompt, and you can no longer scroll the window view to see any part of the file you displayed. This is what happens in the old console window (conhost.exe).
Actual behavior
The visible area is cleared, but the window scrollbar remains active. When you scroll up, you see that most of the file you displayed remains; only the end of the file is erased up to a length determined by your visible window height.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 27
- Comments: 29 (8 by maintainers)
@DHowett In the most recent update of the Terminal from the Store, it still doesn’t quite do the right thing - it clears the scrollback, but it doesn’t always seem to be clearing the screen. For example, try this in PowerShell:
and try scrolling up. Conversely, if you do
cls, then the screen gets cleared, but not the scrollback:What does work is combining them!
Well, almost. For some reason, it doesn’t clear the last line of the scrollback. But this only happens if you do it all in one command - if you clear the screen separately, it does the right thing:
After carefully reading the requisite behavior for this escape sequence, I believe this all is actually correct - Unix terminals behave the same, they don’t clear the scrollback for it.
However, there’s one other thing. I thought that
clsissues the “Reset Device” VT100 escape sequence,␛c. But this doesn’t seem to be the case - if I use that sequence manually, it is ignored altogether by Terminal - it doesn’t affect either the screen or the scrollback:On the other hand, pretty much any Unix terminal I can test handles this by clearing everything. So I think the only real bug here is the handling of this one.
In the meantime, the workaround is to redefine the
clsalias in PowerShell to be a combo ofclear-hostand the escape sequence.Ahh, I must have mixed it up at some point! Thank you for clarifying.
Anyway, for anybody else who runs into this issue, here’s a workaround recipe for your Profile.ps1:
Side note: I’m not sure I fully understand why this needs
[2Jin it. If it’s omitted, and you use it to prefix another command (i.e.cls; ls c:\windows), then this exhibits the aforementioned issue where the final line of scrollback remains, and can be seen if you scroll up. I would expectclear-hostto fully clear the screen, and then[3Jto fully clear scrollback, so[2Jshould be redundant?🎉This issue was addressed in #5627, which has now been successfully released as
Windows Terminal Release Candidate v0.11.1251.0 (1.0rc1).🎉Handy links:
I am thankful to have stumbled upon this issue while looking for something else as I couldn’t quite figure out why prior history would come back after I would run a new command following a clear. Until now, I didn’t scroll up to notice the root of the problem.
I am using Version 0.7.3382.0 of Windows Terminal Preview where the published work-around has no effect.
I see the same issue in VSCode 1.40.2 using the Powershell Extension v2019.11.0, however I am happy to confirm that the given work-around achieves clearing the entire window buffer.
clear-host; echo "$([char]27)[2J$([char]27)[3J"To make this work in my Microsoft.VSCode_profile.ps1 file I had to use the following. Note that rather than overwrite the existing alias, I just used ‘cl’ since it wasn’t an existing command on my machine.
I am using the latest version (0.6.2951.0 ) of the terminal from the store and the workaround does not seem to work.
The command
seems to simply print an empty line. The full
seems to act the same as
which just clears the visible part of the terminal and not the scrollback. And this acts weird with powershell, since it clears the screen, but if the the input cursor was at the bottom, after clearing the screen the cursor is at the bottom of the screen:
Calling
clsin cmd, orclear-hostin powershell, orclearin bash on WLS will all simply clear the visible part of the terminal and not the scrollback. At least in powershell it does not have the weird behavior described above. PressingCtrl+Lin powershell or bash will do the same.To me it looks like there is currently no way to clean the scrollback.
So if this problem originates from the console app and not Terminal, what about PowerShell?
@mixmastamyk the actual issue tracking
\e[3Jnot working in the Windows Terminal is #2715, which is still very open 😉I’ll second @Boereck’s comment for the latest release (Version 0.7.3291.0). Nothing seems to clear the scrollback for me, from
clear,printf "\e[3J",resetortput resetunder WSL (Ubuntu 18.04, withTERMvariable is set toxterm-256color),clsundercmd.exeorecho "$([char]27)[3J"with Powershell.(I just tested locally: Emitting CSI 3 J through conpty does work, and does clear the scrollback.)
Here’s the relevant pwsh issue: https://github.com/PowerShell/PowerShell/issues/8606
There’s also a related corefx issue for
Console.Clear(): https://github.com/dotnet/corefx/issues/34463However, it is not clear to me whether they’re taking the new terminal into account. Of note, the corefx issue relies on the ANSI escape sequence that, if supported, is meant to clear the entire buffer:
␛[3JHowever, it does not appear to be respected by the new terminal:Thus, their fix will not work in this case. You need to implement it on your end, as well.
Furthermore, if you do implement it, then it will also provide an immediate workaround for users, since we can then create aliases that simply echo the above sequence (this is already common on Unix-likes, where most terminals do respect this sequence, but
cleardoesn’t use it).@nelson6e65 Yes, but what are you using?
clstraditionally cleared everything.cleartraditionally scrolled to a new screen, in effect leaving scrollback. Think form-feed.clearon Linux defaults to clearing the scrollback also, but you can pass-xto avoid that.cmddoesn’t support any other way, to my knowledge. All or nothing. This team has said they won’t add anything to it either. It’s done.cmd?However,
Ctrl-L(i.e. form-feed) for clearing just the current “screen.”cmddoesn’t support it, but theyorishell does!I recommend it if you’d like a simple everyday but more modern DOS-like shell.
@nelson6e65 , I believe the terminal supports it, since it supports Unixy behavior. Sounds like it needs to be implemented in your shell. Perhaps make an alias that prints the ansi escapes to do the scroll yourself in the meantime.
as per bot, I just updated Terminal app from store. running
clscmd worked. also I’m not completely sure its the update or the fix mentioned by @jtbrower so far it works for me.So I don’t believe this is something we can change about cmd.exe.
clsis a cmd-intrinsic, something that’s directly built into cmd.exe. It uses the Console API to clear the screen buffer. This works as expected in conhost, but it won’t in any conpty session. In conpty, the only part of the buffer that exists to the commandline application is the actual viewport. So whenclsruns in conpty, it clears the entire viewport, but there’s no scrollback to clear, so that has no affect. Because there’s no way for conpty to magically figure out that the commandline application wanted the scrollback cleared as well, all conpty does in this case is render a “clear viewport” command to the terminal.In a different world, we’d update
clsto use VT to clear the buffer instead of the API. Then,clswould specifically tell conpty that it wants both the viewport and the scrollback cleared. Because the “clear scrollback” VT sequence doesn’t really do anything in conpty mode, we forward it to the terminal. In that world,clswould work exactly as it does in conhost.Unfortunately, we don’t live in that world. We live in the universe where cmd.exe is parked indefinitely, and we can’t make any changes to it. 100% of the time we think we have a trivial change we could make to cmd.exe, it results in a nightmare of back-compat bugs (for whatever reason). So while this does have a technically feasible solution, it has a bureaucratically impossible solution.