Giter Site home page Giter Site logo

yansi's Introduction

yansi logo ย Yansi

A dead simple ANSI terminal color painting library.

Build Status Current Crates.io Version Documentation

Usage

In your Cargo.toml:

[dependencies]
yansi = "1.0"

In your source code:

use yansi::Paint;

println!("Testing, {}, {}, {}!",
    "Ready".bold(),
    "Set".black().on_yellow().invert().italic(),
    "STOP".white().on_red().bright().underline().bold());

> Testing, Ready, Set, STOP!

See the rustdocs for complete usage details.

Features

Why yet another ANSI terminal coloring library? Here are some reasons:

License

yansi is licensed under either of the following, at your option:

yansi's People

Contributors

dkg avatar felixrabe avatar nnethercote avatar sergiobenitez avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

yansi's Issues

Encourage colored-output common practices

Providing a default path for getting people to follow common practices

  • Will help encourage people to do so
  • Ensure people consistently implement the semantics (including precedence levels)

Common practices include:

Since the CLI arg would involve integrating with another crate in the public API (like structopt / clap3), unsure whether that should be left to another crate to avoid coupling their breaking changes to yansi's.

Just me or is Style's PartialEq & Hash behavior weird?

Per the Hash documentation, k1 == k2 -> hash(k1) == hash(k2) should be true.

And yet this fails:

extern crate yansi;

use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};

use yansi::Style;

fn calculate_hash<T: Hash>(t: &T) -> u64 {
    let mut s = DefaultHasher::new();
    t.hash(&mut s);
    s.finish()
}

fn main() {
    let a = Style::new();
    let b = Style::masked();

    assert_eq!(a, b); // passes

    let a_hash = calculate_hash(&a);
    let b_hash = calculate_hash(&b);

    assert_eq!(a_hash, b_hash); // panics
}

I think this is because Style's Hash is derived while PartialEq is implemented differently.

impl PartialEq for Style {

Global enable/disable encourages the wrong behavior

TTY detection is on a per-stream basis, so a user will need to check stdout and stderr and then change their Style appropriately. yansi's "easy path" is to globally enable/disable color which won't take into account which stream the user is writing to, encouraging people to write incorrect code.

Version 1.0?

This has been version 0.5 for 2 years. Is it time to stablise the API for a version 1.0 release now?

Cannot build/compile from source

I don't seem to be able to build from source (using cargo 1.46.0). Are there any flags I should be using at build time? :

   Updating crates.io index
   Compiling yansi v0.6.0-dev (/tmp/yansi-master)
error: unexpected token: `concat`
   --> src/paint.rs:87:17
    |
87  |           #[doc = concat!(
    |                   ^^^^^^
...
205 | /     constructors_for!(T, black: Black, red: Red, green: Green, yellow: Yellow,
206 | |         blue: Blue, magenta: Magenta, cyan: Cyan, white: White);
    | |________________________________________________________________- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: unexpected token: `concat`
   --> src/macros.rs:3:17
    |
3   |           #[doc = concat!(
    |                   ^^^^^^
    | 
   ::: src/paint.rs:335:5
    |
335 | /     style_builder_for!(Paint<T>, |paint| paint.style.properties,
336 | |                        bold: BOLD, dimmed: DIMMED, italic: ITALIC,
337 | |                        underline: UNDERLINE, blink: BLINK, invert: INVERT,
338 | |                        hidden: HIDDEN, strikethrough: STRIKETHROUGH);
    | |_____________________________________________________________________- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: unexpected token: `concat`
   --> src/macros.rs:3:17
    |
3   |           #[doc = concat!(
    |                   ^^^^^^
    | 
   ::: src/style.rs:283:5
    |
283 | /     style_builder_for!(Style, |style| style.properties,
284 | |                        bold: BOLD, dimmed: DIMMED, italic: ITALIC,
285 | |                        underline: UNDERLINE, blink: BLINK, invert: INVERT,
286 | |                        hidden: HIDDEN, strikethrough: STRIKETHROUGH);
    | |_____________________________________________________________________- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: unexpected token: `concat`
   --> src/style.rs:164:17
    |
164 |           #[doc = concat!(
    |                   ^^^^^^
...
366 | /     checker_for!(bold (is_bold): BOLD, dimmed (is_dimmed): DIMMED,
367 | |         italic (is_italic): ITALIC, underline (is_underline): UNDERLINE,
368 | |         blink (is_blink): BLINK, invert (is_invert): INVERT,
369 | |         hidden (is_hidden): HIDDEN,
370 | |         strikethrough (is_strikethrough): STRIKETHROUGH);
    | |_________________________________________________________- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

warning: unused import: `Property`
 --> src/paint.rs:3:20
  |
3 | use style::{Style, Property};
  |                    ^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: trait objects without an explicit `dyn` are deprecated
   --> src/style.rs:184:52
    |
184 | fn write_spliced<T: Display>(c: &mut bool, f: &mut fmt::Write, t: T) -> fmt::Result {
    |                                                    ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Write`
    |
    = note: `#[warn(bare_trait_objects)]` on by default

warning: trait objects without an explicit `dyn` are deprecated
   --> src/style.rs:411:38
    |
411 |     pub fn fmt_prefix(&self, f: &mut fmt::Write) -> fmt::Result {
    |                                      ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Write`

warning: trait objects without an explicit `dyn` are deprecated
   --> src/style.rs:473:38
    |
473 |     pub fn fmt_suffix(&self, f: &mut fmt::Write) -> fmt::Result {
    |                                      ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Write`

warning: trait objects without an explicit `dyn` are deprecated
  --> src/color.rs:73:43
   |
73 |     pub(crate) fn ansi_fmt(&self, f: &mut fmt::Write) -> fmt::Result {
   |                                           ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Write`

error: aborting due to 4 previous errors; 5 warnings emitted

error: could not compile `yansi`.

Gracefully initialize/auto-detect behind the scenes?

For a CLI app, the user will need to support args and might have other constraints.

However, passing color information to a deeply nested crate can be impractical. For example, Someone might use mockall which uses predicates which uses difference, and difference wants to print colored diffs, where appropriate.

Alternatively, some times there isn't a good initialization point for a crate, like with tests. The above example is more likely to live in a test than in a bin.

Depending on the approach, this might be a counter example to #17.

Note: this is more brainstorming, I'm unsure how this will look.

Used parking_lot version is quite old

Yansi uses parking_lot version 0.5, which is over 3 years old. Would it be possible to update it? I can see that the last update to Cargo.toml was a version bump, so I don't know if it would need to wait for something else?

The method `clear` in trait `Paint` causes a conflict with `Vec::clear`

Referring to https://docs.rs/yansi/1.0.0/yansi/trait.Paint.html#tymethod.clear

Here's a simple reproducer:

use yansi::Paint;

fn main() {
    let v = vec![1, 2];
    v.clear();
    println!("length of v: {}", v.len());
}

Output:

length of v: 2

Took me a while to figure out why my vectors were not clearing. Maybe changing the name of the method would help here? I'm honestly surprised that rustc does not complain about this in the first place.

Docify crate

Would you consider creating a crate with the docify macro? It's pretty clever and it's something I've needed before when writing helper macros but settled for just ignoring docs on functions created with the macro in that case.

Console coloring is not working in Windows 7

My system info:
Microsoft Windows 7 Ultimate 64bit

Rust info:
nightly-i686-pc-windows-gnu (default)
rustc 1.21.0-nightly (f774bced5 2017-08-12)

Cargo.toml:
yansi = "0.3.3"

main.rs:
Paint::enable_windows_ascii();
print!("{} light, {} light!",
Paint::green("Green"),
Paint::red("red").underline());

console output:

vhh

#[feature] may not be used on the stable release channel

When I use Rocket, cargo run meet this error

Compiling yansi v0.3.3
error[E0554]: #[feature] may not be used on the stable release channel
 --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/yansi-0.3.3/src/lib.rs:1:32
  |
1 | #![cfg_attr(feature="nightly", feature(const_fn))]
  |                                ^^^^^^^^^^^^^^^^^

error: aborting due to previous error

error: Could not compile `yansi`.

To learn more, run the command again with --verbose.

Error on stable channel

How to fix this problem?. this error occured when i try to install rocket

error[E0554]: #[feature] may not be used on the stable release channel
--> $HOME/.cargo/registry/src/github.com-1ecc6299db9ec823/yansi-0.3.3/src/lib.rs:1:32
|
1 | #![cfg_attr(feature="nightly", feature(const_fn))]
| ^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

error: Could not compile yansi.
Build failed, waiting for other jobs to finish...
error: build failed

thanks

Add a feature flag to automate Windows coloring

Basically, do the following automatically:

if !Paint::enable_windows_ascii() {
    Paint::disable()
}

The implementation should just check if painting is disabled via the already relaxed atomic bool and otherwise check a second atomic bool, also relaxes, to see if we've tried to enable Windows coloring already.

Impl `{Upper,Lower}Hex` for `Paint`

I wish I could color my value like this:

use yansi::Paint;
println!("address = {:04X}", Paint::yellow(0x0000BEEF));

But I get this error:

error[E0277]: the trait bound `Paint<{integer}>: UpperHex` is not satisfied
   --> src\cpu.rs:222:38
    |
222 |         println!("address = {:04X}", Paint::yellow(0x0000BEEF));
    |                             ------   ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `UpperHex` is not implemented for `Paint<{integer}>`
    |                             |
    |                             required by a bound introduced by this call
    |
    = help: the following other types implement trait `UpperHex`:
              &T
              &mut T
              BitArray<A, O>
              BitBox<T, O>
              BitVec<T, O>
              Domain<'a, Const, T, O>
              NonZeroI128
              NonZeroI16
            and 36 others
note: required by a bound in `ArgumentV1::<'a>::new_upper_hex`
   --> C:\<REDACTED>\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\fmt\mod.rs:356:5
    |
356 |     arg_new!(new_upper_hex, UpperHex);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ArgumentV1::<'a>::new_upper_hex`
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `arg_new` (in Nightly builds, run with -Z 
macro-backtrace for more info)

Currently I have to do this:

println!("address = {}", Paint::yellow(format!("{:04x}", 0x0000BEEF)));

But this requires allocating a String.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.