# Terminal crate

**URL:** <https://internals.rust-lang.org/t/terminal-crate/6057>\
**Category:** libs\
**Created:** [October 15, 2017, 7:14pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057 "2017-10-15T19:14:10Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![derekdreery](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/derekdreery/32/2632_2.png) [@derekdreery](https://internals.rust-lang.org/u/derekdreery)\
**Post date:** [October 15, 2017, 7:14pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057/1 "2017-10-15T19:14:10Z")

</div>

I'm currently trying to create a new cross-platform terminal crate currently located at [github.com/terminus](https://github.com/). Eventually, I'd like it to be a sort of backwards-incompatible term-2.0, without the `Box`s 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 🙂.

> 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](http://crates.io) names.

---

<div class="post-metadata">

**Author:** ![derekdreery](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/derekdreery/32/2632_2.png) [@derekdreery](https://internals.rust-lang.org/u/derekdreery)\
**Post date:** [October 16, 2017, 9:27pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057/2 "2017-10-16T21:27:03Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![burntsushi](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/burntsushi/32/279_2.png) [@burntsushi](https://internals.rust-lang.org/u/burntsushi)\
**Post date:** [October 16, 2017, 10:10pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057/3 "2017-10-16T22:10:32Z")

</div>

You might consider investigating [`termcolor`](https://docs.rs/termcolor) (which Cargo now uses) and [`wincolor`](https://docs.rs/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.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [October 16, 2017, 10:41pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057/4 "2017-10-16T22:41:37Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![parkovski](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/parkovski/32/2730_2.png) [@parkovski](https://internals.rust-lang.org/u/parkovski)\
**Post date:** [October 17, 2017, 2:54am UTC](https://internals.rust-lang.org/t/terminal-crate/6057/5 "2017-10-17T02:54:47Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![edmccard](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/edmccard/32/2258_2.png) [@edmccard](https://internals.rust-lang.org/u/edmccard)\
**Post date:** [October 17, 2017, 11:01am UTC](https://internals.rust-lang.org/t/terminal-crate/6057/6 "2017-10-17T11:01:58Z")

</div>

> [@derekdreery](#):
>
> 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](http://crates.io) names.

I've been working on a terminfo (no termcap) crate called [tinf](https://crates.io/crates/tinf), which might be useful to you?

---

<div class="post-metadata">

**Author:** ![burntsushi](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/burntsushi/32/279_2.png) [@burntsushi](https://internals.rust-lang.org/u/burntsushi)\
**Post date:** [October 17, 2017, 11:21am UTC](https://internals.rust-lang.org/t/terminal-crate/6057/9 "2017-10-17T11:21:16Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![derekdreery](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/derekdreery/32/2632_2.png) [@derekdreery](https://internals.rust-lang.org/u/derekdreery)\
**Post date:** [October 17, 2017, 11:23am UTC](https://internals.rust-lang.org/t/terminal-crate/6057/10 "2017-10-17T11:23:02Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![parkovski](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/parkovski/32/2730_2.png) [@parkovski](https://internals.rust-lang.org/u/parkovski)\
**Post date:** [October 17, 2017, 2:49pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057/11 "2017-10-17T14:49:17Z")

</div>

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/PowerShell/PowerShell/issues/2381#issuecomment-256692061)

[https://github.com/lzybkr/PSReadLine/pull/561](https://github.com/lzybkr/PSReadLine/pull/561)

---

<div class="post-metadata">

**Author:** ![burntsushi](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/burntsushi/32/279_2.png) [@burntsushi](https://internals.rust-lang.org/u/burntsushi)\
**Post date:** [October 17, 2017, 3:25pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057/12 "2017-10-17T15:25:37Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![parkovski](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/parkovski/32/2730_2.png) [@parkovski](https://internals.rust-lang.org/u/parkovski)\
**Post date:** [October 17, 2017, 3:55pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057/13 "2017-10-17T15:55:51Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![derekdreery](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/derekdreery/32/2632_2.png) [@derekdreery](https://internals.rust-lang.org/u/derekdreery)\
**Post date:** [October 17, 2017, 4:38pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057/14 "2017-10-17T16:38:24Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Ralith](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ralith/32/4047_2.png) [@Ralith](https://internals.rust-lang.org/u/Ralith)\
**Post date:** [October 19, 2017, 4:15pm UTC](https://internals.rust-lang.org/t/terminal-crate/6057/15 "2017-10-19T16:15:21Z")

</div>

Take care that windows support doesn’t fall prey to [the resource leaks that plague term](https://github.com/Stebalien/term/issues/63).

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:29am UTC](https://internals.rust-lang.org/t/terminal-crate/6057/16 "2019-03-25T08:29:06Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
