digitalmars.D - [RFC] ColorD
- Robik (16/16) Oct 21 2012 Hello,
- Peter Sommerfeld (9/13) Oct 21 2012 On windows I got an error:
- Robik (3/16) Oct 21 2012 What version are you using?
- Peter Sommerfeld (3/23) Oct 21 2012 dmd 2.060. -O -release -inline -property -w -wi
- bearophile (6/7) Oct 21 2012 Maybe it'ìs better to call it ConsoleColorsD, or something.
- Robik (2/9) Oct 21 2012 Moved to https://github.com/robik/ConsoleD
- F i L (7/12) Oct 21 2012 It might be nice to have a solution which works better with
- renoX (9/10) Oct 22 2012 imply that if you forget to put Colors.Reset at the end of
- Jens Mueller (17/39) Oct 21 2012 Interesting looks solid to me.
- Robik (6/27) Oct 21 2012 I will fix this.
- Jens Mueller (7/41) Oct 21 2012 Probably not worth the trouble. But it should be documented.
- Chad J (13/52) Oct 21 2012 Hey that looks cool.
- Jens Mueller (16/74) Oct 21 2012 Yes. I think you cannot make it portable without. Please proof me wrong
- Chad J (47/76) Oct 21 2012 Well, traditionally it's done with automake/autoconf. You'd end up with...
- Chad J (8/8) Oct 21 2012 Additionally note that the format syntax handles Walter's concerns here:
- Jens Mueller (23/119) Oct 21 2012 I mean to detect if your terminal is ANSI compatible without adding
- Chad J (39/158) Oct 21 2012 I completely agree.
- Jens Mueller (26/167) Oct 22 2012 For that purpose in particular I have written ddl.
- Andrei Alexandrescu (5/8) Oct 22 2012 Off the top of my head something that is specific for only certain
- Jens Mueller (5/14) Oct 22 2012 It also works on Windows. Even already implemented. The situation is
- Andrei Alexandrescu (3/17) Oct 22 2012 Cool. Do all systems implement color as escape sequences?
- Jens Mueller (4/23) Oct 22 2012 No. On Windows you have to explicitly call a function.
- Kagamin (4/5) Oct 22 2012 It's still more of a linux tradition. Implementing it as a
- Walter Bright (15/21) Oct 23 2012 A module that only sets the console color is a little too light to be a ...
- Tim (4/18) Oct 23 2012 Just so it's known, I support such a module being created. I
- H. S. Teoh (25/41) Oct 23 2012 IOW, a replacement for libncurses. :)
- Adam D. Ruppe (10/13) Oct 23 2012 Does anybody really care about everything? Unix has de-facto
- H. S. Teoh (28/43) Oct 23 2012 Perhaps the right approach then is to make the code modular, so that
- Robik (4/30) Oct 24 2012 Thanks for your suggestions. I will try to do what I can, but I
- Jens Mueller (13/36) Oct 25 2012 This is easy if you just mean the number of lines and columns.
- Adam D. Ruppe (23/33) Oct 25 2012 Here's how you do it on xterm:
- H. S. Teoh (16/35) Oct 25 2012 And just to add, on Posix it's probably good to do something similar to
- Adam D. Ruppe (10/14) Oct 26 2012 Yeah. Vim does it though, if it can connect to a display, it does
- Robik (2/8) Oct 25 2012 Yeah, the problem is it does not work in all terminals.
- Adam D. Ruppe (3/4) Oct 26 2012 Yeah, but neither will any other feature. But virtually every one
- H. S. Teoh (7/18) Oct 26 2012 The correct solution is to examine the TERM environment variable to find
- Jens Mueller (6/22) Oct 26 2012 Or use a library that does this? There is terminfo. Don't know whether
- H. S. Teoh (13/29) Oct 26 2012 [...]
- Adam D. Ruppe (1/1) Oct 26 2012 I'm slapping together a minimal termcap reader for D now.
- Adam D. Ruppe (66/66) Oct 26 2012 Here we go, some more basic functions:
- Jens Mueller (8/104) Oct 28 2012 I like that you code won't need additional libraries. But how do you
- Jens Mueller (4/56) Oct 26 2012 I see.
- Walter Bright (4/5) Oct 29 2012 Much of this is implemented in one way or another as part of the source ...
- H. S. Teoh (58/91) Oct 25 2012 You can only do this in terminals that support it. XTerm, I believe, has
- Jens Mueller (18/103) Oct 26 2012 So there exists no portable library abstracting mouse input?
- Tobias Pankrath (7/33) Oct 26 2012 This would look like a full blown TUI-Toolkit and we should model
- H. S. Teoh (23/42) Oct 26 2012 If we implement an event loop, I think it should be optional. Many apps
- Adam D. Ruppe (19/20) Oct 26 2012 I think this is another benefit of capturing the input with a
- Adam D. Ruppe (34/36) Oct 27 2012 I've implemented the basic events for linux now:
- Adam D. Ruppe (15/15) Oct 27 2012 It now can translate most PC keyboard input sequences into char
- H. S. Teoh (11/27) Oct 27 2012 This is too cool! You should polish it up and submit a Phobos entry for
- Jens Mueller (4/24) Oct 28 2012 It is. But it is going in the right direction.
- Adam D. Ruppe (16/17) Oct 28 2012 The file /etc/termcap has the data too so opening it and quickly
- Jens Mueller (3/23) Oct 28 2012 Jens
- Adam D. Ruppe (7/8) Oct 28 2012 They must just depend on terminfo. That's more complicated to
- H. S. Teoh (5/14) Oct 28 2012 T
- Adam D. Ruppe (5/6) Oct 28 2012 Sometimes linking in external libraries in Phobos can be a
- Adam D. Ruppe (10/10) Oct 28 2012 Robik let me add my code to his repository with the plan to merge
- Jens Mueller (4/43) Oct 28 2012 If you can add an event loop on top that would be great. What do I need
- Tobias Pankrath (7/11) Oct 28 2012 I don't think that this needs any special consideration. If you
- H. S. Teoh (64/118) Oct 26 2012 Hmm. I googled around a bit, and found that the only portable libraries
- Chad J (34/68) Oct 22 2012 Option A:
- Jens Mueller (24/112) Oct 23 2012 Am I? I think it's not a line. But I see your point.
- Chad J (11/124) Oct 23 2012 That's a reasonable suggestion. The only thing that can't be solved is
- Philippe Sigaud (5/7) Oct 23 2012 Would something like the following be possible?
- Chad J (16/23) Oct 23 2012 Nope. Windows requires function calls to do color formatting. It does
- Jens Mueller (13/154) Oct 23 2012 Ideally, we get some users and ask them what they find easy to read. Or
- Jens Mueller (3/158) Oct 23 2012 Just read the other post. This has the same problem.
- Chad J (25/58) Oct 23 2012 Also I'm intentionally shooting for something very concise. If
- Jens Mueller (38/108) Oct 23 2012 I think is too complicated.
- 1100110 (9/93) Oct 21 2012 Actually, IIRC, You can version it to link with ncurses or pdcurses if
- Era Scarecrow (2/6) Oct 21 2012 Does this rely on nCurses? (or similar)
- Robik (3/9) Oct 21 2012 No, everything is written from scratch. On Windows side it used
- Jens Mueller (3/10) Oct 21 2012 It doesn't. It sends ANSI escape codes on Posix.
- Walter Bright (13/21) Oct 21 2012 Need a method to get the current state, and reset the current state. Oth...
- Jens Mueller (7/35) Oct 21 2012 Very true.
- Robik (6/29) Oct 22 2012 On Windows, setting color to initial sets console colors to ones
- Jens Mueller (4/39) Oct 22 2012 Please look for this. But my research concluded that there is no such
- Adam D. Ruppe (7/8) Oct 22 2012 Yeah, if there was a way to get current colors, you wouldn't have
- Dejan Lekic (5/21) Oct 22 2012 This is very much related to the ycurses and dcurses projects,
- 1100110 (8/36) Oct 22 2012 I had some trouble getting in touch with ylixir last time, and pardon me...
- nazriel (11/27) Oct 28 2012 (Yes, I've seen ConsoleD, but quoting first post in topic is
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
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/ColorDOn 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
On Sunday, 21 October 2012 at 20:19:54 UTC, Peter Sommerfeld wrote:Robik wrote:What version are you using?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/ColorDOn 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
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:dmd 2.060. -O -release -inline -property -w -wi PeterRobik wrote:What version are you using?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/ColorDOn 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
Robik:GitHub: https://github.com/robik/ColorDMaybe 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
On Sunday, 21 October 2012 at 20:39:31 UTC, bearophile wrote:Robik:Moved to https://github.com/robik/ConsoleDGitHub: https://github.com/robik/ColorDMaybe 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
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
This could be improved, the example you givewriteln(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
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/ColorDInteresting 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
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. JensSure, I'm interested in joining forces. Do you have IRC?
Oct 21 2012
Robik wrote:On Sunday, 21 October 2012 at 21:01:21 UTC, Jens Mueller wrote:Do you know how to do this?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.Probably not worth the trouble. But it should be documented.* 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.But the module should not be named colsoled. Because it's a D module anyway. Call it just console.* 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.Yes, I do. JensI 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. JensSure, I'm interested in joining forces. Do you have IRC?
Oct 21 2012
On 10/21/2012 05:01 PM, Jens Mueller wrote:Robik wrote: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.htmlHello, 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/ColorDInteresting 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
Chad J wrote:On 10/21/2012 05:01 PM, Jens Mueller wrote:Yes. I think you cannot make it portable without. Please proof me wrong and I'll fix this.Robik wrote:Hey that looks cool. It seems to have a hard ncurses/termcap/etc dependency.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/ColorDInteresting 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. JensI'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.htmlI 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
On 10/21/2012 06:11 PM, Jens Mueller wrote:Chad J wrote: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.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.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'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.I remember having a plan for this. See below.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.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.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.htmlI 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. JensI 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
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
Chad J wrote:On 10/21/2012 06:11 PM, Jens Mueller wrote: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?Chad J wrote: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.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.I mean it's bad to have Phobos depend on ncurses. Though one can go with loading at run time.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'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.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 remember having a plan for this. See below.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.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.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.htmlI doubt that the Phobos maintainers will accept this. This is very invasive.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 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. JensI 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 ;)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
On 10/21/2012 06:55 PM, Jens Mueller wrote:Chad J wrote: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.On 10/21/2012 06:11 PM, Jens Mueller wrote: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?Chad J wrote: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.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.Yes.I mean it's bad to have Phobos depend on ncurses. Though one can go with loading at run time.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'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.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.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 remember having a plan for this. See below.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.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.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.htmlI doubt that the Phobos maintainers will accept this. This is very invasive.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.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 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. JensI 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 ;)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
Chad J wrote:On 10/21/2012 06:55 PM, Jens Mueller wrote:It is possible since very long time to link dynamically using dmd.Chad J wrote:I completely agree. The difficulty I encountered is actually /doing/ the runtime detection. Does Phobos have a way to dynamically link .so files yet?On 10/21/2012 06:11 PM, Jens Mueller wrote: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?Chad J wrote: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.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.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.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.Is it relevant? I posit that having format syntax is simply better than not. This is on an objective basis.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 remember having a plan for this. See below.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.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.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.htmlI doubt that the Phobos maintainers will accept this. This is very invasive.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");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.I think this is very reasonable. Sounds like a plan! I'll probably make pull requests when I allocate time to work on this.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. JensWould 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
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
Andrei Alexandrescu wrote:On 10/22/12 9:47 AM, Jens Mueller wrote: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. JensThis 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.
Oct 22 2012
On 10/22/12 8:24 AM, Jens Mueller wrote:Andrei Alexandrescu wrote:Cool. Do all systems implement color as escape sequences? AndreiOn 10/22/12 9:47 AM, Jens Mueller wrote: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. JensThis 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.
Oct 22 2012
Andrei Alexandrescu wrote:On 10/22/12 8:24 AM, Jens Mueller wrote: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 JensAndrei Alexandrescu wrote:Cool. Do all systems implement color as escape sequences?On 10/22/12 9:47 AM, Jens Mueller wrote: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. JensThis 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.
Oct 22 2012
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
On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 9:47 AM, Jens Mueller 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).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.
Oct 23 2012
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/12A 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
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
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
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: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).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.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
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: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 :)to make aThis is probably interesting for Phobos. But I'm not the onecertain systemsdecision. The core Phobos developers should decide. Hopefully somebody is reading this.Off the top of my head something that is specific for only(Unixen in this case) is decidedly of less Phobos interest.We could,nevertheless, put such functionality in system-specificmodules. 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 24 2012
Walter Bright wrote:On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 9:47 AM, Jens Mueller wrote:Anybody an idea how to this on Linux?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 inputThis 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.2. getting size of the consoleThis is easy if you just mean the number of lines and columns.3. moving the cursor aroundThis also assuming you just want something like, move 10 lines up, 3 lines right etc.4. drawing boxes in the console windowShould 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 barThe title bar of what?6. supporting cut/pasteDon't know how to do this? Anybody a starting point?7. getting no-echo raw inputTried this but couldn't make it work yet. This is useful for passwords prompts, right?8. setting the size of the cursorThe size of the cursor? Why should I want to change its size? Jens
Oct 25 2012
On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller wrote: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.aspx5. setting the contents of the title barThe title bar of what?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.)6. supporting cut/pasteDon't know how to do this? Anybody a starting point?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.7. getting no-echo raw inputTried this but couldn't make it work yet. This is useful for passwords prompts, right?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.8. setting the size of the cursorThe size of the cursor? Why should I want to change its size?Jens
Oct 25 2012
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: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.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.aspx5. setting the contents of the title barThe title bar of what?[...] 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 WhiteI 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.)6. supporting cut/pasteDon't know how to do this? Anybody a starting point?
Oct 25 2012
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 pasteIt'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
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:Yeah, the problem is it does not work in all terminals.Here's how you do it on xterm: writefln("\033]0;%s\007", title);5. setting the contents of the title barThe title bar of what?
Oct 25 2012
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
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: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!On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller wrote:Yeah, the problem is it does not work in all terminals.Here's how you do it on xterm: writefln("\033]0;%s\007", title);5. setting the contents of the title barThe title bar of what?
Oct 26 2012
H. S. Teoh wrote:On Fri, Oct 26, 2012 at 08:08:36AM +0200, Robik wrote: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. JensOn Friday, 26 October 2012 at 01:35:43 UTC, Adam D. Ruppe wrote: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.On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller wrote:Yeah, the problem is it does not work in all terminals.Here's how you do it on xterm: writefln("\033]0;%s\007", title);5. setting the contents of the title barThe title bar of what?
Oct 26 2012
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:[...] 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.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.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.writefln("\033]0;%s\007", title);Yeah, the problem is it does not work in all terminals.
Oct 26 2012
I'm slapping together a minimal termcap reader for D now.
Oct 26 2012
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
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
Adam D. Ruppe wrote:On Thursday, 25 October 2012 at 22:27:52 UTC, Jens Mueller wrote:I see. Thanks for many pointers. JensHere'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.aspx5. setting the contents of the title barThe title bar of what?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.)6. supporting cut/pasteDon't know how to do this? Anybody a starting point?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.7. getting no-echo raw inputTried this but couldn't make it work yet. This is useful for passwords prompts, right?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.8. setting the size of the cursorThe size of the cursor? Why should I want to change its size?
Oct 26 2012
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
On Fri, Oct 26, 2012 at 12:27:38AM +0200, Jens Mueller wrote:Walter Bright wrote:[...]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.)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 inputAnybody an idea how to this on Linux?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.)2. getting size of the consoleThis is easy if you just mean the number of lines and columns.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).3. moving the cursor aroundThis also assuming you just want something like, move 10 lines up, 3 lines right etc.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.4. drawing boxes in the console windowShould this be done by moving the cursor and inserting characters such that you have a box in the end?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.)5. setting the contents of the title barThe title bar of what?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).6. supporting cut/pasteDon't know how to do this? Anybody a starting point?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. :)7. getting no-echo raw inputTried this but couldn't make it work yet. This is useful for passwords prompts, right?[...] 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."8. setting the size of the cursorThe size of the cursor? Why should I want to change its size?
Oct 25 2012
H. S. Teoh wrote:On Fri, Oct 26, 2012 at 12:27:38AM +0200, Jens Mueller wrote: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]Walter Bright wrote:[...]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.)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 inputAnybody an idea how to this on Linux?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.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).3. moving the cursor aroundThis also assuming you just want something like, move 10 lines up, 3 lines right etc.That means this can also be built on top of cursor moving.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.4. drawing boxes in the console windowShould this be done by moving the cursor and inserting characters such that you have a box in the end?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.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.)5. setting the contents of the title barThe title bar of what?Thanks for the pointers. So these are then two things. First noecho and the other one is raw input.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. :)7. getting no-echo raw inputTried this but couldn't make it work yet. This is useful for passwords prompts, right?Can you say something about incremental updates? Any pointers? Jens[...] 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..8. setting the size of the cursorThe size of the cursor? Why should I want to change its size?
Oct 26 2012
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 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?to make aThis is probably interesting for Phobos. But I'm not the onecertain systemsdecision. The core Phobos developers should decide. Hopefully somebody is reading this.Off the top of my head something that is specific for only(Unixen in this case) is decidedly of less Phobos interest.We could,nevertheless, put such functionality in system-specificmodules. 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 26 2012
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:[...]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.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?[...] 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
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
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
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
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
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
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
Adam D. Ruppe wrote:On Sunday, 28 October 2012 at 10:44:58 UTC, Jens Mueller wrote:I'm running Debian. It doesn't have such a file.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> 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
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
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:Why not use a library? Terminfo is designed precisely for this.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).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
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
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
Tobias Pankrath wrote:On Tuesday, 23 October 2012 at 22:47:40 UTC, Walter Bright wrote: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? JensOn 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 9:47 AM, Jens Mueller wrote: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?to make aThis is probably interesting for Phobos. But I'm not the onecertain systemsdecision. The core Phobos developers should decide. Hopefully somebody is reading this.Off the top of my head something that is specific for only(Unixen in this case) is decidedly of less Phobos interest.We could,nevertheless, put such functionality in system-specificmodules. 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 28 2012
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? JensI 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
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:[...]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.. [...]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.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.)1. getting mouse inputAnybody an idea how to this on Linux?Yeah, noecho is useful for password input; raw input is needed for interactive apps like games or menu-driven programs. Both should be supported. [...]Thanks for the pointers. So these are then two things. First noecho and the other one is raw input.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. :)7. getting no-echo raw inputTried this but couldn't make it work yet. This is useful for passwords prompts, right?[...] 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)The important stuff are cursor positioning, box drawing, incremental updates, cbreak mode, etc..Can you say something about incremental updates? Any pointers?
Oct 26 2012
On 10/22/2012 03:47 AM, Jens Mueller wrote:Chad J wrote:The case is too easy. You're formatting an entire line.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?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.%)");- 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?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.- 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")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>- 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");
Oct 22 2012
Chad J wrote:On 10/22/2012 03:47 AM, Jens Mueller wrote: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?Chad J wrote:The case is too easy. You're formatting an entire line.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?I see. Though I find the last line difficult to decipher (because there are no spaces).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.%)");- 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?It'll be nice then if you can built something using format specifiers on top of a basic library.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.- 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")I see your point now. But we should keep it simple.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. ;)- 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");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
On 10/23/2012 03:51 AM, 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:On 10/22/2012 03:47 AM, Jens Mueller wrote: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?Chad J wrote:The case is too easy. You're formatting an entire line.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?I see. Though I find the last line difficult to decipher (because there are no spaces).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.%)");- 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?It'll be nice then if you can built something using format specifiers on top of a basic library.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.- 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")I see your point now. But we should keep it simple.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. ;)- 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");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. Jenswritefln("The %c(red,white)(widgetometer%) is a deviceformeasuring"); // 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
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...");writefln("The %c(red,white)(widgetometer%) is a device formeasuring"); // for writing red on white
Oct 23 2012
On 10/23/2012 03:56 PM, Philippe Sigaud wrote: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.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...");writefln("The %c(red,white)(widgetometer%) is a device formeasuring"); // for writing red on white
Oct 23 2012
Chad J wrote:On 10/23/2012 03:51 AM, Jens Mueller wrote: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. JensChad 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:On 10/22/2012 03:47 AM, Jens Mueller wrote: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?Chad J wrote:The case is too easy. You're formatting an entire line.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?I see. Though I find the last line difficult to decipher (because there are no spaces).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.%)");- 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?It'll be nice then if you can built something using format specifiers on top of a basic library.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.- 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")I see your point now. But we should keep it simple.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. ;)- 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");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. Jenswritefln("The %c(red,white)(widgetometer%) is a deviceformeasuring"); // 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
Jens Mueller wrote:Chad J wrote:Just read the other post. This has the same problem. JensOn 10/23/2012 03:51 AM, Jens Mueller wrote: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.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:On 10/22/2012 03:47 AM, Jens Mueller wrote: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?Chad J wrote:The case is too easy. You're formatting an entire line.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?I see. Though I find the last line difficult to decipher (because there are no spaces).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.%)");- 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?It'll be nice then if you can built something using format specifiers on top of a basic library.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.- 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")I see your point now. But we should keep it simple.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. ;)- 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");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. Jenswritefln("The %c(red,white)(widgetometer%) is a deviceformeasuring"); // 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
On 10/23/2012 04:42 PM, Jens Mueller wrote:Jens Mueller wrote: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.Chad J wrote:Just read the other post. This has the same problem. JensThat'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: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.writefln("The %c(red,white)(widgetometer%) is a deviceformeasuring"); // 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
Chad J wrote:On 10/23/2012 04:42 PM, Jens Mueller wrote: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. JensJens Mueller wrote: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.Chad J wrote:Just read the other post. This has the same problem. JensThat'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: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.writefln("The %c(red,white)(widgetometer%) is a deviceformeasuring"); // 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
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: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/Chad J wrote: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.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.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'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.I remember having a plan for this. See below.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.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.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.htmlI 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. JensI 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
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
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:No, everything is written from scratch. On Windows side it used WinAPI functions, on Posix, ANSI codes.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
Era Scarecrow wrote:On Sunday, 21 October 2012 at 19:28:21 UTC, Robik wrote:It doesn't. It sends ANSI escape codes on Posix. JensI 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
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
Walter Bright wrote:On 10/21/2012 12:28 PM, Robik wrote: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 JensSimple 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
On Sunday, 21 October 2012 at 22:32:35 UTC, Walter Bright wrote:On 10/21/2012 12:28 PM, Robik wrote: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.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 22 2012
Robik wrote:On Sunday, 21 October 2012 at 22:32:35 UTC, Walter Bright wrote:Please look for this. But my research concluded that there is no such way on Posix. JensOn 10/21/2012 12:28 PM, Robik wrote: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.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 22 2012
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
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
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: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/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
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