Cross-platform Rust library for coloring and formatting terminal output

Overview

Coloring terminal output

Build Status crates.io version GitHub license

Documentation

term-painter is a cross-platform (i.e. also non-ANSI terminals) Rust library for coloring and formatting terminal output. It provides easy ways to format various things and uses the crate rust-lang/term to do the actual formatting. Please read "When (not) to use this crate".

Note: I created another library for coloring terminal text: bunt. I like it much better, so maybe consider using bunt instead of term-painter :-)

Example:

println!("{} | {} | {} | {} | {}",
    Red.bg(Green).bold().paint("Red-Green-Bold"),
    Blue.paint("Blue"),
    Blue.bold().paint("BlueBold"),
    Blue.bg(Magenta).paint("BlueMagentaBG"),
    Plain.underline().paint("Underline")
);

Red.with(|| {
    print!("JustRed");
    Bold.with(|| {
        print!(" BoldRed {} BoldRed ", Underline.paint("Underline"));
    });
    print!("JustRed ");

    print!("{}", Blue.paint("Blue (overwrite) "));
    Green.with(|| {
        println!("Green (overwrite)");
    });
});

alt text

It's easy to use and integrates well with println!/print!. The main design goal was to make it simple. This has one performance disadvantage: It will often reset the terminal style after each printing operation. But performance isn't usually hugely important when printing on the terminal, so simplicity was more important for the design of this library.

More examples here (examples/main.rs) or in the Documentation.

When (not) to use this crate

There are more terminal color crates than stars in the observable universe, therefore it's a valid question to ask "which one is best"? Unfortunately, there is no clear answer, I think.

Don't use this crate, if:

  • you want full power of what happens (consider using rust-lang/term instead), or
  • you want to print from multiple threads (consider using termcolor or bunt instead), or
  • you want to color/format text you print on something else than stdout (however, term-painter might add support for stderr in the future)
  • you want an actively developed crate (see "Status of this crate")
  • you want to use a crate with a fancy name (term-painter is such a boring name 😒 )

You probably shouldn't use this crate, if:

  • you don't need to support non-ANSI terminals (Only supporting ANSI-formatting gives the author of the lib greater flexibility in designing the API, thus potentially making it easier and more powerful. See section "Cross Platform". Consider using ansi-term, colored, yansi, ... instead.), or
  • you expect a time-proven library

Use this crate, if:

  • you need support for non-ANSI terminals, and
  • you are developing a non-mission critical project

Cross Platform

This crate uses rust-lang/term internally. term supports all (or rather: many) platforms, hence term-painter does, too.

How does it work? In order to work, this crate depends on a specific way how println! and friends evaluate their arguments (which is the common-sense way). There are no guarantees about argument evaluation, but currently it works. And honestly, it's unlikely that this way of evaluation ever changes. But, for example, if println!() would always call format!() first and print the resulting String, it wouldn't work.

To give a simplified explanation of the terminal-world: there are ANSI-terminal and non-ANSI Terminals. ANSI-formatting works by inserting special control characters into the string. Thus you can easily store the formatted string in a String to print it later. Non-ANSI terminals work differently, and the most commonly used one is cmd which is part of Windows 7/10. Formatting for cmd works by calling methods of the winapi before and after printing. Thus you cannot easily store a formatted string. Apart from that, AFAIK there are not that many developers mainly using cmd -- most Windows developer use IDEs alone or another terminal for Windows (there are plenty).

In summary: most terminals support ANSI-coloring, non-ANSI-terminals make the world more complicated.

Status of this crate

This crate is not actively developed anymore. The API is likely to stay as it is. I doubt this crate will reach its 1.0 milestone. This doesn't mean that this crate doesn't work! You can still use it, if it fits your needs.

Thanks

I've got some design ideas from rust-ansi-term. I decided to make my own crate though, since my goals were too different from ansi-term (specifically: ansi-term does not work everywhere).


License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Cursor navigation

    Cursor navigation

    Would cursor navigation be a sensible addition to this library, or would this be out of scope / a nonfeature? I think it would be great, since it would make this the only crate with both platform independent terminal colors and movement (that I am aware of).

    I'm willing to implement it for both Windows and ANSI terminals, all I need is the consent.

    opened by Lisoph 3
  • Dim not work

    Dim not work

    The statements:

    println!("{}", Style::default().dimmed().paint("test 1"));  // rust-ansi-term
    println!("{}", Dim.paint("test 2"));  // term-painter
    

    generated the following outputs:

    opened by wenLiangcan 3
  • Equivalent of format! with preserved style information

    Equivalent of format! with preserved style information

    Currently format! and similar macros don't work with term-painter (style won't apply). Since the style information isn't stored in the string (like in rust-ansi-term) to achieve platform independence, there is currently no way to pre-format a string with terminal style.

    One could write something similar to format! that returns a custom data structure which stores the given style information.

    feature 
    opened by LukasKalbertodt 2
  • Tracking issue: v1.0

    Tracking issue: v1.0

    EDIT: ignore the rest of the comment!


    A big part of this year's Roadmap for Rust is to push third level crates to v1.0 maturity. term-painter is one of those third level crates and I'd like to publish 1.0 eventually, preferably this year.

    However, I think a lot still needs to be done. I want this crate to be usable for almost all cases you would use term for, instead of being a library for small toy projects only. In order to add more features and still reach 1.0 stability, I would use a two-phase process:

    1. Adding features and designing the API until, say, September this year. The resulting API is the one planned for 1.0 release and will be release as "last pre-1.0 version".
    2. Afterwards, the API should be tested in production to see if the API has any disadvantages and to find bugs. Sending out PRs to dependent crates to update to the "last pre-1.0 version" would help this process.

    The fixed API is then released as 1.0 by the end of the year (maybe even a bit sooner).


    That said, I haven't planned to redesign the whole API; breaking changes to the current API only where it makes sense. Here are a few things we want to tackle in step 1:

    • [ ] Generalizing API to allow printing on stderr, too (#19)
    • [ ] Evaluate terms features to find out what we still want to support
    • [ ] Think about allowing another kind of API usage (see #18)
    • [ ] Support configuration via environment variable (#16)
    • [ ] Add categories and tags and all that meta data jazz to Cargo.toml
    • [ ] Think about providing a format!() like macro. Storing strings with builtin formatting is a nice thing to have, but could be difficult. (#1)
    • [ ] Maybe talk to dependent crates' authors and ask what features they are missing or if they have ideas how to improve the API.

    Unfortunately, my time this year is limited, but I think I can check all those boxes above before September. If someone wants to help somehow, you're very welcome! I could offer some kind of mentorship, if you need some help. Just get in touch!

    opened by LukasKalbertodt 1
  • It's not possible to set the color to

    It's not possible to set the color to "default" within `with`

    Consider this:

    Color::Red.with(||{
        println!("Red {} Red", Color::Normal.paint("Normal"));
    });
    

    One wants to reset the color to default within a with block. The code above prints all three words in red. One should be able to somehow reset it.

    bug enhancement 
    opened by LukasKalbertodt 1
  • Impl Display for `Style`

    Impl Display for `Style`

    Display could be implemented for Style to allow for something like that:

    println!("{red}This is reeeeed{reset}", red=Color::Red, reset=???);
    
    feature 
    opened by LukasKalbertodt 0
  • Support global toggle via env variable

    Support global toggle via env variable

    Hi @LukasKalbertodt ! I am the author of colored, a library which does similar things to yours, but not as robust (yet ! :).

    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 to comment or propose changes.

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

    opened by mackwic 1
Releases(v0.3.0)
Owner
Lukas Kalbertodt
I like teaching and coding.
Lukas Kalbertodt
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
create and test the style and formatting of text in your terminal applications

description: create and test the style and formatting of text in your terminal applications docs: https://docs.rs/termstyle termstyle is a library tha

Rett Berg 18 Jul 3, 2021
Monorepo for dprint—a pluggable and configurable code formatting platform

dprint Monorepo for dprint—a pluggable and configurable code formatting platform. This project is under active early development. I recommend you chec

null 1.7k Jan 8, 2023
Cross platform terminal library rust

Cross-platform Terminal Manipulation Library Crossterm is a pure-rust, terminal manipulation library that makes it possible to write cross-platform te

crossterm-rs 2.1k Jan 2, 2023
Cross-platform terminal screen clearing library

ClearScreen Cross-platform terminal screen clearing library. API documentation. Dual-licensed with Apache 2.0 and MIT. Uses Caretaker Maintainership.

null 23 Dec 30, 2022
⚡️Highly efficient data and string formatting library for Rust.

⚡️Highly efficient data and string formatting library for Rust. ?? Overview Pad and format string slices and generic vectors efficiently with minimal

Firelink Data 3 Dec 21, 2023
Simple macros to write colored and formatted text to a terminal. Based on `termcolor`, thus also cross-platform.

Bunt: simple macro-based terminal colors and styles bunt offers macros to easily print colored and formatted text to a terminal. It is just a convenie

Lukas Kalbertodt 202 Dec 22, 2022
🍅 A command-line tool to get and set values in toml files while preserving comments and formatting

tomato Get, set, and delete values in TOML files while preserving comments and formatting. That's it. That's the feature set. I wrote tomato to satisf

C J Silverio 15 Dec 23, 2022
Alacritty - A fast, cross-platform, OpenGL terminal emulator

Alacritty is a modern terminal emulator that comes with sensible defaults, but allows for extensive configuration. By integrating with other applications, rather than reimplementing their functionality, it manages to provide a flexible set of features with high performance. The supported platforms currently consist of BSD, Linux, macOS and Windows.

Alacritty 43.8k Dec 31, 2022
Cross-platform terminal program to download IEEE journals

IEEE Journal Downloader A cross-platform terminal program which tries to download every article in a specified journal and merge the documents into on

Fong Chien Yoong 18 Jul 23, 2022
Native cross-platform full feature terminal-based sequence editor for git interactive rebase.

Native cross-platform full feature terminal-based sequence editor for git interactive rebase.

Tim Oram 1.2k Jan 2, 2023
glicol cli: cross-platform music live coding in terminal

glicol-cli What's this? It's a command line interface that you can use for music live coding with Glicol. It watches a file changes and then update th

Glicol 70 Apr 14, 2023
Fmt-rfcs - RFCs for Rust formatting guidelines and changes to Rustfmt

Rust code formatting RFCs This repository exists to decide on a code style for Rust code, to be enforced by the Rustfmt tool. Accepted RFCs live in th

null 397 Jan 9, 2023
Sleek is a CLI tool for formatting SQL. It helps you maintain a consistent style across your SQL code, enhancing readability and productivity.

Sleek: SQL Formatter ✨ Sleek is a CLI tool for formatting SQL. It helps you maintain a consistent style across your SQL code, enhancing readability an

Nick Rempel 40 Apr 20, 2023
hexyl is a simple hex viewer for the terminal. It uses a colored output to distinguish different categories of bytes

hexyl is a simple hex viewer for the terminal. It uses a colored output to distinguish different categories of bytes (NULL bytes, printable ASCII characters, ASCII whitespace characters, other ASCII characters and non-ASCII).

David Peter 7.3k Dec 29, 2022
Fast, minimal, feature-rich, extended formatting syntax for Rust!

Formatting Tools Fast, minimal, feature-rich, extended formatting syntax for Rust! Features include: Arbitrary expressions inside the formatting brace

Casper 58 Dec 26, 2022
Cross-platform WebView library in Rust for Tauri.

Cross-platform WebView rendering library in Rust that supports all major desktop platforms like Windows, macOS, and Linux. Overview Wry connects the w

Tauri 2.2k Jan 9, 2023
A new pure-Rust library for cross-platform low-level access to USB devices.

nusb A new pure-Rust library for cross-platform low-level access to USB devices. Documentation Compared to rusb and libusb Pure Rust, no dependency on

Kevin Mehall 23 Oct 30, 2023
General purpose cross-platform GIS-rendering library written in Rust

Galileo is a general purpose cross-platform geo-rendering library. Web examples Raster tile layer (OSM) Vector tile layer (Maplibre) Use buttons at th

Maxim 16 Dec 15, 2023