[PATCH] log --format: teach %C(auto,black) to paint it black only on terminals

2012-12-17 Thread Junio C Hamano
Traditionally, %C(color attr) always emitted the ANSI color
sequence; it was up to the scripts that wanted to conditionally
color their output to omit %C(...) specifier when they do not want
colors.

Optionally allow auto, to be prefixed to the color, so that the
output is colored iff it goes to the terminal.

Signed-off-by: Junio C Hamano gits...@pobox.com
---
 * This time with minimum test and documentation.

 Documentation/pretty-formats.txt |  4 +++-
 pretty.c | 13 ++---
 t/t6006-rev-list-format.sh   | 30 ++
 3 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index d9edded..2af017c 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -144,7 +144,9 @@ The placeholders are:
 - '%Cgreen': switch color to green
 - '%Cblue': switch color to blue
 - '%Creset': reset color
-- '%C(...)': color specification, as described in color.branch.* config option
+- '%C(...)': color specification, as described in color.branch.* config option;
+  adding `auto,` at the beginning will emit color only when the
+  output is going to a terminal
 - '%m': left, right or boundary mark
 - '%n': newline
 - '%%': a raw '%'
diff --git a/pretty.c b/pretty.c
index dba6828..b9fd972 100644
--- a/pretty.c
+++ b/pretty.c
@@ -960,12 +960,19 @@ static size_t format_commit_one(struct strbuf *sb, const 
char *placeholder,
switch (placeholder[0]) {
case 'C':
if (placeholder[1] == '(') {
-   const char *end = strchr(placeholder + 2, ')');
+   const char *begin = placeholder + 2;
+   const char *end = strchr(begin, ')');
char color[COLOR_MAXLEN];
+
if (!end)
return 0;
-   color_parse_mem(placeholder + 2,
-   end - (placeholder + 2),
+   if (!memcmp(begin, auto,, 5)) {
+   if (!want_color(-1))
+   return end - placeholder + 1;
+   begin += 5;
+   }
+   color_parse_mem(begin,
+   end - begin,
--pretty format, color);
strbuf_addstr(sb, color);
return end - placeholder + 1;
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index f94f0c4..bfcc1c6 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -11,12 +11,12 @@ touch foo  git add foo  git commit -m added foo 
 '
 
 # usage: test_format name format_string expected_output
-test_format() {
+test_format () {
cat expect.$1
test_expect_success format $1 
-git rev-list --pretty=format:'$2' master output.$1 
-test_cmp expect.$1 output.$1
-
+   git rev-list --pretty=format:'$2'${3:+ $3} master output.$1 
+   test_cmp expect.$1 output.$1
+   
 }
 
 test_format percent %%h 'EOF'
@@ -124,6 +124,28 @@ commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
 foo
 EOF
 
+test_format advanced-colors-auto \
+   '%C(auto,red yellow bold)foo%C(auto,reset)' --color 'EOF'
+commit 131a310eb913d107dd3c09a65d1651175898735d
+foo
+commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
+foo
+EOF
+
+# %C(auto,...) should trump --color=always
+#
+# NEEDSWORK: --color=never should also be tested but we need to run a
+# similar test under pseudo-terminal with test_terminal which is too
+# much hassle for its worth.
+
+test_format advanced-colors-forced \
+   '%C(auto,red yellow bold)foo%C(auto,reset)' --color=always 'EOF'
+commit 131a310eb913d107dd3c09a65d1651175898735d
+foo
+commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
+foo
+EOF
+
 cat commit-msg 'EOF'
 Test printing of complex bodies
 
-- 
1.8.1.rc2.126.ge9b7782
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] log --format: teach %C(auto,black) to paint it black only on terminals

2012-12-17 Thread Nguyen Thai Ngoc Duy
On Mon, Dec 17, 2012 at 3:40 PM, Junio C Hamano gits...@pobox.com wrote:
 Traditionally, %C(color attr) always emitted the ANSI color
 sequence; it was up to the scripts that wanted to conditionally
 color their output to omit %C(...) specifier when they do not want
 colors.

 Optionally allow auto, to be prefixed to the color, so that the
 output is colored iff it goes to the terminal.

I see prefix is clearly documented. Still it feels a bit unnatural
that %C(red,auto) won't work. But we can make that case work later if
somebody cares enough.

 if (!end)
 return 0;
 -   color_parse_mem(placeholder + 2,
 -   end - (placeholder + 2),
 +   if (!memcmp(begin, auto,, 5)) {
 +   if (!want_color(-1))
 +   return end - placeholder + 1;

This want_color() checks color.ui and only when color.ui = auto, it
bothers to check if the output is tty. I think the document should say
that auto, (or maybe another name because it's not really auto)
respects color.ui.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] log --format: teach %C(auto,black) to paint it black only on terminals

2012-12-17 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 On Mon, Dec 17, 2012 at 06:44:10PM +0700, Nguyen Thai Ngoc Duy wrote:

  if (!end)
  return 0;
  -   color_parse_mem(placeholder + 2,
  -   end - (placeholder + 2),
  +   if (!memcmp(begin, auto,, 5)) {
  +   if (!want_color(-1))
  +   return end - placeholder + 1;
 
 This want_color() checks color.ui and only when color.ui = auto, it
 bothers to check if the output is tty. I think the document should say
 that auto, (or maybe another name because it's not really auto)
 respects color.ui.

 Yeah, that should definitely be documented. I wonder if it should
 actually respect color.diff, which is what log usually uses (albeit
 mostly for the diff itself, we have always used it for the graph and for
 the commit header of each entry).

I actually do not like this patch very much.  The original motive
behind this auto thing was to relieve the script writers from
the burden of having to write:

if tty -s
then
warn='%C(red)'
reset='%C(reset)'
else
warn= reset=
fi
fmt=${warn}WARNING: boo${reset} %s

and instead let them write:

fmt=%C(auto,red)WARNING: boo%C(auto,reset) %s

but between the two, there is no $cmd.color configuration involved
in the first place.  I am not sure what $cmd.color configuration
should take effect---perhaps for a git frotz script, we should
allow the script writer to honor frotz.color=(auto,never,always)
configuration, not just ui.color variable.

Also the patch as posted deliberately omits support to honor command
line override --color=(auto,never,always), but it may be more
natural to expect

git show --format='%C(auto,red)%s%C(auto,reset)' --color=never

to defeat the auto, part the script writer wrote.

Now, such a script would be run by its end users as

$ git frotz --color=never

It has to do its own option parsing before running the underlying
git show to decide if it passes --color=never from the command
line for that to happen.

But at that point, we are back to the square one.  Such a script
would be doing something like:

if cmdline_has_color_flag
then
use_color=... that flag ...
elif git config --get-colorbool frotz.color
then
use_color=--color=always
else
use_color=--color=never
fi

in its early part to decide $use_color, to be used in the call it
makes to git show later on:

git show --format=$fmt $use_color

Adding the logic to decide if %C(...) should be added to $fmt no
longer is an additional burden to the script writer, making the
whole %C(auto,red) machinery of little use.

So...

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] log --format: teach %C(auto,black) to paint it black only on terminals

2012-12-17 Thread Jeff King
On Mon, Dec 17, 2012 at 11:34:48AM -0800, Junio C Hamano wrote:

  Yeah, that should definitely be documented. I wonder if it should
  actually respect color.diff, which is what log usually uses (albeit
  mostly for the diff itself, we have always used it for the graph and for
  the commit header of each entry).
 
 I actually do not like this patch very much.  The original motive
 behind this auto thing was to relieve the script writers from
 the burden of having to write:
 
   if tty -s
 then
   warn='%C(red)'
 reset='%C(reset)'
   else
   warn= reset=
   fi
 fmt=${warn}WARNING: boo${reset} %s
 
 and instead let them write:
 
   fmt=%C(auto,red)WARNING: boo%C(auto,reset) %s
 
 but between the two, there is no $cmd.color configuration involved
 in the first place.  I am not sure what $cmd.color configuration
 should take effect---perhaps for a git frotz script, we should
 allow the script writer to honor frotz.color=(auto,never,always)
 configuration, not just ui.color variable.

Since this is by definition just talking about the log traversal, I
think it makes sense to respect the log traversal option by default
(which is confusingly color.diff, of course, but that is a separate
issue). That means that scripts which just wrap a regular traversal will
do what the user is accustomed to.

If git frotz wants to have a separate color.frotz option to override
that, then they would need to implement that themselves either with or
without your patch. I do not think its presence makes things any harder.

 Also the patch as posted deliberately omits support to honor command
 line override --color=(auto,never,always), but it may be more
 natural to expect
 
 git show --format='%C(auto,red)%s%C(auto,reset)' --color=never
 
 to defeat the auto, part the script writer wrote.
 
 Now, such a script would be run by its end users as
 
 $ git frotz --color=never
 
 It has to do its own option parsing before running the underlying
 git show to decide if it passes --color=never from the command
 line for that to happen.

Yeah, _if_ it does not just pass its options directly to git-log. Which
I think a reasonable number of scripts do, as well as pretty.* aliases
(which are not really scripts, but have the same relationship with
respect to this feature). For example, git stash list does not use
color in its output, but could be improved to do so after your patch.

So no, I do not think you can cover every conceivable case. But having
git-log respect --color and the usual color.* variables for this feature
seems like the only sane default. It makes the easy cases just work, and
the hard cases are not any worse off (and they may even be better off,
since the script can manipulate --color instead of rewriting their
format strings, but that is a minor difference).

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] log --format: teach %C(auto,black) to paint it black only on terminals

2012-12-17 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 If git frotz wants to have a separate color.frotz option to override
 that, then they would need to implement that themselves either with or
 without your patch. I do not think its presence makes things any harder.

That _was_ (but no longer is) exactly my point.  Eh, rather, its
absense does not make things any harder.

 So no, I do not think you can cover every conceivable case. But having
 git-log respect --color and the usual color.* variables for this feature
 seems like the only sane default. It makes the easy cases just work, and
 the hard cases are not any worse off (and they may even be better off,
 since the script can manipulate --color instead of rewriting their
 format strings, but that is a minor difference).

OK, care to reroll the one with your patch in the other message
squashed in, possibly with fixes to the test (the result should now
honor --color={always,never}, I think)?

Thanks.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] log --format: teach %C(auto,black) to paint it black only on terminals

2012-12-17 Thread Jeff King
On Mon, Dec 17, 2012 at 12:03:40PM -0800, Junio C Hamano wrote:

  So no, I do not think you can cover every conceivable case. But having
  git-log respect --color and the usual color.* variables for this feature
  seems like the only sane default. It makes the easy cases just work, and
  the hard cases are not any worse off (and they may even be better off,
  since the script can manipulate --color instead of rewriting their
  format strings, but that is a minor difference).
 
 OK, care to reroll the one with your patch in the other message
 squashed in, possibly with fixes to the test (the result should now
 honor --color={always,never}, I think)?

Here it is. It was easier to just skip using test_format, so it did not
need to be touched. I broke its cleanups out into a separate patch.

  [1/2]: t6006: clean up whitespace
  [2/2]: log --format: teach %C(auto,black) to respect color config

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html