Windows (Insider) Build is 10.0.17713.1002
I'm trying out the new pseudo terminal support, and capturing the output of a program that simply prints hello, world! to stdout produces the following:
[2J[?25l[39m[49m[Hhello, world
Finally, the ConPTY is a new API and a surprisingly sophisticated Pseudo Console infrastructure. There are likely to be a few issues which we鈥檙e keen to hear about and will work diligently to fix where we can. Please keep the feedback coming, and do continue to file issues with repro鈥檚.
We look forward to hearing from you all.
You should leverages VTE and PTY, lots of application implement their own VTE instead, and they only needs PTY. There are already lots of VTE implementation, people have rights to choose which one they use, not restrict to the provided one.
Also *nix world have already accumulated vast number of libraries based on PTY interface, if a compatible API are provided, with little or no changes, they can be reused.
From https://github.com/Microsoft/console/issues/57 you said:
I do want to make a note, whatever we end up implementing is going to allow existing client applications to continue using the full Win32 console API, and ideally it's going to be without forcing 3rd party terminals from implementing the entire console API surface themselves. We'd love to hide the "black magic", and expose only a sane surface to implement on top of.
But you are still introducing "black magic", this issue is definitely your "black magic". why can't we get a clean PTY api ? At least disable all "black magic" by default.
And with the help of existing VTE libraries, implementing the entire console API surface is pretty easy, given PTY api. Sure someone may prefer provided console API, but CreatePseudoConsole/ResizePseudoConsole/ClosePseudoConsole API is more low level PTY API than console API. So I want to build my own VTE on this API.
This is my opinion:
implementing the entire console API surface is pretty easy,
I'm gonna need to stop you there - This is actually straight up impossible. There are a number of Console API's that can't be translated back into VT sequences of any sort. For instance, ReadConsoleOutput. This API lets a client application read an area of the console buffer. In VT, there's no way of doing this, because there is no buffer. In Unix, only the actual terminal emulator has a buffer, the pty is just there to facilitate communication between the terminal and the commandline application.
The last time I took a look at this, these were the console APIs that had no equivalent VT sequence:
AddConsoleAlias
AllocConsole
AttachConsole
FlushConsoleInputBuffer
FreeConsole
GenerateConsoleCtrlEvent
GetConsoleAlias
GetConsoleAliases
GetConsoleAliasesLength
GetConsoleAliasExes
GetConsoleAliasExesLength
GetConsoleCP
GetConsoleCursorInfo
GetConsoleDisplayMode
GetConsoleHistoryInfo
GetConsoleMode
GetConsoleOriginalTitle
GetConsoleOutputCP
GetConsoleProcessList
elements of GetConsoleScreenBufferInfoEx
GetConsoleSelectionInfo
GetConsoleWindow
GetNumberOfConsoleInputEvents
GetNumberOfConsoleMouseButtons
GetStdHandle
HandlerRoutine
PeekConsoleInput
ReadConsole
ReadConsoleInput
ReadConsoleOutput
ReadConsoleOutputAttribute
ReadConsoleOutputCharacter
SetConsoleActiveScreenBuffer
SetConsoleCP
SetConsoleCtrlHandler
SetConsoleHistoryInfo
SetConsoleMode
SetConsoleOutputCP
elements of SetConsoleScreenBufferInfoEx
SetConsoleScreenBufferSize
SetConsoleWindowInfo
SetStdHandle
WriteConsole
WriteConsoleInput
WriteConsoleOutput
why can't we get a clean PTY api ? At least disable all "black magic" by default.
Actually, the conpty API we've created is super simple. You pass in some handles, then you read text and write text two/from those handles.
What we're doing is hiding the "black magic" of the Console API surface from the application calling the conpty API's. In this way, a terminal emulator doesn't need to worry about the fact that for console applications, some api's behave differently with different fonts selected. This isn't the only case where the console API's are weird, and trying to implement all of the quirks of the console API would be a lesson in insanity.
Fortunately, callers of the conpty API's don't need to know anything at all about the console API, and they'll be able to act as terminal emulators for all existing console applications, without those console applications needing to make any changes, to link against new libraries, or change anything.
Also *nix world have already accumulated vast number of libraries based on PTY interface, if a compatible API are provided, with little or no changes, they can be reused.
Hey wadda ya know, the conpty API's are a compatible interface with existing linux terminal emulators. Here's cmd.exe attached to a conpty running attached to gnome-terminal as a head.

Or here's some more proof, this is putty (a terminal emulator for windows) modified to use conpty instead of an ssh connection to a linux machine.

There are lots of limitations of *nix pty interface. ex, keycode input other than ASCII codes. CONPTY API can support extensions, console API can be implemented with these extensions. But a clean pty compatible API must be provided.
What do you mean hiding the "black magic", I saw some XTerm sequence was injected in to output from nowhere. What if my VT is not XTerm compatible, how can you assume my VT understand XTerm sequence ?
I'm glad you tested the compatibility of common used VTE, but why don't you trust communities ? Provide a clean API and let communities fill the gap. They will do their "open source magic" and complete the job.
Re 1: I actually already have a plan in place for a conpty specific extension to enable Console-compatible INPUT_RECORDs via VT, just waiting on having the time to spec and finish it.
re 2: We're trying to hide the "black magic" of the Console API's implementation, rather than expose that and force terminal authors to implement it themselves. This path lets existing linux terminals work with existing console apps with minimal (if any) modifications.
The VT we're synthesizing to render console apps is pretty simple. I'd guess that it's closer to TERM=vt100-265color (if such a termcap existed) than xterm. We're really not emitting anything too extraordinary.
I could imagine in the future enabling other TERM settings for conpty as well, but I do appreciate the simplicity of only having one TERM setting on Windows currently. That way terminal authors know exactly what they're going to get, and don't really need to worry about what the client is trying to do.
I could also imagine a world where we have "passthrough" commandline apps that speak directly to an attached terminal. These would be text-only commandline applications, and then the sequences received by the terminal application would only be what is emitted by the console app. However, these passthrough console apps would have to be authored from scratch, and mixing traditional console apps and passthrough console apps could result in unexpected behavior. It would need a lot of work to get just right, and that's unfortunately not in the cards for the next release. Maybe after that I'll take another look.
I certainly do trust the community to do wonderful things with ConPTY, we're just trying to make their jobs considerably easier. Trying to implement a Console API server with all the existing quirks of the API is insanity, while taking your existing terminal app and hooking it up to conpty is effectively trivial.
these passthrough console apps would have to be authored from scratch, and mixing traditional console apps and passthrough console apps could result in unexpected behavior.
This is why I feel you don't trust communities, leave it to communities, they will fix all unexpected behaviors.
Trying to implement a Console API server with all the existing quirks of the API is insanity, while taking your existing terminal app and hooking it up to conpty is effectively trivial.
From my point of view, hooking up to pure pty is much more easier. Check wslbridge, it exposes a pure pty interface, and there are already several terminal implementations build on it. How could something which has already been easily achieved be insanity ?
Ah but see, wslbridge, winpty, etc are trying to be pseudoterminals on Windows. That's a much easier task then being a pseudoconsole. wslbridge and things like mintty are really useful at running linux-like commandline applications that only read and write text. That's why wslbridge works so well with WSL - any apps you're running in WSL are just reading and writing text. They aren't using the Console API, and they don't emulate the Console behavior. They simply act as Terminal emulators, not Console emulators.
In this sense, WSLBridge exposes a pty interface for applications that can use a TTY interface.
What WSLBridge doesn't do is expose a pty interface for the Console interface. That was our goal with conpty.
If you really want to write a passthrough style application, that only reads and writes text, I'm sure it'll work great in wslbridge/winpty without any extra work, and you can surely write a terminal emulator on top of those interfaces today. However, if you want to be able to write a terminal emulator that can be attached to console applications, using the full console API, you wouldn't be able to do that with wslbridge alone.
For reasons that are hard to explain fully... fixing #279 also contains the fix for this.
Well... it's not that hard to explain... While I was fixing the code for optimizing scrolling, I needed to improve our class for manipulating rectangles and coordinates. And while I was improving that class and adding unit tests, I found an error-prone constructor scattered throughout the code. And then I removed that constructor and lo-and-behold, one of the error-prone uses of the constructor was the ConPTY renderer and it was using it in an erroneous way. Now it's not.
The ConPTY renderer was using the rectangle inclusive of the coordinate 0,0 as its default invalidation area when it ended paint because @zadjii-msft thought he was setting it to an empty rectangle but aforementioned erroneous constructor made it very easy to accidentally set the rectangle encompassing 0,0 instead. Oops.
So the problem should be solved in 3-4 weeks in Insiders builds and I've made it harder for us to make this mistake again in the future.
Most helpful comment
For reasons that are hard to explain fully... fixing #279 also contains the fix for this.
Well... it's not that hard to explain... While I was fixing the code for optimizing scrolling, I needed to improve our class for manipulating rectangles and coordinates. And while I was improving that class and adding unit tests, I found an error-prone constructor scattered throughout the code. And then I removed that constructor and lo-and-behold, one of the error-prone uses of the constructor was the ConPTY renderer and it was using it in an erroneous way. Now it's not.
The ConPTY renderer was using the rectangle inclusive of the coordinate 0,0 as its default invalidation area when it ended paint because @zadjii-msft thought he was setting it to an empty rectangle but aforementioned erroneous constructor made it very easy to accidentally set the rectangle encompassing 0,0 instead. Oops.
So the problem should be solved in 3-4 weeks in Insiders builds and I've made it harder for us to make this mistake again in the future.