October 23, 2012
Jens Mueller wrote:
> Chad J wrote:
> > On 10/23/2012 03:51 AM, Jens Mueller wrote:
> > >Chad J wrote:
> > >>On 10/22/2012 03:47 AM, Jens Mueller wrote:
> > >>>Chad J wrote:
> > >>>>There is no weakness to this.  The only shred of a counterargument I can think of is that it makes the format strings more difficult to learn. Other than that, it is possible to detect the destination of the formatter, so color codes will never end up in places where they shouldn't.  A conservative approach to this should handle most desires and never interfere with all the people with no interest in color.
> > >>>>
> > >>>>On the upshot are the things I've mentioned:
> > >>>>- A format specifier is potentially more discoverable.
> > >>>>- A format specifier is more concise.  This keeps your lines from
> > >>>>wrapping.  They are probably too long already.
> > >>>
> > >>>Do you consider this
> > >>>writecf(Color.red, "something %s", "here")
> > >>>concise as well?
> > >>>
> > >>
> > >>The case is too easy.  You're formatting an entire line.
> > >
> > >Am I? I think it's not a line. But I see your point.
> > >You mean something like
> > >writec(Color.red, "red")
> > >writec(Color.blue, "blue")
> > >writec(Color.green, "green")
> > >is too verbose.
> > >You want something like
> > >writef("%CFred(red%)%CFblue(blue%)%CFgreeng(reen%)");
> > >Right?
> > >
> > >>>>- To cement the previous point: nesting requires a few extra characters with a format specifier, rather than a couple extra /lines/ for extra function calls.
> > >>>
> > >>>Don't understand this point. Can you give an example?
> > >>>
> > >>
> > >>Option A:
> > >>
> > >>     auto save = getConsoleState();
> > >>     scope (exit) setConsoleState(save);
> > >>     setConsoleColors(Fg.red, Bg.blue);
> > >>     writeln("Red text on blue background.");
> > >>
> > >>Option B:
> > >>
> > >>     writefln("%CFredBblu(Red text on blue background.%)");
> > >
> > >I see. Though I find the last line difficult to decipher (because there
> > >are no spaces).
> > >
> > >>>>- Calls to stateful console functions allow people to write bugs like saving console state and then forgetting to restore it (or throwing an exception and neglecting to restore from within a scope guard).  Format specifiers do not have this problem.
> > >>>
> > >>>The same holds for
> > >>>writecf(Color.red, "something %s", "here")
> > >>>
> > >>
> > >>See my above example.  In that case the formatter no longer requires even using the scope feature because there are no resources to clean up.  The library handles that mess.
> > >>
> > >>Also statefulness is a pain to deal with.  Stack-like operation with push/pop or bracketing constructs is usually much less troublesome for this sort of thing.
> > >
> > >It'll be nice then if you can built something using format specifiers on top of a basic library.
> > >
> > >>>>- etc (I'm sure I'm forgetting one or two.)
> > >>>>
> > >>>>These are the reasons why my ideal language has color formatting built into its I/O routines.
> > >>>
> > >>>Just wanted to point out that instead of that you can add writec*
> > >>>functions. I think the only thing is that these are less discoverable
> > >>>but they also work without formatting, e.g.
> > >>>writec(Color.red, "my text");
> > >>>
> > >>
> > >>The thing I found very difficult with other color formatting APIs was formatting individual words or characters.  Entire lines are easy-peasy stuff in any API.  Solving the entire-lines case won't impress me. ;)
> > >
> > >I see your point now. But we should keep it simple.
> > >
> > >>Here's my more typical use case:
> > >>
> > >>writefln("The %CFred(widgetometer%) is a device for measuring");
> > >>writefln("widget effectiveness.  It is possible to ");
> > >>writefln("reconcile transcendental properties by hitting");
> > >>writefln("%CFblu(B%) for blue coefficients, %CFgrn(G%) for green");
> > >>writefln("coefficients, or %CFyel(Y%) for yellow coefficients.");
> > >>writefln("Here is a correspondence table:");
> > >>writefln("  %CFnue( %) | %CFblu( B %) %CFgrn( G %) %CFyel( Y %) ");
> > >>writefln("  %CFnue(-%)-+-%CFnue(---%)-%CFnue(---%)-%CFnue(---%)-");
> > >>writefln("  %CFblu(B%) | %CFblu(200%) %CFwht(330%) %CFwht(303%) ");
> > >>writefln("  %CFgrn(G%) | %CFwht(110%) %CFgrn(020%) %CFwht(033%) ");
> > >>writefln("  %CFyel(Y%) | %CFwht(101%) %CFwht(011%) %CFyel(002%) ");
> > >>
> > >>I realized that I wanted a "nue" color that has no effect but allows me to align things effectively ;)
> > >>
> > >>Anyhow, please try to write the above example using any other style. Interleaved function calls are particularly "fun"<g>
> > >
> > >I'm convinced. But I find that it difficult to read. Though that's a problem I usually have with format strings. Can these format strings be made easier to read. I mean
> > >
> > >writefln("The %CF(red)(widgetometer) is a device for measuring");
> > >or
> > >writefln("The %c(red,white)(widgetometer) is a device for measuring"); // for writing red on white
> > >
> > >is already easier to my eyes.
> > >I'd be happy to see it built on top.
> > >
> > >Jens
> > 
> > That's a reasonable suggestion.  The only thing that can't be solved is the trailing ) enclosing the text to be formatted.  That needs a % before it to prevent ambiguity with parentheses in the text itself.  So I could make your example:
> > 
> > > writefln("The %c(red,white)(widgetometer%) is a device
> > formeasuring"); // for writing red on white
> > 
> > I was also considering the possibility of separating layout and style by allowing some kind of style specification before the printing, with a limited formatting spec for using the styles:
> > 
> > stdout.addTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline");
> > 
> > writefln("The %c(myStyle)(widgetometer%) is a device for measuring");
> 
> Ideally, we get some users and ask them what they find easy to read. Or
> look how other languages solve this.
> Because I myself don't color my terminals that much I find it hard to
> imagine.
> I searched for some ruby libraries. I find ruby syntax often very easy.
> We could use UFCS, e.g.
> "some string".red
> or
> "some string".foreground(Color.red)
> 
> What do you think?
> I find this way easier than format strings.

Just read the other post. This has the same problem.

Jens
October 23, 2012
On 10/23/2012 04:42 PM, Jens Mueller wrote:
> Jens Mueller wrote:
>> Chad J wrote:
>>>
>>> That's a reasonable suggestion.  The only thing that can't be solved
>>> is the trailing ) enclosing the text to be formatted.  That needs a
>>> % before it to prevent ambiguity with parentheses in the text
>>> itself.  So I could make your example:
>>>
>>>> writefln("The %c(red,white)(widgetometer%) is a device
>>> formeasuring"); // for writing red on white
>>>
>>> I was also considering the possibility of separating layout and
>>> style by allowing some kind of style specification before the
>>> printing, with a limited formatting spec for using the styles:
>>>
>>> stdout.addTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline");
>>>
>>> writefln("The %c(myStyle)(widgetometer%) is a device for measuring");
>>
>> Ideally, we get some users and ask them what they find easy to read. Or
>> look how other languages solve this.
>> Because I myself don't color my terminals that much I find it hard to
>> imagine.
>> I searched for some ruby libraries. I find ruby syntax often very easy.
>> We could use UFCS, e.g.
>> "some string".red
>> or
>> "some string".foreground(Color.red)
>>
>> What do you think?
>> I find this way easier than format strings.
>
> Just read the other post. This has the same problem.
>
> Jens

Also I'm intentionally shooting for something very concise.  If verbosity conflicts, then it loses.  I say verbosity because I find that things get /less/ readable in situations like these if the syntax/naming is lengthy.  It causes alignment issues, text wrapping, noise, etc.

The thing I liked about the styling notion is that it allows things to be spelled out more, but places this noise outside of the string being formatted.

More thoughts:

// Do style parsing at compile-time if desired.
const myStyle = parseTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline"

// At runtime, stdout is told to use this.
stdout.addTermTextStyle(myStyle);

// I'm thinking it might look better by dropping a pair of parens,
//   but using a . to make it clear where the formatter type ends
//   and the style id begins.
writefln("The %C.myStyle(widgetometer%) is a device for measuring");

// Overloaded for convenience.
stdout.addTermTextStyle("id=rw, fg=red, bg=white, dark, underline");

// The user can choose how verbose they want their formatter to look.
// This is a very concise one.
writefln("The %C.rw(widgetometer%) is a device for measuring");

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

I think is too complicated.
It needs to be a one liner.
Here is an idea:

struct Proxy
{
    this(string s)
    {
        _s = s;
    }

    this(this)
    {
        _s = _s.idup;
    }

    string toString()
    {
        _oldColor = stdout.foregroundColor(Color.red);
        return _s;
    }

    ~this()
    {
        stdout.foregroundColor(_oldColor);
    }

    Color _oldColor;
    string _s;
}

@property
Proxy red(string s)
{
    return Proxy(s);
}

unittest
{
    writeln("string".red);
}

It works in this case. Not sure about the implications of such an implementation.

Jens
October 23, 2012
On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 9:47 AM, Jens Mueller wrote:
>> This is probably interesting for Phobos. But I'm not the one to make a
>> decision. The core Phobos developers should decide.
>> Hopefully somebody is reading this.
>
> Off the top of my head something that is specific for only certain systems
> (Unixen in this case) is decidedly of less Phobos interest. We could,
> nevertheless, put such functionality in system-specific modules.

A module that only sets the console color is a little too light to be a phobos entry.

A more comprehensive module that included:

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

would be a definite candidate. I.e. a module that can support building a text mode screen app (like a text editor).

October 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

> A module that only sets the console color is a little too light to be a phobos entry.
>
> A more comprehensive module that included:
>
> 1. getting mouse input
> 2. getting size of the console
> 3. moving the cursor around
> 4. drawing boxes in the console window
> 5. setting the contents of the title bar
> 6. supporting cut/paste
> 7. getting no-echo raw input
> 8. setting the size of the cursor
>
> would be a definite candidate. I.e. a module that can support building a text mode screen app (like a text editor).

Just so it's known, I support such a module being created.  I shall
provide (what limited) help I can.
October 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.
October 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.
October 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:
> >try, esp. if you're dealing with Unix terminals, which are many and varied, and have all sorts of idiosyncrasies that make it a pain to write a generic library that works for everything.
> 
> Does anybody really care about everything? Unix has de-facto standardized on vt100 emulators, and among them, there's only a few variants I'd care about: xterm, rxvt, gnu screen, putty, and the linux console.

Perhaps the right approach then is to make the code modular, so that terminal-specific stuff is separated off into submodules (which are imported as needed automatically or otherwise). That way, the initial Phobos entry can just have the most common terminals supported: windows command prompt, vt100, and perhaps linux or xterm. I'd say vt100 alone should be good enough from the *nix perspective, at least for an initial stab at the module. Xterm, putty, etc., can then be added later more or less painlessly (if the design is properly done in a modular fashion).

Later on, if people are ambitious, they can try interfacing with terminfo/termcap (but be prepared for long sleepless nights, this stuff is way more complicated than one might expect, and arguably, than is necessary).


> The differences are now brought way down to size, and we can use some of the more interesting extensions without worrying about lowest common denominator dragging us down.
> 
> And then doing Windows (or DOS) is pretty easy to match and perhaps
> exceed it.

I'm not familiar enough with the new Windows prompt (haha, I'm so dating myself by calling it new) to say, but at least for DOS, terminal capabilities are pretty straightforward: color is encoded directly in the screen buffer, and there are standard system calls to move the cursor around, set the display mode, etc.. Raw character mode is pretty much the default (unless you fall back to the BIOS input reading routines -- if those even exist anymore nowadays). So there's almost no escape sequences that need special treatment, etc..  None of the hair-tearing complexities of Unix terminals.

So the windows component of this module should pretty much be a cinch.


T

-- 
"A one-question geek test. If you get the joke, you're a geek: Seen on a California license plate on a VW Beetle: 'FEATURE'..." -- Joshua D. Wachs - Natural Intelligence, Inc.
October 24, 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 is probably interesting for Phobos. But I'm not the one
> to make a
> >> decision. The core Phobos developers should decide.
> >> Hopefully somebody is reading this.
> >
> > Off the top of my head something that is specific for only
> certain systems
> > (Unixen in this case) is decidedly of less Phobos interest.
> We could,
> > nevertheless, put such functionality in system-specific
> modules.
>
> A module that only sets the console color is a little too light to be a phobos entry.
>
> A more comprehensive module that included:
>
> 1. getting mouse input
> 2. getting size of the console
> 3. moving the cursor around
> 4. drawing boxes in the console window
> 5. setting the contents of the title bar
> 6. supporting cut/paste
> 7. getting no-echo raw input
> 8. setting the size of the cursor
>
> would be a definite candidate. I.e. a module that can support building a text mode screen app (like a text editor).


Thanks for your suggestions. I will try to do what I can, but I think there may be some problems because of differences in terminals. Although some of them should not be the problem :)
October 25, 2012
Walter Bright wrote:
> On 10/22/2012 3:55 AM, Andrei Alexandrescu wrote:> On 10/22/12 9:47 AM, Jens Mueller wrote:
> >> This is probably interesting for Phobos. But I'm not the one to make a
> >> decision. The core Phobos developers should decide.
> >> Hopefully somebody is reading this.
> >
> > Off the top of my head something that is specific for only certain systems (Unixen in this case) is decidedly of less Phobos interest. We could, nevertheless, put such functionality in system-specific modules.
> 
> A module that only sets the console color is a little too light to be a phobos entry.
> 
> A more comprehensive module that included:
> 
> 1. getting mouse input

Anybody an idea how to this on Linux?

> 2. getting size of the console

This is easy if you just mean the number of lines and columns.

> 3. moving the cursor around

This also assuming you just want something like, move 10 lines up, 3 lines right etc.

> 4. drawing boxes in the console window

Should this be done by moving the cursor and inserting characters such that you have a box in the end?

> 5. setting the contents of the title bar

The title bar of what?

> 6. supporting cut/paste

Don't know how to do this? Anybody a starting point?

> 7. getting no-echo raw input

Tried this but couldn't make it work yet. This is useful for passwords prompts, right?

> 8. setting the size of the cursor

The size of the cursor? Why should I want to change its size?

Jens