adamdruppe / arsd

This is a collection of modules that I've released over the years. Most of them stand alone, or have just one or two dependencies in here, so you don't have to download this whole repo.
http://arsd-official.dpldocs.info/arsd.html
530 stars 125 forks source link

[terminal] stderr output in Terminal #319

Closed rtbo closed 2 years ago

rtbo commented 2 years ago

Hi Adam, I use your Terminal struct in log module to log info in colors when connected to tty. AFAICT, Terminal only allows to print to stdout, is it correct? Is there a possibility to print to stderr as well?

adamdruppe commented 2 years ago

This constructor: http://arsd-official.dpldocs.info/arsd.terminal.Terminal.this.3.html

lets you specify different file descriptors. 1 = stdout, 2 = stderr. I've never tested it with stderr, possible it won't work right, especially if it has been redirected to a file (that will almost definitely throw an exception).

But there's a pretty good chance it will work at least on linux.

rtbo commented 2 years ago

Indeed, the following code do not compile on Windows, but works as intended on Linux:

    auto term = Terminal(ConsoleOutputType.linear, 0, 2);

We miss the Terminal.stderrIsTerminal helper though, but that one is not too difficult to write! (isatty(2) is even much shorter)

adamdruppe commented 2 years ago

Yeah, on Windows, it always uses STD_OUTPUT_HANDLE. I could probably move that to a thing too.

The reason that fileno constructor exists is actually to support my nested terminal emulator, which doesn't work on Windows anyway. Hence why it is posix only.

But I could add it if you need it, it is just a bit of copy pasta.

rtbo commented 2 years ago

Don't bother for me, your module is really overkill for my simple needs, I will probably switch for a code of my own. But thanks for the help!

adamdruppe commented 2 years ago

Cool, yeah, for just colors you can simply embed the escape sequences. Even on Windows nowadays, you have to call a function to enable it (https://docs.microsoft.com/en-us/windows/console/setconsolemode note specifically the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag), but then it should work there too. Can be done in like 1% of the lines of my whole module.

rtbo commented 2 years ago

Thanks for pointing this out! I was not sure how it's done on Windows and was looking through the 7800 lines of your module!

adamdruppe commented 2 years ago

Yeah, the module uses the older Windows functions (which i think are generally better designed, and obviously far more compatible since they'll work back for decades whereas the new way is only the last couple years) but anyway the code is here:

https://github.com/adamdruppe/arsd/blob/master/terminal.d#L1569

The main function being this one: https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute

You just have to manage your buffer since the color isn't inline with the string. That's why mine has a flush() call first. Still not too hard, but the new way is a bit simpler to do cross platform since it is the same as the Linux way.

BTW when navigating a new codebase, what I like to do is jump to the definition of the function you use. Then jump to the next definition if there's a version block or other call, etc. That's how I work almost all the time - hence why the size of the file isn't as important as the call depth of functions in my style.

Some of the terminal stuff is legitimately complicated - dealing with mouse input on linux for example is a huge pain - but some of it is really simple too, just tucked in the middle of it. color is on the easier side. let me know if you have more trouble, I can walk through more as needed.