www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [RFC] ColorD

reply "Robik" <szadows gmail.com> writes:
Hello,

I would like to introduce ColorD, small library that allows to 
simply manipulate console output colors, both on Windows and 
Posix operating systems. It also supports font styles such as 
underline and strikethrough(Posix feature only).


Simple example:

import std.stdio, colord;
void main()
{
     setConsoleColors(Fg.red, Bg.blue);
     writeln("Red text on blue background.");
     resetConsoleColors(); // Bring back initial state
}


Feedback welcome.

GitHub: https://github.com/robik/ColorD

Regards.
Oct 21 2012
next sibling parent reply "Peter Sommerfeld" <noreply rubrica.at> writes:
Robik wrote:

 I would like to introduce ColorD, small library that allows to simply  
 manipulate console output colors, both on Windows and Posix operating  
 systems.
 GitHub: https://github.com/robik/ColorD
On windows I got an error: Not a property <EnumTypedef!<color,"fg">>.opDispatch Same for "bg". void resetConsoleColors() { setConsoleColors(Fg.initial, Bg.initial); // here } Peter
Oct 21 2012
parent reply "Robik" <szadows gmail.com> writes:
On Sunday, 21 October 2012 at 20:19:54 UTC, Peter Sommerfeld 
wrote:
 Robik wrote:

 I would like to introduce ColorD, small library that allows to 
 simply manipulate console output colors, both on Windows and 
 Posix operating systems.
 GitHub: https://github.com/robik/ColorD
On windows I got an error: Not a property <EnumTypedef!<color,"fg">>.opDispatch Same for "bg". void resetConsoleColors() { setConsoleColors(Fg.initial, Bg.initial); // here } Peter
What version are you using?
Oct 21 2012
parent "Peter Sommerfeld" <noreply rubrica.at> writes:
Am 21.10.2012, 22:24 Uhr, schrieb Robik <szadows gmail.com>:

 On Sunday, 21 October 2012 at 20:19:54 UTC, Peter Sommerfeld wrote:
 Robik wrote:

 I would like to introduce ColorD, small library that allows to simply  
 manipulate console output colors, both on Windows and Posix operating  
 systems.
 GitHub: https://github.com/robik/ColorD
On windows I got an error: Not a property <EnumTypedef!<color,"fg">>.opDispatch Same for "bg". void resetConsoleColors() { setConsoleColors(Fg.initial, Bg.initial); // here } Peter
What version are you using?
dmd 2.060. -O -release -inline -property -w -wi Peter
Oct 21 2012
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Robik:

 GitHub: https://github.com/robik/ColorD
Maybe it'ìs better to call it ConsoleColorsD, or something. ColorD seems more fit for a (handy) library about color theory, color space conversions, etc. Bye, bearophile
Oct 21 2012
parent "Robik" <szadows gmail.com> writes:
On Sunday, 21 October 2012 at 20:39:31 UTC, bearophile wrote:
 Robik:

 GitHub: https://github.com/robik/ColorD
Maybe it'ìs better to call it ConsoleColorsD, or something. ColorD seems more fit for a (handy) library about color theory, color space conversions, etc. Bye, bearophile
Moved to https://github.com/robik/ConsoleD
Oct 21 2012
prev sibling next sibling parent reply "F i L" <witte2008 gmail.com> writes:
Robik wrote:
 Hello,

 I would like to introduce ColorD, small library that allows to 
 simply manipulate console output colors, both on Windows and 
 Posix operating systems. It also supports font styles such as 
 underline and strikethrough(Posix feature only).
It might be nice to have a solution which works better with native writeln(), aka, something like: import std.stdio, colord; void main() { writeln(Colors.Red, "Foo Bar", Colors.Reset); }
Oct 21 2012
parent "renoX" <renozyx gmail.com> writes:
This could be improved, the example you give
         writeln(Colors.Red, "Foo Bar", Colors.Reset);
imply that if you forget to put Colors.Reset at the end of writeln then all the following call will be made in Colors.Red which I don't like, IMHO "writeln(Colors.Red, "Foo Bar");" is better and at the end of the writeln your settings are resetted. If you want to change the current settings, you have to use a different function call.. BR, renoX
Oct 22 2012
prev sibling next sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Robik wrote:
 Hello,
 
 I would like to introduce ColorD, small library that allows to
 simply manipulate console output colors, both on Windows and Posix
 operating systems. It also supports font styles such as underline
 and strikethrough(Posix feature only).
 
 
 Simple example:
 
 import std.stdio, colord;
 void main()
 {
     setConsoleColors(Fg.red, Bg.blue);
     writeln("Red text on blue background.");
     resetConsoleColors(); // Bring back initial state
 }
 
 
 Feedback welcome.
 
 GitHub: https://github.com/robik/ColorD
Interesting looks solid to me. Some nit-picks: * Coloring on Posix depends a ANSI terminal. Can you check that a terminal is ANSI compatible? * There are some magic numbers in the code. These may be difficult to figure out for maintaining. * enum Color should maybe be same on all systems. This is a rather small issue. But I may transfer the Color to another system. So if it is possible there should only be one enum Color for all systems. * Call it terminal or similar. Because other terminal related stuff can be added and IMHO it's a better name. I have written a similar library. Not finished. Let's join forces. https://github.com/jkm/terminal Johannes Pfau has written a progress bar. I will add this. Jens
Oct 21 2012
next sibling parent reply "Robik" <szadows gmail.com> writes:
On Sunday, 21 October 2012 at 21:01:21 UTC, Jens Mueller wrote:
 Interesting looks solid to me.
 Some nit-picks:
 * Coloring on Posix depends a ANSI terminal. Can you check that 
 a terminal is ANSI compatible?
Sure, why not.
 * There are some magic numbers in the code. These may be 
 difficult to
   figure out for maintaining.
I will fix this.
 * enum Color should maybe be same on all systems.
   This is a rather small issue. But I may transfer the Color to 
 another
   system. So if it is possible there should only be one enum 
 Color for
   all systems.
I think that this will only complicate the code.
 * Call it terminal or similar. Because other terminal related 
 stuff can
   be added and IMHO it's a better name.
It got renamed to ConsoleD.
 I have written a similar library. Not finished. Let's join 
 forces.
 https://github.com/jkm/terminal

 Johannes Pfau has written a progress bar. I will add this.

 Jens
Sure, I'm interested in joining forces. Do you have IRC?
Oct 21 2012
parent Jens Mueller <jens.k.mueller gmx.de> writes:
Robik wrote:
 On Sunday, 21 October 2012 at 21:01:21 UTC, Jens Mueller wrote:
Interesting looks solid to me.
Some nit-picks:
* Coloring on Posix depends a ANSI terminal. Can you check that a
terminal is ANSI compatible?
Sure, why not.
Do you know how to do this?
* There are some magic numbers in the code. These may be difficult
to
  figure out for maintaining.
I will fix this.
* enum Color should maybe be same on all systems.
  This is a rather small issue. But I may transfer the Color to
another
  system. So if it is possible there should only be one enum Color
for
  all systems.
I think that this will only complicate the code.
Probably not worth the trouble. But it should be documented.
* Call it terminal or similar. Because other terminal related
stuff can
  be added and IMHO it's a better name.
It got renamed to ConsoleD.
But the module should not be named colsoled. Because it's a D module anyway. Call it just console.
I have written a similar library. Not finished. Let's join forces.
https://github.com/jkm/terminal

Johannes Pfau has written a progress bar. I will add this.

Jens
Sure, I'm interested in joining forces. Do you have IRC?
Yes, I do. Jens
Oct 21 2012
prev sibling parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 10/21/2012 05:01 PM, Jens Mueller wrote:
 Robik wrote:
 Hello,

 I would like to introduce ColorD, small library that allows to
 simply manipulate console output colors, both on Windows and Posix
 operating systems. It also supports font styles such as underline
 and strikethrough(Posix feature only).


 Simple example:

 import std.stdio, colord;
 void main()
 {
      setConsoleColors(Fg.red, Bg.blue);
      writeln("Red text on blue background.");
      resetConsoleColors(); // Bring back initial state
 }


 Feedback welcome.

 GitHub: https://github.com/robik/ColorD
Interesting looks solid to me. Some nit-picks: * Coloring on Posix depends a ANSI terminal. Can you check that a terminal is ANSI compatible? * There are some magic numbers in the code. These may be difficult to figure out for maintaining. * enum Color should maybe be same on all systems. This is a rather small issue. But I may transfer the Color to another system. So if it is possible there should only be one enum Color for all systems. * Call it terminal or similar. Because other terminal related stuff can be added and IMHO it's a better name. I have written a similar library. Not finished. Let's join forces. https://github.com/jkm/terminal Johannes Pfau has written a progress bar. I will add this. Jens
Hey that looks cool. It seems to have a hard ncurses/termcap/etc dependency. I'll admit when I started trying to work on doing this thing, I never got anything onto the screen. What stopped me was that I couldn't figure out how to detect ncurses/termcap/etc. I was going to shoot for Phobos inclusion and making Phobos always link with ncurses seems like a bad idea. Ultimately I expect it to work with writeln or writefln to make it discoverable and easy to work with. Back then I did design a format spec for introducing colors into format strings: www.chadjoan.com/d/dmd.2.058/html/d/phobos/std_format.html
Oct 21 2012
parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Chad J wrote:
 On 10/21/2012 05:01 PM, Jens Mueller wrote:
Robik wrote:
Hello,

I would like to introduce ColorD, small library that allows to
simply manipulate console output colors, both on Windows and Posix
operating systems. It also supports font styles such as underline
and strikethrough(Posix feature only).


Simple example:

import std.stdio, colord;
void main()
{
     setConsoleColors(Fg.red, Bg.blue);
     writeln("Red text on blue background.");
     resetConsoleColors(); // Bring back initial state
}


Feedback welcome.

GitHub: https://github.com/robik/ColorD
Interesting looks solid to me. Some nit-picks: * Coloring on Posix depends a ANSI terminal. Can you check that a terminal is ANSI compatible? * There are some magic numbers in the code. These may be difficult to figure out for maintaining. * enum Color should maybe be same on all systems. This is a rather small issue. But I may transfer the Color to another system. So if it is possible there should only be one enum Color for all systems. * Call it terminal or similar. Because other terminal related stuff can be added and IMHO it's a better name. I have written a similar library. Not finished. Let's join forces. https://github.com/jkm/terminal Johannes Pfau has written a progress bar. I will add this. Jens
Hey that looks cool. It seems to have a hard ncurses/termcap/etc dependency.
Yes. I think you cannot make it portable without. Please proof me wrong and I'll fix this.
 I'll admit when I started trying to work on doing this thing, I
 never got anything onto the screen.  What stopped me was that I
 couldn't figure out how to detect ncurses/termcap/etc.  I was going
 to shoot for Phobos inclusion and making Phobos always link with
 ncurses seems like a bad idea.
Dependence on Phobos is bad. If you can detect whether a terminal is ANSI compatible then this mode should be default. But I don't know how to detect this.
 Ultimately I expect it to work with writeln or writefln to make it
 discoverable and easy to work with.
One could try this. At least for Linux. You just have to add the appropriate escape sequences. But this won't work on Windows.
 Back then I did design a format spec for introducing colors into
 format strings:
 www.chadjoan.com/d/dmd.2.058/html/d/phobos/std_format.html
I doubt that the Phobos maintainers will accept this. This is very invasive. I added writecf, writec, etc. with additional arguments. writec(Color.red, "some text") or writecf(Color.red, "%s", "some text") This is fine I think. But better options may be worth investigating. Jens
Oct 21 2012
parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 10/21/2012 06:11 PM, Jens Mueller wrote:
 Chad J wrote:
 On 10/21/2012 05:01 PM, Jens Mueller wrote:

 It seems to have a hard ncurses/termcap/etc dependency.
Yes. I think you cannot make it portable without. Please proof me wrong and I'll fix this.
Well, traditionally it's done with automake/autoconf. You'd end up with preprocessor defines that tell you whether the lib has been statically linked or not. This isn't available here because Phobos doesn't use these as a build system and I hope it never does.
 I'll admit when I started trying to work on doing this thing, I
 never got anything onto the screen.  What stopped me was that I
 couldn't figure out how to detect ncurses/termcap/etc.  I was going
 to shoot for Phobos inclusion and making Phobos always link with
 ncurses seems like a bad idea.
Dependence on Phobos is bad. If you can detect whether a terminal is ANSI compatible then this mode should be default. But I don't know how to detect this.
Wrong direction on the dependency. I wouldn't expect Terminal coloring/detection to rely on Phobos. I'd expect it to be one of the lower-level modules built into Phobos.
 Ultimately I expect it to work with writeln or writefln to make it
 discoverable and easy to work with.
One could try this. At least for Linux. You just have to add the appropriate escape sequences. But this won't work on Windows.
I remember having a plan for this. See below.
 Back then I did design a format spec for introducing colors into
 format strings:
 www.chadjoan.com/d/dmd.2.058/html/d/phobos/std_format.html
I doubt that the Phobos maintainers will accept this. This is very invasive.
Hmmm, depends what is meant by invasive. I feel it's the only way to have discoverable and concise syntax. I'd be pretty disappointed if they didn't, regardless of who submits the pull request. I remember it being possible in Phobos to determine the destination of the format operation. If the destination is a string in memory, then no color formatting would be applied. If the destination is a Linux terminal of some kind, then some ncurses terminal info would be looked up (possible a cached lookup) and escape sequences generated based on that. If the destination is a Windows terminal, then these approaches can be considered: (1) Split the formatted text up on the color format boundaries. Send the slices into the stream one by one, calling the necessary WinAPI color formatting functions inbetween. I think this might not have been possible with Phobos' architecture. (2) Insert ANSI escape sequences into the text. The I/O code for Windows would then have to intercept these and convert them into the appropriate WinAPI calls. I think this was possible, and even distinguishable from the case of writing to a string in memory. If the invasiveness worry comes from the possibility of dumping escape sequences into non-terminal destinations, then I hope the above wall of text can alleviate that concern.
 I added writecf, writec, etc. with additional arguments.
 writec(Color.red, "some text")
 or
 writecf(Color.red, "%s", "some text")
 This is fine I think. But better options may be worth investigating.

 Jens
I really think this should be in Phobos. If it doesn't go into Phobos, then people will write crappy terminal apps with no color. If it does go into Phobos, then the better devs will see the opportunity and use it. Something 3rd party is much less discoverable and won't have nearly as much impact. The use case is almost all CLI apps, so it's not like an uncommon corner-case or something. I run a Gentoo system where things are configured to use color output wherever possible. The portage devs went through all of the necessary contortions to get Python to output colored text, somehow. I feel the end result is indispensable. Color is an extremely useful tool for making sure that the user doesn't overlook important bits while scanning text. Outside of Gentoo, I find this most notable in grep: uncolored grep output is just awful, but the coloring makes it possible to easily identify why the regular expression behaved the way it did. I look forward to a better CLI ecosystem where highly reliable D programs are written quickly and write beautiful colored output ;)
Oct 21 2012
next sibling parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
Additionally note that the format syntax handles Walter's concerns here:
http://forum.dlang.org/post/k61t63$pi4$1 digitalmars.com

The color format syntax uses a pair of matched parentheses, and thus 
makes it impossible to leave the console in a different state than when 
the formatting call was entered.

Lower level stuff like terminal functions dedicated specifically to 
saving/restoring state would make sense and be used underneath the 
formatter to accomplish what it does.
Oct 21 2012
prev sibling next sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Chad J wrote:
 On 10/21/2012 06:11 PM, Jens Mueller wrote:
Chad J wrote:
On 10/21/2012 05:01 PM, Jens Mueller wrote:

It seems to have a hard ncurses/termcap/etc dependency.
Yes. I think you cannot make it portable without. Please proof me wrong and I'll fix this.
Well, traditionally it's done with automake/autoconf. You'd end up with preprocessor defines that tell you whether the lib has been statically linked or not. This isn't available here because Phobos doesn't use these as a build system and I hope it never does.
I mean to detect if your terminal is ANSI compatible without adding another dependency. It's easy to provide different version(...) to support different modes. One could do something like: 1. Check at run time if ncurses etc. are available. * If they are use them. * Otherwise fall back to ANSI codes or throw an Exception. What do you think?
I'll admit when I started trying to work on doing this thing, I
never got anything onto the screen.  What stopped me was that I
couldn't figure out how to detect ncurses/termcap/etc.  I was going
to shoot for Phobos inclusion and making Phobos always link with
ncurses seems like a bad idea.
Dependence on Phobos is bad. If you can detect whether a terminal is ANSI compatible then this mode should be default. But I don't know how to detect this.
Wrong direction on the dependency. I wouldn't expect Terminal coloring/detection to rely on Phobos. I'd expect it to be one of the lower-level modules built into Phobos.
I mean it's bad to have Phobos depend on ncurses. Though one can go with loading at run time.
Ultimately I expect it to work with writeln or writefln to make it
discoverable and easy to work with.
One could try this. At least for Linux. You just have to add the appropriate escape sequences. But this won't work on Windows.
I remember having a plan for this. See below.
Back then I did design a format spec for introducing colors into
format strings:
www.chadjoan.com/d/dmd.2.058/html/d/phobos/std_format.html
I doubt that the Phobos maintainers will accept this. This is very invasive.
Hmmm, depends what is meant by invasive. I feel it's the only way to have discoverable and concise syntax. I'd be pretty disappointed if they didn't, regardless of who submits the pull request. I remember it being possible in Phobos to determine the destination of the format operation. If the destination is a string in memory, then no color formatting would be applied. If the destination is a Linux terminal of some kind, then some ncurses terminal info would be looked up (possible a cached lookup) and escape sequences generated based on that. If the destination is a Windows terminal, then these approaches can be considered: (1) Split the formatted text up on the color format boundaries. Send the slices into the stream one by one, calling the necessary WinAPI color formatting functions inbetween. I think this might not have been possible with Phobos' architecture. (2) Insert ANSI escape sequences into the text. The I/O code for Windows would then have to intercept these and convert them into the appropriate WinAPI calls. I think this was possible, and even distinguishable from the case of writing to a string in memory. If the invasiveness worry comes from the possibility of dumping escape sequences into non-terminal destinations, then I hope the above wall of text can alleviate that concern.
Checking whether something is a terminal can be done using isatty on the file handle. I think this will work. But it is invasive because you want to add it to the formatting spec. Is this the usual way it is done? I don't know how it is done in Python or other languages.
I added writecf, writec, etc. with additional arguments.
writec(Color.red, "some text")
or
writecf(Color.red, "%s", "some text")
This is fine I think. But better options may be worth investigating.

Jens
I really think this should be in Phobos. If it doesn't go into Phobos, then people will write crappy terminal apps with no color. If it does go into Phobos, then the better devs will see the opportunity and use it. Something 3rd party is much less discoverable and won't have nearly as much impact. The use case is almost all CLI apps, so it's not like an uncommon corner-case or something.
True. When I asked there was less/no interest. I think we should just join and make one module that shows up top ten when googled for "D terminal/console color".
 I run a Gentoo system where things are configured to use color
 output wherever possible.  The portage devs went through all of the
 necessary contortions to get Python to output colored text, somehow.
 I feel the end result is indispensable.  Color is an extremely
 useful tool for making sure that the user doesn't overlook important
 bits while scanning text.  Outside of Gentoo, I find this most
 notable in grep: uncolored grep output is just awful, but the
 coloring makes it possible to easily identify why the regular
 expression behaved the way it did.
 
 I look forward to a better CLI ecosystem where highly reliable D
 programs are written quickly and write beautiful colored output ;)
It is. I'd like you to join and get this done. And you're right we should have Phobos integration in mind. Maybe they will add it. But in the mean time we can have a separate module. Jens
Oct 21 2012
parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 10/21/2012 06:55 PM, Jens Mueller wrote:
 Chad J wrote:
 On 10/21/2012 06:11 PM, Jens Mueller wrote:
 Chad J wrote:
 On 10/21/2012 05:01 PM, Jens Mueller wrote:

 It seems to have a hard ncurses/termcap/etc dependency.
Yes. I think you cannot make it portable without. Please proof me wrong and I'll fix this.
Well, traditionally it's done with automake/autoconf. You'd end up with preprocessor defines that tell you whether the lib has been statically linked or not. This isn't available here because Phobos doesn't use these as a build system and I hope it never does.
I mean to detect if your terminal is ANSI compatible without adding another dependency. It's easy to provide different version(...) to support different modes. One could do something like: 1. Check at run time if ncurses etc. are available. * If they are use them. * Otherwise fall back to ANSI codes or throw an Exception. What do you think?
I completely agree. The difficulty I encountered is actually /doing/ the runtime detection. Does Phobos have a way to dynamically link .so files yet? If yes, then we could search the obvious places ("/lib/libncurses.so.5" matches on my machine right now) and link to any files found. Since color is probably never necessary for program correctness, I think it is acceptable to ignore color formatting and produce plain text when detection fails. It would make sense to make this configurable though: the Terminal object could have a .throwOnDetectionFailure flag that can be set if people want to be a bit more hardcore about it.
 I'll admit when I started trying to work on doing this thing, I
 never got anything onto the screen.  What stopped me was that I
 couldn't figure out how to detect ncurses/termcap/etc.  I was going
 to shoot for Phobos inclusion and making Phobos always link with
 ncurses seems like a bad idea.
Dependence on Phobos is bad. If you can detect whether a terminal is ANSI compatible then this mode should be default. But I don't know how to detect this.
Wrong direction on the dependency. I wouldn't expect Terminal coloring/detection to rely on Phobos. I'd expect it to be one of the lower-level modules built into Phobos.
I mean it's bad to have Phobos depend on ncurses. Though one can go with loading at run time.
Yes.
 Ultimately I expect it to work with writeln or writefln to make it
 discoverable and easy to work with.
One could try this. At least for Linux. You just have to add the appropriate escape sequences. But this won't work on Windows.
I remember having a plan for this. See below.
 Back then I did design a format spec for introducing colors into
 format strings:
 www.chadjoan.com/d/dmd.2.058/html/d/phobos/std_format.html
I doubt that the Phobos maintainers will accept this. This is very invasive.
Hmmm, depends what is meant by invasive. I feel it's the only way to have discoverable and concise syntax. I'd be pretty disappointed if they didn't, regardless of who submits the pull request. I remember it being possible in Phobos to determine the destination of the format operation. If the destination is a string in memory, then no color formatting would be applied. If the destination is a Linux terminal of some kind, then some ncurses terminal info would be looked up (possible a cached lookup) and escape sequences generated based on that. If the destination is a Windows terminal, then these approaches can be considered: (1) Split the formatted text up on the color format boundaries. Send the slices into the stream one by one, calling the necessary WinAPI color formatting functions inbetween. I think this might not have been possible with Phobos' architecture. (2) Insert ANSI escape sequences into the text. The I/O code for Windows would then have to intercept these and convert them into the appropriate WinAPI calls. I think this was possible, and even distinguishable from the case of writing to a string in memory. If the invasiveness worry comes from the possibility of dumping escape sequences into non-terminal destinations, then I hope the above wall of text can alleviate that concern.
Checking whether something is a terminal can be done using isatty on the file handle. I think this will work. But it is invasive because you want to add it to the formatting spec. Is this the usual way it is done? I don't know how it is done in Python or other languages.
Is it relevant? I posit that having format syntax is simply better than not. This is on an objective basis. There is no weakness to this. The only shred of a counterargument I can think of is that it makes the format strings more difficult to learn. Other than that, it is possible to detect the destination of the formatter, so color codes will never end up in places where they shouldn't. A conservative approach to this should handle most desires and never interfere with all the people with no interest in color. On the upshot are the things I've mentioned: - A format specifier is potentially more discoverable. - A format specifier is more concise. This keeps your lines from wrapping. They are probably too long already. - To cement the previous point: nesting requires a few extra characters with a format specifier, rather than a couple extra /lines/ for extra function calls. - Calls to stateful console functions allow people to write bugs like saving console state and then forgetting to restore it (or throwing an exception and neglecting to restore from within a scope guard). Format specifiers do not have this problem. - etc (I'm sure I'm forgetting one or two.) These are the reasons why my ideal language has color formatting built into its I/O routines.
 I added writecf, writec, etc. with additional arguments.
 writec(Color.red, "some text")
 or
 writecf(Color.red, "%s", "some text")
 This is fine I think. But better options may be worth investigating.

 Jens
I really think this should be in Phobos. If it doesn't go into Phobos, then people will write crappy terminal apps with no color. If it does go into Phobos, then the better devs will see the opportunity and use it. Something 3rd party is much less discoverable and won't have nearly as much impact. The use case is almost all CLI apps, so it's not like an uncommon corner-case or something.
True. When I asked there was less/no interest. I think we should just join and make one module that shows up top ten when googled for "D terminal/console color".
 I run a Gentoo system where things are configured to use color
 output wherever possible.  The portage devs went through all of the
 necessary contortions to get Python to output colored text, somehow.
 I feel the end result is indispensable.  Color is an extremely
 useful tool for making sure that the user doesn't overlook important
 bits while scanning text.  Outside of Gentoo, I find this most
 notable in grep: uncolored grep output is just awful, but the
 coloring makes it possible to easily identify why the regular
 expression behaved the way it did.

 I look forward to a better CLI ecosystem where highly reliable D
 programs are written quickly and write beautiful colored output ;)
It is. I'd like you to join and get this done. And you're right we should have Phobos integration in mind. Maybe they will add it. But in the mean time we can have a separate module. Jens
I think this is very reasonable. Sounds like a plan! I'll probably make pull requests when I allocate time to work on this. Would implementing the format spec make sense? It might give me a good excuse to write an snprintf alternative in D that can be used at compile-time and won't introduce nasty link-time dependencies.
Oct 21 2012
parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Chad J wrote:
 On 10/21/2012 06:55 PM, Jens Mueller wrote:
Chad J wrote:
On 10/21/2012 06:11 PM, Jens Mueller wrote:
Chad J wrote:
On 10/21/2012 05:01 PM, Jens Mueller wrote:

It seems to have a hard ncurses/termcap/etc dependency.
Yes. I think you cannot make it portable without. Please proof me wrong and I'll fix this.
Well, traditionally it's done with automake/autoconf. You'd end up with preprocessor defines that tell you whether the lib has been statically linked or not. This isn't available here because Phobos doesn't use these as a build system and I hope it never does.
I mean to detect if your terminal is ANSI compatible without adding another dependency. It's easy to provide different version(...) to support different modes. One could do something like: 1. Check at run time if ncurses etc. are available. * If they are use them. * Otherwise fall back to ANSI codes or throw an Exception. What do you think?
I completely agree. The difficulty I encountered is actually /doing/ the runtime detection. Does Phobos have a way to dynamically link .so files yet?
It is possible since very long time to link dynamically using dmd.
 If yes, then we could search the obvious places
 ("/lib/libncurses.so.5" matches on my machine right now) and link to
 any files found.
For that purpose in particular I have written ddl. https://github.com/jkm/ddl http://jkm.github.com/ddl/ddl.html Just haven't found the time to integrate with the terminal stuff.
 Since color is probably never necessary for program correctness, I
 think it is acceptable to ignore color formatting and produce plain
 text when detection fails.  It would make sense to make this
 configurable though: the Terminal object could have a
 .throwOnDetectionFailure flag that can be set if people want to be a
 bit more hardcore about it.
Sounds useful.
Ultimately I expect it to work with writeln or writefln to make it
discoverable and easy to work with.
One could try this. At least for Linux. You just have to add the appropriate escape sequences. But this won't work on Windows.
I remember having a plan for this. See below.
Back then I did design a format spec for introducing colors into
format strings:
www.chadjoan.com/d/dmd.2.058/html/d/phobos/std_format.html
I doubt that the Phobos maintainers will accept this. This is very invasive.
Hmmm, depends what is meant by invasive. I feel it's the only way to have discoverable and concise syntax. I'd be pretty disappointed if they didn't, regardless of who submits the pull request. I remember it being possible in Phobos to determine the destination of the format operation. If the destination is a string in memory, then no color formatting would be applied. If the destination is a Linux terminal of some kind, then some ncurses terminal info would be looked up (possible a cached lookup) and escape sequences generated based on that. If the destination is a Windows terminal, then these approaches can be considered: (1) Split the formatted text up on the color format boundaries. Send the slices into the stream one by one, calling the necessary WinAPI color formatting functions inbetween. I think this might not have been possible with Phobos' architecture. (2) Insert ANSI escape sequences into the text. The I/O code for Windows would then have to intercept these and convert them into the appropriate WinAPI calls. I think this was possible, and even distinguishable from the case of writing to a string in memory. If the invasiveness worry comes from the possibility of dumping escape sequences into non-terminal destinations, then I hope the above wall of text can alleviate that concern.
Checking whether something is a terminal can be done using isatty on the file handle. I think this will work. But it is invasive because you want to add it to the formatting spec. Is this the usual way it is done? I don't know how it is done in Python or other languages.
Is it relevant? I posit that having format syntax is simply better than not. This is on an objective basis.
Maybe. Don't know. But in any case this is a add on. On top of the basic API. It is a Phobos integration thing.
 There is no weakness to this.  The only shred of a counterargument I
 can think of is that it makes the format strings more difficult to
 learn. Other than that, it is possible to detect the destination of
 the formatter, so color codes will never end up in places where they
 shouldn't.  A conservative approach to this should handle most
 desires and never interfere with all the people with no interest in
 color.
 
 On the upshot are the things I've mentioned:
 - A format specifier is potentially more discoverable.
 - A format specifier is more concise.  This keeps your lines from
 wrapping.  They are probably too long already.
Do you consider this writecf(Color.red, "something %s", "here") concise as well?
 - To cement the previous point: nesting requires a few extra
 characters with a format specifier, rather than a couple extra
 /lines/ for extra function calls.
Don't understand this point. Can you give an example?
 - Calls to stateful console functions allow people to write bugs
 like saving console state and then forgetting to restore it (or
 throwing an exception and neglecting to restore from within a scope
 guard).  Format specifiers do not have this problem.
The same holds for writecf(Color.red, "something %s", "here")
 - etc (I'm sure I'm forgetting one or two.)
 
 These are the reasons why my ideal language has color formatting
 built into its I/O routines.
Just wanted to point out that instead of that you can add writec* functions. I think the only thing is that these are less discoverable but they also work without formatting, e.g. writec(Color.red, "my text");
I run a Gentoo system where things are configured to use color
output wherever possible.  The portage devs went through all of the
necessary contortions to get Python to output colored text, somehow.
I feel the end result is indispensable.  Color is an extremely
useful tool for making sure that the user doesn't overlook important
bits while scanning text.  Outside of Gentoo, I find this most
notable in grep: uncolored grep output is just awful, but the
coloring makes it possible to easily identify why the regular
expression behaved the way it did.

I look forward to a better CLI ecosystem where highly reliable D
programs are written quickly and write beautiful colored output ;)
It is. I'd like you to join and get this done. And you're right we should have Phobos integration in mind. Maybe they will add it. But in the mean time we can have a separate module. Jens
I think this is very reasonable. Sounds like a plan! I'll probably make pull requests when I allocate time to work on this.
That would be nice. Let's coordinate with Robik. I think having Robik's ANSI stuff as a fall back would be nice. And we need to decide on a repository.
 Would implementing the format spec make sense?  It might give me a
 good excuse to write an snprintf alternative in D that can be used
 at compile-time and won't introduce nasty link-time dependencies.
This is probably interesting for Phobos. But I'm not the one to make a decision. The core Phobos developers should decide. Hopefully somebody is reading this. Jens
Oct 22 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/22/12 9:47 AM, Jens Mueller wrote:
 This is probably interesting for Phobos. But I'm not the one to make a
 decision. The core Phobos developers should decide.
 Hopefully somebody is reading this.
Off the top of my head something that is specific for only certain systems (Unixen in this case) is decidedly of less Phobos interest. We could, nevertheless, put such functionality in system-specific modules. Andrei
Oct 22 2012
next sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Andrei Alexandrescu wrote:
 On 10/22/12 9:47 AM, Jens Mueller wrote:
This is probably interesting for Phobos. But I'm not the one to make a
decision. The core Phobos developers should decide.
Hopefully somebody is reading this.
Off the top of my head something that is specific for only certain systems (Unixen in this case) is decidedly of less Phobos interest. We could, nevertheless, put such functionality in system-specific modules.
It also works on Windows. Even already implemented. The situation is similar to the file abstraction which has a different API in the Unix world and the Windows world. Jens
Oct 22 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/22/12 8:24 AM, Jens Mueller wrote:
 Andrei Alexandrescu wrote:
 On 10/22/12 9:47 AM, Jens Mueller wrote:
 This is probably interesting for Phobos. But I'm not the one to make a
 decision. The core Phobos developers should decide.
 Hopefully somebody is reading this.
Off the top of my head something that is specific for only certain systems (Unixen in this case) is decidedly of less Phobos interest. We could, nevertheless, put such functionality in system-specific modules.
It also works on Windows. Even already implemented. The situation is similar to the file abstraction which has a different API in the Unix world and the Windows world. Jens
Cool. Do all systems implement color as escape sequences? Andrei
Oct 22 2012
parent Jens Mueller <jens.k.mueller gmx.de> writes:
Andrei Alexandrescu wrote:
 On 10/22/12 8:24 AM, Jens Mueller wrote:
Andrei Alexandrescu wrote:
On 10/22/12 9:47 AM, Jens Mueller wrote:
This is probably interesting for Phobos. But I'm not the one to make a
decision. The core Phobos developers should decide.
Hopefully somebody is reading this.
Off the top of my head something that is specific for only certain systems (Unixen in this case) is decidedly of less Phobos interest. We could, nevertheless, put such functionality in system-specific modules.
It also works on Windows. Even already implemented. The situation is similar to the file abstraction which has a different API in the Unix world and the Windows world. Jens
Cool. Do all systems implement color as escape sequences?
No. On Windows you have to explicitly call a function. http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047%28v=vs.85%29.aspx Jens
Oct 22 2012
prev sibling parent "Kagamin" <spam here.lot> writes:
On Monday, 22 October 2012 at 12:26:29 UTC, Jens Mueller wrote:
 It also works on Windows.
It's still more of a linux tradition. Implementing it as a separate package will be also a good exercise of writing a layer over Phobos I/O system.
Oct 22 2012
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 9:47 AM, Jens 
Mueller wrote:
 This is probably interesting for Phobos. But I'm not the one to make a
 decision. The core Phobos developers should decide.
 Hopefully somebody is reading this.
Off the top of my head something that is specific for only certain systems (Unixen in this case) is decidedly of less Phobos interest. We could, nevertheless, put such functionality in system-specific modules.
A module that only sets the console color is a little too light to be a phobos entry. A more comprehensive module that included: 1. getting mouse input 2. getting size of the console 3. moving the cursor around 4. drawing boxes in the console window 5. setting the contents of the title bar 6. supporting cut/paste 7. getting no-echo raw input 8. setting the size of the cursor would be a definite candidate. I.e. a module that can support building a text mode screen app (like a text editor).
Oct 23 2012
next sibling parent "Tim" <Lt.Infiltrator gmail.com> writes:
On Tuesday, 23 October 2012 at 22:47:40 UTC, Walter Bright wrote:
 On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12
 A module that only sets the console color is a little too light 
 to be a phobos entry.

 A more comprehensive module that included:

 1. getting mouse input
 2. getting size of the console
 3. moving the cursor around
 4. drawing boxes in the console window
 5. setting the contents of the title bar
 6. supporting cut/paste
 7. getting no-echo raw input
 8. setting the size of the cursor

 would be a definite candidate. I.e. a module that can support 
 building a text mode screen app (like a text editor).
Just so it's known, I support such a module being created. I shall provide (what limited) help I can.
Oct 23 2012
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Oct 23, 2012 at 03:46:37PM -0700, Walter Bright wrote:
[...]
 A module that only sets the console color is a little too light to be
 a phobos entry.
 
 A more comprehensive module that included:
 
 1. getting mouse input
 2. getting size of the console
 3. moving the cursor around
 4. drawing boxes in the console window
 5. setting the contents of the title bar
 6. supporting cut/paste
 7. getting no-echo raw input
 8. setting the size of the cursor
 
 would be a definite candidate. I.e. a module that can support
 building a text mode screen app (like a text editor).
IOW, a replacement for libncurses. :) I think (1), (6), and (8) may be a bit too much to expect from a first try, esp. if you're dealing with Unix terminals, which are many and varied, and have all sorts of idiosyncrasies that make it a pain to write a generic library that works for everything. But I would say at least (2), (3), (4), (5), and (7) are a must for a Phobos entry. And in addition to that, I'd say incremental screen updates (along the lines of libncurses) are also very important. It will be hard for seasoned Unix coders to take D seriously if its standard library's console module has to repaint the screen everytime. Ideally, though, a console module in Phobos should do a better job at supporting text-mode windows than libncurses currently does. Text-mode apps are an easy niche for D to gain a strong presence, esp. if we have a console module that does a better job at simulating a windowing system than ncurses. (Hopefully we're not just reinventing ncurses here -- we should do better than it.) T -- Laissez-faire is a French term commonly interpreted by Conservatives to mean 'lazy fairy,' which is the belief that if governments are lazy enough, the Good Fairy will come down from heaven and do all their work for them.
Oct 23 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 23 October 2012 at 23:07:18 UTC, H. S. Teoh wrote:
 try, esp. if you're dealing with Unix terminals, which are many 
 and varied, and have all sorts of idiosyncrasies that make it a 
 pain to write a generic library that works for everything.
Does anybody really care about everything? Unix has de-facto standardized on vt100 emulators, and among them, there's only a few variants I'd care about: xterm, rxvt, gnu screen, putty, and the linux console. The differences are now brought way down to size, and we can use some of the more interesting extensions without worrying about lowest common denominator dragging us down. And then doing Windows (or DOS) is pretty easy to match and perhaps exceed it.
Oct 23 2012
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Oct 24, 2012 at 01:16:38AM +0200, Adam D. Ruppe wrote:
 On Tuesday, 23 October 2012 at 23:07:18 UTC, H. S. Teoh wrote:
try, esp. if you're dealing with Unix terminals, which are many
and varied, and have all sorts of idiosyncrasies that make it a
pain to write a generic library that works for everything.
Does anybody really care about everything? Unix has de-facto standardized on vt100 emulators, and among them, there's only a few variants I'd care about: xterm, rxvt, gnu screen, putty, and the linux console.
Perhaps the right approach then is to make the code modular, so that terminal-specific stuff is separated off into submodules (which are imported as needed automatically or otherwise). That way, the initial Phobos entry can just have the most common terminals supported: windows command prompt, vt100, and perhaps linux or xterm. I'd say vt100 alone should be good enough from the *nix perspective, at least for an initial stab at the module. Xterm, putty, etc., can then be added later more or less painlessly (if the design is properly done in a modular fashion). Later on, if people are ambitious, they can try interfacing with terminfo/termcap (but be prepared for long sleepless nights, this stuff is way more complicated than one might expect, and arguably, than is necessary).
 The differences are now brought way down to size, and we can use
 some of the more interesting extensions without worrying about
 lowest common denominator dragging us down.
 
 And then doing Windows (or DOS) is pretty easy to match and perhaps
 exceed it.
I'm not familiar enough with the new Windows prompt (haha, I'm so dating myself by calling it new) to say, but at least for DOS, terminal capabilities are pretty straightforward: color is encoded directly in the screen buffer, and there are standard system calls to move the cursor around, set the display mode, etc.. Raw character mode is pretty much the default (unless you fall back to the BIOS input reading routines -- if those even exist anymore nowadays). So there's almost no escape sequences that need special treatment, etc.. None of the hair-tearing complexities of Unix terminals. So the windows component of this module should pretty much be a cinch. T -- "A one-question geek test. If you get the joke, you're a geek: Seen on a California license plate on a VW Beetle: 'FEATURE'..." -- Joshua D. Wachs - Natural Intelligence, Inc.
Oct 23 2012
prev sibling next sibling parent "Robik" <szadows gmail.com> writes:
On Tuesday, 23 October 2012 at 22:47:40 UTC, Walter Bright wrote:
 On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 
 9:47 AM, Jens Mueller wrote:
 This is probably interesting for Phobos. But I'm not the one
to make a
 decision. The core Phobos developers should decide.
 Hopefully somebody is reading this.
Off the top of my head something that is specific for only
certain systems
 (Unixen in this case) is decidedly of less Phobos interest.
We could,
 nevertheless, put such functionality in system-specific
modules. A module that only sets the console color is a little too light to be a phobos entry. A more comprehensive module that included: 1. getting mouse input 2. getting size of the console 3. moving the cursor around 4. drawing boxes in the console window 5. setting the contents of the title bar 6. supporting cut/paste 7. getting no-echo raw input 8. setting the size of the cursor would be a definite candidate. I.e. a module that can support building a text mode screen app (like a text editor).
Thanks for your suggestions. I will try to do what I can, but I think there may be some problems because of differences in terminals. Although some of them should not be the problem :)
Oct 24 2012
prev sibling next sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Walter Bright wrote:
 On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 9:47
 AM, Jens Mueller wrote:
 This is probably interesting for Phobos. But I'm not the one to make a
 decision. The core Phobos developers should decide.
 Hopefully somebody is reading this.
Off the top of my head something that is specific for only certain systems (Unixen in this case) is decidedly of less Phobos interest. We could, nevertheless, put such functionality in system-specific modules.
A module that only sets the console color is a little too light to be a phobos entry. A more comprehensive module that included: 1. getting mouse input
Anybody an idea how to this on Linux?
 2. getting size of the console
This is easy if you just mean the number of lines and columns.
 3. moving the cursor around
This also assuming you just want something like, move 10 lines up, 3 lines right etc.
 4. drawing boxes in the console window
Should this be done by moving the cursor and inserting characters such that you have a box in the end?
 5. setting the contents of the title bar
The title bar of what?
 6. supporting cut/paste
Don't know how to do this? Anybody a starting point?
 7. getting no-echo raw input
Tried this but couldn't make it work yet. This is useful for passwords prompts, right?
 8. setting the size of the cursor
The size of the cursor? Why should I want to change its size? Jens
Oct 25 2012
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller wrote:
 5. setting the contents of the title bar
The title bar of what?
Here's how you do it on xterm: writefln("\033]0;%s\007", title); On Windows it is an api function: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686050%28v=vs.85%29.aspx
 6. supporting cut/paste
Don't know how to do this? Anybody a starting point?
I wouldn't worry about it up front, the system will give simple stuff for you and getting it right is a bit of a pain because you have to bring in other api calls (on both Windows and Linux; linux will need some X11 calls I believe.)
 7. getting no-echo raw input
Tried this but couldn't make it work yet. This is useful for passwords prompts, right?
Here's a brief example for unix: http://arsdnet.net/dcode/input.d On Windows I'm almost certain it is actually easier but I haven't done that for a while and don't remember it right now. The reason my code there puts it in a struct is so it is automatically put back to the previous mode when you go out of scope.
 8. setting the size of the cursor
The size of the cursor? Why should I want to change its size?
There's a way to do this on windows i'm pretty sure and it is hit and miss on linux - sometimes works, sometimes doesn't. But a reason you might want it is to visually indicate the difference between insert and overwrite mode. In a text editor for instance, a short cursor means insert. If you press the insert key on the keyboard, you switch to replace mode, and a taller cursor can show that.
 Jens
Oct 25 2012
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 26, 2012 at 03:35:42AM +0200, Adam D. Ruppe wrote:
 On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller wrote:
5. setting the contents of the title bar
The title bar of what?
Here's how you do it on xterm: writefln("\033]0;%s\007", title); On Windows it is an api function: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686050%28v=vs.85%29.aspx
And just to add, on Posix it's probably good to do something similar to Windows, where exiting the program will reset the title back to what it originally was. There's an xterm escape sequence that lets you read the current title string from stdin, so that can be used to save the original title.
6. supporting cut/paste
Don't know how to do this? Anybody a starting point?
I wouldn't worry about it up front, the system will give simple stuff for you and getting it right is a bit of a pain because you have to bring in other api calls (on both Windows and Linux; linux will need some X11 calls I believe.)
[...] I don't think you can assume X11 calls will work. You may be running on GNU screen, or on a remote SSH connection. Regardless, I think on Linux this feature is not needed, since most terminals will give the user a way to cut and paste independently of the program running in them, so implementing this in a console library is probably redundant. T -- A bend in the road is not the end of the road unless you fail to make the turn. -- Brian White
Oct 25 2012
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 26 October 2012 at 03:28:43 UTC, H. S. Teoh wrote:
 I don't think you can assume X11 calls will work. You may be 
 running on GNU screen, or on a remote SSH connection.
Yeah. Vim does it though, if it can connect to a display, it does and enhances its copy/paste ability. If it can't, it carries on without. There is a problem where sometimes the program dies with a BadWindow error if you move it in a screen from one to another....but it works most the time so they are doing something right.
 Regardless, I think on Linux this feature is not needed, since 
 most terminals will give the user a way to cut and paste
It's still nice to be able to improve it but yeah i would agree it is a low priority since the built in is usually good enough.
Oct 26 2012
prev sibling next sibling parent reply "Robik" <szadows gmail.com> writes:
On Friday, 26 October 2012 at 01:35:43 UTC, Adam D. Ruppe wrote:
 On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller 
 wrote:
 5. setting the contents of the title bar
The title bar of what?
Here's how you do it on xterm: writefln("\033]0;%s\007", title);
Yeah, the problem is it does not work in all terminals.
Oct 25 2012
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 26 October 2012 at 06:08:39 UTC, Robik wrote:
 Yeah, the problem is it does not work in all terminals.
Yeah, but neither will any other feature. But virtually every one used in practice nowadays supports it though.
Oct 26 2012
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 26, 2012 at 08:08:36AM +0200, Robik wrote:
 On Friday, 26 October 2012 at 01:35:43 UTC, Adam D. Ruppe wrote:
On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller wrote:
5. setting the contents of the title bar
The title bar of what?
Here's how you do it on xterm: writefln("\033]0;%s\007", title);
Yeah, the problem is it does not work in all terminals.
The correct solution is to examine the TERM environment variable to find out what kind of terminal it is, and then use escape sequences specific to that terminal. T -- IBM = I'll Buy Microsoft!
Oct 26 2012
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
H. S. Teoh wrote:
 On Fri, Oct 26, 2012 at 08:08:36AM +0200, Robik wrote:
 On Friday, 26 October 2012 at 01:35:43 UTC, Adam D. Ruppe wrote:
On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller wrote:
5. setting the contents of the title bar
The title bar of what?
Here's how you do it on xterm: writefln("\033]0;%s\007", title);
Yeah, the problem is it does not work in all terminals.
The correct solution is to examine the TERM environment variable to find out what kind of terminal it is, and then use escape sequences specific to that terminal.
Or use a library that does this? There is terminfo. Don't know whether this is supported on all Posix platforms. I think the terminal's capabilities are stored in some files on the system. Jens
Oct 26 2012
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 26, 2012 at 04:46:26PM +0200, Jens Mueller wrote:
 H. S. Teoh wrote:
 On Fri, Oct 26, 2012 at 08:08:36AM +0200, Robik wrote:
 On Friday, 26 October 2012 at 01:35:43 UTC, Adam D. Ruppe wrote:
[...]
writefln("\033]0;%s\007", title);
Yeah, the problem is it does not work in all terminals.
The correct solution is to examine the TERM environment variable to find out what kind of terminal it is, and then use escape sequences specific to that terminal.
Or use a library that does this? There is terminfo. Don't know whether this is supported on all Posix platforms. I think the terminal's capabilities are stored in some files on the system.
[...] Well, if you're going to use a library, terminfo is the way to go. All modern Posix systems should have it. As for terminal description files, don't rely on that, because it varies wildly from system to system. Your best bet is to either recognize known values of $TERM, or use a library like terminfo that takes care of all the dirty details for you. It does get very messy once you get down to the nitty gritty of how different *nixes handle terminal capabilities. T -- People tell me that I'm paranoid, but they're just out to get me.
Oct 26 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
I'm slapping together a minimal termcap reader for D now.
Oct 26 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
Here we go, some more basic functions:

http://arsdnet.net/dcode/terminal.d

The unix stuff is more implemented than the windows.


Let's walk through main and I'll discuss why I'm doing things the 
way I am. I'm throwing this out just to show one possible way 
this can be done and to explain why I like this way. Feel free to 
take some or all of my code if you want.


	auto terminal = Terminal(ConsoleOutputType.cellular);

First, the terminal is a separate type, a struct, rather than 
just magic functions. This way it can use the struct destructor 
to reset things to normal.

The argument here is either linear or cellular - do you want line 
based output or do you want to control the whole screen as a grid 
of cells?

If you use cellular, it will use the alternative screen buffer on 
unix terminals. IIRC Windows works basically the same way. This 
is what we want for a TUI app.

The escape sequences to make this happen is based on the 
envrionment variable TERMCAP, which is set by gnu screen, xterm, 
and most other emulators.

It is *not* set by the linux console or rxvt on my box, so this 
isn't perfect yet, but it is a start. If it can't find a 
capability in there, it simply ignores those method calls, 
meaning it should be backward compatible (once fully implemented 
- I haven't done this on title yet.)

	terminal.setTitle("Basic I/O");

All changes are done with methods. This is how Windows does it 
and is cleaner anyway.

	auto input = terminal.captureInput(ConsoleInputFlags.raw);

To get real time input, you use a special method which returns an 
input struct. Which could probably be an input range actually but 
isn't now.

Anyway the reason is you have to change the terminal mode in 
linux to get real time input. Otherwise it will be line buffered. 
Again, a struct lets us reset the mode automatically in the 
destructor. The flags let you control automatic echo.

	terminal.color(Color.green | Bright, Color.black);

I insist that you set foreground and background colors together. 
This ensure you get readable text.

The colors are defined with a platform independent color enum and 
you can flag in bright to get brighter colors.


BTW I'm thinking about calling it LowContrast instead of 
bright... then your color definitions can always be the same 
regardless of bg, and it automatically flips the bright bit if 
needed. But since I'm forcing you to specify background here too 
it isn't a big deal with now.


	int centerX = terminal.width / 2;
	int centerY = terminal.height / 2;

I prefer width and height to rows and columns. I think more in 
terms of gui here.

	while(true) {
		if(input.kbhit()) {

Since we have real time capture, can poll for new input instead 
of blocking.

			auto c = input.getch();

Get our character... (BTW this function still needs a lot of work)

			if(c == 'q' || c == 'Q')
				break;
			terminal.moveTo(centerX, centerY);
			terminal.writef("%c", c);
			terminal.flush();

And output the stuff, centering the text. All output methods are 
attached to the terminal to ensure the proper api stuff is 
handled.

		usleep(10000);

This is just there so we don't eat too much cpu waiting on input.
Oct 26 2012
parent Jens Mueller <jens.k.mueller gmx.de> writes:
Adam D. Ruppe wrote:
 Here we go, some more basic functions:
 
 http://arsdnet.net/dcode/terminal.d
 
 The unix stuff is more implemented than the windows.
 
 
 Let's walk through main and I'll discuss why I'm doing things the
 way I am. I'm throwing this out just to show one possible way this
 can be done and to explain why I like this way. Feel free to take
 some or all of my code if you want.
 
 
 	auto terminal = Terminal(ConsoleOutputType.cellular);
 
 First, the terminal is a separate type, a struct, rather than just
 magic functions. This way it can use the struct destructor to reset
 things to normal.
 
 The argument here is either linear or cellular - do you want line
 based output or do you want to control the whole screen as a grid of
 cells?
 
 If you use cellular, it will use the alternative screen buffer on
 unix terminals. IIRC Windows works basically the same way. This is
 what we want for a TUI app.
 
 The escape sequences to make this happen is based on the envrionment
 variable TERMCAP, which is set by gnu screen, xterm, and most other
 emulators.
 
 It is *not* set by the linux console or rxvt on my box, so this
 isn't perfect yet, but it is a start. If it can't find a capability
 in there, it simply ignores those method calls, meaning it should be
 backward compatible (once fully implemented - I haven't done this on
 title yet.)
I like that you code won't need additional libraries. But how do you plan to handle the linux console or rxvt if setting TERMCAP is not portable?
 	terminal.setTitle("Basic I/O");
 
 All changes are done with methods. This is how Windows does it and
 is cleaner anyway.
 
 	auto input = terminal.captureInput(ConsoleInputFlags.raw);
 
 To get real time input, you use a special method which returns an
 input struct. Which could probably be an input range actually but
 isn't now.
 
 Anyway the reason is you have to change the terminal mode in linux
 to get real time input. Otherwise it will be line buffered. Again, a
 struct lets us reset the mode automatically in the destructor. The
 flags let you control automatic echo.
 
 	terminal.color(Color.green | Bright, Color.black);
 
 I insist that you set foreground and background colors together.
 This ensure you get readable text.
 
 The colors are defined with a platform independent color enum and
 you can flag in bright to get brighter colors.
 
 
 BTW I'm thinking about calling it LowContrast instead of bright...
 then your color definitions can always be the same regardless of bg,
 and it automatically flips the bright bit if needed. But since I'm
 forcing you to specify background here too it isn't a big deal with
 now.
 
 
 	int centerX = terminal.width / 2;
 	int centerY = terminal.height / 2;
 
 I prefer width and height to rows and columns. I think more in terms
 of gui here.
 
 	while(true) {
 		if(input.kbhit()) {
 
 Since we have real time capture, can poll for new input instead of
 blocking.
 
 			auto c = input.getch();
 
 Get our character... (BTW this function still needs a lot of work)
 
 			if(c == 'q' || c == 'Q')
 				break;
 			terminal.moveTo(centerX, centerY);
 			terminal.writef("%c", c);
 			terminal.flush();
 
 And output the stuff, centering the text. All output methods are
 attached to the terminal to ensure the proper api stuff is handled.
 
 		usleep(10000);
 
 This is just there so we don't eat too much cpu waiting on input.
This looks well thought-out. I'm unsure about TERMCAP. Currently I'm using tinfo instead. Probably I'm going will all your ideas but still using tinfo. Jens
Oct 28 2012
prev sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Adam D. Ruppe wrote:
 On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller wrote:
5. setting the contents of the title bar
The title bar of what?
Here's how you do it on xterm: writefln("\033]0;%s\007", title); On Windows it is an api function: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686050%28v=vs.85%29.aspx
6. supporting cut/paste
Don't know how to do this? Anybody a starting point?
I wouldn't worry about it up front, the system will give simple stuff for you and getting it right is a bit of a pain because you have to bring in other api calls (on both Windows and Linux; linux will need some X11 calls I believe.)
7. getting no-echo raw input
Tried this but couldn't make it work yet. This is useful for passwords prompts, right?
Here's a brief example for unix: http://arsdnet.net/dcode/input.d On Windows I'm almost certain it is actually easier but I haven't done that for a while and don't remember it right now. The reason my code there puts it in a struct is so it is automatically put back to the previous mode when you go out of scope.
8. setting the size of the cursor
The size of the cursor? Why should I want to change its size?
There's a way to do this on windows i'm pretty sure and it is hit and miss on linux - sometimes works, sometimes doesn't. But a reason you might want it is to visually indicate the difference between insert and overwrite mode. In a text editor for instance, a short cursor means insert. If you press the insert key on the keyboard, you switch to replace mode, and a taller cursor can show that.
I see. Thanks for many pointers. Jens
Oct 26 2012
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 10/25/2012 3:27 PM, Jens Mueller wrote:
 Anybody an idea how to this on Linux?
Much of this is implemented in one way or another as part of the source code for MicroEmacs, downloadable from digitalmars.com. https://github.com/DigitalMars/me
Oct 29 2012
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 26, 2012 at 12:27:38AM +0200, Jens Mueller wrote:
 Walter Bright wrote:
[...]
 A module that only sets the console color is a little too light to
 be a phobos entry.
 
 A more comprehensive module that included:
 
 1. getting mouse input
Anybody an idea how to this on Linux?
You can only do this in terminals that support it. XTerm, I believe, has escape sequences that you can send to turn on mouse tracking. Those will show up as special escape sequences on stdin, which will have to be intercepted and removed from the program's normal input stream. Other modern terminals probably have their own way of doing mouse tracking. AFAIK, there isn't any standard for this, so you'll have to stick with terminal-specific code. (Which is why I recommended earlier that this module must be modular so that support for specific terminals can be plugged in easily -- for the initial stab, something very simple such as vt100 support may be good enough, as long as it's easy to add support for new terminals.)
 2. getting size of the console
This is easy if you just mean the number of lines and columns.
I think that's good enough. A text-mode app doesn't need to know pixel sizes. (If it does, it really should be using a real GUI toolkit instead.)
 3. moving the cursor around
This also assuming you just want something like, move 10 lines up, 3 lines right etc.
Handling absolute positions (x columns y rows from upper left corner of terminal) is a must. Pixel positions is not necessary (and probably impossible -- text terminals AFAIK don't provide that kind of info).
 4. drawing boxes in the console window
Should this be done by moving the cursor and inserting characters such that you have a box in the end?
I think the implementation details are unimportant, as long as there's a way to say "draw a box at (x,y) with dimensions (w,h)" and the module will do whatever is necessary to accomplish that.
 5. setting the contents of the title bar
The title bar of what?
The terminal window. Many X11 terminals, like xterm and rxvt, support an escape sequence that lets you set/change what's displayed on the title bar of the window. (Personally, though, I don't like this feature; I find it very annoying. But many people like it, so it should still be supported, I think.)
 6. supporting cut/paste
Don't know how to do this? Anybody a starting point?
I'm not sure what Walter is referring to specifically. Usually cut and paste is supported directly by the terminal, and the program running in the terminal doesn't get to control it. It only sees pasted text as a sudden large chunk of data on stdin. I don't think this is the job of the console module (Walter, correct me if I'm wrong).
 7. getting no-echo raw input
Tried this but couldn't make it work yet. This is useful for passwords prompts, right?
Not just that, but also for fully-interactive programs that want to capture every keystroke immediately (instead of waiting for the user to hit Enter). Like games and stuff. Or menu-driven systems where the user can navigate between menus and items without needing to hit Enter each time. For Unix terminals, you need to send certain escape sequences (specific to the terminal) to enable what is called 'raw' mode or 'cbreak' mode. (Googling for 'cbreak' should give you useful references.) This will cause the terminal to immediately transmit keystrokes, instead of buffering them until the user hits Enter. Also, make sure that there is a way to turn off this mode after the program is finished, otherwise the terminal may become unusable when it returns to the shell prompt. :)
 8. setting the size of the cursor
The size of the cursor? Why should I want to change its size?
[...] I think Walter is referring to the DOS/Windows-specific feature that certain BIOS calls allow you to change the starting/ending scanlines of the cursor. I suppose some people like to see a big flashing white box for their cursor and others prefer just a flashing underscore, but personally, I don't see this as a must-have feature. I think some terminals don't even support such a setting. In any case, I think this is a low-priority nice-to-have thing. The important stuff are cursor positioning, box drawing, incremental updates, cbreak mode, etc.. T -- A linguistics professor was lecturing to his class one day. "In English," he said, "A double negative forms a positive. In some languages, though, such as Russian, a double negative is still a negative. However, there is no language wherein a double positive can form a negative." A voice from the back of the room piped up, "Yeah, yeah."
Oct 25 2012
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
H. S. Teoh wrote:
 On Fri, Oct 26, 2012 at 12:27:38AM +0200, Jens Mueller wrote:
 Walter Bright wrote:
[...]
 A module that only sets the console color is a little too light to
 be a phobos entry.
 
 A more comprehensive module that included:
 
 1. getting mouse input
Anybody an idea how to this on Linux?
You can only do this in terminals that support it. XTerm, I believe, has escape sequences that you can send to turn on mouse tracking. Those will show up as special escape sequences on stdin, which will have to be intercepted and removed from the program's normal input stream. Other modern terminals probably have their own way of doing mouse tracking. AFAIK, there isn't any standard for this, so you'll have to stick with terminal-specific code. (Which is why I recommended earlier that this module must be modular so that support for specific terminals can be plugged in easily -- for the initial stab, something very simple such as vt100 support may be good enough, as long as it's easy to add support for new terminals.)
So there exists no portable library abstracting mouse input? If that's the case then being modular is the only option. How would you design it? I don't plan to implement this. But leaving the door open for others should be possible. [snip]
 3. moving the cursor around
This also assuming you just want something like, move 10 lines up, 3 lines right etc.
Handling absolute positions (x columns y rows from upper left corner of terminal) is a must. Pixel positions is not necessary (and probably impossible -- text terminals AFAIK don't provide that kind of info).
Okay. But this is no problem to build on top. I forget to mention that there is one sequence that move the cursor a specific line/column.
 4. drawing boxes in the console window
Should this be done by moving the cursor and inserting characters such that you have a box in the end?
I think the implementation details are unimportant, as long as there's a way to say "draw a box at (x,y) with dimensions (w,h)" and the module will do whatever is necessary to accomplish that.
That means this can also be built on top of cursor moving.
 5. setting the contents of the title bar
The title bar of what?
The terminal window. Many X11 terminals, like xterm and rxvt, support an escape sequence that lets you set/change what's displayed on the title bar of the window. (Personally, though, I don't like this feature; I find it very annoying. But many people like it, so it should still be supported, I think.)
I have to look up that. I find it strange because the Linux console does not have a title bar. But if that is accessible using tinfo I will add this. I find it strange, too. I think changing the title of a window is more like a GUI thing.
 7. getting no-echo raw input
Tried this but couldn't make it work yet. This is useful for passwords prompts, right?
Not just that, but also for fully-interactive programs that want to capture every keystroke immediately (instead of waiting for the user to hit Enter). Like games and stuff. Or menu-driven systems where the user can navigate between menus and items without needing to hit Enter each time. For Unix terminals, you need to send certain escape sequences (specific to the terminal) to enable what is called 'raw' mode or 'cbreak' mode. (Googling for 'cbreak' should give you useful references.) This will cause the terminal to immediately transmit keystrokes, instead of buffering them until the user hits Enter. Also, make sure that there is a way to turn off this mode after the program is finished, otherwise the terminal may become unusable when it returns to the shell prompt. :)
Thanks for the pointers. So these are then two things. First noecho and the other one is raw input.
 8. setting the size of the cursor
The size of the cursor? Why should I want to change its size?
[...] I think Walter is referring to the DOS/Windows-specific feature that certain BIOS calls allow you to change the starting/ending scanlines of the cursor. I suppose some people like to see a big flashing white box for their cursor and others prefer just a flashing underscore, but personally, I don't see this as a must-have feature. I think some terminals don't even support such a setting. In any case, I think this is a low-priority nice-to-have thing. The important stuff are cursor positioning, box drawing, incremental updates, cbreak mode, etc..
Can you say something about incremental updates? Any pointers? Jens
Oct 26 2012
prev sibling next sibling parent reply "Tobias Pankrath" <tobias pankrath.net> writes:
On Tuesday, 23 October 2012 at 22:47:40 UTC, Walter Bright wrote:
 On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 
 9:47 AM, Jens Mueller wrote:
 This is probably interesting for Phobos. But I'm not the one
to make a
 decision. The core Phobos developers should decide.
 Hopefully somebody is reading this.
Off the top of my head something that is specific for only
certain systems
 (Unixen in this case) is decidedly of less Phobos interest.
We could,
 nevertheless, put such functionality in system-specific
modules. A module that only sets the console color is a little too light to be a phobos entry. A more comprehensive module that included: 1. getting mouse input 2. getting size of the console 3. moving the cursor around 4. drawing boxes in the console window 5. setting the contents of the title bar 6. supporting cut/paste 7. getting no-echo raw input 8. setting the size of the cursor would be a definite candidate. I.e. a module that can support building a text mode screen app (like a text editor).
This would look like a full blown TUI-Toolkit and we should model the API after successfull GUI-Frameworks like Qt, i.e. provide a event loop, use a Signal/Slot mechanism etc. That would be a real improvement over nCurses. What do you think?
Oct 26 2012
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 26, 2012 at 01:56:28PM +0200, Tobias Pankrath wrote:
 On Tuesday, 23 October 2012 at 22:47:40 UTC, Walter Bright wrote:
[...]
A more comprehensive module that included:

1. getting mouse input
2. getting size of the console
3. moving the cursor around
4. drawing boxes in the console window
5. setting the contents of the title bar
6. supporting cut/paste
7. getting no-echo raw input
8. setting the size of the cursor

would be a definite candidate. I.e. a module that can support
building a text mode screen app (like a text editor).
This would look like a full blown TUI-Toolkit and we should model the API after successfull GUI-Frameworks like Qt, i.e. provide a event loop, use a Signal/Slot mechanism etc.
If we implement an event loop, I think it should be optional. Many apps only need to do simple things like allow editing operations on the current input line (support backspace, insert, delete, moving cursor left/right, etc.). Having a full-blown event loop is overkill. OTOH, having the *option* of using an event loop makes it easier to write things like network-based apps, where input from many different directions can be handled asynchronously. It also makes it possible to "skin" an app to work with both GUI and TUI if the underlying code is pretty much the same, except for different low-level calls at the bottom. :) So I think it's a good thing to have. Just make it optional, not mandatory.
 That would be a real improvement over nCurses. What do you think?
[...] Anything that improves on ncurses is welcome by me. Although ncurses does what it does very well, the API is a poorly-designed patchwork of functions that overlap too much in some areas, and not enough in others. (Try UTF-8 processing on ncurses sometime. Or maybe, _don't_, because it leads to pain and suffering.) Having a well-designed, consistent API would be a major plus. T -- You have to expect the unexpected. -- RL
Oct 26 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 26 October 2012 at 18:05:09 UTC, H. S. Teoh wrote:
 If we implement an event loop, I think it should be optional.
I think this is another benefit of capturing the input with a special type and method. auto input = terminal.captureInput(ConsoleInputFlags.raw | ConsoleInputFlags.mouse); while(true) { InputEvent = input.nextEvent(); // blah blah blah } Then you can loop on it and get all kinds of data, or you can use the more plain read/write functions. This is more or less how it works on Windows. (Really, the people who say text programming on Windows sucks always confuse me. It's a pretty decent design, lightyears better than the garbage you have to put up with on Linux.) http://msdn.microsoft.com/en-us/library/windows/desktop/ms684961%28v=vs.85%29.aspx for the fancier events or http://msdn.microsoft.com/en-us/library/windows/desktop/ms684958%28v=vs.85%29.aspx if all you care about is keyboard input.
Oct 26 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 26 October 2012 at 18:58:20 UTC, Adam D. Ruppe wrote:
 I think this is another benefit of capturing the input with a 
 special type and method.
I've implemented the basic events for linux now: http://arsdnet.net/dcode/terminal.d Still need to check more of the input sequences, but it correctly detects mouse events (when requested) and has set the groundwork for the rest. Just a matter of actually making it happen yet. It uses $TERM and sometimes $TERMCAP to check for a requested feature before enabling it to keep out trash output. The loop looks like this right now: loop: while(true) { auto event = input.nextEvent(); terminal.writef("%s\n", event.type); final switch(event.type) { case InputEvent.Type.CharacterEvent: auto ev = event.get!(InputEvent.Type.CharacterEvent); terminal.writef("\t%s\n", ev); if(ev.character == 'Q') break loop; break; case InputEvent.Type.NonCharacterKeyEvent: terminal.writef("\t%s\n", event.get!(InputEvent.Type.NonCharacterKeyEvent)); break; case InputEvent.Type.PasteEvent: terminal.writef("\t%s\n", event.get!(InputEvent.Type.PasteEvent)); break; case InputEvent.Type.MouseEvent: terminal.writef("\t%s\n", event.get!(InputEvent.Type.MouseEvent)); break; } }
Oct 27 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
It now can translate most PC keyboard input sequences into char 
or non-char key events, including requesting UTF-8 input for 
chars:

http://arsdnet.net/dcode/terminal.d


We could just about start writing real apps with this now. 
Biggest problem left is it doesn't actually scan the termcap file 
- it only looks for a TERMCAP environment variable. This means 
many keys are ignored on some terminals.

Should be a fairly easy fix I just haven't gotten around to it 
yet.


Then finish the Windows support side of it and we have a fairly 
functional, totally standalone, little text library here.



BTW this is actually kinda off topic for ColorD since I'm going 
more fancy - if you just want to add color to stdout, my code has 
probably gone too far.
Oct 27 2012
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Oct 28, 2012 at 04:49:03AM +0100, Adam D. Ruppe wrote:
 It now can translate most PC keyboard input sequences into char or
 non-char key events, including requesting UTF-8 input for chars:
 
 http://arsdnet.net/dcode/terminal.d
 
 We could just about start writing real apps with this now. Biggest
 problem left is it doesn't actually scan the termcap file - it only
 looks for a TERMCAP environment variable. This means many keys are
 ignored on some terminals.
This is too cool! You should polish it up and submit a Phobos entry for it. I would use it!
 Should be a fairly easy fix I just haven't gotten around to it yet.
 
 Then finish the Windows support side of it and we have a fairly
 functional, totally standalone, little text library here.
Yeah, I would vote for it as a Phobos entry.
 BTW this is actually kinda off topic for ColorD since I'm going more
 fancy - if you just want to add color to stdout, my code has probably
 gone too far.
I don't think it's too far, I think it's just about right for the beginnings of a console module in Phobos. If you'd put it on github, I might submit a pull request to add some ddocs, then with added Windows support, it should be just about ready for a Phobos entry. T -- The diminished 7th chord is the most flexible and fear-instilling chord. Use it often, use it unsparingly, to subdue your listeners into submission!
Oct 27 2012
prev sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Adam D. Ruppe wrote:
 It now can translate most PC keyboard input sequences into char or
 non-char key events, including requesting UTF-8 input for chars:
 
 http://arsdnet.net/dcode/terminal.d
 
 
 We could just about start writing real apps with this now. Biggest
 problem left is it doesn't actually scan the termcap file - it only
 looks for a TERMCAP environment variable. This means many keys are
 ignored on some terminals.
 
 Should be a fairly easy fix I just haven't gotten around to it yet.
How?
 Then finish the Windows support side of it and we have a fairly
 functional, totally standalone, little text library here.
 
 
 
 BTW this is actually kinda off topic for ColorD since I'm going more
 fancy - if you just want to add color to stdout, my code has
 probably gone too far.
It is. But it is going in the right direction. Jens
Oct 28 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 28 October 2012 at 10:44:58 UTC, Jens Mueller wrote:
 How?
The file /etc/termcap has the data too so opening it and quickly parsing should give the same result as the environment variable. It looks like this: vg|vt-generic|Generic VT entries:\ <snip> 1996): lx|linux|console|con80x25|LINUX System Console:\ <snip> and so on. The $TERM variable is used as a key into one of those names, then the rest of the data is on the following lines. The termcap entries can also inherit from other entries, but again it is just a key lookup into the list.
Oct 28 2012
next sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Adam D. Ruppe wrote:
 On Sunday, 28 October 2012 at 10:44:58 UTC, Jens Mueller wrote:
How?
The file /etc/termcap has the data too so opening it and quickly parsing should give the same result as the environment variable.
I'm running Debian. It doesn't have such a file.
 It looks like this:
 
 vg|vt-generic|Generic VT entries:\

 <snip>

 lx|linux|console|con80x25|LINUX System Console:\

 <snip>
 
 and so on. The $TERM variable is used as a key into one of those
 names, then the rest of the data is on the following lines.
 
 The termcap entries can also inherit from other entries, but again
 it is just a key lookup into the list.
Jens
Oct 28 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 28 October 2012 at 14:09:09 UTC, Jens Mueller wrote:
 I'm running Debian. It doesn't have such a file.
They must just depend on terminfo. That's more complicated to read though - it isn't a plain text file anymore, so doing it without a library is going to be more of a pain. I think I'll also copy/paste a few of the entries from my system into the code to use as generic fallback if nothing else is available (they aren't long).
Oct 28 2012
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Oct 28, 2012 at 03:15:46PM +0100, Adam D. Ruppe wrote:
 On Sunday, 28 October 2012 at 14:09:09 UTC, Jens Mueller wrote:
I'm running Debian. It doesn't have such a file.
They must just depend on terminfo. That's more complicated to read though - it isn't a plain text file anymore, so doing it without a library is going to be more of a pain.
Why not use a library? Terminfo is designed precisely for this.
 I think I'll also copy/paste a few of the entries from my system
 into the code to use as generic fallback if nothing else is
 available (they aren't long).
T -- If it's green, it's biology, If it stinks, it's chemistry, If it has numbers it's math, If it doesn't work, it's technology.
Oct 28 2012
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 28 October 2012 at 14:53:31 UTC, H. S. Teoh wrote:
 Why not use a library? Terminfo is designed precisely for this.
Sometimes linking in external libraries in Phobos can be a problem for licensing or Just Works portability. idk about terminfo, I haven't really looked at it. (tbh I just don't like using libraries in general either :-p )
Oct 28 2012
prev sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
Robik let me add my code to his repository with the plan to merge 
the two files later, but for now I just pushed my file up there.

https://github.com/robik/ConsoleD/blob/master/terminal.d

It now has /etc/termcap support, a builtin termcap to work in a 
pinch if the system doesn't have one, and most of the stuff 
needed for Windows support (the events aren't translated 
perfectly, but basic programs already work).

I'm done with it for today, but the idea is to eventually merge 
our two files completely so we have both low level event, etc., 
and high level drawing in the one module.
Oct 28 2012
prev sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Tobias Pankrath wrote:
 On Tuesday, 23 October 2012 at 22:47:40 UTC, Walter Bright wrote:
On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12
9:47 AM, Jens Mueller wrote:
 This is probably interesting for Phobos. But I'm not the one
to make a
 decision. The core Phobos developers should decide.
 Hopefully somebody is reading this.
Off the top of my head something that is specific for only
certain systems
 (Unixen in this case) is decidedly of less Phobos interest.
We could,
 nevertheless, put such functionality in system-specific
modules. A module that only sets the console color is a little too light to be a phobos entry. A more comprehensive module that included: 1. getting mouse input 2. getting size of the console 3. moving the cursor around 4. drawing boxes in the console window 5. setting the contents of the title bar 6. supporting cut/paste 7. getting no-echo raw input 8. setting the size of the cursor would be a definite candidate. I.e. a module that can support building a text mode screen app (like a text editor).
This would look like a full blown TUI-Toolkit and we should model the API after successfull GUI-Frameworks like Qt, i.e. provide a event loop, use a Signal/Slot mechanism etc. That would be a real improvement over nCurses. What do you think?
If you can add an event loop on top that would be great. What do I need to make sure that you can add the event handling on top? Jens
Oct 28 2012
parent "Tobias Pankrath" <tobias pankrath.net> writes:
 If you can add an event loop on top that would be great. What 
 do I need
 to make sure that you can add the event handling on top?

 Jens
I don't think that this needs any special consideration. If you look at Adams code samples in this thread, he's building his own event loop on input.getch. That's fine. I just think, that you shouldn't have to write your own and having a standard one and common mechanism to dispatch events to some kind of widgets, will make sharing those widgets so much easier.
Oct 28 2012
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 26, 2012 at 10:06:38AM +0200, Jens Mueller wrote:
 H. S. Teoh wrote:
 On Fri, Oct 26, 2012 at 12:27:38AM +0200, Jens Mueller wrote:
 Walter Bright wrote:
[...]
[...]
 1. getting mouse input
Anybody an idea how to this on Linux?
You can only do this in terminals that support it. XTerm, I believe, has escape sequences that you can send to turn on mouse tracking. Those will show up as special escape sequences on stdin, which will have to be intercepted and removed from the program's normal input stream. Other modern terminals probably have their own way of doing mouse tracking. AFAIK, there isn't any standard for this, so you'll have to stick with terminal-specific code. (Which is why I recommended earlier that this module must be modular so that support for specific terminals can be plugged in easily -- for the initial stab, something very simple such as vt100 support may be good enough, as long as it's easy to add support for new terminals.)
So there exists no portable library abstracting mouse input? If that's the case then being modular is the only option. How would you design it? I don't plan to implement this. But leaving the door open for others should be possible.
Hmm. I googled around a bit, and found that the only portable libraries for abstracting terminal capabilities appear to be curses and its derivatives like ncurses. So if we're going to reengineer a D console library that doesn't depend on ncurses, we'll have to get our hands dirty with interpreting $TERM and parsing terminal capabilities. :-( As for design, I think a very simple and easily extensible design would be something along these lines: Have a generic Terminal base class that contains all the API functions for various terminal capabilities, like interacting with the mouse, setting color, moving the cursor, etc. These functions are stubbed to throw an UnsupportedTerminalCapability (or something like that) exception when they are called. Then each supported terminal type will derive from Terminal, and override those functions that are supported for that terminal type. The module initialization code will determine at runtime which of these subclasses to instantiate. Then build an additional layer on top, with higher-level API functions that eventually call the object's methods to perform various terminal functions (e.g., writeln can be extended to support color by interpreting color escape sequences that ultimately result in calling some underlying method in Terminal). When the module is extended to handle new capabilities, we just add new methods to Terminal, stubbed to throw UnsupportedTerminalCapability. When we add support for new terminal types, we just create a new subclass of Terminal that implements the new methods. I think for maintainability, Terminal should not be directly accessed by the user, so that its methods can be kept concise and at the correct abstraction level for interacting with low-level terminal functions. The module should provide a higher-level API with underlying calls to these functions, say by extending writeln, implementing screen buffering, etc.. [...]
 7. getting no-echo raw input
Tried this but couldn't make it work yet. This is useful for passwords prompts, right?
Not just that, but also for fully-interactive programs that want to capture every keystroke immediately (instead of waiting for the user to hit Enter). Like games and stuff. Or menu-driven systems where the user can navigate between menus and items without needing to hit Enter each time. For Unix terminals, you need to send certain escape sequences (specific to the terminal) to enable what is called 'raw' mode or 'cbreak' mode. (Googling for 'cbreak' should give you useful references.) This will cause the terminal to immediately transmit keystrokes, instead of buffering them until the user hits Enter. Also, make sure that there is a way to turn off this mode after the program is finished, otherwise the terminal may become unusable when it returns to the shell prompt. :)
Thanks for the pointers. So these are then two things. First noecho and the other one is raw input.
Yeah, noecho is useful for password input; raw input is needed for interactive apps like games or menu-driven programs. Both should be supported. [...]
 The important stuff are cursor positioning, box drawing, incremental
 updates, cbreak mode, etc..
Can you say something about incremental updates? Any pointers?
[...] The idea behind incremental updates is this: if I write a string "ABCDEF" at position (10,10), then I write "ABDCEF" at the same position, the console library should know to only replace "CD" with "DC" the second time round, instead of redrawing the entire string. Or, on larger scale, if my app draws an almost-identical copy of the current screen, the library should know to only redraw the "diff" between the previous state of the screen and the new one. This is commonly implemented by buffering the current state of the screen in the library, and marking parts of the buffer "dirty" when they are changed. Then when there is a pause (say the app is waiting for input) or the screen needs to scroll, etc., the library updates only the parts of the screen that correspond with the "dirty" buffers, and clears the dirty flag. The basic motivation is that the terminal may be connected to a remote machine via a slow or congested network, so it's faster to keep track of things locally and only send "diffs" to the remote end. Waiting for a pause also allows you to group several updates into a single network packet, instead of sending one packet per character, which is very slow. (Even if the terminal is local, it can be faster to do things this way, because it minimizes writes to video RAM, which is slower than writing to main memory. Or in the case of X11 terminal emulators, it saves the cost of redrawing the same pixels over and over.) T -- People demand freedom of speech to make up for the freedom of thought which they avoid. -- Soren Aabye Kierkegaard (1813-1855)
Oct 26 2012
prev sibling parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 10/22/2012 03:47 AM, Jens Mueller wrote:
 Chad J wrote:
 There is no weakness to this.  The only shred of a counterargument I
 can think of is that it makes the format strings more difficult to
 learn. Other than that, it is possible to detect the destination of
 the formatter, so color codes will never end up in places where they
 shouldn't.  A conservative approach to this should handle most
 desires and never interfere with all the people with no interest in
 color.

 On the upshot are the things I've mentioned:
 - A format specifier is potentially more discoverable.
 - A format specifier is more concise.  This keeps your lines from
 wrapping.  They are probably too long already.
Do you consider this writecf(Color.red, "something %s", "here") concise as well?
The case is too easy. You're formatting an entire line.
 - To cement the previous point: nesting requires a few extra
 characters with a format specifier, rather than a couple extra
 /lines/ for extra function calls.
Don't understand this point. Can you give an example?
Option A: auto save = getConsoleState(); scope (exit) setConsoleState(save); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background."); Option B: writefln("%CFredBblu(Red text on blue background.%)");
 - Calls to stateful console functions allow people to write bugs
 like saving console state and then forgetting to restore it (or
 throwing an exception and neglecting to restore from within a scope
 guard).  Format specifiers do not have this problem.
The same holds for writecf(Color.red, "something %s", "here")
See my above example. In that case the formatter no longer requires even using the scope feature because there are no resources to clean up. The library handles that mess. Also statefulness is a pain to deal with. Stack-like operation with push/pop or bracketing constructs is usually much less troublesome for this sort of thing.
 - etc (I'm sure I'm forgetting one or two.)

 These are the reasons why my ideal language has color formatting
 built into its I/O routines.
Just wanted to point out that instead of that you can add writec* functions. I think the only thing is that these are less discoverable but they also work without formatting, e.g. writec(Color.red, "my text");
The thing I found very difficult with other color formatting APIs was formatting individual words or characters. Entire lines are easy-peasy stuff in any API. Solving the entire-lines case won't impress me. ;) Here's my more typical use case: writefln("The %CFred(widgetometer%) is a device for measuring"); writefln("widget effectiveness. It is possible to "); writefln("reconcile transcendental properties by hitting"); writefln("%CFblu(B%) for blue coefficients, %CFgrn(G%) for green"); writefln("coefficients, or %CFyel(Y%) for yellow coefficients."); writefln("Here is a correspondence table:"); writefln(" %CFnue( %) | %CFblu( B %) %CFgrn( G %) %CFyel( Y %) "); writefln(" %CFnue(-%)-+-%CFnue(---%)-%CFnue(---%)-%CFnue(---%)-"); writefln(" %CFblu(B%) | %CFblu(200%) %CFwht(330%) %CFwht(303%) "); writefln(" %CFgrn(G%) | %CFwht(110%) %CFgrn(020%) %CFwht(033%) "); writefln(" %CFyel(Y%) | %CFwht(101%) %CFwht(011%) %CFyel(002%) "); I realized that I wanted a "nue" color that has no effect but allows me to align things effectively ;) Anyhow, please try to write the above example using any other style. Interleaved function calls are particularly "fun" <g>
Oct 22 2012
parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Chad J wrote:
 On 10/22/2012 03:47 AM, Jens Mueller wrote:
Chad J wrote:
There is no weakness to this.  The only shred of a counterargument I
can think of is that it makes the format strings more difficult to
learn. Other than that, it is possible to detect the destination of
the formatter, so color codes will never end up in places where they
shouldn't.  A conservative approach to this should handle most
desires and never interfere with all the people with no interest in
color.

On the upshot are the things I've mentioned:
- A format specifier is potentially more discoverable.
- A format specifier is more concise.  This keeps your lines from
wrapping.  They are probably too long already.
Do you consider this writecf(Color.red, "something %s", "here") concise as well?
The case is too easy. You're formatting an entire line.
Am I? I think it's not a line. But I see your point. You mean something like writec(Color.red, "red") writec(Color.blue, "blue") writec(Color.green, "green") is too verbose. You want something like writef("%CFred(red%)%CFblue(blue%)%CFgreeng(reen%)"); Right?
- To cement the previous point: nesting requires a few extra
characters with a format specifier, rather than a couple extra
/lines/ for extra function calls.
Don't understand this point. Can you give an example?
Option A: auto save = getConsoleState(); scope (exit) setConsoleState(save); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background."); Option B: writefln("%CFredBblu(Red text on blue background.%)");
I see. Though I find the last line difficult to decipher (because there are no spaces).
- Calls to stateful console functions allow people to write bugs
like saving console state and then forgetting to restore it (or
throwing an exception and neglecting to restore from within a scope
guard).  Format specifiers do not have this problem.
The same holds for writecf(Color.red, "something %s", "here")
See my above example. In that case the formatter no longer requires even using the scope feature because there are no resources to clean up. The library handles that mess. Also statefulness is a pain to deal with. Stack-like operation with push/pop or bracketing constructs is usually much less troublesome for this sort of thing.
It'll be nice then if you can built something using format specifiers on top of a basic library.
- etc (I'm sure I'm forgetting one or two.)

These are the reasons why my ideal language has color formatting
built into its I/O routines.
Just wanted to point out that instead of that you can add writec* functions. I think the only thing is that these are less discoverable but they also work without formatting, e.g. writec(Color.red, "my text");
The thing I found very difficult with other color formatting APIs was formatting individual words or characters. Entire lines are easy-peasy stuff in any API. Solving the entire-lines case won't impress me. ;)
I see your point now. But we should keep it simple.
 Here's my more typical use case:
 
 writefln("The %CFred(widgetometer%) is a device for measuring");
 writefln("widget effectiveness.  It is possible to ");
 writefln("reconcile transcendental properties by hitting");
 writefln("%CFblu(B%) for blue coefficients, %CFgrn(G%) for green");
 writefln("coefficients, or %CFyel(Y%) for yellow coefficients.");
 writefln("Here is a correspondence table:");
 writefln("  %CFnue( %) | %CFblu( B %) %CFgrn( G %) %CFyel( Y %) ");
 writefln("  %CFnue(-%)-+-%CFnue(---%)-%CFnue(---%)-%CFnue(---%)-");
 writefln("  %CFblu(B%) | %CFblu(200%) %CFwht(330%) %CFwht(303%) ");
 writefln("  %CFgrn(G%) | %CFwht(110%) %CFgrn(020%) %CFwht(033%) ");
 writefln("  %CFyel(Y%) | %CFwht(101%) %CFwht(011%) %CFyel(002%) ");
 
 I realized that I wanted a "nue" color that has no effect but allows
 me to align things effectively ;)
 
 Anyhow, please try to write the above example using any other style.
 Interleaved function calls are particularly "fun" <g>
I'm convinced. But I find that it difficult to read. Though that's a problem I usually have with format strings. Can these format strings be made easier to read. I mean writefln("The %CF(red)(widgetometer) is a device for measuring"); or writefln("The %c(red,white)(widgetometer) is a device for measuring"); // for writing red on white is already easier to my eyes. I'd be happy to see it built on top. Jens
Oct 23 2012
parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 10/23/2012 03:51 AM, Jens Mueller wrote:
 Chad J wrote:
 On 10/22/2012 03:47 AM, Jens Mueller wrote:
 Chad J wrote:
 There is no weakness to this.  The only shred of a counterargument I
 can think of is that it makes the format strings more difficult to
 learn. Other than that, it is possible to detect the destination of
 the formatter, so color codes will never end up in places where they
 shouldn't.  A conservative approach to this should handle most
 desires and never interfere with all the people with no interest in
 color.

 On the upshot are the things I've mentioned:
 - A format specifier is potentially more discoverable.
 - A format specifier is more concise.  This keeps your lines from
 wrapping.  They are probably too long already.
Do you consider this writecf(Color.red, "something %s", "here") concise as well?
The case is too easy. You're formatting an entire line.
Am I? I think it's not a line. But I see your point. You mean something like writec(Color.red, "red") writec(Color.blue, "blue") writec(Color.green, "green") is too verbose. You want something like writef("%CFred(red%)%CFblue(blue%)%CFgreeng(reen%)"); Right?
 - To cement the previous point: nesting requires a few extra
 characters with a format specifier, rather than a couple extra
 /lines/ for extra function calls.
Don't understand this point. Can you give an example?
Option A: auto save = getConsoleState(); scope (exit) setConsoleState(save); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background."); Option B: writefln("%CFredBblu(Red text on blue background.%)");
I see. Though I find the last line difficult to decipher (because there are no spaces).
 - Calls to stateful console functions allow people to write bugs
 like saving console state and then forgetting to restore it (or
 throwing an exception and neglecting to restore from within a scope
 guard).  Format specifiers do not have this problem.
The same holds for writecf(Color.red, "something %s", "here")
See my above example. In that case the formatter no longer requires even using the scope feature because there are no resources to clean up. The library handles that mess. Also statefulness is a pain to deal with. Stack-like operation with push/pop or bracketing constructs is usually much less troublesome for this sort of thing.
It'll be nice then if you can built something using format specifiers on top of a basic library.
 - etc (I'm sure I'm forgetting one or two.)

 These are the reasons why my ideal language has color formatting
 built into its I/O routines.
Just wanted to point out that instead of that you can add writec* functions. I think the only thing is that these are less discoverable but they also work without formatting, e.g. writec(Color.red, "my text");
The thing I found very difficult with other color formatting APIs was formatting individual words or characters. Entire lines are easy-peasy stuff in any API. Solving the entire-lines case won't impress me. ;)
I see your point now. But we should keep it simple.
 Here's my more typical use case:

 writefln("The %CFred(widgetometer%) is a device for measuring");
 writefln("widget effectiveness.  It is possible to ");
 writefln("reconcile transcendental properties by hitting");
 writefln("%CFblu(B%) for blue coefficients, %CFgrn(G%) for green");
 writefln("coefficients, or %CFyel(Y%) for yellow coefficients.");
 writefln("Here is a correspondence table:");
 writefln("  %CFnue( %) | %CFblu( B %) %CFgrn( G %) %CFyel( Y %) ");
 writefln("  %CFnue(-%)-+-%CFnue(---%)-%CFnue(---%)-%CFnue(---%)-");
 writefln("  %CFblu(B%) | %CFblu(200%) %CFwht(330%) %CFwht(303%) ");
 writefln("  %CFgrn(G%) | %CFwht(110%) %CFgrn(020%) %CFwht(033%) ");
 writefln("  %CFyel(Y%) | %CFwht(101%) %CFwht(011%) %CFyel(002%) ");

 I realized that I wanted a "nue" color that has no effect but allows
 me to align things effectively ;)

 Anyhow, please try to write the above example using any other style.
 Interleaved function calls are particularly "fun"<g>
I'm convinced. But I find that it difficult to read. Though that's a problem I usually have with format strings. Can these format strings be made easier to read. I mean writefln("The %CF(red)(widgetometer) is a device for measuring"); or writefln("The %c(red,white)(widgetometer) is a device for measuring"); // for writing red on white is already easier to my eyes. I'd be happy to see it built on top. Jens
That's a reasonable suggestion. The only thing that can't be solved is the trailing ) enclosing the text to be formatted. That needs a % before it to prevent ambiguity with parentheses in the text itself. So I could make your example:
 writefln("The %c(red,white)(widgetometer%) is a device 
formeasuring"); // for writing red on white I was also considering the possibility of separating layout and style by allowing some kind of style specification before the printing, with a limited formatting spec for using the styles: stdout.addTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline"); writefln("The %c(myStyle)(widgetometer%) is a device for measuring");
Oct 23 2012
next sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
 writefln("The %c(red,white)(widgetometer%) is a device formeasuring"); //
 for writing red on white
Would something like the following be possible? // col is a string-accepting function that returns a correctly formatted string // red and white are from a general Color enum alias col!(Color.red, Color.white) rw; writeln("The ", rw("widgetometer"), " is a device for measuring...");
Oct 23 2012
parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 10/23/2012 03:56 PM, Philippe Sigaud wrote:
 writefln("The %c(red,white)(widgetometer%) is a device formeasuring"); //
 for writing red on white
Would something like the following be possible? // col is a string-accepting function that returns a correctly formatted string // red and white are from a general Color enum alias col!(Color.red, Color.white) rw; writeln("The ", rw("widgetometer"), " is a device for measuring...");
Nope. Windows requires function calls to do color formatting. It does not use escape sequences. That said, it is always possible to scan all text about to be sent off to Windows and look for escape sequences, then reinterpret them as WinAPI coloring calls. The difficulty then is getting the "rw" construct above to know if it should emit escape sequences or not: the text it creates might eventually be bound for a file, a network socket, or some buffer in memory, but not a terminal. If it's heading for a terminal it has to know which one because they might use different escape sequences. So there always has to be some way of contextualizing the color formatting to its destination so that it can select the right form of output, including no formatting if its inappropriate for the destination. Also, it doesn't nest. It should be possible to push/pop terminal attributes in mid-string.
Oct 23 2012
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Chad J wrote:
 On 10/23/2012 03:51 AM, Jens Mueller wrote:
Chad J wrote:
On 10/22/2012 03:47 AM, Jens Mueller wrote:
Chad J wrote:
There is no weakness to this.  The only shred of a counterargument I
can think of is that it makes the format strings more difficult to
learn. Other than that, it is possible to detect the destination of
the formatter, so color codes will never end up in places where they
shouldn't.  A conservative approach to this should handle most
desires and never interfere with all the people with no interest in
color.

On the upshot are the things I've mentioned:
- A format specifier is potentially more discoverable.
- A format specifier is more concise.  This keeps your lines from
wrapping.  They are probably too long already.
Do you consider this writecf(Color.red, "something %s", "here") concise as well?
The case is too easy. You're formatting an entire line.
Am I? I think it's not a line. But I see your point. You mean something like writec(Color.red, "red") writec(Color.blue, "blue") writec(Color.green, "green") is too verbose. You want something like writef("%CFred(red%)%CFblue(blue%)%CFgreeng(reen%)"); Right?
- To cement the previous point: nesting requires a few extra
characters with a format specifier, rather than a couple extra
/lines/ for extra function calls.
Don't understand this point. Can you give an example?
Option A: auto save = getConsoleState(); scope (exit) setConsoleState(save); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background."); Option B: writefln("%CFredBblu(Red text on blue background.%)");
I see. Though I find the last line difficult to decipher (because there are no spaces).
- Calls to stateful console functions allow people to write bugs
like saving console state and then forgetting to restore it (or
throwing an exception and neglecting to restore from within a scope
guard).  Format specifiers do not have this problem.
The same holds for writecf(Color.red, "something %s", "here")
See my above example. In that case the formatter no longer requires even using the scope feature because there are no resources to clean up. The library handles that mess. Also statefulness is a pain to deal with. Stack-like operation with push/pop or bracketing constructs is usually much less troublesome for this sort of thing.
It'll be nice then if you can built something using format specifiers on top of a basic library.
- etc (I'm sure I'm forgetting one or two.)

These are the reasons why my ideal language has color formatting
built into its I/O routines.
Just wanted to point out that instead of that you can add writec* functions. I think the only thing is that these are less discoverable but they also work without formatting, e.g. writec(Color.red, "my text");
The thing I found very difficult with other color formatting APIs was formatting individual words or characters. Entire lines are easy-peasy stuff in any API. Solving the entire-lines case won't impress me. ;)
I see your point now. But we should keep it simple.
Here's my more typical use case:

writefln("The %CFred(widgetometer%) is a device for measuring");
writefln("widget effectiveness.  It is possible to ");
writefln("reconcile transcendental properties by hitting");
writefln("%CFblu(B%) for blue coefficients, %CFgrn(G%) for green");
writefln("coefficients, or %CFyel(Y%) for yellow coefficients.");
writefln("Here is a correspondence table:");
writefln("  %CFnue( %) | %CFblu( B %) %CFgrn( G %) %CFyel( Y %) ");
writefln("  %CFnue(-%)-+-%CFnue(---%)-%CFnue(---%)-%CFnue(---%)-");
writefln("  %CFblu(B%) | %CFblu(200%) %CFwht(330%) %CFwht(303%) ");
writefln("  %CFgrn(G%) | %CFwht(110%) %CFgrn(020%) %CFwht(033%) ");
writefln("  %CFyel(Y%) | %CFwht(101%) %CFwht(011%) %CFyel(002%) ");

I realized that I wanted a "nue" color that has no effect but allows
me to align things effectively ;)

Anyhow, please try to write the above example using any other style.
Interleaved function calls are particularly "fun"<g>
I'm convinced. But I find that it difficult to read. Though that's a problem I usually have with format strings. Can these format strings be made easier to read. I mean writefln("The %CF(red)(widgetometer) is a device for measuring"); or writefln("The %c(red,white)(widgetometer) is a device for measuring"); // for writing red on white is already easier to my eyes. I'd be happy to see it built on top. Jens
That's a reasonable suggestion. The only thing that can't be solved is the trailing ) enclosing the text to be formatted. That needs a % before it to prevent ambiguity with parentheses in the text itself. So I could make your example:
 writefln("The %c(red,white)(widgetometer%) is a device
formeasuring"); // for writing red on white I was also considering the possibility of separating layout and style by allowing some kind of style specification before the printing, with a limited formatting spec for using the styles: stdout.addTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline"); writefln("The %c(myStyle)(widgetometer%) is a device for measuring");
Ideally, we get some users and ask them what they find easy to read. Or look how other languages solve this. Because I myself don't color my terminals that much I find it hard to imagine. I searched for some ruby libraries. I find ruby syntax often very easy. We could use UFCS, e.g. "some string".red or "some string".foreground(Color.red) What do you think? I find this way easier than format strings. Jens
Oct 23 2012
prev sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Jens Mueller wrote:
 Chad J wrote:
 On 10/23/2012 03:51 AM, Jens Mueller wrote:
Chad J wrote:
On 10/22/2012 03:47 AM, Jens Mueller wrote:
Chad J wrote:
There is no weakness to this.  The only shred of a counterargument I
can think of is that it makes the format strings more difficult to
learn. Other than that, it is possible to detect the destination of
the formatter, so color codes will never end up in places where they
shouldn't.  A conservative approach to this should handle most
desires and never interfere with all the people with no interest in
color.

On the upshot are the things I've mentioned:
- A format specifier is potentially more discoverable.
- A format specifier is more concise.  This keeps your lines from
wrapping.  They are probably too long already.
Do you consider this writecf(Color.red, "something %s", "here") concise as well?
The case is too easy. You're formatting an entire line.
Am I? I think it's not a line. But I see your point. You mean something like writec(Color.red, "red") writec(Color.blue, "blue") writec(Color.green, "green") is too verbose. You want something like writef("%CFred(red%)%CFblue(blue%)%CFgreeng(reen%)"); Right?
- To cement the previous point: nesting requires a few extra
characters with a format specifier, rather than a couple extra
/lines/ for extra function calls.
Don't understand this point. Can you give an example?
Option A: auto save = getConsoleState(); scope (exit) setConsoleState(save); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background."); Option B: writefln("%CFredBblu(Red text on blue background.%)");
I see. Though I find the last line difficult to decipher (because there are no spaces).
- Calls to stateful console functions allow people to write bugs
like saving console state and then forgetting to restore it (or
throwing an exception and neglecting to restore from within a scope
guard).  Format specifiers do not have this problem.
The same holds for writecf(Color.red, "something %s", "here")
See my above example. In that case the formatter no longer requires even using the scope feature because there are no resources to clean up. The library handles that mess. Also statefulness is a pain to deal with. Stack-like operation with push/pop or bracketing constructs is usually much less troublesome for this sort of thing.
It'll be nice then if you can built something using format specifiers on top of a basic library.
- etc (I'm sure I'm forgetting one or two.)

These are the reasons why my ideal language has color formatting
built into its I/O routines.
Just wanted to point out that instead of that you can add writec* functions. I think the only thing is that these are less discoverable but they also work without formatting, e.g. writec(Color.red, "my text");
The thing I found very difficult with other color formatting APIs was formatting individual words or characters. Entire lines are easy-peasy stuff in any API. Solving the entire-lines case won't impress me. ;)
I see your point now. But we should keep it simple.
Here's my more typical use case:

writefln("The %CFred(widgetometer%) is a device for measuring");
writefln("widget effectiveness.  It is possible to ");
writefln("reconcile transcendental properties by hitting");
writefln("%CFblu(B%) for blue coefficients, %CFgrn(G%) for green");
writefln("coefficients, or %CFyel(Y%) for yellow coefficients.");
writefln("Here is a correspondence table:");
writefln("  %CFnue( %) | %CFblu( B %) %CFgrn( G %) %CFyel( Y %) ");
writefln("  %CFnue(-%)-+-%CFnue(---%)-%CFnue(---%)-%CFnue(---%)-");
writefln("  %CFblu(B%) | %CFblu(200%) %CFwht(330%) %CFwht(303%) ");
writefln("  %CFgrn(G%) | %CFwht(110%) %CFgrn(020%) %CFwht(033%) ");
writefln("  %CFyel(Y%) | %CFwht(101%) %CFwht(011%) %CFyel(002%) ");

I realized that I wanted a "nue" color that has no effect but allows
me to align things effectively ;)

Anyhow, please try to write the above example using any other style.
Interleaved function calls are particularly "fun"<g>
I'm convinced. But I find that it difficult to read. Though that's a problem I usually have with format strings. Can these format strings be made easier to read. I mean writefln("The %CF(red)(widgetometer) is a device for measuring"); or writefln("The %c(red,white)(widgetometer) is a device for measuring"); // for writing red on white is already easier to my eyes. I'd be happy to see it built on top. Jens
That's a reasonable suggestion. The only thing that can't be solved is the trailing ) enclosing the text to be formatted. That needs a % before it to prevent ambiguity with parentheses in the text itself. So I could make your example:
 writefln("The %c(red,white)(widgetometer%) is a device
formeasuring"); // for writing red on white I was also considering the possibility of separating layout and style by allowing some kind of style specification before the printing, with a limited formatting spec for using the styles: stdout.addTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline"); writefln("The %c(myStyle)(widgetometer%) is a device for measuring");
Ideally, we get some users and ask them what they find easy to read. Or look how other languages solve this. Because I myself don't color my terminals that much I find it hard to imagine. I searched for some ruby libraries. I find ruby syntax often very easy. We could use UFCS, e.g. "some string".red or "some string".foreground(Color.red) What do you think? I find this way easier than format strings.
Just read the other post. This has the same problem. Jens
Oct 23 2012
parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 10/23/2012 04:42 PM, Jens Mueller wrote:
 Jens Mueller wrote:
 Chad J wrote:
 That's a reasonable suggestion.  The only thing that can't be solved
 is the trailing ) enclosing the text to be formatted.  That needs a
 % before it to prevent ambiguity with parentheses in the text
 itself.  So I could make your example:

 writefln("The %c(red,white)(widgetometer%) is a device
formeasuring"); // for writing red on white I was also considering the possibility of separating layout and style by allowing some kind of style specification before the printing, with a limited formatting spec for using the styles: stdout.addTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline"); writefln("The %c(myStyle)(widgetometer%) is a device for measuring");
Ideally, we get some users and ask them what they find easy to read. Or look how other languages solve this. Because I myself don't color my terminals that much I find it hard to imagine. I searched for some ruby libraries. I find ruby syntax often very easy. We could use UFCS, e.g. "some string".red or "some string".foreground(Color.red) What do you think? I find this way easier than format strings.
Just read the other post. This has the same problem. Jens
Also I'm intentionally shooting for something very concise. If verbosity conflicts, then it loses. I say verbosity because I find that things get /less/ readable in situations like these if the syntax/naming is lengthy. It causes alignment issues, text wrapping, noise, etc. The thing I liked about the styling notion is that it allows things to be spelled out more, but places this noise outside of the string being formatted. More thoughts: // Do style parsing at compile-time if desired. const myStyle = parseTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline" // At runtime, stdout is told to use this. stdout.addTermTextStyle(myStyle); // I'm thinking it might look better by dropping a pair of parens, // but using a . to make it clear where the formatter type ends // and the style id begins. writefln("The %C.myStyle(widgetometer%) is a device for measuring"); // Overloaded for convenience. stdout.addTermTextStyle("id=rw, fg=red, bg=white, dark, underline"); // The user can choose how verbose they want their formatter to look. // This is a very concise one. writefln("The %C.rw(widgetometer%) is a device for measuring"); // Other note: %C is necessary. %c can't be used because that is // already used for formatting single characters.
Oct 23 2012
parent Jens Mueller <jens.k.mueller gmx.de> writes:
Chad J wrote:
 On 10/23/2012 04:42 PM, Jens Mueller wrote:
Jens Mueller wrote:
Chad J wrote:
That's a reasonable suggestion.  The only thing that can't be solved
is the trailing ) enclosing the text to be formatted.  That needs a
% before it to prevent ambiguity with parentheses in the text
itself.  So I could make your example:

writefln("The %c(red,white)(widgetometer%) is a device
formeasuring"); // for writing red on white I was also considering the possibility of separating layout and style by allowing some kind of style specification before the printing, with a limited formatting spec for using the styles: stdout.addTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline"); writefln("The %c(myStyle)(widgetometer%) is a device for measuring");
Ideally, we get some users and ask them what they find easy to read. Or look how other languages solve this. Because I myself don't color my terminals that much I find it hard to imagine. I searched for some ruby libraries. I find ruby syntax often very easy. We could use UFCS, e.g. "some string".red or "some string".foreground(Color.red) What do you think? I find this way easier than format strings.
Just read the other post. This has the same problem. Jens
Also I'm intentionally shooting for something very concise. If verbosity conflicts, then it loses. I say verbosity because I find that things get /less/ readable in situations like these if the syntax/naming is lengthy. It causes alignment issues, text wrapping, noise, etc. The thing I liked about the styling notion is that it allows things to be spelled out more, but places this noise outside of the string being formatted. More thoughts: // Do style parsing at compile-time if desired. const myStyle = parseTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline" // At runtime, stdout is told to use this. stdout.addTermTextStyle(myStyle); // I'm thinking it might look better by dropping a pair of parens, // but using a . to make it clear where the formatter type ends // and the style id begins. writefln("The %C.myStyle(widgetometer%) is a device for measuring"); // Overloaded for convenience. stdout.addTermTextStyle("id=rw, fg=red, bg=white, dark, underline"); // The user can choose how verbose they want their formatter to look. // This is a very concise one. writefln("The %C.rw(widgetometer%) is a device for measuring"); // Other note: %C is necessary. %c can't be used because that is // already used for formatting single characters.
I think is too complicated. It needs to be a one liner. Here is an idea: struct Proxy { this(string s) { _s = s; } this(this) { _s = _s.idup; } string toString() { _oldColor = stdout.foregroundColor(Color.red); return _s; } ~this() { stdout.foregroundColor(_oldColor); } Color _oldColor; string _s; } property Proxy red(string s) { return Proxy(s); } unittest { writeln("string".red); } It works in this case. Not sure about the implications of such an implementation. Jens
Oct 23 2012
prev sibling parent 1100110 <0b1100110 gmail.com> writes:
On Sun, 21 Oct 2012 17:32:41 -0500, Chad J  
<chadjoan __spam.is.bad__gmail.com.is.bad__gmail.com.com> wrote:

 On 10/21/2012 06:11 PM, Jens Mueller wrote:
 Chad J wrote:
 On 10/21/2012 05:01 PM, Jens Mueller wrote:

 It seems to have a hard ncurses/termcap/etc dependency.
Yes. I think you cannot make it portable without. Please proof me wrong and I'll fix this.
Well, traditionally it's done with automake/autoconf. You'd end up with preprocessor defines that tell you whether the lib has been statically linked or not. This isn't available here because Phobos doesn't use these as a build system and I hope it never does.
 I'll admit when I started trying to work on doing this thing, I
 never got anything onto the screen.  What stopped me was that I
 couldn't figure out how to detect ncurses/termcap/etc.  I was going
 to shoot for Phobos inclusion and making Phobos always link with
 ncurses seems like a bad idea.
Dependence on Phobos is bad. If you can detect whether a terminal is ANSI compatible then this mode should be default. But I don't know how to detect this.
Wrong direction on the dependency. I wouldn't expect Terminal coloring/detection to rely on Phobos. I'd expect it to be one of the lower-level modules built into Phobos.
 Ultimately I expect it to work with writeln or writefln to make it
 discoverable and easy to work with.
One could try this. At least for Linux. You just have to add the appropriate escape sequences. But this won't work on Windows.
I remember having a plan for this. See below.
 Back then I did design a format spec for introducing colors into
 format strings:
 www.chadjoan.com/d/dmd.2.058/html/d/phobos/std_format.html
I doubt that the Phobos maintainers will accept this. This is very invasive.
Hmmm, depends what is meant by invasive. I feel it's the only way to have discoverable and concise syntax. I'd be pretty disappointed if they didn't, regardless of who submits the pull request. I remember it being possible in Phobos to determine the destination of the format operation. If the destination is a string in memory, then no color formatting would be applied. If the destination is a Linux terminal of some kind, then some ncurses terminal info would be looked up (possible a cached lookup) and escape sequences generated based on that. If the destination is a Windows terminal, then these approaches can be considered: (1) Split the formatted text up on the color format boundaries. Send the slices into the stream one by one, calling the necessary WinAPI color formatting functions inbetween. I think this might not have been possible with Phobos' architecture. (2) Insert ANSI escape sequences into the text. The I/O code for Windows would then have to intercept these and convert them into the appropriate WinAPI calls. I think this was possible, and even distinguishable from the case of writing to a string in memory. If the invasiveness worry comes from the possibility of dumping escape sequences into non-terminal destinations, then I hope the above wall of text can alleviate that concern.
 I added writecf, writec, etc. with additional arguments.
 writec(Color.red, "some text")
 or
 writecf(Color.red, "%s", "some text")
 This is fine I think. But better options may be worth investigating.

 Jens
I really think this should be in Phobos. If it doesn't go into Phobos, then people will write crappy terminal apps with no color. If it does go into Phobos, then the better devs will see the opportunity and use it. Something 3rd party is much less discoverable and won't have nearly as much impact. The use case is almost all CLI apps, so it's not like an uncommon corner-case or something. I run a Gentoo system where things are configured to use color output wherever possible. The portage devs went through all of the necessary contortions to get Python to output colored text, somehow. I feel the end result is indispensable. Color is an extremely useful tool for making sure that the user doesn't overlook important bits while scanning text. Outside of Gentoo, I find this most notable in grep: uncolored grep output is just awful, but the coloring makes it possible to easily identify why the regular expression behaved the way it did. I look forward to a better CLI ecosystem where highly reliable D programs are written quickly and write beautiful colored output ;)
Actually, IIRC, You can version it to link with ncurses or pdcurses if available. The interface to pdcurses and ncurses is the same, or simply similar enough that it works. I agree color is an important bit to not forget. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 21 2012
prev sibling next sibling parent reply "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Sunday, 21 October 2012 at 19:28:21 UTC, Robik wrote:
 I would like to introduce ColorD, small library that allows to 
 simply manipulate console output colors, both on Windows and 
 Posix operating systems. It also supports font styles such as 
 underline and strikethrough(Posix feature only).
Does this rely on nCurses? (or similar)
Oct 21 2012
next sibling parent "Robik" <szadows gmail.com> writes:
On Sunday, 21 October 2012 at 21:25:14 UTC, Era Scarecrow wrote:
 On Sunday, 21 October 2012 at 19:28:21 UTC, Robik wrote:
 I would like to introduce ColorD, small library that allows to 
 simply manipulate console output colors, both on Windows and 
 Posix operating systems. It also supports font styles such as 
 underline and strikethrough(Posix feature only).
Does this rely on nCurses? (or similar)
No, everything is written from scratch. On Windows side it used WinAPI functions, on Posix, ANSI codes.
Oct 21 2012
prev sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Era Scarecrow wrote:
 On Sunday, 21 October 2012 at 19:28:21 UTC, Robik wrote:
I would like to introduce ColorD, small library that allows to
simply manipulate console output colors, both on Windows and Posix
operating systems. It also supports font styles such as underline
and strikethrough(Posix feature only).
Does this rely on nCurses? (or similar)
It doesn't. It sends ANSI escape codes on Posix. Jens
Oct 21 2012
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 10/21/2012 12:28 PM, Robik wrote:
 Simple example:

 import std.stdio, colord;
 void main()
 {
      setConsoleColors(Fg.red, Bg.blue);
      writeln("Red text on blue background.");
      resetConsoleColors(); // Bring back initial state
 }
Need a method to get the current state, and reset the current state. Otherwise, nested calls to the console functions will screw up the state. I.e.: auto save = getConsoleState(); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background."); setConsoleState(save); // Bring back initial state Or better: auto save = getConsoleState(); scope (exit) setConsoleState(save); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background.");
Oct 21 2012
next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Walter Bright wrote:
 On 10/21/2012 12:28 PM, Robik wrote:
 Simple example:

 import std.stdio, colord;
 void main()
 {
      setConsoleColors(Fg.red, Bg.blue);
      writeln("Red text on blue background.");
      resetConsoleColors(); // Bring back initial state
 }
Need a method to get the current state, and reset the current state. Otherwise, nested calls to the console functions will screw up the state. I.e.: auto save = getConsoleState(); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background."); setConsoleState(save); // Bring back initial state Or better: auto save = getConsoleState(); scope (exit) setConsoleState(save); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background.");
Very true. Problem is that on Linux (probably most Unix* systems) you cannot get the current color. Only the default one. I added wrappers like above. https://github.com/jkm/terminal/blob/master/src/terminal.d#L187 Jens
Oct 21 2012
prev sibling parent reply "Robik" <szadows gmail.com> writes:
On Sunday, 21 October 2012 at 22:32:35 UTC, Walter Bright wrote:
 On 10/21/2012 12:28 PM, Robik wrote:
 Simple example:

 import std.stdio, colord;
 void main()
 {
      setConsoleColors(Fg.red, Bg.blue);
      writeln("Red text on blue background.");
      resetConsoleColors(); // Bring back initial state
 }
Need a method to get the current state, and reset the current state. Otherwise, nested calls to the console functions will screw up the state. I.e.: auto save = getConsoleState(); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background."); setConsoleState(save); // Bring back initial state Or better: auto save = getConsoleState(); scope (exit) setConsoleState(save); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background.");
On Windows, setting color to initial sets console colors to ones that were set before launch of the program. On Posix it sets default (ANSI remove formatting). I will try to check if it is possible to get current colors on Posix.
Oct 22 2012
parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Robik wrote:
 On Sunday, 21 October 2012 at 22:32:35 UTC, Walter Bright wrote:
On 10/21/2012 12:28 PM, Robik wrote:
 Simple example:

 import std.stdio, colord;
 void main()
 {
      setConsoleColors(Fg.red, Bg.blue);
      writeln("Red text on blue background.");
      resetConsoleColors(); // Bring back initial state
 }
Need a method to get the current state, and reset the current state. Otherwise, nested calls to the console functions will screw up the state. I.e.: auto save = getConsoleState(); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background."); setConsoleState(save); // Bring back initial state Or better: auto save = getConsoleState(); scope (exit) setConsoleState(save); setConsoleColors(Fg.red, Bg.blue); writeln("Red text on blue background.");
On Windows, setting color to initial sets console colors to ones that were set before launch of the program. On Posix it sets default (ANSI remove formatting). I will try to check if it is possible to get current colors on Posix.
Please look for this. But my research concluded that there is no such way on Posix. Jens
Oct 22 2012
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Monday, 22 October 2012 at 12:30:38 UTC, Jens Mueller wrote:
 But my research concluded that there is no such way on Posix.
Yeah, if there was a way to get current colors, you wouldn't have to set environment variables for programs like vi to know if the background is light or dark. It's a pity the unix designers didn't change the definition slightly of the text palette way back when so you didn't have to know anyway...
Oct 22 2012
prev sibling next sibling parent reply "Dejan Lekic" <dejan.lekic gmail.com> writes:
On Sunday, 21 October 2012 at 19:28:21 UTC, Robik wrote:
 Hello,

 I would like to introduce ColorD, small library that allows to 
 simply manipulate console output colors, both on Windows and 
 Posix operating systems. It also supports font styles such as 
 underline and strikethrough(Posix feature only).


 Simple example:

 import std.stdio, colord;
 void main()
 {
     setConsoleColors(Fg.red, Bg.blue);
     writeln("Red text on blue background.");
     resetConsoleColors(); // Bring back initial state
 }


 Feedback welcome.

 GitHub: https://github.com/robik/ColorD

 Regards.
This is very much related to the ycurses and dcurses projects, and I strongly suggest you work with people behind those projects and come up with a nice/flexible/robust "console" API/package for D.
Oct 22 2012
parent 1100110 <0b1100110 gmail.com> writes:
On Mon, 22 Oct 2012 06:04:51 -0500, Dejan Lekic <dejan.lekic gmail.com>  
wrote:

 On Sunday, 21 October 2012 at 19:28:21 UTC, Robik wrote:
 Hello,

 I would like to introduce ColorD, small library that allows to simply  
 manipulate console output colors, both on Windows and Posix operating  
 systems. It also supports font styles such as underline and  
 strikethrough(Posix feature only).


 Simple example:

 import std.stdio, colord;
 void main()
 {
     setConsoleColors(Fg.red, Bg.blue);
     writeln("Red text on blue background.");
     resetConsoleColors(); // Bring back initial state
 }


 Feedback welcome.

 GitHub: https://github.com/robik/ColorD

 Regards.
This is very much related to the ycurses and dcurses projects, and I strongly suggest you work with people behind those projects and come up with a nice/flexible/robust "console" API/package for D.
I had some trouble getting in touch with ylixir last time, and pardon me if I'm wrong, but *you* are the 'people behind' dcurses. =P I would be willing to chip in for something like this though. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 22 2012
prev sibling parent "nazriel" <spam dzfl.pl> writes:
On Sunday, 21 October 2012 at 19:28:21 UTC, Robik wrote:
 Hello,

 I would like to introduce ColorD, small library that allows to 
 simply manipulate console output colors, both on Windows and 
 Posix operating systems. It also supports font styles such as 
 underline and strikethrough(Posix feature only).


 Simple example:

 import std.stdio, colord;
 void main()
 {
     setConsoleColors(Fg.red, Bg.blue);
     writeln("Red text on blue background.");
     resetConsoleColors(); // Bring back initial state
 }


 Feedback welcome.

 GitHub: https://github.com/robik/ColorD

 Regards.
(Yes, I've seen ConsoleD, but quoting first post in topic is easier) WoW looks cool! I've been using own solution (probably like 50% of hackers around D) but this looks really promising. Would be cool to see this as addition to standard library. I noticed you joined forces with Adam Ruppe. For sure ConsoleD will rock I wish you guys good luck :) Keep going.
Oct 28 2012