rang icon indicating copy to clipboard operation
rang copied to clipboard

Two features that would be nice to have

Open zethon opened this issue 8 years ago • 14 comments

  • [x] 1 A switch to turn this on and off. Not sure how this could be done in with the relative statelessness of the library, but it would be nice to be able to provide my users with an option to disable colors (some people hate it) and not have to have two different code paths. In other words, something like std::cout << rang::fg::red << "Error"; would be red or not according to some switch.

  • [ ] 2 Storing the colors in a stream for later printing It would be nice if we could do something like:

std::ostream foo;
foo << rang::fg::red << "Error";
std::cout << foo.cstr() << std::endl;

And still have the text be red. I realize this would probably require significant changes and would probably be something more like:

rang::ostream foo;
foo << rang::fg::red << "Error";
std::cout << foo << std::endl;

But it would be a great feature!

Anyway, I'm definitely using this library already. Great work.

zethon avatar Dec 17 '16 16:12 zethon

Thankyou for your kind words 😄 . About 1st - one thing we could try is having rang::colors::off or something so when next time it prints, colors are not shown. or I'm open to ideas if you've any. For 2nd - it was on my mind when I started but I somehow forgot along the way. I do have some exams coming this month but I'll work on it when I get some time. Meanwhile I'm open to accepting Pull Requests :octocat: for the same.

agauniyal avatar Dec 17 '16 19:12 agauniyal

I think the 1st can be done simply via the non-tty-output mechanics: just setting the rang::coutbuf to nullptr should disable the coloring. It would still be sensitive to the "force color" thing of course but perhaps this is even a desired behavior?
(congratulations on the release by the way :smile: )

AxelStrem avatar Dec 18 '16 00:12 AxelStrem

or maybe by using enum class control { autoColor = 0, forceColor = 1 }; with another added member offColor = 2? or infact enum class control { offColor = 0, autoColor = 1, forceColor = 2 }; and then we could do -

template <typename T>
inline rang_implementation::enableControl<T> operator<<(
  std::ostream &os, T const value)
{
        ....
        } else if (value == rang::control::offColor) {
		os.iword(rang_implementation::getIword()) = 0;
	}
	return os;
}

and at last modify this bit -

template <typename T>
inline rang_implementation::enableStd<T> operator<<(
  std::ostream &os, T const value)
{
	....
	return (os.iword(rang_implementation::getIword())
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                              
	....
}

to accept 3 values instead of 0 and 1 which acted as bool. What's your thought about this @AxelStrem ?

agauniyal avatar Dec 18 '16 07:12 agauniyal

@agauniyal That implementation for #1 is the path I started going down to implement this on my own. If I get something working well in the next few days I'll submit a pull request.

zethon avatar Dec 19 '16 13:12 zethon

@zethon sure thing 👍

agauniyal avatar Dec 19 '16 20:12 agauniyal

@agauniyal yeah, that looks like a proper way to do it. Can't find any reasons for that not to work:)
No ideas on #2 though

AxelStrem avatar Dec 20 '16 09:12 AxelStrem

The second one looks like one of the feature request made up in #51 though.

agauniyal avatar Dec 21 '16 18:12 agauniyal

@zethon the first request has landed in develop branch and for now it's stable so you can fork the repo if you need that option right now. I'm putting halt on further feature development till #56 is completed which is going to bring major changes in the lib. I'll take look at the 2nd request after it.

agauniyal avatar Dec 24 '16 05:12 agauniyal

I was testing some scratch code and your 2nd request is also possible without changing much code. instead of direct writing to cout, you'll have to force rang to output colors(instead of autodetect itself) and write to a std::ostream object. then there would be a function where you'll feed that object along with a number (0 = offColor, 1 = autoColor, 2 = forceColor) again and feed that function to std::cout which will handle the stream again.

However there are 2 blocking task before this, one that I mentioned above and another being a terminfo parser that I'll be working on before I start out on this again. However I'm open to accepting PRs if someone wants to do this before me 😄 .

agauniyal avatar Dec 24 '16 13:12 agauniyal

Will your suggested implementation work for concatenating streams? If other words, I would like to do something like:

std::ostream buffer1;
buffer1 << rang::fg::red << "This is red";

std::ostream buffer2;
buffer2 << rang::fg::yellow << "This is yellow";

std::cout << buffer1.cstr() << " " << buffer2.cstr();

Or even have buffer1 and buffer2 feed into a buffer3 and then call std::cout << buffer3.cstr();

zethon avatar Jan 08 '17 11:01 zethon

What I was thinking of was along the lines of a function rang::someFunc(buffer, mode) where you could pass a single buffer or two concatenated buffers and it would either strip out escape codes or autodetect or let them remain in the stream before printing to cout -

std::ostream buffer1;
buffer1 << rang::fg::red << "This is red";

std::ostream buffer2;
buffer2 << rang::fg::yellow << "This is yellow";

std::cout << rang::method(buffer1, autoDetect) << " " << rang::method(buffer2, force)

I'm open to suggestions and PRs if you've anything else in mind.

agauniyal avatar Jan 08 '17 12:01 agauniyal

Regarding the "turn on/off colors", what about an environment variable RANG_COLORS that can be set to on/off to force to turn on or off colors? That way code can stay the same but the user can control whether to enable or disable colors if the automatic detection says otherwise?

sbellon avatar Jan 11 '18 17:01 sbellon

I think it would be better to leave that choice to the user of this library. This way user can decide whether to use 'RANG_COLORS' or something other like 'COLORS' etc and call setControlMode() after detecting the env variable themselves 😸

agauniyal avatar Jan 20 '18 21:01 agauniyal

I am beginner but i can help. (I may need a mentor). If we make another class RangBuffer. it will contain all the enums and it will implement the output operator '<<'. I am on it

HemilTheRebel avatar Nov 02 '18 14:11 HemilTheRebel