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