Stebalien / term

A Rust library for terminfo parsing and terminal colors.
https://stebalien.github.io/doc/term/term/
Apache License 2.0
178 stars 49 forks source link

Color with macros ? #39

Closed azerupi closed 9 years ago

azerupi commented 9 years ago

I was wondering if there was a way to use macros to color the terminal output.

Instead of

let mut t = term::stdout().unwrap();

t.fg(term::color::GREEN).unwrap();
write!(t, "hello, ").unwrap();

You could write something like this:

println!(green!("Hello"));

If it is possible, it would be really nice to have as a more lightweight alternative to the existing method :)

LukasKalbertodt commented 9 years ago

This term crate is a low level abstraction over os-dependent stuff. If you want to use a high level library, there are plenty:

azerupi commented 9 years ago

I am aware that there are other options :) I didn't found any that used macro's though. What I dislike about the current crates is that they require you to use placeholders.

println!("{}", Green.paint(""Some green stuff"");

I would have hoped that macros could solve this problem and make you able to use something similar to:

println!(green!("Some green stuff));

This "issue" is both a question and feature request at the same time. First I would like to know if it's feasible. And if it is I would really like to see that implemented.

But I can understand if my idea may not be in the scope of this crate.

LukasKalbertodt commented 9 years ago

Yes, this probably doesn't belong into a term issue, but I'll answer anyway:

In general it's just a design choice. You can use macros, just functions (fn green) or something like a builder pattern, like in the two crates mentioned. Everything has advantages and disadvantages. To define a macro for each color would pollute the namespace, since macros are not handled by the standard name resolution. And even when using functions or macro, what would they "return"? The function could just return some kind of wrapper object that implements the Display, ... trait. Now you can define more methods, like bold(), on it and bam: You have some kind of builder. A macro could return another string literal with hardcoded color information. But that would just work for unix.

Btw this:

println!(green!("Some green stuff"));

is not possible AFAIK. println is a special macro that needs a string literal as first parameter.

TL;DR: Somehow most of what you said is possible, but has many disadvantages over other solutions IMO.

azerupi commented 9 years ago

Thank you for your answer! I understand better know why no one (as far as I know) has used macros.

println!(green!("Some green stuff"));

is not possible AFAIK. println is a special macro that needs a string literal as first parameter.

It would be possible, but only on unix right?

Anyways, since this has no chance of being implemented I can close the issue. Thank you for your time :)

LukasKalbertodt commented 9 years ago

is not possible AFAIK. println is a special macro that needs a string literal as first parameter.

It would be possible, but only on unix right?

I guess so. I thought something wrong about how println! works before. But yes, this code works:

macro_rules! foo { () => {"hi"} }
println!(foo!());