Rust library for ANSI terminal colours and styles (bold, underline)

Overview

rust-ansi-term ansi-term on crates.io Build status Build status Coverage status

This is a library for controlling colours and formatting, such as red bold text or blue underlined text, on ANSI terminals.

View the Rustdoc

Installation

This crate works with Cargo. Add the following to your Cargo.toml dependencies section:

[dependencies]
ansi_term = "0.12"

Basic usage

There are three main types in this crate that you need to be concerned with: ANSIString, Style, and Colour.

A Style holds stylistic information: foreground and background colours, whether the text should be bold, or blinking, or other properties. The Colour enum represents the available colours. And an ANSIString is a string paired with a Style.

Color is also available as an alias to Colour.

To format a string, call the paint method on a Style or a Colour, passing in the string you want to format as the argument. For example, here’s how to get some red text:

use ansi_term::Colour::Red;

println!("This is in red: {}", Red.paint("a red string"));

It’s important to note that the paint method does not actually return a string with the ANSI control characters surrounding it. Instead, it returns an ANSIString value that has a Display implementation that, when formatted, returns the characters. This allows strings to be printed with a minimum of String allocations being performed behind the scenes.

If you do want to get at the escape codes, then you can convert the ANSIString to a string as you would any other Display value:

use ansi_term::Colour::Red;

let red_string = Red.paint("a red string").to_string();

Note for Windows 10 users: On Windows 10, the application must enable ANSI support first:

let enabled = ansi_term::enable_ansi_support();

Bold, underline, background, and other styles

For anything more complex than plain foreground colour changes, you need to construct Style values themselves, rather than beginning with a Colour. You can do this by chaining methods based on a new Style, created with Style::new(). Each method creates a new style that has that specific property set. For example:

use ansi_term::Style;

println!("How about some {} and {}?",
         Style::new().bold().paint("bold"),
         Style::new().underline().paint("underline"));

For brevity, these methods have also been implemented for Colour values, so you can give your styles a foreground colour without having to begin with an empty Style value:

use ansi_term::Colour::{Blue, Yellow};

println!("Demonstrating {} and {}!",
         Blue.bold().paint("blue bold"),
         Yellow.underline().paint("yellow underline"));

println!("Yellow on blue: {}", Yellow.on(Blue).paint("wow!"));

The complete list of styles you can use are: bold, dimmed, italic, underline, blink, reverse, hidden, and on for background colours.

In some cases, you may find it easier to change the foreground on an existing Style rather than starting from the appropriate Colour. You can do this using the fg method:

use ansi_term::Style;
use ansi_term::Colour::{Blue, Cyan, Yellow};

println!("Yellow on blue: {}", Style::new().on(Blue).fg(Yellow).paint("yow!"));
println!("Also yellow on blue: {}", Cyan.on(Blue).fg(Yellow).paint("zow!"));

You can turn a Colour into a Style with the normal method. This will produce the exact same ANSIString as if you just used the paint method on the Colour directly, but it’s useful in certain cases: for example, you may have a method that returns Styles, and need to represent both the “red bold” and “red, but not bold” styles with values of the same type. The Style struct also has a Default implementation if you want to have a style with nothing set.

use ansi_term::Style;
use ansi_term::Colour::Red;

Red.normal().paint("yet another red string");
Style::default().paint("a completely regular string");

Extended colours

You can access the extended range of 256 colours by using the Colour::Fixed variant, which takes an argument of the colour number to use. This can be included wherever you would use a Colour:

use ansi_term::Colour::Fixed;

Fixed(134).paint("A sort of light purple");
Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup");

The first sixteen of these values are the same as the normal and bold standard colour variants. There’s nothing stopping you from using these as Fixed colours instead, but there’s nothing to be gained by doing so either.

You can also access full 24-bit colour by using the Colour::RGB variant, which takes separate u8 arguments for red, green, and blue:

use ansi_term::Colour::RGB;

RGB(70, 130, 180).paint("Steel blue");

Combining successive coloured strings

The benefit of writing ANSI escape codes to the terminal is that they stack: you do not need to end every coloured string with a reset code if the text that follows it is of a similar style. For example, if you want to have some blue text followed by some blue bold text, it’s possible to send the ANSI code for blue, followed by the ANSI code for bold, and finishing with a reset code without having to have an extra one between the two strings.

This crate can optimise the ANSI codes that get printed in situations like this, making life easier for your terminal renderer. The ANSIStrings struct takes a slice of several ANSIString values, and will iterate over each of them, printing only the codes for the styles that need to be updated as part of its formatting routine.

The following code snippet uses this to enclose a binary number displayed in red bold text inside some red, but not bold, brackets:

use ansi_term::Colour::Red;
use ansi_term::{ANSIString, ANSIStrings};

let some_value = format!("{:b}", 42);
let strings: &[ANSIString<'static>] = &[
    Red.paint("["),
    Red.bold().paint(some_value),
    Red.paint("]"),
];

println!("Value: {}", ANSIStrings(strings));

There are several things to note here. Firstly, the paint method can take either an owned String or a borrowed &str. Internally, an ANSIString holds a copy-on-write (Cow) string value to deal with both owned and borrowed strings at the same time. This is used here to display a String, the result of the format! call, using the same mechanism as some statically-available &str slices. Secondly, that the ANSIStrings value works in the same way as its singular counterpart, with a Display implementation that only performs the formatting when required.

Byte strings

This library also supports formatting [u8] byte strings; this supports applications working with text in an unknown encoding. Style and Colour support painting [u8] values, resulting in an ANSIByteString. This type does not implement Display, as it may not contain UTF-8, but it does provide a method write_to to write the result to any value that implements Write:

use ansi_term::Colour::Green;

Green.paint("user data".as_bytes()).write_to(&mut std::io::stdout()).unwrap();

Similarly, the type ANSIByteStrings supports writing a list of ANSIByteString values with minimal escape sequences:

use ansi_term::Colour::Green;
use ansi_term::ANSIByteStrings;

ANSIByteStrings(&[
    Green.paint("user data 1\n".as_bytes()),
    Green.bold().paint("user data 2\n".as_bytes()),
]).write_to(&mut std::io::stdout()).unwrap();
Comments
  • dynamic linking against regex_macros causes problems unless LD_LIBRARY_PATH is set

    dynamic linking against regex_macros causes problems unless LD_LIBRARY_PATH is set

    While trying to get exa to build I encounter

    target/exa: error while loading shared libraries: libregex_macros-bdbdbfedad0748ac.so: cannot open shared object file: No such file or directory
    

    It only works if I add the target/deps folder to the LD_LIBRARY_PATH.

    This seems related to rust#21861.

    opened by mriehl 9
  • add no-op enable_ansi_support method for other platforms

    add no-op enable_ansi_support method for other platforms

    This commit also moves the code base to the 2018 edition of Rust. This involved changing the import scheme of used modules. Crates do not need to be declared within lib.rs explicitly. The rather get pulled in as soon as they are imported via 'use' the first time.

    opened by mainrs 6
  • Fails to compile on rustc 1.8.0 (db2939409 2016-04-11)

    Fails to compile on rustc 1.8.0 (db2939409 2016-04-11)

    ansi-term fails to build on Debian Stretch testing with above said rustc version.

    The error output is:

    .cargo/registry/src/github.com-88ac128001ac3a9a/ansi_term-0.9.0/src/lib.rs:189:5: 189:23 error: user-defined types or type parameters cannot shadow the primitive types [E0317]
    .cargo/registry/src/github.com-88ac128001ac3a9a/ansi_term-0.9.0/src/lib.rs:189     type str : ?Sized;
                                                                                              ^~~~~~~~~~~~~~~~~~
    .cargo/registry/src/github.com-88ac128001ac3a9a/ansi_term-0.9.0/src/lib.rs:189:5: 189:23 help: run `rustc --explain E0317` to see a detailed explanation
    
    opened by eFrane 5
  • Fix escape sequences for reverse-video and hidden text

    Fix escape sequences for reverse-video and hidden text

    Based on the documentation in: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

    Tested with xterm and gnome-terminal, both of which render reverse-video and hidden text as expected with this change. Without this change, hidden text would show up as reverse-video instead.

    opened by joshtriplett 5
  • Implement Color alias to Colour

    Implement Color alias to Colour

    I thought this was sufficiently silly, so feel free to reject this PR.

    Rust is nice because we can alias exports and we don't have to argue over the Queen's spelling vs. patriotic way to spell color.

    I was able to verify that this does allow for one to use ansi_color::Color::Green

    This PR may be accompanied by changes to the readme or modifications to the version.

    opened by DavidJFelix 5
  • Explicitly set the VT processing ConsoleMode flag

    Explicitly set the VT processing ConsoleMode flag

    A small change to enable_ansi_support to query for the current ConsoleMode setting before optionally setting the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag explicitly, if required.

    This avoids accidentally overwriting any existing changes made to the ConsoleMode setting.

    opened by deadalusai 4
  • Please support painting bytes (&[u8])

    Please support painting bytes (&[u8])

    ansi_term currently only supports painting strings (String or &str). Sometimes, to handle text in unknown character sets, a program will need to emit raw bytes; for instance, git diffs from git2-rs provide the diff text as bytes, because the files diffed might not use UTF-8. I'd like to render diffs with color using ansi_term.

    Please consider adding support to paint bytes with a Colour or Style, perhaps via a new paint_bytes method. This would need to return a new type like ANSIBytes, which couldn't implement Display, but which could support writing to a std::io::Write via .write_all.

    opened by joshtriplett 4
  • fix some ESC codes

    fix some ESC codes

    Hi,

    According to various docs on the web, and to some tests I did on GNOME-terminal and XTerm, some of the codes you use are wrong. Could you fix them ?

    • 6 is another blink (useless)
    • 7 is reverse
    • 8 is hidden

    I can do a PR if you prefer.

    opened by bestouff 4
  • Add the default terminal foreground/background color

    Add the default terminal foreground/background color

    The standard color escape sequences include an escape sequence to set the foreground or background color to the terminal default.

    This uses the name Def rather than Default, to avoid a name conflict with std::default::Default.

    opened by joshtriplett 4
  • Fix the colour chart link for `Colour::Fixed(u8)`

    Fix the colour chart link for `Colour::Fixed(u8)`

    When looking through the docs for some pointers towards designing my own library for ANSI colours I found that the link to the colour chart was broken. I thought I may as well submit a PR fixing it since I'm basically copying your API :wink:

    opened by severen 4
  • Support global toggle via env variable

    Support global toggle via env variable

    Hi @ogham ! I am the author of colored, a library highly influenced by yours, ansi_term. So, thanks for that. :)

    One of the biggest feedback I got when publishing the release notes, was about an option for the user to turn on or off globally the coloring, so I think I should report to you too.

    I was planning to use the RUST_NOCOLOR and RUST_FORCECOLOR env variable for that, I think it would be great if both our lib used the same variable names. What do you think ? I have no strong feeling on anything, I just want the user experience to be superb, so don't hesitate

    linking to Colored tracking issue: https://github.com/mackwic/colored/issues/2

    opened by mackwic 4
  • Rewrite to support generic Display types inside of ANSIString

    Rewrite to support generic Display types inside of ANSIString

    Motivation here was to make ANSIString work with arbitrary Display types such that values don’t need to be first converted into a String. For example, in the past one would have to write something along the lines of:

    let (red, green, blue) = (255, 248, 231);
    let red = Red.paint(format!("{red:02x}");
    let green = Green.paint(format!("{green:02x}");
    let blue = Blue.paint(format!("{blue:02x}");
    let latte = format!("#{red}{green}{blue}");
    

    This of course works but results in three String allocations. Those can now be avoided since ANSIString can take any Display type and postpone formatting to when the entire string is formatted:

    let (red, green, blue) = (255, 248, 231);
    let red = Red.paint(red);
    let green = Green.paint(green);
    let blue = Blue.paint(blue);
    let latte = format!("#{red:02x}{green:02x}{blue:02x}");
    

    Adding this feature lead to a rabbit hole of changing a lot of other interfaces around ANSIString type.

    Most notably, ANSIGenericString and ANSIByteString types no longer exists. ANSIString is now the only type. Implementation of Display trait and write_to method are now limited by the bounds on the generic argument rather than on the type being ANSIString or ANSIByteString.

    Similarly, there’s now just one ANSIStrings type which points at a slice of strings.

    Furthermore, util::substring now works on generic types and doesn’t perform allocations on its own. E.g. when doing a substring over Strings or Cows, the resulting substring borrows from the underlying strings.

    Lastly, how strings and bytes are written out has been completely refactored. This is just an internal change though not observable by the user.

    opened by mina86 0
  • Add optional support for ansi_colours crate

    Add optional support for ansi_colours crate

    Add Colour::approx_rgb and Colour::into_256 which convert RGB variant into Fixed variant. This is useful when an application is running on a terminal which does not support True Colour control codes. By using the approximation the utility can fallback to using 256-colour palette which is more widely supported.

    Furthermore, add Colour::into_rgb method which performs conversion in the opposite direction. Naturally, the results for the first 16 colours aren’t exactly reliable (since those colours can be configured by the user) but indexes from the 6×6x6 cube or greyscale ramp will be returned correctly.

    opened by mina86 0
  • Maintenance status

    Maintenance status

    Hi, I've found that this is the most popular crate for ANSI terminal in Rust, however the last release was two years ago... There are also outstanding PRs, like one to update it to rust2018 edition (#63), when edition 2021 is already upcoming and other issues that don't get attention. I see that @ogham and @joshtriplett have the ownership permissions on crates.io here. Could you please clarify the status of maintenance of this crate? Should we pass the maintainership to other members of the community or deprecate and archive this crate?

    opened by Veetaha 2
  • custom derserialize for support u8 and seq directly

    custom derserialize for support u8 and seq directly

    Hi,

    I have created a custom deserializer for Colour, after using the custom one, we can deserialize like below:

    {"colour": "Red"}
    
    {"colour": 255}
    
    {
      "colour": {
        "Fixed": 255
      }
    }
    
    {"colour": [255,255,255]}
    
    {
      "colour": {
        "Red": [255,255,255]
      }
    }
    

    this keeps the compatibility and provided a more convenient way to deserialize Colour

    opened by zwpaper 2
A CLI tool to find the dominant colours in an image 🎨

dominant_colours This is a command-line tool for finding the dominant colours of an image. It prints their hex codes to the terminal, along with a pre

Alex Chan 65 Nov 10, 2022
A dead simple ANSI terminal color painting library for Rust.

yansi A dead simple ANSI terminal color painting library for Rust. use yansi::Paint; print!("{} light, {} light!", Paint::green("Green"), Paint::red(

Sergio Benitez 169 Dec 25, 2022
colorStyle is a library of styles for command-line text write in Rust.

Colorstyle colorStyle is a library of styles for command-line text. Inspired by flylog/colorstyle (golang) Example let text = colorstyle::green("gre

Code Translation 6 Nov 12, 2022
Build terminal dashboards using ascii/ansi art and javascript

blessed-contrib Build dashboards (or any other application) using ascii/ansi art and javascript. Friendly to terminals, ssh and developers.

Yaron Naveh 15k Jan 2, 2023
Terminal text styling via ANSI escape sequences.

Iridescent Features iridescent is a library for styling terminal text easily. It supports basic ANSI sequences, Xterm-256 colors, and RGB. You can ope

Rob 2 Oct 20, 2022
100% stream-based O(n) syntax highlighter for ANSI terminal

Lex-highlighter 100% stream-based $\mathcal O(n)$ syntax highlighter for ANSI terminal Warning This is proof-of-concept implementation and WON't be co

Abiria 10 Nov 17, 2023
omekasy is a command line application that converts alphanumeric characters in your input to various styles defined in Unicode.

omekasy is a command line application that converts alphanumeric characters in your input to various styles defined in Unicode. omekasy means "dress up" in Japanese.

null 105 Nov 16, 2022
A simple solution for scoped styles in Leptos

Styled: Easy Styling for Leptos Components If you're looking for an easy way to apply scoped styles to your Leptos components, Styled is the Leptos ma

Eran Boodnero 8 Mar 5, 2023
Rust library to convert RGB 24-bit colors into ANSI 256 (8-bit) color codes with zero dependencies and at compile-time.

rgb2ansi256 rgb2ansi256 is a small Rust library to convert RGB 24-bit colors into ANSI 256 (8-bit) color codes with zero dependencies and const fn. Th

Linda_pp 7 Nov 17, 2022
Rust crate to enable ANSI escape code support on Windows.

enable-ansi-support: Enable ANSI escape code support on Windows 10 About This crate provides one function, enable_ansi_support, which allows ANSI esca

Rain 9 Nov 18, 2022
convert images to ansi or irc, with a bunch of post-processing filters

img2irc (0.2.0) img2irc is a utility which converts images to halfblock irc/ansi art, with a lot of post-processing filters halfblock means that each

null 6 Apr 4, 2023
ask.sh: AI terminal assistant that can read and write your terminal directly!

ask.sh: AI terminal assistant that read from & write to your terminal ask.sh is an AI terminal assistant based on OpenAI APIs such as GPT-3.5/4! What'

hmirin 5 Jun 20, 2023
A simple and efficient terminal UI implementation with ratatui.rs for getting quick insights from csv files right on the terminal

CSV-GREP csv-grep is an intuitive TUI application writting with ratatui.rs for reading, viewing and quickly analysing csv files right on the terminal.

Anthony Ezeabasili 16 Mar 10, 2024
A terminal ASCII media player. View images, gifs, videos, webcam, YouTube, etc.. directly in the terminal as ASCII art.

Terminal Media Player View images, videos (files or YouTube links), webcam, etc directly in the terminal as ASCII. All images you see below are just m

Max Curzi 36 May 8, 2023
Cross-platform Rust library for coloring and formatting terminal output

Coloring terminal output Documentation term-painter is a cross-platform (i.e. also non-ANSI terminals) Rust library for coloring and formatting termin

Lukas Kalbertodt 75 Jul 28, 2022
Vari (Väri) is a Rust library for formatting strings with colors and cosmetic stuff to the terminal.

Vari Vari (Väri) is a Rust library for formatting strings with colors and cosmetic stuff to the terminal. Like Rich library for Python. Väri means "co

azur 13 Nov 2, 2022
A library that creates a terminal-like window with feature-packed drawing of text and easy input handling. MIRROR.

BearLibTerminal provides a pseudoterminal window with a grid of character cells and a simple yet powerful API for flexible textual output and uncompli

Tommy Ettinger 43 Oct 31, 2022
A tiny library and application for animating text in the terminal.

?? snailshell A tiny library and application for animating text in the terminal. ?? It's so easy to add some flair to your text RPGs or console progra

null 45 Mar 5, 2023
Warp is a blazingly fast, Rust-based terminal that makes you and your team more productive at running, debugging, and deploying code and infrastructure.

Warp is a blazingly fast, Rust-based terminal that makes you and your team more productive at running, debugging, and deploying code and infrastructure.

Warp 10.4k Jan 4, 2023