Skip to content
This repository was archived by the owner on Aug 12, 2021. It is now read-only.

Commit 871dc00

Browse files
committed
Import libterm from rust-lang/rust
2 parents 2465b19 + a82fd46 commit 871dc00

File tree

7 files changed

+1778
-0
lines changed

7 files changed

+1778
-0
lines changed

src/libterm/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
authors = ["The Rust Project Developers"]
3+
name = "term"
4+
version = "0.0.0"
5+
edition = "2018"
6+
7+
[lib]
8+
name = "term"
9+
path = "lib.rs"
10+
crate-type = ["dylib", "rlib"]

src/libterm/lib.rs

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
//! Terminal formatting library.
2+
//!
3+
//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
4+
//! Terminal][ansi] to provide color printing, among other things. There are two
5+
//! implementations, the `TerminfoTerminal`, which uses control characters from
6+
//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
7+
//! API][win].
8+
//!
9+
//! # Examples
10+
//!
11+
//! ```no_run
12+
//! # #![feature(rustc_private)]
13+
//! extern crate term;
14+
//! use std::io::prelude::*;
15+
//!
16+
//! fn main() {
17+
//! let mut t = term::stdout().unwrap();
18+
//!
19+
//! t.fg(term::color::GREEN).unwrap();
20+
//! write!(t, "hello, ").unwrap();
21+
//!
22+
//! t.fg(term::color::RED).unwrap();
23+
//! writeln!(t, "world!").unwrap();
24+
//!
25+
//! assert!(t.reset().unwrap());
26+
//! }
27+
//! ```
28+
//!
29+
//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
30+
//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
31+
//! [ti]: https://en.wikipedia.org/wiki/Terminfo
32+
33+
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
34+
html_playground_url = "https://play.rust-lang.org/",
35+
test(attr(deny(warnings))))]
36+
#![deny(missing_docs)]
37+
38+
#![deny(rust_2018_idioms)]
39+
40+
#![cfg_attr(windows, feature(libc))]
41+
// Handle rustfmt skips
42+
#![feature(custom_attribute)]
43+
#![allow(unused_attributes)]
44+
45+
use std::io::prelude::*;
46+
use std::io::{self, Stdout, Stderr};
47+
48+
pub use terminfo::TerminfoTerminal;
49+
#[cfg(windows)]
50+
pub use win::WinConsole;
51+
52+
pub mod terminfo;
53+
54+
#[cfg(windows)]
55+
mod win;
56+
57+
/// Alias for stdout terminals.
58+
pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send;
59+
/// Alias for stderr terminals.
60+
pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send;
61+
62+
#[cfg(not(windows))]
63+
/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
64+
/// opened.
65+
pub fn stdout() -> Option<Box<StdoutTerminal>> {
66+
TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
67+
}
68+
69+
#[cfg(windows)]
70+
/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
71+
/// opened.
72+
pub fn stdout() -> Option<Box<StdoutTerminal>> {
73+
TerminfoTerminal::new(io::stdout())
74+
.map(|t| Box::new(t) as Box<StdoutTerminal>)
75+
.or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
76+
}
77+
78+
#[cfg(not(windows))]
79+
/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
80+
/// opened.
81+
pub fn stderr() -> Option<Box<StderrTerminal>> {
82+
TerminfoTerminal::new(io::stderr()).map(|t| Box::new(t) as Box<StderrTerminal>)
83+
}
84+
85+
#[cfg(windows)]
86+
/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
87+
/// opened.
88+
pub fn stderr() -> Option<Box<StderrTerminal>> {
89+
TerminfoTerminal::new(io::stderr())
90+
.map(|t| Box::new(t) as Box<StderrTerminal>)
91+
.or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>))
92+
}
93+
94+
95+
/// Terminal color definitions
96+
#[allow(missing_docs)]
97+
pub mod color {
98+
/// Number for a terminal color
99+
pub type Color = u16;
100+
101+
pub const BLACK: Color = 0;
102+
pub const RED: Color = 1;
103+
pub const GREEN: Color = 2;
104+
pub const YELLOW: Color = 3;
105+
pub const BLUE: Color = 4;
106+
pub const MAGENTA: Color = 5;
107+
pub const CYAN: Color = 6;
108+
pub const WHITE: Color = 7;
109+
110+
pub const BRIGHT_BLACK: Color = 8;
111+
pub const BRIGHT_RED: Color = 9;
112+
pub const BRIGHT_GREEN: Color = 10;
113+
pub const BRIGHT_YELLOW: Color = 11;
114+
pub const BRIGHT_BLUE: Color = 12;
115+
pub const BRIGHT_MAGENTA: Color = 13;
116+
pub const BRIGHT_CYAN: Color = 14;
117+
pub const BRIGHT_WHITE: Color = 15;
118+
}
119+
120+
/// Terminal attributes for use with term.attr().
121+
///
122+
/// Most attributes can only be turned on and must be turned off with term.reset().
123+
/// The ones that can be turned off explicitly take a boolean value.
124+
/// Color is also represented as an attribute for convenience.
125+
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
126+
pub enum Attr {
127+
/// Bold (or possibly bright) mode
128+
Bold,
129+
/// Dim mode, also called faint or half-bright. Often not supported
130+
Dim,
131+
/// Italics mode. Often not supported
132+
Italic(bool),
133+
/// Underline mode
134+
Underline(bool),
135+
/// Blink mode
136+
Blink,
137+
/// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
138+
Standout(bool),
139+
/// Reverse mode, inverts the foreground and background colors
140+
Reverse,
141+
/// Secure mode, also called invis mode. Hides the printed text
142+
Secure,
143+
/// Convenience attribute to set the foreground color
144+
ForegroundColor(color::Color),
145+
/// Convenience attribute to set the background color
146+
BackgroundColor(color::Color),
147+
}
148+
149+
/// A terminal with similar capabilities to an ANSI Terminal
150+
/// (foreground/background colors etc).
151+
pub trait Terminal: Write {
152+
/// The terminal's output writer type.
153+
type Output: Write;
154+
155+
/// Sets the foreground color to the given color.
156+
///
157+
/// If the color is a bright color, but the terminal only supports 8 colors,
158+
/// the corresponding normal color will be used instead.
159+
///
160+
/// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
161+
/// if there was an I/O error.
162+
fn fg(&mut self, color: color::Color) -> io::Result<bool>;
163+
164+
/// Sets the background color to the given color.
165+
///
166+
/// If the color is a bright color, but the terminal only supports 8 colors,
167+
/// the corresponding normal color will be used instead.
168+
///
169+
/// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
170+
/// if there was an I/O error.
171+
fn bg(&mut self, color: color::Color) -> io::Result<bool>;
172+
173+
/// Sets the given terminal attribute, if supported. Returns `Ok(true)`
174+
/// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
175+
/// there was an I/O error.
176+
fn attr(&mut self, attr: Attr) -> io::Result<bool>;
177+
178+
/// Returns `true` if the given terminal attribute is supported.
179+
fn supports_attr(&self, attr: Attr) -> bool;
180+
181+
/// Resets all terminal attributes and colors to their defaults.
182+
///
183+
/// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
184+
/// was an I/O error.
185+
///
186+
/// *Note: This does not flush.*
187+
///
188+
/// That means the reset command may get buffered so, if you aren't planning on doing anything
189+
/// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
190+
/// calling reset.
191+
fn reset(&mut self) -> io::Result<bool>;
192+
193+
/// Gets an immutable reference to the stream inside
194+
fn get_ref(&self) -> &Self::Output;
195+
196+
/// Gets a mutable reference to the stream inside
197+
fn get_mut(&mut self) -> &mut Self::Output;
198+
199+
/// Returns the contained stream, destroying the `Terminal`
200+
fn into_inner(self) -> Self::Output where Self: Sized;
201+
}

0 commit comments

Comments
 (0)