Terminal crate


#1

I’m currently trying to create a new cross-platform terminal crate currently located at github.com/terminus. Eventually, I’d like it to be a sort of backwards-incompatible term-2.0, without the Boxs and with some extra features, enough to build a library like ncurses on top that is cross-platform.

Eventually, I’m hoping I can get it merged into term, but this is a way for me to make progress without having to make changes to the term crate.

Currently it’s missing a lot of the functionality in term (for example terminfo is entirely missing as I’m on windows at the moment).

I’m just posting here in case anyone can offer any help or encouragement, or maybe tell me that I’m wasting my time and someone else has already done it :slight_smile:.

A part of this is going to be creating a separate termcap/terminfo crate with the TerminfoTerminal part of term, and I’d want advice on this before I claimed any crates.io names.


Terminal platform abstraction
#2

Update: Old functionality from WinConsole is finished, plus cursor positioning.


#3

You might consider investigating termcolor (which Cargo now uses) and wincolor for the underlying Windows console functionality. The crate only covers colors and doesn’t do as much as the term crate does (it is a design decision to ignore the terminfo database), but it is cross platform and was specifically designed to work well in mutlithreaded command line applications.

I’m open to expanding the reach of termcolor or making its API better, or you might consider building on top of it.


#4

If someone switches rustc from trem-2 to termcolor or something else, which does not try to read terminfo on windows and just uses ANSI escapes, that would be super-duper useful for IntelliJ Rust, which at the moment can’t show colored output for rustc on windows!


#5

Win10 supports ansi escapes, new term libraries should try to use that if it’s supported by the system, since it looks like the legacy console API is not going to be updated further.


#6

I’ve been working on a terminfo (no termcap) crate called tinf, which might be useful to you?


#9

The wincolor crate is for interacting with the Windows console. Why do you think it should use ANSI escapes? ANSI escapes are handled in termcolor. If you want to output ANSI escapes on Windows, then all you need to do is ask termcolor to do it. But if you want to use the console, then you can do that too. In fact, termcolor will first try to detect the presence of a console, and if it exists, use it, but otherwise, will fall back to ANSI. In practice, you often combine this with something like the atty crate, which has a cross platform way (including for MSYS2 terminals) of determining whether you’re printing to a tty or not.

Not using the console isn’t actually acceptable in applications that ship to end users because not everyone is using Windows with support for ANSI escapes. Moreover, I don’t think ANSI escape support is enabled by default on Windows, you need to toggle an option somewhere to enable it.


#10

I see - I hadn’t read the source of termcolor, thanks for clarifying.

What I’d like is a single library for handling terminal activity, using something like the capabilities that I’m messing about with to let the programmer know what functionality is available.

I’d like the programmer not to have to really know anything about the history of vt100s etc.

The way I see this happening is to have a single Terminal struct that delegates methods to different internal structs depending on what is available, as you say in your post, but doing this for the programmer.

You can do some filtering at compiletime, as in winterm, and some at runtime.

I’d like this to include commands/sequences for moving the cursor/etc besides color. You could then build a really nice cross-platform TUI toolkit for quickly knocking up user interfaces that will work anywhere.


#11

New versions of Windows default to the new console that supports ANSI escapes - there is a “use legacy console” option but it’s not the default. This is what the next versions of PowerShell and PSReadLine use, instead of the console APIs. You’d have to detect support for it - obviously you can’t just blindly enable ANSI on all Windows, but it’s the better option on versions that support it.

https://github.com/PowerShell/PowerShell/issues/2381#issuecomment-256692061

https://github.com/lzybkr/PSReadLine/pull/561


#12

I had two points:

  1. ANSI needs to be explicitly enabled by setting ENABLE_VIRTUAL_TERMINAL_PROCESSING on the console.
  2. Not all Windows users have this functionality, so the console is still useful.

That’s it.


#13

Not disagreeing with either of those. Just pointing out that MS has decided to support ANSI (and only that for new features) going forward. I certainly don’t think you should alienate users in older versions.


#14

I was thinking that whatever the canonical terminal crate was, it could have many internal terminal implementations and then have some logic to detect and use the best at runtime (filtering at compiletime as well).

So windows would have a WinconTerminal, and a WinAnsiTerminal (or maybe just AnsiTerminal for both windows and linux), and maybe a TerminfoTerminal. These could delegate to external crates if it was useful.


#15

Take care that windows support doesn’t fall prey to the resource leaks that plague term.