-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"System.Console.Clear()" does not clear the scroll buffer on Linux. #84351
Comments
Tagging subscribers to this area: @dotnet/area-system-console Issue DetailsDescriptionIn this document, scroll buffer refers to "an area that is normally outside the display range of the console screen and is not displayed, but can be displayed by scrolling". The spec notes for
In Linux, the Reproduction Steps
Expected behaviorLike the Actual behaviorUnlike the 'clear' command, it clears the screen but not the scroll buffer. Regression?No response Known WorkaroundsExecute ConfigurationOS: Ubuntu 20.04.6 LTS (Linux on Windows) Other information1. Findings of source codeAfter examining the source code of the UNIX version of the
2. Findings on a real machine (ubuntu on "Linux on Windows")
3. My thoughts on this issue3.1 About the implementation of
|
Author: | rougemeilland |
---|---|
Assignees: | - |
Labels: |
|
Milestone: | - |
Footnotes
-
I think a better way to find out about this is to examine the source code of the Linux
clear
command (which is actually thetput
command). However, I couldn't find the source code for it, so I checked it with a real machine.
In many terminals including ubuntu (Windows terminal) the capabilityclear_screen
is defined as"\u001bH\u001b[2J"
.
At least on a real machine (Ubuntu 20.04.6 LTS), outputting"\u001b[3J"
followed by"\u001b[2J"
does not clear the scroll buffer completely. ↩
Big thanks for a very detailed analysis of the problem.
It sounds very reasonable to me. Would you like to send a PR with a fix? |
Does "PR" mean "pre-release"?
I'm sorry if I misunderstood. |
Hi @rougemeilland , PR means Pull Request, that is, offer a fix to this repo if you would like. We are always happy to have new contributors. |
Some terminals define an extra sequence to clear the terminal scroll buffer. Using it after the clear sequence makes Clear() work like the 'clear' command. Fix dotnet#84351
* Use E3 to clear console on Unix when possible Some terminals define an extra sequence to clear the terminal scroll buffer. Using it before the clear sequence makes Clear() work like the 'clear' command. Fix #84351
Description
In this document, scroll buffer refers to "an area that is normally outside the display range of the console screen and is not displayed, but can be displayed by scrolling".
The spec notes for
System.Console.Clear()
says:In Linux, the
clear
command is equivalent to the MS-DOScls
command. But in LinuxSystem.Console.Clear()
only clears the console screen and not the scroll buffer. This is a different behavior than theclear
command.Reproduction Steps
System.Console.Clear()
.Expected behavior
Like the
clear
command, both the scroll buffer and the screen are cleared.Actual behavior
Unlike the 'clear' command, it clears the screen but not the scroll buffer.
Regression?
No response
Known Workarounds
Execute
System.Console.Out.Write("\u001b[3J")
after executingSystem.Console.Clear()
. (unless standard output is redirected)This workaround is not perfect. Because the escape sequence
"\u001b[3J"
is not supported by all terminals.Configuration
OS: Ubuntu 20.04.6 LTS (Linux on Windows)
Architecture: x64
.NET Runtime: .NET 6.0.15 / .NET 7.0.4
Terminal: ubuntu (Windows terminal version)
Other information
1. Findings of source code
After examining the source code of the UNIX version of the
System.ConsolePal
class, I found the following.System.Console.Clear()
outputs the value of the terminfo string capabilityclear_screen
to standard output. (I was wondering why the output destination is fixed to standard output, but I won't touch on that in this document.)2. Findings on a real machine (ubuntu on "Linux on Windows")
man terminfo
, the description of the capabilityclear_screen
said "clear screen and home cursor".TERM
environment variable and it seems to be emulating a terminal called "xterm-256color".clear_screen
is"\u001b[H\u001b[2J"
. The action of this escape sequence is "move the cursor to the upper left corner of the console window and clear the console window".3. My thoughts on this issue
3.1 About the implementation of
System.Console.Clear()
in .NETThe current .NET implementation prints the value of the string capability
clear_screen
to the terminal.The terminfo manual defines the behavior of the string capability
clear_screen
as "clear the screen and move the cursor to the home position", and doesn't say anything about scroll buffers.On my real machine the string capability
clear_screen
value is"\u001b[H\u001b[2J"
. This value means "move the cursor to the upper left corner and clear the screen".This is probably due to the lack of a general way to determine the size of the scroll buffer in the first place.
I guess that's why .NET implements it like this:
System.Console.Clear()
is to "clear the console buffer", but since "console buffer = = console window", it only clears the console window (screen).3.2. Problems with current
System.Console.Clear()
Admittedly, the above logic is correct when it comes to working within a .NET application.
However, many virtual consoles such as the Windows terminal allow the screen to be scrolled by operating the scrollbar or mouse, allowing the user to view the contents of the scroll buffer before
System.Console.Clear()
is called.Text that the application should have cleared by calling
System.Console.Clear()
is visible to the user. I find this very inconvenient in some cases.Am I stating something I can't deal with? I do not think so. Because the Linux
clear
command can actually clear the scroll buffer and screen. This is exactly the behavior I would expect.3.3. Countermeasures
So why is the
clear
command capable of such behavior? The clue was in the online manual for theclear
command.Some terminals define the extended capability
E3
. According to the confirmation on the actual machine (Ubuntu 20.04.6 LTS), the extended capabilityE3
is defined in the terminfo of the terminal below.I suggest the following method.
E3
,System.Console.Clear()
uses it to clear the console.E3
is not defined,System.Console.Clear()
clears the console in the traditional way using only the capabilityclear_screen
.3.4. How to implement countermeasures
On most terminals, with a few exceptions, the extended capability
E3
has the value"\u001b[3J"
, and the "xterm" manual describes this escape sequence as "Erase Saved Lines".When I checked the operation of extended capability
E3
on the actual machine, only the scroll buffer was cleared, and the screen was not cleared. In other words, even when using the extended capabilityE3
, it must be used in conjunction with the capabilityclear_screen
.I think it's good to output the escape sequence in the following procedure.
E3
is defined.E3
is defined, print the value of the capabilityclear_screen
followed by the value ofE3
.E3
is not defined, print the value of the capabilityclear_screen
.Note that you must print
E3
afterclear_screen
1.April 12th, 2023 postscript: I found the source code for the
clear
command on debian. Below is an excerpt.According to this, it seems that the value of the capability
clear_screen
is obtained from terminfo and output, and if the capabilityE3
exists in terminfo, its value is obtained and output.The
clear
command can suppress clearing of the scroll buffer by specifying the-x
option. I think that's what thelegacy
parameter in the above source code is for.Footnotes
I think a better way to find out about this is to examine the source code of the LinuxHowever, I couldn't find the source code for it, so I checked it with a real machine.clear
command (which is actually thetput
command).In many terminals including ubuntu (Windows terminal) the capability
clear_screen
is defined as"\u001bH\u001b[2J"
.At least on a real machine (Ubuntu 20.04.6 LTS), outputting
"\u001b[3J"
followed by"\u001b[2J"
does not clear the scroll buffer completely. ↩The text was updated successfully, but these errors were encountered: