View mode: basic / threaded / horizontal-split · Log in · Help
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On 03/12/2012 10:37 PM, James Miller wrote:
>
> I think the problem with putting it into formatting is that it is
> inherently not output. IOW formatting should go anywhere, but colored
> output is terminal-only.
>
> Also, there are differences between terminals and all sorts of crap
> that just make this harder to do "simply". However, there's no reason
> why there cant be an easy way to colorize output in std.terminal (or
> whatever), that are basically just modified writef(ln) calls
> (colorWritef?) that only output to stdout (and maybe stderr). I think
> this would be a good way around it, because then everything that is
> terminal-specific is kept in one place, and you don't get mistakes
> like outputting color to a file because you did the wrong sequence, or
> forgot to check that stdout is a terminal and all that.
>
> --
> James Miller

I do want to be able to format things besides color with the color 
formatting function.  Maybe I can pick out the color format specifiers 
first and then pass the rest to format.  It'd be a shame to reimplement 
format.

At that point it would be cool if thrown exceptions and the like could 
do color formatting, and also know when to strip it out when writing to 
log files and such.  I don't know how difficult or practical it would 
be, but I think that stack traces with color highlights would be 
awesome.  It's pretty in-your-face user experience-wise too; might be 
good PR for D.

So then, now for the fun part.  What to name this function?

zoosmellPooplord(ln)("%Cred(Text.%)");
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On 03/12/2012 11:58 PM, Chad J wrote:
> On 03/12/2012 10:37 PM, James Miller wrote:
>>
>> I think the problem with putting it into formatting is that it is
>> inherently not output. IOW formatting should go anywhere, but colored
>> output is terminal-only.
>>
>> Also, there are differences between terminals and all sorts of crap
>> that just make this harder to do "simply". However, there's no reason
>> why there cant be an easy way to colorize output in std.terminal (or
>> whatever), that are basically just modified writef(ln) calls
>> (colorWritef?) that only output to stdout (and maybe stderr). I think
>> this would be a good way around it, because then everything that is
>> terminal-specific is kept in one place, and you don't get mistakes
>> like outputting color to a file because you did the wrong sequence, or
>> forgot to check that stdout is a terminal and all that.
>>
>> --
>> James Miller
>
> I do want to be able to format things besides color with the color
> formatting function. Maybe I can pick out the color format specifiers
> first and then pass the rest to format. It'd be a shame to reimplement
> format.
>
> At that point it would be cool if thrown exceptions and the like could
> do color formatting, and also know when to strip it out when writing to
> log files and such. I don't know how difficult or practical it would be,
> but I think that stack traces with color highlights would be awesome.
> It's pretty in-your-face user experience-wise too; might be good PR for D.
>
> So then, now for the fun part. What to name this function?
>
> zoosmellPooplord(ln)("%Cred(Text.%)");

Actually, wait a sec.

So I don't do it in format.

But I can create a color-format function that takes a terminal spec does 
some color formats and optionally some std.format formats as well.  It 
would output a string with the correct escape sequences (hey, you never 
know when you might want to inspect the escape sequences it produces).

So we define
string std.terminal.colorFormat(TerminalSpec spec, string fmtstr);
and std.format remains untouched.
And then...

Why not have writef(ln) use it?  writef(ln) functions know what they are 
attached to right?

They can just strip the formatting out for non-terminal destinations.

I would much prefer this.  I don't like the idea of having different 
writefln and termfln when they both do the same damn thing sans some 
simple coloring functionality.
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On 13 March 2012 16:58, Chad J <chadjoan@__spam.is.bad__gmail.com> wrote:
> On 03/12/2012 10:37 PM, James Miller wrote:
>>
>>
>> I think the problem with putting it into formatting is that it is
>> inherently not output. IOW formatting should go anywhere, but colored
>> output is terminal-only.
>>
>> Also, there are differences between terminals and all sorts of crap
>> that just make this harder to do "simply". However, there's no reason
>> why there cant be an easy way to colorize output in std.terminal (or
>> whatever), that are basically just modified writef(ln) calls
>> (colorWritef?) that only output to stdout (and maybe stderr). I think
>> this would be a good way around it, because then everything that is
>> terminal-specific is kept in one place, and you don't get mistakes
>> like outputting color to a file because you did the wrong sequence, or
>> forgot to check that stdout is a terminal and all that.
>>
>> --
>> James Miller
>
>
> I do want to be able to format things besides color with the color
> formatting function.  Maybe I can pick out the color format specifiers first
> and then pass the rest to format.  It'd be a shame to reimplement format.
>
> At that point it would be cool if thrown exceptions and the like could do
> color formatting, and also know when to strip it out when writing to log
> files and such.  I don't know how difficult or practical it would be, but I
> think that stack traces with color highlights would be awesome.  It's pretty
> in-your-face user experience-wise too; might be good PR for D.
>
> So then, now for the fun part.  What to name this function?
>
> zoosmellPooplord(ln)("%Cred(Text.%)");

I wasn't suggesting to actually re-implement format, actually my idea
was similar to yours in that it would wrap over writef(ln). But doing
it this way, rather than extending writef, means that you can check
for output conditions first. It also allows people to realise that the
function they are reading /isn't/ just a bog-standard writefln, and
should be parsed (mentally) differently.

However, I think that any more than just sequential output should
probably have its own set of functions, so a clearLine function,
clearScreen function, setColor functions and all that. This also
suggests that a color-writef should reset to a "default" color at the
end of output, which makes sense.

One thing I would change is to not use syntax quite so similar to
writef though, and also (since it matches better with terminal
operation anyway) not have it wrap, just set the color for the
remaining output, otherwise parsing will be more difficult, since you
have to check for yet more escape sequences, and using it would be
more error-prone. (For an example, vim has some weird escaping rules
for its regex-implementation that catch me out all the time)

--
James Miller
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On 03/13/2012 12:15 AM, James Miller wrote:
> On 13 March 2012 16:58, Chad J<chadjoan@__spam.is.bad__gmail.com>  wrote:
>> On 03/12/2012 10:37 PM, James Miller wrote:
>>>
>>>
>>> I think the problem with putting it into formatting is that it is
>>> inherently not output. IOW formatting should go anywhere, but colored
>>> output is terminal-only.
>>>
>>> Also, there are differences between terminals and all sorts of crap
>>> that just make this harder to do "simply". However, there's no reason
>>> why there cant be an easy way to colorize output in std.terminal (or
>>> whatever), that are basically just modified writef(ln) calls
>>> (colorWritef?) that only output to stdout (and maybe stderr). I think
>>> this would be a good way around it, because then everything that is
>>> terminal-specific is kept in one place, and you don't get mistakes
>>> like outputting color to a file because you did the wrong sequence, or
>>> forgot to check that stdout is a terminal and all that.
>>>
>>> --
>>> James Miller
>>
>>
>> I do want to be able to format things besides color with the color
>> formatting function.  Maybe I can pick out the color format specifiers first
>> and then pass the rest to format.  It'd be a shame to reimplement format.
>>
>> At that point it would be cool if thrown exceptions and the like could do
>> color formatting, and also know when to strip it out when writing to log
>> files and such.  I don't know how difficult or practical it would be, but I
>> think that stack traces with color highlights would be awesome.  It's pretty
>> in-your-face user experience-wise too; might be good PR for D.
>>
>> So then, now for the fun part.  What to name this function?
>>
>> zoosmellPooplord(ln)("%Cred(Text.%)");
>
> I wasn't suggesting to actually re-implement format, actually my idea
> was similar to yours in that it would wrap over writef(ln). But doing
> it this way, rather than extending writef, means that you can check
> for output conditions first. It also allows people to realise that the
> function they are reading /isn't/ just a bog-standard writefln, and
> should be parsed (mentally) differently.
>

Why?  This would be an addition of features for writef(ln), not an 
alteration.  Existing writef(ln) usage would remain exactly the same.

> However, I think that any more than just sequential output should
> probably have its own set of functions, so a clearLine function,
> clearScreen function, setColor functions and all that. This also
> suggests that a color-writef should reset to a "default" color at the
> end of output, which makes sense.
>

I totally agree with separating all of that stuff out into a separate 
block of code/functionality/API.  I actually see those all as being 
quite different in usage from the very simple sequential case.

I'm not sure I agree with resetting to a default color.  What if I want 
to write to the stream without altering the terminal's graphics settings?

(IMO those terminal graphics attributes are user data, and user data is 
always sacred.)

> One thing I would change is to not use syntax quite so similar to
> writef though, and also (since it matches better with terminal
> operation anyway) not have it wrap, just set the color for the
> remaining output, otherwise parsing will be more difficult, since you
> have to check for yet more escape sequences, and using it would be
> more error-prone. (For an example, vim has some weird escaping rules
> for its regex-implementation that catch me out all the time)
>
> --
> James Miller

Ah, maybe it's preference.  I'd probably do both nesting and not-nesting 
variants.  I always /hated/ being /forced/ to use the modal 
(non-nesting) idea of changing THE color.  Instead, I see it very easily 
as a stack: push and pop the colors.  Otherwise I start writing 
"original format and then %Cred this text is red and then back to the 
%C. .. ... " FFFFFFFffff nooo!  what do I do to get back to the original 
formatting if I don't know what it is?!?!  Maybe I'm drainbamaged, but 
stuff like that will drive me nuts and leave me in mental lockout for a 
number of minutes.

Care to share some examples of the things that frustrate you?

I would prefer that any unclosed/unmatched nesting formatters would be 
automatically closed at the end of the format string.  If only nesting 
formatters are used, it would be least surprising to me if the formatter 
just didn't change the terminal's original settings at all:

// Terminal is currently set to bold-green.
writefln("%Cred(But this text will be red.");
writefln("And this text will be bold-green.");

If I used a non-nesting variant at toplevel and change the current mode, 
then I would expect /that/ to alter the terminal's original settings and 
leave it in a different state than from before the formatted write:

// Terminal is currently set to bold-green.
writefln("%Cred(But this text will be red.");
writefln("And this text will be bold-green.");
writefln("Still bold-green, until %Cblu hey, it's blue now.");
// Terminal is currently set to blue.
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On Tue, Mar 13, 2012 at 03:17:42PM +1300, James Miller wrote:
> On 13 March 2012 15:17, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> > We could start off with said module just doing colors for now, and
> > then gradually add more stuff to it later.
> 
> We could end up at a D-flavoured ncurses library!
[...]

That would be a dream come true for me.

I have to admit that I find the ncurses API quite ugly, and not very
well-designed. It's the curse (pun intended) of inheriting a decades-old
API that was designed back in the days when people didn't know very much
about good API design.


T

-- 
Marketing: the art of convincing people to pay for what they didn't need
before which you can't deliver after.
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On 3/12/2012 10:58 PM, Chad J wrote:
> On 03/12/2012 10:37 PM, James Miller wrote:
>
> I do want to be able to format things besides color with the color
> formatting function. Maybe I can pick out the color format specifiers
> first and then pass the rest to format. It'd be a shame to reimplement
> format.
>

There are something like 4 million UTF characters designated for 
user-defined use.  I had hooked some range of this into RGBA color codes 
for easy rendering text for D3D, as the function needs to parse the 
string to generate texture UVs for the glyphs, and might as well be 
setting some vertex attributes for color along the way etc.
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On 13 March 2012 18:24, Chad J <chadjoan@__spam.is.bad__gmail.com> wrote:
> I'm not sure I agree with resetting to a default color.  What if I want to
> write to the stream without altering the terminal's graphics settings?

Actually, I meant more to make sure that any output is reset to the
terminal's default. I'm pretty sure there is a way to do this. The
point is that not undoing mode changes is bad form.

Otherwise, I can live with the colourings being nested, but I would
suggest a change in syntax, I understand that yours is mostly just for
show, but using parenthesis will be annoying, I'd probably use braces
('{' and '}') instead, since they are less common.

writefln('%Cred(\(this is in color\))');
vs
writefln('%Cred{(this is in color)}');

Neither are /that/ pretty, but at least the second one requires less
escaping in the common case.

--
James Miller
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On 03/13/2012 01:41 AM, James Miller wrote:
> On 13 March 2012 18:24, Chad J<chadjoan@__spam.is.bad__gmail.com>  wrote:
>> I'm not sure I agree with resetting to a default color.  What if I want to
>> write to the stream without altering the terminal's graphics settings?
>
> Actually, I meant more to make sure that any output is reset to the
> terminal's default. I'm pretty sure there is a way to do this. The
> point is that not undoing mode changes is bad form.
>
> Otherwise, I can live with the colourings being nested, but I would
> suggest a change in syntax, I understand that yours is mostly just for
> show, but using parenthesis will be annoying, I'd probably use braces
> ('{' and '}') instead, since they are less common.
>
> writefln('%Cred(\(this is in color\))');
>   vs
> writefln('%Cred{(this is in color)}');
>
> Neither are /that/ pretty, but at least the second one requires less
> escaping in the common case.
>
> --
> James Miller

Oh, I see what you mean.

This is why the second paren always had a % before it:

writefln('%Cred((this is in color)%)');

Is this OK?  I know that escaping is still involved, but the text itself 
does not need escaping: only the special closing element does.

I like this constraint because it means that the only character you ever 
have to escape in your normal text is %, which you write by using %% 
instead.
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On 03/13/2012 01:34 AM, H. S. Teoh wrote:
> On Tue, Mar 13, 2012 at 03:17:42PM +1300, James Miller wrote:
>> On 13 March 2012 15:17, H. S. Teoh<hsteoh@quickfur.ath.cx>  wrote:
>>> We could start off with said module just doing colors for now, and
>>> then gradually add more stuff to it later.
>>
>> We could end up at a D-flavoured ncurses library!
> [...]
>
> That would be a dream come true for me.
>
> I have to admit that I find the ncurses API quite ugly, and not very
> well-designed. It's the curse (pun intended) of inheriting a decades-old
> API that was designed back in the days when people didn't know very much
> about good API design.
>
>
> T
>

Yes.

Maybe someday...
March 13, 2012
Re: How about colors and terminal graphics in std.format?
On 13 March 2012 18:50, Chad J <chadjoan@__spam.is.bad__gmail.com> wrote:
> On 03/13/2012 01:41 AM, James Miller wrote:
>>
>> On 13 March 2012 18:24, Chad J<chadjoan@__spam.is.bad__gmail.com>  wrote:
>>>
>>> I'm not sure I agree with resetting to a default color.  What if I want
>>> to
>>>
>>> write to the stream without altering the terminal's graphics settings?
>>
>>
>> Actually, I meant more to make sure that any output is reset to the
>> terminal's default. I'm pretty sure there is a way to do this. The
>> point is that not undoing mode changes is bad form.
>>
>> Otherwise, I can live with the colourings being nested, but I would
>> suggest a change in syntax, I understand that yours is mostly just for
>> show, but using parenthesis will be annoying, I'd probably use braces
>> ('{' and '}') instead, since they are less common.
>>
>> writefln('%Cred(\(this is in color\))');
>>  vs
>> writefln('%Cred{(this is in color)}');
>>
>> Neither are /that/ pretty, but at least the second one requires less
>> escaping in the common case.
>>
>> --
>> James Miller
>
>
> Oh, I see what you mean.
>
> This is why the second paren always had a % before it:
>
> writefln('%Cred((this is in color)%)');
>
> Is this OK?  I know that escaping is still involved, but the text itself
> does not need escaping: only the special closing element does.
>
> I like this constraint because it means that the only character you ever
> have to escape in your normal text is %, which you write by using %%
> instead.

That works, and I think it matches zsh's style. I still think that
'{', '}' would be better, but I'm not dead-set on it.

--
James Miller
1 2 3 4 5
Top | Discussion index | About this forum | D home