Expand description
Terminal output for CLIs. It decides whether to write colour and at what depth, how wide the output is, and where an escape sequence is written.
The crate works on the plain lines ctl_text produces, which it
re-exports. A Terminal states what is known about one output stream. An
Encoder turns lines into bytes, adding the styling after layout. A
Console puts the two together: it renders any
Renderable at the width of its stream and writes
it.
§Quick start
Decide once for a stream, then print. from_probe takes the stream’s
facts and an environment lookup, so this example needs no terminal; a
program calls Console::from_process instead and passes
ColorMode::Auto.
use std::collections::HashMap;
use ctl_term::ctl_text::anstyle::AnsiColor;
use ctl_term::ctl_text::{Style, Text};
use ctl_term::{ColorMode, Console, DetectOptions, Probe, Stream, Terminal};
let variables = HashMap::from([("FORCE_COLOR", "3")]);
let env = |name: &str| variables.get(name).map(|value| (*value).to_owned());
let terminal = Terminal::from_probe(
Probe::Redirected,
ColorMode::Auto,
DetectOptions::new(),
&env,
);
let console = Console::new(Stream::Stdout, terminal);
let red = Style::new().fg_color(Some(AnsiColor::Red.into()));
let text = Text::styled("failed", red);
assert_eq!(console.render(&text), "\u{1b}[31mfailed\u{1b}[0m\n");§Colour
ColorMode::Always writes colour and ColorMode::Never writes none,
whatever NO_COLOR, CLICOLOR, CLICOLOR_FORCE, FORCE_COLOR, and
TERM=dumb hold. They still read the variables that set the depth and the
width, COLORTERM, TERM, FORCE_COLOR, and COLUMNS. Under
ColorMode::Auto these rules apply in order, and the first that matches
wins:
NO_COLORset and non-empty: no colour.CLICOLOR_FORCEset, non-empty, and not0: colour.FORCE_COLORset, non-empty, and not0orfalse: colour.CLICOLOR=0: no colour.TERM=dumb: no colour.- Otherwise colour only when the stream is a terminal.
FORCE_COLOR=0 and FORCE_COLOR=false are neutral: they neither force
colour nor turn it off, so rules 4 to 6 still apply. When the crate reads
the process environment, a value that is not valid UTF-8 counts as set, so
such a NO_COLOR still turns colour off.
When colour is on, the depth is 24-bit when COLORTERM is truecolor or
24bit or FORCE_COLOR=3. It is 256 colours when TERM contains
256color or FORCE_COLOR=2, and 16 colours otherwise.
Terminal::at_depth overrides it.
The Encoder converts every colour to the nearest colour at that depth.
A 24-bit colour on a 16-colour terminal prints as the nearest named
colour, and an underline colour is dropped at 16 colours.
§Width
Widths count terminal cells: a column is one terminal cell. A width takes the first of these that applies:
- An explicit width, which is exact.
- The window of the stream being written.
COLUMNS, when it holds a number from 1 to 65535.- The fallback of
DEFAULT_FALLBACK_WIDTH, 80.
A detected width loses a column buffer of DEFAULT_COLUMN_BUFFER, 2
cells, and never drops below DEFAULT_MINIMUM_WIDTH, 20, unless the
window itself is narrower. A width is at least 1.
The buffer reads no variable until DetectOptions::column_buffer_envs
names some. DetectOptions overrides each of these and can turn each
off.
§A closed pipe
When the reader closes the stream, as head does, a write fails with
Error::BrokenPipe, which is a variant of its own. This crate reports
it and leaves the exit code to the caller. A caller that returns
std::io::Result converts Error with From, and a closed pipe stays
std::io::ErrorKind::BrokenPipe.
§Platforms
The crate supports and tests Unix only. Windows is not supported: the crate does not turn on virtual-terminal mode. On other targets the crate builds but reports no window width.
§Cargo features
detect, on by default, asks the operating system about a stream. It adds
Probe::of, Terminal::detect, the from_process constructors, and
Console::print, and brings in terminal_size. Without it the crate holds
the Encoder, the colour conversion, and Terminal::from_probe, which
need no terminal.
Re-exports§
pub use ctl_text;
Structs§
- Console
- Writes widgets to one output stream, in the colour and at the width decided for that stream.
- Detect
Options - How the width of a stream is decided, and every default it applies.
- Encoder
- Turns lines of styled spans into the bytes a terminal reads.
- Terminal
- What is known about one output stream: whether it is a terminal, whether to write colour, at what depth, and how wide the output is.
Enums§
- Color
Depth - How many colours the terminal can show.
- Color
Mode - Whether to write colour, as the caller asked.
- Error
- Why writing failed.
- Probe
- What the operating system says about one stream: redirected away from a terminal, or a terminal of some width.
- Stream
- A standard output stream.
Constants§
- DEFAULT_
COLUMN_ BUFFER - The cells reserved from a detected width, so a line never touches the edge of the window.
- DEFAULT_
FALLBACK_ WIDTH - The width used when the stream gives none and
COLUMNSis unset, empty, zero, or not a number from 1 to 65535. - DEFAULT_
MINIMUM_ WIDTH - The width a detected width never shrinks below, unless the window itself is narrower.
- RESET
- The SGR sequence that clears every attribute.
Functions§
- ansi256_
to_ ansi16 - The nearest of the 16 named colours to a colour of the 256-colour palette.
- rgb_
to_ ansi16 - The nearest of the 16 named colours to
color. - rgb_
to_ ansi256 - The nearest colour to
colorin the 256-colour palette.