Skip to content
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

cls - Clear screen API and hotkey #273

Closed
mixmastamyk opened this issue Oct 7, 2018 · 10 comments
Closed

cls - Clear screen API and hotkey #273

mixmastamyk opened this issue Oct 7, 2018 · 10 comments
Labels
Issue-Docs It's a documentation issue that really should be on MicrosoftDocs/Console-Docs Issue-Question For questions or discussion Product-Cmd.exe The issue is related to the legacy command interpreter, CMD.exe. Product-Conhost For issues in the Console codebase

Comments

@mixmastamyk
Copy link

Thanks for all the improvements lately and apologies that I'm not registered on the other site.

I'm here to complain about the API to clear the screen/console. Looks like it was designed by clowns, where you have to iterate over the whole grid to fill it with spaces. This is particularly hard to implement with Python and ctypes, though it doesn't get much easier in other languages:

Could we get a simple method, like for example, setting the title is?

- kernel32.SetConsoleTitleW(title)
- kernel32.ClearConsoleScreenPlease()

Also, while we're on the subject, please add a "Ctrl+L" hotkey to clear the screen. I hit that instinctively when away from Linux and OSX, and always a pain when it doesn't work on Windows.

Thanks again! 

Your Windows build number: 17134

@oising
Copy link
Collaborator

oising commented Oct 7, 2018

The CTRL+L keystroke works in powershell by way of the default psreadline module that is loaded in every session. It's unlikely to be ever added by default to the cmd.exe command processor.

@zadjii-msft
Copy link
Member

Well, if you're on Windows 10 you can always use Virtual Terminal Sequences to clear the screen too. If you enable VT processing (with SetConsoleMode), you can emit "\x1b[2J" to clear the current viewport, or "\x1b[3J" to clear the "scrollback" (the region of the screen above the viewport). Emitting 2J then 3J would then clear the viewport, then the entire history, much like cls does today.

It should be known that in bash and other Linux shells, \x1b[2J is how the Ctrl+L keystroke is usually implemented.

As far as adding a hotkey to cmd.exe, @oising is correct about that. Cmd uses line input, meaning it reads an entire line of input from the console at a time, not character-by-character. That means cmd.exe can't know immediately when you've pressed ctrl+L. Changing this behavior (using line input for cmd.exe) is definitely not something we're about to change.

@zadjii-msft zadjii-msft added Issue-Question For questions or discussion Product-Conhost For issues in the Console codebase labels Oct 8, 2018
@eryksun
Copy link

eryksun commented Oct 8, 2018

Cmd uses line input, meaning it reads an entire line of input from the console at a time, not character-by-character. That means cmd.exe can't know immediately when you've pressed ctrl+L.

CMD uses the pInputControl parameter of ReadConsole to implement tab (Ctrl+I) completion. A cooked read with this parameter defined returns immediately whenever any wakeup-mask control character is typed. So there's no technical limitation that prevents extending CMD to support clearing the screen via Ctrl+L. That said, it isn't possible to retain the current line of input unchanged since the console writes the control character in the input buffer, which may overwrite an existing input character, depending on the cursor position.

@miniksa
Copy link
Member

miniksa commented Oct 8, 2018

The simplest way to clear the screen is to use the ScrollConsoleScreenBuffer API.

Set the scroll rectangle to the entire screen, use a null clip rectangle, set the destination origin to scroll everything up and off the top of the screen (X = 0, Y = -buffer height from GetConsoleScreenBufferInfoEx), and give us a fill value in the last parameter that you want to apply to every cell.

This is actually how cmd.exe's cls performs it.

I've filed MicrosoftDocs/Console-Docs#44 for you so I can go update the documentation with this information when I get a chance.


As for Ctrl+L, we're not going to be changing cmd.exe to do that. Technical limitations are never the problem changing cmd.exe, it's the compatibility nightmare.


Unless proven otherwise, I think that provides a solution to the two concerns in this issue so I'll close it. We'll follow up with the documentation issue on the other side. Thanks.

@miniksa miniksa closed this as completed Oct 8, 2018
@miniksa miniksa added Issue-Docs It's a documentation issue that really should be on MicrosoftDocs/Console-Docs Product-Cmd.exe The issue is related to the legacy command interpreter, CMD.exe. Product-Conhost For issues in the Console codebase and removed Product-Conhost For issues in the Console codebase labels Oct 8, 2018
@mixmastamyk
Copy link
Author

mixmastamyk commented Oct 8, 2018

Hold on one sec. ;-)

That's still a lot of work to do what should be a single method invocation. When clearing the screen there is basically one decision, include the scrollback buffer or not? .ClearScreen(true) is the proper level for that API.

To disagree with that would be similar to making an argument "let's necessitate that everyone who sets the console title should be forced to draw the characters manually on the title bar, it's not hard. First just clear the rectangle and paint..." Too much implementation is exposed.

Next, the fact that the bash window (and apparently Powershell) implement Ctrl+L to clear should make it clear that this is not only possible, but highly possible, hehe.

Re: Compatibility nightmare with Ctrl+L? Console recently implemented Ctrl+C which is far more problematic, and several others like Ctrl+V. Ctrl+L was never as highly used in console apps, and in any case, that's what the "Enable Ctrl key shortcuts" preference is for.

So basically Powershell, WSL, MacOS, Linux, and BSDs handle the hotkey, but not cmd?

Thanks,

@miniksa
Copy link
Member

miniksa commented Oct 8, 2018

You can manage a clear screen with or without the backing buffer using GetConsoleScreenBufferInfo and ScrollConsoleScreenBuffer relatively simply. If you want just the viewport, restrict your scroll rectangle to just the viewport window returned. If you want the whole thing, use the entire buffer size. It's not one API, it's two, sure. But it's a bit easier than all the fill steps.

I'm not disagreeing that it could be easier. It could. We're just actively avoiding adding new Win32 APIs to the console wherever possible. We're focusing our efforts on things like Virtual Terminal processing and the PTY interfaces instead. I want to set expectations here that it's extremely unlikely we build a new API to do this. We would rather folks move to VT instead to align with every other platform.


For part 2, we're not making changes to CMD.exe. It's in maintenance mode. Yes, absolutely everyone will handle that hotkey except CMD.exe. My apologies. It's the same boilerplate reasoning from #217 (comment).

The fact that the key sequences you mention that were implemented were problematic is exactly why we're resisting adding more. It doesn't matter if we think they're a little less problematic or a little more... we learned our lesson from that and we're not intercepting more keys in conhost unless it is impossible to do it anywhere else and a high enough priority to outrank the other things that folks want us to accomplish.

@zadjii-msft
Copy link
Member

zadjii-msft commented Oct 8, 2018

First, Ctrl+C is a lot easier. You can presume the only time you want to copy text is when there's a selection. If there's not a selection, then send the ctrl-C event. If there is a selection, copy the text. That's easy.

Ctrl+V is much harder, because that can be invoked at any time. Which is also why we placed the handling of it on Ctrl+Shift+V, and required users to opt into that behavior. If users have some legacy app that maps something important to Ctrl+Shift+V, then users had to opt in to that behavior.

Secondly, we're not about to change the Console API. We might add more modes to the console modes accessibly with Get/SetConsoleMode, but we're definitely not about to add new client APIs. We are adding support for more and more VT sequences, which I've described how to use above, and are an easy, cross-platform way for manipulating the terminal state.

I'm not suggesting that the console API wasn't written by clowns, just that it was written a LONG time ago, before any of us were here, and we're not about to change that.

You're also confusing cmd and conhost. cmd.exe is the shell (like bash, powershell, zsh, fish, and so many more). Conhost is the terminal (like Terminal.app, Iterm2, gnome-terminal, etc). Shells are the ones that implement Ctrl+L clearing the screen, not terminals.

Ctrl+L was never as highly used in console apps

Just because something's not highly used also doesn't mean it isn't being used. Someone's workflow somewhere depends to them being able to type "^L" in the input to a cmd.exe script somewhere. I don't judge why, I just don't break.


EDIT: Yea what @miniksa said

@mixmastamyk
Copy link
Author

Ok, thanks for the info, I appreciate it. To be honest, I would have been happier if y'all never touched conhost etc, and just built a brand new modern "terminal subsystem" so to speak. But, you started improving the console. So be it.

On compatibility: There is an opt-in preference for the new Ctrl-key behavior. Shouldn't that avoid the woes? Ancient software has legacy mode as well.

@miniksa
Copy link
Member

miniksa commented Oct 8, 2018

In hindsight, we maybe should have never touched conhost.exe and started fresh. But I don't think it would have been possible to be successful without what we know now, which was only possible by mucking about with conhost.exe. Everything's a trade off. In our case, a lot of what we've done is driven by on-the-job learning. No one ever dropped an instruction manual (or any documentation or spec) when they handed us the console project. :(

Yeah, there's a preference. But now we have 3 states. The legacy one, the 2015-2018 state, and the 2019+ state. I'd rather just not get into a deeper mess. There's a handful of people writing CMD.exe clones that are better than CMD.exe out there. There are alternative shells and scripting languages that suck a whole lot less than CMD and batch script. If Ctrl+L is the last straw that makes you choose one of those alternatives over sticking with CMD.exe, wonderful. Go to the promised land of a better shell.

@mixmastamyk
Copy link
Author

Ok, I use Windows primarily in VMs with snapshots so the non-powershell cmd default is important for casual interactive commands. For scripting I normally use Python.

Luckily this VM has bash in it, so guess I'll use that. But it feels a bit disconnected, in its own world.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Docs It's a documentation issue that really should be on MicrosoftDocs/Console-Docs Issue-Question For questions or discussion Product-Cmd.exe The issue is related to the legacy command interpreter, CMD.exe. Product-Conhost For issues in the Console codebase
Projects
None yet
Development

No branches or pull requests

5 participants