{"thread":{"id":"10263","subject":"[PATCH] Color support added to git-add--interactive.","startedAt":"2007-10-13T04:13:14Z","lastAt":"2007-11-23T10:21:57Z","messageCount":86,"participants":["Dan Zwell","Jeff King","Johannes Schindelin","Frank Lichtenheld","Wincent Colaiuta","Jean-Luc Herren","Andreas Ericsson","Tom Tobin","Dan Z","Shawn O. Pearce","Junio C Hamano","Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"55590","messageId":"471045DA.5050902@gmail.com","threadId":"10263","inReplyTo":null,"subject":"[PATCH] Color support added to git-add--interactive.","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-10-13T04:13:14Z","receivedAt":"2007-10-13T04:13:14Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"Recently there was some talk of color for git-add--interactive, but the \nperson who said he already had a patch didn't produce it.\n\n-Reads configuration from git-config (using a new key,\n  color.add-interactive), respects \"auto\" if called from a script\n-Uses the library Term::ANSIColor, which is included with modern\n  versions of perl.\n\nThere is one problem--a block is commented out, because adding the \n\"--color\" option to git-diff-files somehow breaks git-add--interactive, \nand I would love some help from someone who knows a little more about \nthe rest of the script than I do. Also, this is the first perl I have \nwritten, and criticism is welcome. A gzipped patch is attached, in case \nthunderbird mangles the tabs. Feel free to replace the colors that I \nchose with something that better conforms to the \"git style\", if there \nis such a thing.\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex be68814..f55d787 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -2,6 +2,18 @@\n\n  use strict;\n\n+my $use_color;\n+my $color_config = qx(git config --get color.add-interactive);\n+if ($color_config=~\"true\" || -t STDOUT && $color_config=~\"auto\") {\n+\t$use_color = \"true\";\n+\trequire Term::ANSIColor;\n+}\n+sub print_ansi_color {\n+\tif ($use_color) {\n+\t\tprint Term::ANSIColor::color($_[0]);\n+\t}\n+}\n+\n  sub run_cmd_pipe {\n  \tif ($^O eq 'MSWin32') {\n  \t\tmy @invalid = grep {m/[\":*]/} @_;\n@@ -175,7 +187,9 @@ sub list_and_choose {\n  \t\t\tif (!$opts->{LIST_FLAT}) {\n  \t\t\t\tprint \"     \";\n  \t\t\t}\n+\t\t\tprint_ansi_color \"bold\";\n  \t\t\tprint \"$opts->{HEADER}\\n\";\n+\t\t\tprint_ansi_color \"clear\";\n  \t\t}\n  \t\tfor ($i = 0; $i < @stuff; $i++) {\n  \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n@@ -205,7 +219,9 @@ sub list_and_choose {\n\n  \t\treturn if ($opts->{LIST_ONLY});\n\n+\t\tprint_ansi_color \"bold blue\";\n  \t\tprint $opts->{PROMPT};\n+\t\tprint_ansi_color \"reset\";\n  \t\tif ($opts->{SINGLETON}) {\n  \t\t\tprint \"> \";\n  \t\t}\n@@ -338,6 +354,16 @@ sub add_untracked_cmd {\n\n  sub parse_diff {\n  \tmy ($path) = @_;\n+\t# FIXME: the following breaks git, and I'm not sure why. When\n+\t# the following is uncommented, git no longer asks whether we\n+\t# want to add given hunks.\n+\t#my @diff;\n+\t#if ($use_color) {\n+\t#    #@diff = run_cmd_pipe(qw(git diff-files --color -p --), $path);\n+\t#}\n+\t#else {\n+\t#    #@diff = run_cmd_pipe(qw(git diff-files -p --), $path);\n+\t#}\n  \tmy @diff = run_cmd_pipe(qw(git diff-files -p --), $path);\n  \tmy (@hunk) = { TEXT => [] };\n\n@@ -544,6 +570,7 @@ sub coalesce_overlapping_hunks {\n  }\n\n  sub help_patch_cmd {\n+\tprint_ansi_color \"blue\";\n  \tprint <<\\EOF ;\n  y - stage this hunk\n  n - do not stage this hunk\n@@ -555,6 +582,7 @@ k - leave this hunk undecided, see previous \nundecided hunk\n  K - leave this hunk undecided, see previous hunk\n  s - split the current hunk into smaller hunks\n  EOF\n+\tprint_ansi_color \"clear\";\n  }\n\n  sub patch_update_cmd {\n@@ -619,7 +647,9 @@ sub patch_update_cmd {\n  \t\tfor (@{$hunk[$ix]{TEXT}}) {\n  \t\t\tprint;\n  \t\t}\n+\t\tprint_ansi_color \"bold\";\n  \t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n+\t\tprint_ansi_color \"reset\";\n  \t\tmy $line = <STDIN>;\n  \t\tif ($line) {\n  \t\t\tif ($line =~ /^y/i) {\n-- \n1.5.3.4.207.gc0ee\n\nDan Zwell\n"},{"id":"55596","messageId":"20071013081205.GB27533@coredump.intra.peff.net","threadId":"10263","inReplyTo":"471045DA.5050902@gmail.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-13T08:12:06Z","receivedAt":"2007-10-13T08:12:06Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 12, 2007 at 11:13:14PM -0500, Dan Zwell wrote:\n\n> Recently there was some talk of color for git-add--interactive, but the \n> person who said he already had a patch didn't produce it.\n\nNeat, thanks for working on this.\n\n> There is one problem--a block is commented out, because adding the \"--color\" \n> option to git-diff-files somehow breaks git-add--interactive, and I would \n\nI believe it's because add--interactive parses the output of\ngit-diff-files, so it expects unadorned diffs. I think you may be stuck\nre-coloring the diffs yourself, which is a little ugly.\n\n> tabs. Feel free to replace the colors that I chose with something that \n> better conforms to the \"git style\", if there is such a thing.\n\nTwo suggestions:\n  - every color should be configurable (e.g., see diff color options)\n  - where possible, use existing color config (e.g., for diffs)\n\nYou will never come up with a color scheme that satisfies everyone\n(e.g., white text on black background versus black text on white\nbackground), so configurability is a good idea (not to mention that\nnobody will ever agree on what looks \"good\").\n\n> +if ($color_config=~\"true\" || -t STDOUT && $color_config=~\"auto\") {\n\nShouldn't these just be 'eq' instead of a regex?\n\n> +\t\t\tprint_ansi_color \"bold\";\n>  \t\t\tprint \"$opts->{HEADER}\\n\";\n> +\t\t\tprint_ansi_color \"clear\";\n\nISTR some terminals had issues with leaving ANSI attributes set across a\nnewline. That was the reason for the color_fprintf_ln business in\ncolor.[ch]. You might replace this with something like:\n\n  print_color_ln 'bold', $opts->{HEADER};\n\nwhere \"print_color_ln\" turns off the attribute before the newline.\n\n> +\t# FIXME: the following breaks git, and I'm not sure why. When\n> +\t# the following is uncommented, git no longer asks whether we\n> +\t# want to add given hunks.\n> +\t#my @diff;\n> +\t#if ($use_color) {\n> +\t#    #@diff = run_cmd_pipe(qw(git diff-files --color -p --), $path);\n> +\t#}\n> +\t#else {\n> +\t#    #@diff = run_cmd_pipe(qw(git diff-files -p --), $path);\n> +\t#}\n>  \tmy @diff = run_cmd_pipe(qw(git diff-files -p --), $path);\n\nSee how we are pulling the diff into lines? Look a few lines below and\nyou will see that we start parsing without regard to the color.\n\nUnfortunately, that parsed form ends up being output to the user, so we\nwill have to do colorization at that point (fortunately, diff\ncolorization with regexes isn't _that_ hard).\n\n> +\tprint_ansi_color \"blue\";\n>  \tprint <<\\EOF ;\n>  y - stage this hunk\n>  n - do not stage this hunk\n> @@ -555,6 +582,7 @@ k - leave this hunk undecided, see previous undecided \n> hunk\n>  K - leave this hunk undecided, see previous hunk\n>  s - split the current hunk into smaller hunks\n>  EOF\n> +\tprint_ansi_color \"clear\";\n\nHrm, splitting this with print_color_ln as I mentioned above would be a\nlittle painful. Maybe something like this (totally untested):\n\n# Turn on ansi attributes at the beginning of the string and at\n# the beginning of each line, but then turn them off before each\n# newline. This should give the effect of covering the whole string\n# with the attribute, but not have attributes cross newline boundaries.\nsub color_print {\n  my $attr = shift;\n  local $_ = shift;\n  if ($use_color) {\n    s/^/Term::ANSIColor::color($attr)/mge;\n    s/\\n/Term::ANSIColor::color('reset') . $&/ge;\n  }\n  print $_;\n}\n\n-Peff\n"},{"id":"55597","messageId":"Pine.LNX.4.64.0710131321520.25221@racer.site","threadId":"10263","inReplyTo":"471045DA.5050902@gmail.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-10-13T12:25:56Z","receivedAt":"2007-10-13T12:25:56Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\n[Cc'ed Wincent correctly]\n\nOn Fri, 12 Oct 2007, Dan Zwell wrote:\n\n> diff --git a/git-add--interactive.perl b/git-add--interactive.perl\n> index be68814..f55d787 100755\n> --- a/git-add--interactive.perl\n> +++ b/git-add--interactive.perl\n> @@ -2,6 +2,18 @@\n> \n>  use strict;\n> \n> +my $use_color;\n> +my $color_config = qx(git config --get color.add-interactive);\n> +if ($color_config=~\"true\" || -t STDOUT && $color_config=~\"auto\") {\n> +\t$use_color = \"true\";\n> +\trequire Term::ANSIColor;\n> +}\n\nGood.  If you do not have color enabled, it does not require that package \nthat is only default with modern Perl.\n\n> @@ -175,7 +187,9 @@ sub list_and_choose {\n>  \t\t\tif (!$opts->{LIST_FLAT}) {\n>  \t\t\t\tprint \"     \";\n>  \t\t\t}\n> +\t\t\tprint_ansi_color \"bold\";\n>  \t\t\tprint \"$opts->{HEADER}\\n\";\n> +\t\t\tprint_ansi_color \"clear\";\n\nHere you say \"clear\", and ...\n\n>  \t\t}\n>  \t\tfor ($i = 0; $i < @stuff; $i++) {\n>  \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n> @@ -205,7 +219,9 @@ sub list_and_choose {\n> \n>  \t\treturn if ($opts->{LIST_ONLY});\n> \n> +\t\tprint_ansi_color \"bold blue\";\n>  \t\tprint $opts->{PROMPT};\n> +\t\tprint_ansi_color \"reset\";\n\nhere you say \"reset\".  Is it because of the added colour?\n\n> @@ -338,6 +354,16 @@ sub add_untracked_cmd {\n> \n>  sub parse_diff {\n>  \tmy ($path) = @_;\n> +\t# FIXME: the following breaks git, and I'm not sure why. When\n> +\t# the following is uncommented, git no longer asks whether we\n> +\t# want to add given hunks.\n> +\t#my @diff;\n> +\t#if ($use_color) {\n> +\t#    #@diff = run_cmd_pipe(qw(git diff-files --color -p --), $path);\n> +\t#}\n> +\t#else {\n> +\t#    #@diff = run_cmd_pipe(qw(git diff-files -p --), $path);\n> +\t#}\n>  \tmy @diff = run_cmd_pipe(qw(git diff-files -p --), $path);\n>  \tmy (@hunk) = { TEXT => [] };\n\nThis fails because of the next two lines:\n\n        for (@diff) {\n                if (/^@@ /) {\n\nReplace the if with \"if (/^[^-+ ]*@@ /)\", or something even stricter.  \n--color adds magic sequences to make color.\n\nI cannot comment on the Perl style ;-)\n\nCiao,\nDscho\n"},{"id":"55598","messageId":"20071013124957.GZ31659@planck.djpig.de","threadId":"10263","inReplyTo":"20071013081205.GB27533@coredump.intra.peff.net","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Frank Lichtenheld","fromEmail":"frank@lichtenheld.de","sentAt":"2007-10-13T12:49:57Z","receivedAt":"2007-10-13T12:49:57Z","isPatch":true,"sender":{"key":"frank@lichtenheld.de","avatar":"https://gravatar.com/avatar/b9f1d4b120e138f157c9e480d0818197c474628923786adb98f30017cdb99c3c?d=mp&s=160"},"body":"On Sat, Oct 13, 2007 at 04:12:06AM -0400, Jeff King wrote:\n> > +if ($color_config=~\"true\" || -t STDOUT && $color_config=~\"auto\") {\n> \n> Shouldn't these just be 'eq' instead of a regex?\n\nWhat would mean you have to chomp it first. But it should at least\nbe written as =~ /.../ to make it clear that using a regex was a\nconcious decision here and not an accident.\n\nGruesse,\n-- \nFrank Lichtenheld <frank@lichtenheld.de>\nwww: http://www.djpig.de/\n"},{"id":"55608","messageId":"19271E58-5C4F-41AF-8F9D-F114F36A34AC@wincent.com","threadId":"10263","inReplyTo":"471045DA.5050902@gmail.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Wincent Colaiuta","fromEmail":"win@wincent.com","sentAt":"2007-10-13T14:45:41Z","receivedAt":"2007-10-13T14:45:41Z","isPatch":true,"sender":{"key":"greg@hurrell.net","avatar":"https://avatars.githubusercontent.com/u/7074?v=4"},"body":"El 13/10/2007, a las 6:13, Dan Zwell escribió:\n\n> Dan Zwell<Color-add-interactive.patch.gz>\n\nBased on a couple of the suggestions you've received I made a couple  \nof changes to your patch and given it a quick try-out. I'm no perl  \nhacker so there may be better ways.\n\n- as per Jeff's suggestion, changed your print_ansi_color method,  \nmodelling it after the print_color_ln and color_vprintf functions  \ndefined in color.c; accepts a color, a string, and an optional  \ntrailer (where if there is a newline you pass it as the trailer)\n\n- as Johannes pointed out, \"clear\" and \"reset\" are not used  \nconsistently even though the Term::ANSIColor documentation says that  \nthey're the same, so settled on \"clear\"; although in any case, the  \nchanges to the print_ansi_color function mean that it is now the only  \nsite where clearing takes place\n\n- changed the regex as suggested by Johannes, and a couple of others  \nthat are used when splitting hunks\n\n- used more explicit notation for regex as proposed by Frank\n\nTook it for a basic spin here and seems to work. Didn't even think  \nabout implementing user-settable colors.\n\nCheers,\nWincent\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex be68814..ae3d11e 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -2,6 +2,28 @@\n\n  use strict;\n\n+my $use_color;\n+my $color_config = qx(git config --get color.add-interactive);\n+if ($color_config =~ /true/ || -t STDOUT && $color_config =~ /auto/) {\n+\t$use_color = \"true\";\n+\trequire Term::ANSIColor;\n+}\n+\n+sub print_ansi_color($$;$) {\n+\tmy $color = shift;\n+\tmy $string = shift;\n+\tmy $trailer = shift;\n+\tif ($use_color) {\n+\t\tprintf '%s%s%s', Term::ANSIColor::color($color), $string,\n+\t\t    Term::ANSIColor::color('clear');\n+\t} else {\n+\t\tprint $string;\n+\t}\n+\tif ($trailer) {\n+\t\tprint $trailer;\n+\t}\n+}\n+\n  sub run_cmd_pipe {\n  \tif ($^O eq 'MSWin32') {\n  \t\tmy @invalid = grep {m/[\":*]/} @_;\n@@ -175,7 +197,7 @@ sub list_and_choose {\n  \t\t\tif (!$opts->{LIST_FLAT}) {\n  \t\t\t\tprint \"     \";\n  \t\t\t}\n-\t\t\tprint \"$opts->{HEADER}\\n\";\n+\t\t\tprint_ansi_color \"bold\", \"$opts->{HEADER}\", \"\\n\";\n  \t\t}\n  \t\tfor ($i = 0; $i < @stuff; $i++) {\n  \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n@@ -205,7 +227,7 @@ sub list_and_choose {\n\n  \t\treturn if ($opts->{LIST_ONLY});\n\n-\t\tprint $opts->{PROMPT};\n+\t\tprint_ansi_color \"bold blue\", $opts->{PROMPT};\n  \t\tif ($opts->{SINGLETON}) {\n  \t\t\tprint \"> \";\n  \t\t}\n@@ -338,11 +360,17 @@ sub add_untracked_cmd {\n\n  sub parse_diff {\n  \tmy ($path) = @_;\n-\tmy @diff = run_cmd_pipe(qw(git diff-files -p --), $path);\n+\tmy @diff;\n+\tif ($use_color) {\n+\t\t@diff = run_cmd_pipe(qw(git diff-files --color -p --), $path);\n+\t}\n+\telse {\n+\t\t@diff = run_cmd_pipe(qw(git diff-files -p --), $path);\n+\t}\n  \tmy (@hunk) = { TEXT => [] };\n\n  \tfor (@diff) {\n-\t\tif (/^@@ /) {\n+\t\tif (/^[^-+ ]*@@ /) {\n  \t\t\tpush @hunk, { TEXT => [] };\n  \t\t}\n  \t\tpush @{$hunk[-1]{TEXT}}, $_;\n@@ -360,7 +388,7 @@ sub hunk_splittable {\n  sub parse_hunk_header {\n  \tmy ($line) = @_;\n  \tmy ($o_ofs, $o_cnt, $n_ofs, $n_cnt) =\n-\t    $line =~ /^@@ -(\\d+)(?:,(\\d+)) \\+(\\d+)(?:,(\\d+)) @@/;\n+\t    $line =~ /^[^-+ ]*@@ -(\\d+)(?:,(\\d+)) \\+(\\d+)(?:,(\\d+)) @@/;\n  \treturn ($o_ofs, $o_cnt, $n_ofs, $n_cnt);\n  }\n\n@@ -426,7 +454,7 @@ sub split_hunk {\n  \t\t\t}\n  \t\t\tpush @{$this->{TEXT}}, $line;\n  \t\t\t$this->{ADDDEL}++;\n-\t\t\tif ($line =~ /^-/) {\n+\t\t\tif ($line =~ /^[^-+ ]*-/) {\n  \t\t\t\t$this->{OCNT}++;\n  \t\t\t}\n  \t\t\telse {\n@@ -483,7 +511,7 @@ sub merge_hunk {\n  \t$o_cnt = $n_cnt = 0;\n  \tfor ($i = 1; $i < @{$prev->{TEXT}}; $i++) {\n  \t\tmy $line = $prev->{TEXT}[$i];\n-\t\tif ($line =~ /^\\+/) {\n+\t\tif ($line =~ /^[^-+ ]*\\+/) {\n  \t\t\t$n_cnt++;\n  \t\t\tpush @line, $line;\n  \t\t\tnext;\n@@ -501,7 +529,7 @@ sub merge_hunk {\n\n  \tfor ($i = 1; $i < @{$this->{TEXT}}; $i++) {\n  \t\tmy $line = $this->{TEXT}[$i];\n-\t\tif ($line =~ /^\\+/) {\n+\t\tif ($line =~ /^[^-+ ]*\\+/) {\n  \t\t\t$n_cnt++;\n  \t\t\tpush @line, $line;\n  \t\t\tnext;\n@@ -544,7 +572,7 @@ sub coalesce_overlapping_hunks {\n  }\n\n  sub help_patch_cmd {\n-\tprint <<\\EOF ;\n+\tmy $help = <<\\EOF ;\n  y - stage this hunk\n  n - do not stage this hunk\n  a - stage this and all the remaining hunks\n@@ -555,6 +583,7 @@ k - leave this hunk undecided, see previous  \nundecided hunk\n  K - leave this hunk undecided, see previous hunk\n  s - split the current hunk into smaller hunks\n  EOF\n+\tprint_ansi_color \"blue\", $_, \"\\n\" foreach (split /[\\r\\n]/, $help);\n  }\n\n  sub patch_update_cmd {\n@@ -619,7 +648,7 @@ sub patch_update_cmd {\n  \t\tfor (@{$hunk[$ix]{TEXT}}) {\n  \t\t\tprint;\n  \t\t}\n-\t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n+\t\tprint_ansi_color \"bold\", \"Stage this hunk [y/n/a/d$other/?]? \";\n  \t\tmy $line = <STDIN>;\n  \t\tif ($line) {\n  \t\t\tif ($line =~ /^y/i) {\n"},{"id":"55612","messageId":"4710F47D.2070306@gmx.ch","threadId":"10263","inReplyTo":"19271E58-5C4F-41AF-8F9D-F114F36A34AC@wincent.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Jean-Luc Herren","fromEmail":"jlh@gmx.ch","sentAt":"2007-10-13T16:38:21Z","receivedAt":"2007-10-13T16:38:21Z","isPatch":true,"sender":{"key":"jlh@gmx.ch","avatar":null},"body":"Hi!\n\nI really like the idea of colorizing git add -i, especially the\nprompt.  Here are my two cents.\n\nWincent Colaiuta wrote:\n> +sub print_ansi_color($$;$) {\n> +    my $color = shift;\n> +    my $string = shift;\n> +    my $trailer = shift;\n\nNone of the other subs in this file have a prototype, so for\nconsistency I'd suggest to not add it on this function either.\nHowever maybe a patch that adds it to all subs would be welcome.\n(I wouldn't see the necessity though.)\n\nAnd the common way of getting the arguments is reading @_ (see all\nother subs in the file).  So maybe instead write:\n\n[...]\nsub print_ansi_color {\n\tmy ($color, $string, $trailer) = @_;\n[...]\n\n> +    if ($use_color) {\n> +        printf '%s%s%s', Term::ANSIColor::color($color), $string,\n> +            Term::ANSIColor::color('clear');\n> +    } else {\n\nWhy use printf when you could directly use print here?  It's only\nused for concatenating.\n\n> +    if ($trailer) {\n> +        print $trailer;\n> +    }\n\nThis will fail to print $trailer when $trailer happens to be a\nstring that evaluates to false in bool context, like '0'.  Write\nthis as:\n\n\tif (defined $trailer) {\n\t    print $trailer;\n\t}\n\nIMHO, parsing the output of 'git diff-files --color' is a very bad\nidea and it makes all regexes uglier and more difficult to read.\nYou're much better off recolorizing it yourself, which makes it a\nmore localized change.  Especially, I don't think that you have\nany guarantee that escape sequences won't ever contain the\ncharacters '+', '-' or ' ' (space), which would break your code on\nlines like this:\n\n> +        if ($line =~ /^[^-+ ]*\\+/) { \n\nFinally -- and this might be just my eyes -- blue is a very nice\ncolor, but it looks a bit too dark on black background.  Maybe\nchoose a default color that looks reasonable on black *and* white\nbackground.\n\nCheers,\njlh\n"},{"id":"55613","messageId":"Pine.LNX.4.64.0710131737010.25221@racer.site","threadId":"10263","inReplyTo":"19271E58-5C4F-41AF-8F9D-F114F36A34AC@wincent.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-10-13T16:38:25Z","receivedAt":"2007-10-13T16:38:25Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 13 Oct 2007, Wincent Colaiuta wrote:\n\n> Didn't even think about implementing user-settable colors.\n\nFWIW, this is what Documentation/config.txt has to say about it:\n\ncolor.diff.<slot>::\n        Use customized color for diff colorization.  `<slot>` specifies\n        which part of the patch to use the specified color, and is one\n        of `plain` (context text), `meta` (metainformation), `frag`\n        (hunk header), `old` (removed lines), `new` (added lines),\n        `commit` (commit headers), or `whitespace` (highlighting dubious\n        whitespace).  The values of these variables may be specified as\n        in color.branch.<slot>.\n\nHth,\nDscho\n"},{"id":"55615","messageId":"6E1CBEF5-C2EA-447A-9FED-1423A17C2D19@wincent.com","threadId":"10263","inReplyTo":"4710F47D.2070306@gmx.ch","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Wincent Colaiuta","fromEmail":"win@wincent.com","sentAt":"2007-10-13T17:14:19Z","receivedAt":"2007-10-13T17:14:19Z","isPatch":true,"sender":{"key":"greg@hurrell.net","avatar":"https://avatars.githubusercontent.com/u/7074?v=4"},"body":"El 13/10/2007, a las 18:38, Jean-Luc Herren escribió:\n\n> Here are my two cents.\n>\n> Wincent Colaiuta wrote:\n>> +sub print_ansi_color($$;$) {\n>> +    my $color = shift;\n>> +    my $string = shift;\n>> +    my $trailer = shift;\n>\n> None of the other subs in this file have a prototype, so for\n> consistency I'd suggest to not add it on this function either.\n> However maybe a patch that adds it to all subs would be welcome.\n> (I wouldn't see the necessity though.)\n\nYes, I saw that the other functions didn't use prototypes and I agree  \nthat consistency would be a good thing. I liked the idea of it in  \nthis case because it makes explicit the fact that the function takes  \ntwo params plus a third, optional one. So definitely not necessary,  \nbut a preference of mine. In any case, a change to all the other  \nfunctions is a question for a separate patch.\n\n> And the common way of getting the arguments is reading @_ (see all\n> other subs in the file).  So maybe instead write:\n>\n> [...]\n> sub print_ansi_color {\n> \tmy ($color, $string, $trailer) = @_;\n> [...]\n\nYes, I actually did write it that way first but then my doubts about  \nPerl made me write it the longer way; but if they are equivalent then  \nI prefer the shorter way.\n\n>> +    if ($use_color) {\n>> +        printf '%s%s%s', Term::ANSIColor::color($color), $string,\n>> +            Term::ANSIColor::color('clear');\n>> +    } else {\n>\n> Why use printf when you could directly use print here?  It's only\n> used for concatenating.\n\nTrue. I had may brain in the C-world.\n\n>> +    if ($trailer) {\n>> +        print $trailer;\n>> +    }\n>\n> This will fail to print $trailer when $trailer happens to be a\n> string that evaluates to false in bool context, like '0'.  Write\n> this as:\n>\n> \tif (defined $trailer) {\n> \t    print $trailer;\n> \t}\n\nAgain, I actually wrote it that way the first time, and then changed  \nit, this time because I thought they were the same. Like I said, not  \na perl hacker.\n\n> IMHO, parsing the output of 'git diff-files --color' is a very bad\n> idea and it makes all regexes uglier and more difficult to read.\n> You're much better off recolorizing it yourself, which makes it a\n> more localized change.\n\nYou're probably right, although it is also duplicating the work  \nthat's already done elsewhere. In general I favor making the simplest  \nchange that would work, and tweaking a few of the regexes did look  \nsimpler than re-implementing the colorization logic.\n\nBut the approach you suggest might be more robust, perhaps, seeing as  \nthere's not much to the diff output. As far as I can tell there are  \nreally only five or six different things to look for, and they'd be  \nfairly easy to catch:\n\n- lines beginning with \"@@ \" (hunk headers)\n\n- lines beginning with \"+\" (insertions)\n\n- lines beginning with \"-\" (deletions)\n\n- lines beginning with \" \" (context lines, no color)\n\n- lines beginning with \"\\\" (things like \"\\ No newline at end of  \nfile\", again, no color)\n\n- everything else; ie. the diff header stuff (eg \"diff --git a/foo b/ \nfoo\")\n\nThe only special cases seem to be the \"+++\" and \"---\" lines in the  \nheader, which look like insertions and deletions when they're not.\n\nTrickier would be the highlighting of dubious whitespace, and that's  \nwhen it starts to sound like re-inventing the wheel and duplicating  \nthe logic for the detection that's defined elsewhere (possibly in  \ndiff-lib.c? haven't found the exact spot yet).\n\n> Especially, I don't think that you have\n> any guarantee that escape sequences won't ever contain the\n> characters '+', '-' or ' ' (space)\n\nYes, that was one of the things I didn't like about the sloppy  \nregexes. I couldn't really make them any stricter though because I  \nwasn't confident about the range of possible characters that might be  \nincluded in the escape sequences.\n\n> Finally -- and this might be just my eyes -- blue is a very nice\n> color, but it looks a bit too dark on black background.  Maybe\n> choose a default color that looks reasonable on black *and* white\n> background.\n\nYeah, well I didn't choose the colours and I didn't really want to  \nget into it. Before being considered for inclusion a patch like this  \nwould need to tap in to the existing config settings for color.diff  \nand color.diff.<slot> anyway...\n\nWincent\n"},{"id":"55616","messageId":"20071013172745.GA2624@coredump.intra.peff.net","threadId":"10263","inReplyTo":"19271E58-5C4F-41AF-8F9D-F114F36A34AC@wincent.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-13T17:27:45Z","receivedAt":"2007-10-13T17:27:45Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Oct 13, 2007 at 04:45:41PM +0200, Wincent Colaiuta wrote:\n\n> - as Johannes pointed out, \"clear\" and \"reset\" are not used consistently \n> even though the Term::ANSIColor documentation says that they're the same, so \n> settled on \"clear\"; although in any case, the changes to the \n> print_ansi_color function mean that it is now the only site where clearing \n> takes place\n\nPlease use \"reset\", as that is the term used by the C color code.\n\n> - changed the regex as suggested by Johannes, and a couple of others that \n> are used when splitting hunks\n\nI believe there are other places where the diff output is parsed, and\nthe colors will mess that up, too (e.g., split_hunk). All of those\nregexes need to be changed, too. I am a bit concerned that we are\nputting intimate knowledge of the colorization scheme here. As much as\nit pains me to have two diff colorizers, I wonder if that would be a\nbetter solution than having a diff colorizer, and a colorized diff\nparser.\n\n-Peff\n"},{"id":"55619","messageId":"20071013175127.GA3183@coredump.intra.peff.net","threadId":"10263","inReplyTo":"20071013172745.GA2624@coredump.intra.peff.net","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-13T17:51:27Z","receivedAt":"2007-10-13T17:51:27Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Oct 13, 2007 at 01:27:45PM -0400, Jeff King wrote:\n\n> I believe there are other places where the diff output is parsed, and\n> the colors will mess that up, too (e.g., split_hunk). All of those\n\nOops, I see you actually dealt with those already (I just responded to\nyour cover letter first). Though I am still concerned about the\nrobustness of the re-parsing scheme.\n\n-Peff\n"},{"id":"55621","messageId":"47110EF6.7090108@op5.se","threadId":"10263","inReplyTo":"4710F47D.2070306@gmx.ch","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2007-10-13T18:31:18Z","receivedAt":"2007-10-13T18:31:18Z","isPatch":true,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Jean-Luc Herren wrote:\n> Hi!\n> \n> I really like the idea of colorizing git add -i, especially the\n> prompt.  Here are my two cents.\n> \n> Wincent Colaiuta wrote:\n>> +sub print_ansi_color($$;$) {\n>> +    my $color = shift;\n>> +    my $string = shift;\n>> +    my $trailer = shift;\n> \n> None of the other subs in this file have a prototype, so for\n> consistency I'd suggest to not add it on this function either.\n> However maybe a patch that adds it to all subs would be welcome.\n> (I wouldn't see the necessity though.)\n> \n> And the common way of getting the arguments is reading @_ (see all\n> other subs in the file).  So maybe instead write:\n> \n> [...]\n> sub print_ansi_color {\n> \tmy ($color, $string, $trailer) = @_;\n> [...]\n> \n>> +    if ($use_color) {\n>> +        printf '%s%s%s', Term::ANSIColor::color($color), $string,\n>> +            Term::ANSIColor::color('clear');\n>> +    } else {\n> \n> Why use printf when you could directly use print here?  It's only\n> used for concatenating.\n> \n>> +    if ($trailer) {\n>> +        print $trailer;\n>> +    }\n> \n> This will fail to print $trailer when $trailer happens to be a\n> string that evaluates to false in bool context, like '0'.  Write\n> this as:\n> \n> \tif (defined $trailer) {\n> \t    print $trailer;\n> \t}\n> \n> IMHO, parsing the output of 'git diff-files --color' is a very bad\n> idea and it makes all regexes uglier and more difficult to read.\n> You're much better off recolorizing it yourself, which makes it a\n> more localized change.  Especially, I don't think that you have\n> any guarantee that escape sequences won't ever contain the\n> characters '+', '-' or ' ' (space), which would break your code on\n> lines like this:\n> \n>> +        if ($line =~ /^[^-+ ]*\\+/) { \n> \n> Finally -- and this might be just my eyes -- blue is a very nice\n> color, but it looks a bit too dark on black background.  Maybe\n> choose a default color that looks reasonable on black *and* white\n> background.\n> \n\nRed for removed and green for added seems to be the standard, although\nI know it makes life terribly difficult for red-green colorblind people,\nwho usually prefer yellow/lightblue for black bg, or beige/blue for\nwhite background.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"55625","messageId":"47112491.8070309@gmail.com","threadId":"10263","inReplyTo":"20071013175127.GA3183@coredump.intra.peff.net","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-10-13T20:03:29Z","receivedAt":"2007-10-13T20:03:29Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"Jeff King wrote:\n> On Sat, Oct 13, 2007 at 01:27:45PM -0400, Jeff King wrote:\n> \n> <snip> Though I am still concerned about the\n> robustness of the re-parsing scheme.\n> \n> -Peff\n> \n\nThe importance of the diff coloring pales in comparison to the prompt \ncoloring. Diff coloring is useful, but prompt coloring is a basic \nusability concern (if people can't easily tell where a hunk begins, the \ntool becomes annoying). Perhaps we could split this into two patches, \nmerging the first after a few small changes can be taken care of, while \nthe second may need more discussion and testing. The coloring of the \nprompts is relatively low risk. It just needs to be modified to take \ncolor settings from .git/config. I was thinking that this might be the \nexample that I would take settings from:\n\n[color]\n         add-interactive = auto\n[color \"add-interactive\"]\n         prompt = bold blue\n         header = bold\n         help = blue\n\nFor the sake of a unified interface, the \"Stage this hunk?\" prompt \nshould be colored the same as the other prompts. I will give a bit of \nthought to the default colors, though it's important to avoid red and \ngreen (as those will look like diff output when the second patch is \napplied).\n\nAlso needed is some command line parsing so that \"--color\" can be \nspecified on the command line (very small change), and all of this \nshould be added to the documentation.\n\nObviously, the suggestions/fixes from other parts of this thread must be \ntaken into account, as well. I can probably do all this tomorrow (and \nsend low-risk/high-risk patches), unless someone takes it before me.\n\nDan\n"},{"id":"55641","messageId":"1192306873.6103.14.camel@athena","threadId":"10263","inReplyTo":"471045DA.5050902@gmail.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Tom Tobin","fromEmail":"korpios@gmail.com","sentAt":"2007-10-13T20:21:13Z","receivedAt":"2007-10-13T20:21:13Z","isPatch":true,"sender":{"key":"korpios@gmail.com","avatar":null},"body":"On Fri, 2007-10-12 at 23:13 -0500, Dan Zwell wrote:\n> Recently there was some talk of color for git-add--interactive, but the \n> person who said he already had a patch didn't produce it.\n\nMeh, I really need to start posting the stuff I've hacked into git.\nFirst the git-stash changes, now this.  Sigh.  ^_^\n\nI have a variant of git-add--interactive that properly adds coloration\nto diffs, taking the config file values already set for the color.diff\nkey and colorizing the unadorned diffs internally (rather than expecting\nthe output of git-diff/git-diff-files to be colorized).\n\nGive me a couple of hours (still setting up my Macbook after repaving it\nand installing Ubuntu) and I'll post what I've got for others to tear\napart and point out where I screwed up.  ;)\n"},{"id":"55642","messageId":"1192307206.6103.18.camel@athena","threadId":"10263","inReplyTo":"1192306873.6103.14.camel@athena","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Tom Tobin","fromEmail":"korpios@gmail.com","sentAt":"2007-10-13T20:26:46Z","receivedAt":"2007-10-13T20:26:46Z","isPatch":true,"sender":{"key":"korpios@gmail.com","avatar":null},"body":"On Sat, 2007-10-13 at 15:21 -0500, Tom Tobin wrote:\n> Meh, I really need to start posting the stuff I've hacked into git.\n> First the git-stash changes, now this.  Sigh.  ^_^\n> \n> I have a variant of git-add--interactive that properly adds coloration\n> to diffs, taking the config file values already set for the color.diff\n> key and colorizing the unadorned diffs internally (rather than expecting\n> the output of git-diff/git-diff-files to be colorized).\n> \n> Give me a couple of hours (still setting up my Macbook after repaving it\n> and installing Ubuntu) and I'll post what I've got for others to tear\n> apart and point out where I screwed up.  ;)\n\n... and now Evolution is screwing up my From: address (it should be\n\"korpios@korpios.com\"; probably since I'm routing everything through\nGoogle Apps).  Ah well, one more thing to fix first....\n"},{"id":"55645","messageId":"8DDFBF9A-2C68-404B-843C-BE63C52F0DAF@wincent.com","threadId":"10263","inReplyTo":"47112491.8070309@gmail.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Wincent Colaiuta","fromEmail":"win@wincent.com","sentAt":"2007-10-13T20:36:55Z","receivedAt":"2007-10-13T20:36:55Z","isPatch":true,"sender":{"key":"greg@hurrell.net","avatar":"https://avatars.githubusercontent.com/u/7074?v=4"},"body":"El 13/10/2007, a las 22:03, Dan Zwell escribió:\n\n> The importance of the diff coloring pales in comparison to the  \n> prompt coloring. Diff coloring is useful, but prompt coloring is a  \n> basic usability concern (if people can't easily tell where a hunk  \n> begins, the tool becomes annoying). Perhaps we could split this  \n> into two patches, merging the first after a few small changes can  \n> be taken care of, while the second may need more discussion and  \n> testing. The coloring of the prompts is relatively low risk. It  \n> just needs to be modified to take color settings from .git/config.  \n> I was thinking that this might be the example that I would take  \n> settings from:\n>\n> [color]\n>         add-interactive = auto\n> [color \"add-interactive\"]\n>         prompt = bold blue\n>         header = bold\n>         help = blue\n\nOr could you just piggy-back on the settings for color.diff.<slot>?\n\nAnd if a separate group for git-add is necessary, perhaps \"add\" would  \nbe enough, rather than \"add-interactive\".\n\nWincent\n"},{"id":"55649","messageId":"cff973550710131450r3b54a328k8db97488f4b50e2a@mail.gmail.com","threadId":"10263","inReplyTo":"8DDFBF9A-2C68-404B-843C-BE63C52F0DAF@wincent.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Dan Z","fromEmail":"dzwell@gmail.com","sentAt":"2007-10-13T21:50:35Z","receivedAt":"2007-10-13T21:50:35Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"On 10/13/07, Wincent Colaiuta <win@wincent.com> wrote:\n> Or could you just piggy-back on the settings for color.diff.<slot>?\n>\n> And if a separate group for git-add is necessary, perhaps \"add\" would\n> be enough, rather than \"add-interactive\".\n>\n> Wincent\n>\n\nI think color.add is better, because git-add--interactive goes beyond\ncoloring diffs. When this is complete, it should probably use\ncolor.diff.<slot> for the actual diff output, and color.add.<slot> for\ncolored prompts/commands.\n\nDan\n"},{"id":"55651","messageId":"47114550.6070505@gmx.ch","threadId":"10263","inReplyTo":"cff973550710131450r3b54a328k8db97488f4b50e2a@mail.gmail.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Jean-Luc Herren","fromEmail":"jlh@gmx.ch","sentAt":"2007-10-13T22:23:12Z","receivedAt":"2007-10-13T22:23:12Z","isPatch":true,"sender":{"key":"jlh@gmx.ch","avatar":null},"body":"Dan Z wrote:\n> I think color.add is better, because git-add--interactive goes beyond\n> coloring diffs. When this is complete, it should probably use\n> color.diff.<slot> for the actual diff output, and color.add.<slot> for\n> colored prompts/commands.\n\nOr maybe rather color.interactive.<slot>, where <slot> could be\n'prompt', 'header', etc.  It's better to give it a name that\ndescribes what it is for, instead of one that describes which tool\nuses it.  This way it could possibly be used for other potential\ninteractive tools in the future.\n\njlh\n"},{"id":"55807","messageId":"20071015034338.GA4844@coredump.intra.peff.net","threadId":"10263","inReplyTo":"47112491.8070309@gmail.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-15T03:43:39Z","receivedAt":"2007-10-15T03:43:39Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Oct 13, 2007 at 03:03:29PM -0500, Dan Zwell wrote:\n\n> The importance of the diff coloring pales in comparison to the prompt \n> coloring. Diff coloring is useful, but prompt coloring is a basic usability \n> concern (if people can't easily tell where a hunk begins, the tool becomes \n> annoying). Perhaps we could split this into two patches, merging the first \n> after a few small changes can be taken care of, while the second may need \n\nYes, I think it is worth splitting into two patches, here. There seems\nto be orthogonal discussion on (colorizing and configuration of prompts versus\nhow to handle colorized diffs).\n\n-Peff\n"},{"id":"55809","messageId":"20071015041202.GA5939@coredump.intra.peff.net","threadId":"10263","inReplyTo":"19271E58-5C4F-41AF-8F9D-F114F36A34AC@wincent.com","subject":"Re: [PATCH] Color support added to git-add--interactive.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-15T04:12:02Z","receivedAt":"2007-10-15T04:12:02Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Oct 13, 2007 at 04:45:41PM +0200, Wincent Colaiuta wrote:\n\n> - changed the regex as suggested by Johannes, and a couple of others\n> that are used when splitting hunks\n\nBTW, this approach is totally bogus. The hunks that we store end up\ngetting fed back to git-apply when we stage them (which doesn't\nunderstand the color codes).\n\nJust try using your patch to actually stage a hunk; nothing happens (and\nthe error is almost impossible to see, since we show the bogus diff on\nstderr).\n\nSo now I am doubly convinced that colorizing the diffs in\nadd--interactive is the right thing (and it looks like Tom Tobin has\nalready done a fair bit of the work).\n\n-Peff\n"},{"id":"56163","messageId":"20071016194709.3c1cb3a8@danzwell.com","threadId":"10263","inReplyTo":"20071015034338.GA4844@coredump.intra.peff.net","subject":"Re: revised: [PATCH] Color support added to git-add--interactive.","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-10-17T00:47:09Z","receivedAt":"2007-10-17T00:47:09Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"Adds color to the prompts and output of git-add--interactive.\n\n-Reads config color.interactive, respects \"auto\", \"true\",\n\"always\", and anything else.\n-Uses the library Term::ANSIColor, which is included with modern\n versions of perl. This is optional, and should not need to be\n present if color.interactive is not on.\n-Reads color.interactive.<slot>, where slot is \"header\", \"prompt\",\n or \"help\", colorizing output accordingly.\n\nDocumentation/config.txt is updated to reflect the new keys.\nI cannot test this or see how it looks in manpages, however,\nas I cannot install the documentation build tools.\n\nUnfortunately, I think the default colors are ugly, but all colors that\nare readable on both black and white backgrounds are probably ugly.\n\nThis patch does not colorize the diffs, because that is a larger\njob, and very distinct from this (simple) task.\n\nDan\n\ngzipped patch is also attached, just in case.\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 971fd9f..17e29e4 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -381,6 +381,27 @@ color.diff.<slot>::\n \twhitespace).  The values of these variables may be specified as\n \tin color.branch.<slot>.\n\n+color.interactive::\n+\tWhen true (or `always`), always use colors in add--interactive.\n+\tWhen false (or `never`), never.  When set to `auto`, use\n+\tcolors only when the output is to the terminal. Defaults to\n+        false.\n+\n+color.interactive.<slot>::\n+        Use customized color for add--interactive output. `<slot>`\n+        may be `prompt`, `header`, or `help`, for three distinct types\n+        of common output from interactive programs. The values may be a\n+        space-delimited combination of up to three of the following:\n++\n+(optional attribute, optional foreground color, and optional\nbackground) ++\n+dark, bold, underline, underscore, blink, reverse, concealed,\n+black, red, green, yellow, blue, magenta, cyan, white, on_black,\n+on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white\n++\n+Note: these are not the same colors/attributes that the\n+rest of git supports, but are specific to git-add--interactive.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex be68814..125655b 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -2,6 +2,33 @@\n\n use strict;\n\n+my ($use_color, $prompt_color, $header_color, $help_color);\n+my $color_config = qx(git config --get color.interactive);\n+if ($color_config=~/true|always/ || -t STDOUT &&\n$color_config=~/auto/) {\n+\t$use_color = \"true\";\n+\tchomp( $prompt_color = qx(git config --get\ncolor.interactive.prompt) );\n+\tchomp( $header_color = qx(git config --get\ncolor.interactive.header) );\n+\tchomp( $help_color = qx(git config --get\ncolor.interactive.help) );\n+\t$prompt_color ||= \"red bold\";\n+\t$header_color ||= \"bold\";\n+\t$help_color ||= \"blue bold\";\n+\n+\trequire Term::ANSIColor;\n+}\n+\n+sub print_colored {\n+\tmy $color = shift;\n+\tmy @strings = @_;\n+\n+\tif ($use_color) {\n+\t\tprint Term::ANSIColor::color($color);\n+\t\tprint(@strings);\n+\t\tprint Term::ANSIColor::color(\"reset\");\n+\t} else {\n+\t\tprint @strings;\n+\t}\n+}\n+\n sub run_cmd_pipe {\n \tif ($^O eq 'MSWin32') {\n \t\tmy @invalid = grep {m/[\":*]/} @_;\n@@ -175,7 +202,7 @@ sub list_and_choose {\n \t\t\tif (!$opts->{LIST_FLAT}) {\n \t\t\t\tprint \"     \";\n \t\t\t}\n-\t\t\tprint \"$opts->{HEADER}\\n\";\n+\t\t\tprint_colored $header_color,\n\"$opts->{HEADER}\\n\"; }\n \t\tfor ($i = 0; $i < @stuff; $i++) {\n \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n@@ -205,7 +232,7 @@ sub list_and_choose {\n\n \t\treturn if ($opts->{LIST_ONLY});\n\n-\t\tprint $opts->{PROMPT};\n+\t\tprint_colored $prompt_color, $opts->{PROMPT};\n \t\tif ($opts->{SINGLETON}) {\n \t\t\tprint \"> \";\n \t\t}\n@@ -544,7 +571,7 @@ sub coalesce_overlapping_hunks {\n }\n\n sub help_patch_cmd {\n-\tprint <<\\EOF ;\n+\tprint_colored $help_color, <<\\EOF ;\n y - stage this hunk\n n - do not stage this hunk\n a - stage this and all the remaining hunks\n@@ -619,7 +646,7 @@ sub patch_update_cmd {\n \t\tfor (@{$hunk[$ix]{TEXT}}) {\n \t\t\tprint;\n \t\t}\n-\t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n+\t\tprint_colored $prompt_color, \"Stage this hunk\n[y/n/a/d$other/?]? \"; my $line = <STDIN>;\n \t\tif ($line) {\n \t\t\tif ($line =~ /^y/i) {\n@@ -673,7 +700,7 @@ sub patch_update_cmd {\n \t\t\telsif ($other =~ /s/ && $line =~ /^s/) {\n \t\t\t\tmy @split =\nsplit_hunk($hunk[$ix]{TEXT}); if (1 < @split) {\n-\t\t\t\t\tprint \"Split into \",\n+\t\t\t\t\tprint_colored \"$header_color\",\n\"Split into \", scalar(@split), \" hunks.\\n\";\n \t\t\t\t}\n \t\t\t\tsplice(@hunk, $ix, 1,\n@@ -769,7 +796,7 @@ sub quit_cmd {\n }\n\n sub help_cmd {\n-\tprint <<\\EOF ;\n+\tprint_colored $help_color, <<\\EOF ;\n status        - show paths with changes\n update        - add working tree state to the staged set of changes\n revert        - revert staged set of changes back to the HEAD version\n--\n1.5.3.4.207.gc0ee\n\n"},{"id":"56174","messageId":"20071017015152.GN13801@spearce.org","threadId":"10263","inReplyTo":"20071016194709.3c1cb3a8@danzwell.com","subject":"Re: revised: [PATCH] Color support added to git-add--interactive.","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-10-17T01:51:52Z","receivedAt":"2007-10-17T01:51:52Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Dan Zwell <dzwell@gmail.com> wrote:\n> Adds color to the prompts and output of git-add--interactive.\n\nI'm probbaly going to publish this in `pu` tonight but I have some\ncomments that I think need to be addressed before this graduates\nany further.\n\nFirst off, no Signed-off-by?  This is big enough that I refuse to\nput it in the main tree without one.  Second it would really have\nhelped if the email was formatted with `git format-patch`.  Copying\nthe message headers and body over for the commit message was less\nthan fun.  I have better things to do with my time.\n \n> +color.interactive.<slot>::\n> +        Use customized color for add--interactive output. `<slot>`\n\nYou probably should talk about `git add --interactive` as that\nis what the git-add documentation calls it.  Many end-users don't\neven know that `git add -i` is exec()'ing into another program to\naccomplish its task.  I fixed this up when I applied the patch.\n\n> +Note: these are not the same colors/attributes that the\n> +rest of git supports, but are specific to git-add--interactive.\n\nThis is a problem in my opinion.  Why can't it match the same\nnames that the C code recognizes?  What if we one day were to\nsee git-add--interactive.perl converted to C?  How would we then\nreconcile the color handling at that point in time?\n\n-- \nShawn.\n"},{"id":"56220","messageId":"cff973550710170057i7a09eff6m5bd8268498774238@mail.gmail.com","threadId":"10263","inReplyTo":"20071017015152.GN13801@spearce.org","subject":"Re: revised: [PATCH] Color support added to git-add--interactive.","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-10-17T07:57:46Z","receivedAt":"2007-10-17T07:57:46Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"On 10/16/07, Shawn O. Pearce <spearce@spearce.org> wrote:\n> Dan Zwell <dzwell@gmail.com> wrote:\n> > Adds color to the prompts and output of git-add--interactive.\n>\n> I'm probbaly going to publish this in `pu` tonight but I have some\n> comments that I think need to be addressed before this graduates\n> any further.\n>\n> First off, no Signed-off-by?  This is big enough that I refuse to\n> put it in the main tree without one.  Second it would really have\n> helped if the email was formatted with `git format-patch`.  Copying\n> the message headers and body over for the commit message was less\n> than fun.  I have better things to do with my time.\n\nSorry, that I didn't read the document on submitting patches before\nthis. I will make the other changes you mention and re-send this in\nthe proper formatting.\n\n>\n> > +color.interactive.<slot>::\n> > +        Use customized color for add--interactive output. `<slot>`\n>\n> You probably should talk about `git add --interactive` as that\n> is what the git-add documentation calls it.  Many end-users don't\n> even know that `git add -i` is exec()'ing into another program to\n> accomplish its task.  I fixed this up when I applied the patch.\n>\n> > +Note: these are not the same colors/attributes that the\n> > +rest of git supports, but are specific to git-add--interactive.\n>\n> This is a problem in my opinion.  Why can't it match the same\n> names that the C code recognizes?  What if we one day were to\n> see git-add--interactive.perl converted to C?  How would we then\n> reconcile the color handling at that point in time?\nMakes sense. I am adding a bit of code to parse git color strings into\nperl color strings (so the user can use the same color names as with\nthe rest of git). I know this is a small change, but I'm learning perl\nas I go, and I have exams this week, so it will take at least a day or\ntwo. I will fix the color issue, and send a properly formatted and\nsigned-off patch. (Yes, I do agree to the Developer's Certificate of\nOrigin wrt to this patch.)\n\nThanks for your patience,\nDan\n\n>\n> --\n> Shawn.\n>\n"},{"id":"56221","messageId":"20071017081128.GC13801@spearce.org","threadId":"10263","inReplyTo":"cff973550710170057i7a09eff6m5bd8268498774238@mail.gmail.com","subject":"Re: revised: [PATCH] Color support added to git-add--interactive.","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-10-17T08:11:28Z","receivedAt":"2007-10-17T08:11:28Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Dan Zwell <dzwell@gmail.com> wrote:\n> Sorry, that I didn't read the document on submitting patches before\n> this. I will make the other changes you mention and re-send this in\n> the proper formatting.\n\nI really should have pointed you to Documentation/SubmittingPatches\nwhen I responded to your email in the first place.  Sorry I didn't\ndo that.  Looks like you already found it though so good.\n \n> > > +Note: these are not the same colors/attributes that the\n> > > +rest of git supports, but are specific to git-add--interactive.\n> >\n> > This is a problem in my opinion.  Why can't it match the same\n> > names that the C code recognizes?  What if we one day were to\n> > see git-add--interactive.perl converted to C?  How would we then\n> > reconcile the color handling at that point in time?\n> \n> Makes sense. I am adding a bit of code to parse git color strings into\n> perl color strings (so the user can use the same color names as with\n> the rest of git). I know this is a small change, but I'm learning perl\n> as I go, and I have exams this week, so it will take at least a day or\n> two. I will fix the color issue, and send a properly formatted and\n> signed-off patch. (Yes, I do agree to the Developer's Certificate of\n> Origin wrt to this patch.)\n> \n> Thanks for your patience,\n\nThanks for working on this.  I played around with your patch tonight\nand although I use git-gui more often than `git add -i` for hunk\nmanipulation I really preferred your colorized version of git-add\n-i over the non-colorized one.  So I'm looking forward to seeing\nthe final result of this and getting it into the main tree.\n\nOf course there is also no rush to getting your change in.  We don't\nhave any sort of release deadlines.  So don't stress out about it\ntoo much.  :)\n\n-- \nShawn.\n"},{"id":"56922","messageId":"20071022163244.4af72973@danzwell.com","threadId":"10263","inReplyTo":"20071017015152.GN13801@spearce.org","subject":"[PATCH 1/2] Added basic color support to git add --interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-10-22T21:32:44Z","receivedAt":"2007-10-22T21:32:44Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Added function \"print_colored\" that prints text with a color that\nis passed in. Converted many calls to \"print\" to being calls to\n\"print_colored\".\n\nThe prompt, the header, and the help output are the 3 types of\ncolorized output, and each has its own color.\n\nColorization is done through Term::ANSIColor, which is included\nwith modern versions of perl. This is optional, and should not\nneed to be present if color.interactive is not turned on.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\n Documentation/config.txt  |    6 ++++++\n git-add--interactive.perl |   37 +++++++++++++++++++++++++++++++------\n 2 files changed, 37 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 971fd9f..c795a35 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -381,6 +381,12 @@ color.diff.<slot>::\n \twhitespace).  The values of these variables may be specified as\n \tin color.branch.<slot>.\n \n+color.interactive::\n+\tWhen true (or `always`), always use colors in `git add\n+\t--interactive`.  When false (or `never`), never.  When set to\n+\t`auto`, use colors only when the output is to the\n+\tterminal. Defaults to false.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex be68814..c66ed4d 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -2,6 +2,31 @@\n \n use strict;\n \n+my ($use_color, $prompt_color, $header_color, $help_color);\n+my $color_config = qx(git config --get color.interactive);\n+if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n+\t$use_color = \"true\";\n+        # Sane (visible) defaults:\n+        $prompt_color = \"blue bold\";\n+        $header_color = \"bold\";\n+        $help_color = \"red bold\";\n+\n+\trequire Term::ANSIColor;\n+}\n+\n+sub print_colored {\n+\tmy $color = shift;\n+\tmy @strings = @_;\n+\n+\tif ($use_color) {\n+\t\tprint Term::ANSIColor::color($color);\n+\t\tprint(@strings);\n+\t\tprint Term::ANSIColor::color(\"reset\");\n+\t} else {\n+\t\tprint @strings;\n+\t}\n+}\n+\n sub run_cmd_pipe {\n \tif ($^O eq 'MSWin32') {\n \t\tmy @invalid = grep {m/[\":*]/} @_;\n@@ -175,7 +200,7 @@ sub list_and_choose {\n \t\t\tif (!$opts->{LIST_FLAT}) {\n \t\t\t\tprint \"     \";\n \t\t\t}\n-\t\t\tprint \"$opts->{HEADER}\\n\";\n+\t\t\tprint_colored $header_color, \"$opts->{HEADER}\\n\";\n \t\t}\n \t\tfor ($i = 0; $i < @stuff; $i++) {\n \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n@@ -205,7 +230,7 @@ sub list_and_choose {\n \n \t\treturn if ($opts->{LIST_ONLY});\n \n-\t\tprint $opts->{PROMPT};\n+\t\tprint_colored $prompt_color, $opts->{PROMPT};\n \t\tif ($opts->{SINGLETON}) {\n \t\t\tprint \"> \";\n \t\t}\n@@ -544,7 +569,7 @@ sub coalesce_overlapping_hunks {\n }\n \n sub help_patch_cmd {\n-\tprint <<\\EOF ;\n+\tprint_colored $help_color, <<\\EOF ;\n y - stage this hunk\n n - do not stage this hunk\n a - stage this and all the remaining hunks\n@@ -619,7 +644,7 @@ sub patch_update_cmd {\n \t\tfor (@{$hunk[$ix]{TEXT}}) {\n \t\t\tprint;\n \t\t}\n-\t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n+\t\tprint_colored $prompt_color, \"Stage this hunk [y/n/a/d$other/?]? \";\n \t\tmy $line = <STDIN>;\n \t\tif ($line) {\n \t\t\tif ($line =~ /^y/i) {\n@@ -673,7 +698,7 @@ sub patch_update_cmd {\n \t\t\telsif ($other =~ /s/ && $line =~ /^s/) {\n \t\t\t\tmy @split = split_hunk($hunk[$ix]{TEXT});\n \t\t\t\tif (1 < @split) {\n-\t\t\t\t\tprint \"Split into \",\n+\t\t\t\t\tprint_colored \"$header_color\", \"Split into \",\n \t\t\t\t\tscalar(@split), \" hunks.\\n\";\n \t\t\t\t}\n \t\t\t\tsplice(@hunk, $ix, 1,\n@@ -769,7 +794,7 @@ sub quit_cmd {\n }\n \n sub help_cmd {\n-\tprint <<\\EOF ;\n+\tprint_colored $help_color, <<\\EOF ;\n status        - show paths with changes\n update        - add working tree state to the staged set of changes\n revert        - revert staged set of changes back to the HEAD version\n-- \n1.5.3.4.207.gc0ee\n"},{"id":"56923","messageId":"20071022164048.71a3dceb@danzwell.com","threadId":"10263","inReplyTo":"20071017015152.GN13801@spearce.org","subject":"[PATCH 2/2] Let git-add--interactive read colors from git-config","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-10-22T21:40:48Z","receivedAt":"2007-10-22T21:40:48Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Colors are specified in color.interactive.{prompt,header,help}.\nThey are specified as git color strings as described in the\ndocumentation, then parsed into perl color strings (slightly\ndifferent). Ugly but visible defaults are still used.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\nNote: the code to parse git-style color strings to perl-style color\nstrings should eventually be added to Git.pm so that other (perl)\nparts of git can be configured to read colors from .gitconfig in\na nicer way. A git-style string is \"ul red black\", while perl \nlikes strings like \"underline red on_black\".\n\n Documentation/config.txt  |    7 ++++\n git-add--interactive.perl |   76\n++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 79\ninsertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex c795a35..75a976a 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -387,6 +387,13 @@ color.interactive::\n \t`auto`, use colors only when the output is to the\n \tterminal. Defaults to false.\n \n+color.interactive.<slot>::\n+\tUse customized color for `git add --interactive`\n+\toutput. `<slot>` may be `prompt`, `header`, or `help`, for\n+\tthree distinct types of normal output from interactive\n+\tprograms.  The values of these variables may be specified as\n+\tin color.branch.<slot>.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex c66ed4d..d85ec92 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -6,10 +6,78 @@ my ($use_color, $prompt_color, $header_color, $help_color);\n my $color_config = qx(git config --get color.interactive);\n if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n \t$use_color = \"true\";\n-        # Sane (visible) defaults:\n-        $prompt_color = \"blue bold\";\n-        $header_color = \"bold\";\n-        $help_color = \"red bold\";\n+\t# Grab the 3 main colors in git color string format:\n+\tmy @git_prompt_color =\n+\t\tsplit(/\\s+/, qx(git config --get color.interactive.prompt));\n+\tmy @git_header_color =\n+\t\tsplit(/\\s+/, qx(git config --get color.interactive.header));\n+\tmy @git_help_color =\n+\t\tsplit(/\\s+/, qx(git config --get color.interactive.help));\n+\n+\t# Sane (visible) defaults:\n+\tif (! @git_prompt_color) {\n+\t\t@git_prompt_color = (\"blue\", \"bold\");\n+\t}\n+\tif (! @git_header_color) {\n+\t\t@git_header_color = (\"bold\");\n+\t}\n+\tif (! @git_help_color) {\n+\t\t@git_help_color = (\"red\", \"bold\");\n+\t}\n+\n+\t# Parse the git colors into perl colors:\n+\tmy %attrib_mappings = (\n+\t\t\"bold\"    => \"bold\",\n+\t\t\"ul\"      => \"underline\",\n+\t\t\"blink\"   => \"blink\",\n+\t\t# not supported:\n+\t\t#\"dim\"     => \"\",\n+\t\t\"reverse\" => \"reverse\"\n+\t);\n+\n+\tmy @tmp_perl_colors;\n+\tmy $color_list;\n+\t# Loop over the array of (arrays of) git-style colors\n+\tforeach $color_list ([@git_prompt_color], [@git_header_color],\n+\t                     [@git_help_color]) {\n+\t\tmy $fg_done;\n+\t\tmy @perl_attribs;\n+\t\tmy $word;\n+\t\tforeach $word (@{$color_list}) {\n+\t\t\tif ($word =~ /normal/) {\n+\t\t\t\t$fg_done = \"true\";\n+\t\t\t}\n+\t\t\telsif ($word =~ /black|red|green|yellow/ ||\n+\t\t\t       $word =~ /blue|magenta|cyan|white/) {\n+\t\t\t\t# is a color.\n+\t\t\t\tif ($fg_done) {\n+\t\t\t\t\t# this is the background\n+\t\t\t\t\tpush @perl_attribs, \"on_\" . $word;\n+\t\t\t\t}\n+\t\t\t\telse {\n+\t\t\t\t\t# this is foreground\n+\t\t\t\t\t$fg_done = \"true\";\n+\t\t\t\t\tpush @perl_attribs, $word;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\t# this is an attribute, not a color.\n+\t\t\t\tif ($attrib_mappings{$word}) {\n+\t\t\t\t\tpush(@perl_attribs,\n+\t\t\t\t\t\t $attrib_mappings{$word});\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t\tif (@perl_attribs) {\n+\t\t\tpush @tmp_perl_colors, join(\" \", @perl_attribs);\n+\t\t}\n+\t\telse {\n+\t\t\t#@perl_attribs is empty, need a placeholder\n+\t\t\tpush @tmp_perl_colors, \"reset\";\n+\t\t}\n+\t}\n+\t($prompt_color, $header_color, $help_color) =\n+\t\t@tmp_perl_colors;\n \n \trequire Term::ANSIColor;\n }\n-- \n1.5.3.4.207.gc0ee\n"},{"id":"56940","messageId":"20071022211114.07c927e8@danzwell.com","threadId":"10263","inReplyTo":"20071022163244.4af72973@danzwell.com","subject":"Re: [PATCH] resend of git-add--interactive color patch against spearce/pu","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-10-23T02:11:14Z","receivedAt":"2007-10-23T02:11:14Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"I apparently missed the e-mail where Shawn Pearce explained where his\nrepository was. The following patch is my recent change(s), rebased\nagainst that.\n\nDan\n"},{"id":"56941","messageId":"20071022211958.045895ac@danzwell.com","threadId":"10263","inReplyTo":"20071022163244.4af72973@danzwell.com","subject":"[PATCH] Let git-add--interactive read \"git colors\" from git-config","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-10-23T02:19:58Z","receivedAt":"2007-10-23T02:19:58Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Colors are specified in color.interactive.{prompt,header,help}.\nThey are specified as git color strings as described in the\ndocumentation, then parsed into perl color strings (slightly\ndifferent). Ugly but visible defaults are still used.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\nThis patch is againts Shawn Pearce's \"pu\" branch.\n Documentation/config.txt  |   17 ++-------\n git-add--interactive.perl |   78 +++++++++++++++++++++++++++++++++++++++++---\n 2 files changed, 76 insertions(+), 19 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 99b3817..d06f55f 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -390,19 +390,10 @@ color.interactive::\n \n color.interactive.<slot>::\n \tUse customized color for `git add --interactive`\n-\toutput. `<slot>` may be `prompt`, `header`, or `help`,\n-\tfor three distinct types of common output from interactive\n-\tprograms. The values may be a space-delimited combination\n-\tof up to three of the following:\n-+\n-(optional attribute, optional foreground color, and optional background)\n-+\n-dark, bold, underline, underscore, blink, reverse, concealed,\n-black, red, green, yellow, blue, magenta, cyan, white, on_black,\n-on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white\n-+\n-Note these are not the same colors/attributes that the rest of\n-git supports, but are specific to `git-add --interactive`.\n+\toutput. `<slot>` may be `prompt`, `header`, or `help`, for\n+\tthree distinct types of normal output from interactive\n+\tprograms.  The values of these variables may be specified as\n+\tin color.branch.<slot>.\n \n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 37be4b0..ca1ca28 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -6,12 +6,78 @@ my ($use_color, $prompt_color, $header_color, $help_color);\n my $color_config = qx(git config --get color.interactive);\n if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n \t$use_color = \"true\";\n-\tchomp( $prompt_color = qx(git config --get color.interactive.prompt) );\n-\tchomp( $header_color = qx(git config --get color.interactive.header) );\n-\tchomp( $help_color = qx(git config --get color.interactive.help) );\n-\t$prompt_color ||= \"red bold\";\n-\t$header_color ||= \"bold\";\n-\t$help_color ||= \"blue bold\";\n+\t# Grab the 3 main colors in git color string format:\n+\tmy @git_prompt_color =\n+\t\tsplit(/\\s+/, qx(git config --get color.interactive.prompt));\n+\tmy @git_header_color =\n+\t\tsplit(/\\s+/, qx(git config --get color.interactive.header));\n+\tmy @git_help_color =\n+\t\tsplit(/\\s+/, qx(git config --get color.interactive.help));\n+\n+\t# Sane (visible) defaults:\n+\tif (! @git_prompt_color) {\n+\t\t@git_prompt_color = (\"blue\", \"bold\");\n+\t}\n+\tif (! @git_header_color) {\n+\t\t@git_header_color = (\"bold\");\n+\t}\n+\tif (! @git_help_color) {\n+\t\t@git_help_color = (\"red\", \"bold\");\n+\t}\n+\n+\t# Parse the git colors into perl colors:\n+\tmy %attrib_mappings = (\n+\t\t\"bold\"    => \"bold\",\n+\t\t\"ul\"      => \"underline\",\n+\t\t\"blink\"   => \"blink\",\n+\t\t# not supported:\n+\t\t#\"dim\"     => \"\",\n+\t\t\"reverse\" => \"reverse\"\n+\t);\n+\n+\tmy @tmp_perl_colors;\n+\tmy $color_list;\n+\t# Loop over the array of (arrays of) git-style colors\n+\tforeach $color_list ([@git_prompt_color], [@git_header_color],\n+\t                     [@git_help_color]) {\n+\t\tmy $fg_done;\n+\t\tmy @perl_attribs;\n+\t\tmy $word;\n+\t\tforeach $word (@{$color_list}) {\n+\t\t\tif ($word =~ /normal/) {\n+\t\t\t\t$fg_done = \"true\";\n+\t\t\t}\n+\t\t\telsif ($word =~ /black|red|green|yellow/ ||\n+\t\t\t       $word =~ /blue|magenta|cyan|white/) {\n+\t\t\t\t# is a color.\n+\t\t\t\tif ($fg_done) {\n+\t\t\t\t\t# this is the background\n+\t\t\t\t\tpush @perl_attribs, \"on_\" . $word;\n+\t\t\t\t}\n+\t\t\t\telse {\n+\t\t\t\t\t# this is foreground\n+\t\t\t\t\t$fg_done = \"true\";\n+\t\t\t\t\tpush @perl_attribs, $word;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\t# this is an attribute, not a color.\n+\t\t\t\tif ($attrib_mappings{$word}) {\n+\t\t\t\t\tpush(@perl_attribs,\n+\t\t\t\t\t\t $attrib_mappings{$word});\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t\tif (@perl_attribs) {\n+\t\t\tpush @tmp_perl_colors, join(\" \", @perl_attribs);\n+\t\t}\n+\t\telse {\n+\t\t\t#@perl_attribs is empty, need a placeholder\n+\t\t\tpush @tmp_perl_colors, \"reset\";\n+\t\t}\n+\t}\n+\t($prompt_color, $header_color, $help_color) =\n+\t\t@tmp_perl_colors;\n \n \trequire Term::ANSIColor;\n }\n-- \n1.5.3.4.207.gc0ee\n"},{"id":"56947","messageId":"20071023040315.GA28312@coredump.intra.peff.net","threadId":"10263","inReplyTo":"20071022163244.4af72973@danzwell.com","subject":"Re: [PATCH 1/2] Added basic color support to git add --interactive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-23T04:03:16Z","receivedAt":"2007-10-23T04:03:16Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Oct 22, 2007 at 04:32:44PM -0500, Dan Zwell wrote:\n\n> +my ($use_color, $prompt_color, $header_color, $help_color);\n> +my $color_config = qx(git config --get color.interactive);\n> +if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n> +\t$use_color = \"true\";\n> +        # Sane (visible) defaults:\n> +        $prompt_color = \"blue bold\";\n> +        $header_color = \"bold\";\n> +        $help_color = \"red bold\";\n\nBad indentation?\n\n> +sub print_colored {\n> +\tmy $color = shift;\n> +\tmy @strings = @_;\n> +\n> +\tif ($use_color) {\n> +\t\tprint Term::ANSIColor::color($color);\n> +\t\tprint(@strings);\n> +\t\tprint Term::ANSIColor::color(\"reset\");\n> +\t} else {\n> +\t\tprint @strings;\n> +\t}\n> +}\n\nThis does nothing for embedded newlines in the strings, which means that\nyou can end up with ${COLOR}text\\n${RESET}, which fouls up changed\nbackgrounds. See commit 50f575fc. Since the strings you are printing are\nsmall, I don't see any problem with making a copy, using a regex to\ninsert the color coding, and printing that (I think I even posted\nexample code in a previous thread on this subject).\n\n-Peff\n"},{"id":"56950","messageId":"20071023042702.GB28312@coredump.intra.peff.net","threadId":"10263","inReplyTo":"20071022164048.71a3dceb@danzwell.com","subject":"Re: [PATCH 2/2] Let git-add--interactive read colors from git-config","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-23T04:27:02Z","receivedAt":"2007-10-23T04:27:02Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Oct 22, 2007 at 04:40:48PM -0500, Dan Zwell wrote:\n\n> Note: the code to parse git-style color strings to perl-style color\n> strings should eventually be added to Git.pm so that other (perl)\n> parts of git can be configured to read colors from .gitconfig in\n> a nicer way. A git-style string is \"ul red black\", while perl \n> likes strings like \"underline red on_black\".\n\nWhy not do it as part of this patch, then?\n\n> +\t# Sane (visible) defaults:\n> +\tif (! @git_prompt_color) {\n> +\t\t@git_prompt_color = (\"blue\", \"bold\");\n> +\t}\n\nI think it might be a bit more readable to keep the assignment and\ndefaults together:\n\n  my @git_prompt_color = split /\\s+/,\n    qx(git config --get color.interactive.prompt) || 'blue bold';\n\nThough I wonder why we are splitting here at all, since we just end up\nconverting the list into a scalar below. And if we just turned that into\na function, we could get a nice:\n\n  my $prompt_color = git_color_to_ansicolor(\n    qx(git config --get color.interactive.prompt) || 'blue bold');\n\n-Peff\n"},{"id":"56952","messageId":"20071023042956.GC28312@coredump.intra.peff.net","threadId":"10263","inReplyTo":"20071022211958.045895ac@danzwell.com","subject":"Re: [PATCH] Let git-add--interactive read \"git colors\" from git-config","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-23T04:29:57Z","receivedAt":"2007-10-23T04:29:57Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Oct 22, 2007 at 09:19:58PM -0500, Dan Zwell wrote:\n\n> This patch is againts Shawn Pearce's \"pu\" branch.\n\nDon't do that. The code in 'pu' is a mess of half-working features. If\nyour patch is accepted, then it has to be picked apart from those\nhalf-working features that aren't being accepted (which hopefully isn't\nhard if nobody has been working in the same area, but can be quite\nugly).  Base your work on 'master' if possible, or 'next' if it relies\non features only in next. If it relies on some topic branch that is\n_only_ in pu, then mention explicitly which topic.\n\n-Peff\n"},{"id":"56957","messageId":"20071023044055.GB14735@spearce.org","threadId":"10263","inReplyTo":"20071023042956.GC28312@coredump.intra.peff.net","subject":"Re: [PATCH] Let git-add--interactive read \"git colors\" from git-config","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-10-23T04:40:55Z","receivedAt":"2007-10-23T04:40:55Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jeff King <peff@peff.net> wrote:\n> On Mon, Oct 22, 2007 at 09:19:58PM -0500, Dan Zwell wrote:\n> \n> > This patch is againts Shawn Pearce's \"pu\" branch.\n> \n> Don't do that. The code in 'pu' is a mess of half-working features. If\n> your patch is accepted, then it has to be picked apart from those\n> half-working features that aren't being accepted (which hopefully isn't\n> hard if nobody has been working in the same area, but can be quite\n> ugly).  Base your work on 'master' if possible, or 'next' if it relies\n> on features only in next. If it relies on some topic branch that is\n> _only_ in pu, then mention explicitly which topic.\n\nAnd even when you base work on things in next, don't base it on the\ntip of next.  Base it on a specific topic that is merged into next.\nNext is also a mess of features, but they are more likely to be in\na working state than the features in pu.\n\nTopics in next will merge to master at different times.  If your\nchanges depend on more than one topic that may make it more difficult\nfor the maintainer to merge your topic to master.\n\nFortunately In Dan's case the only topic in pu that impacted\ngit-add--interactive was his dz/color-addi topic, so this probably\napplies to the tip of it just as well as it does to the tip of pu.\n\n-- \nShawn.\n"},{"id":"56981","messageId":"D1795135-AD5E-491C-99E6-30486E189B13@wincent.com","threadId":"10263","inReplyTo":"20071023040315.GA28312@coredump.intra.peff.net","subject":"Re: [PATCH 1/2] Added basic color support to git add --interactive","fromName":"Wincent Colaiuta","fromEmail":"win@wincent.com","sentAt":"2007-10-23T06:28:28Z","receivedAt":"2007-10-23T06:28:28Z","isPatch":true,"sender":{"key":"greg@hurrell.net","avatar":"https://avatars.githubusercontent.com/u/7074?v=4"},"body":"El 23/10/2007, a las 6:03, Jeff King escribió:\n\n> This does nothing for embedded newlines in the strings, which means  \n> that\n> you can end up with ${COLOR}text\\n${RESET}, which fouls up changed\n> backgrounds. See commit 50f575fc. Since the strings you are  \n> printing are\n> small, I don't see any problem with making a copy, using a regex to\n> insert the color coding, and printing that (I think I even posted\n> example code in a previous thread on this subject).\n\nI did too, where you add a third, optional \"trailer\" parameter to the  \nfunction where you pass the newline if there is one (following the  \nstyle of the functions in color.c). Pasting it below.\n\nHaving said that, I think this kind of function belongs in Git.pm,  \nand the dependency on Term::ANSIColor should be replaced with  \ndependency-free code that generates the colors itself; this should be  \neasy because the number of possible colors is small, Git thus far  \nonly uses a subset of the possible ANSI colors, and the C code for  \ndoing it is already there in color.c and just needs to be translated  \ninto Perl.\n\nsub print_ansi_color {\n\tmy $color = shift;\n\tmy $string = shift;\n\tmy $trailer = shift;\n\tif ($use_color) {\n\t\tprint Term::ANSIColor::color($color), $string,\n\t\t    Term::ANSIColor::color('clear');\n\t} else {\n\t\tprint $string;\n\t}\n\tif ($trailer) {\n\t\tprint $trailer;\n\t}\n}\n\nCheers,\nWincent\n"},{"id":"56983","messageId":"20071023064106.GA30351@coredump.intra.peff.net","threadId":"10263","inReplyTo":"D1795135-AD5E-491C-99E6-30486E189B13@wincent.com","subject":"Re: [PATCH 1/2] Added basic color support to git add --interactive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-23T06:41:07Z","receivedAt":"2007-10-23T06:41:07Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Oct 23, 2007 at 08:28:28AM +0200, Wincent Colaiuta wrote:\n\n> I did too, where you add a third, optional \"trailer\" parameter to the \n> function where you pass the newline if there is one (following the style of \n> the functions in color.c). Pasting it below.\n\nThe problem with that approach is that you can only send in a single\nline at a time (with the newline detached!), so it makes life harder for\nthe caller. E.g., there is at least one spot that uses a here-doc with\nmany lines; splitting that into a bunch of print_ansi_color calls would\nbe unnecessarily ugly.\n\n> Having said that, I think this kind of function belongs in Git.pm, and the \n\nYes! Most of this is obviously library-ish code, and should go into the\nlibrary.\n\n> dependency on Term::ANSIColor should be replaced with dependency-free code \n> that generates the colors itself; this should be easy because the number of \n\nOut of curiosity, are people really running perl < 5.6?  Term::ANSIColor\nhas been in the base distribution for 7 years now.\n\n-Peff\n"},{"id":"56988","messageId":"A225BBC0-2607-4952-8578-EC9A181C418E@wincent.com","threadId":"10263","inReplyTo":"20071023064106.GA30351@coredump.intra.peff.net","subject":"Re: [PATCH 1/2] Added basic color support to git add --interactive","fromName":"Wincent Colaiuta","fromEmail":"win@wincent.com","sentAt":"2007-10-23T07:44:59Z","receivedAt":"2007-10-23T07:44:59Z","isPatch":true,"sender":{"key":"greg@hurrell.net","avatar":"https://avatars.githubusercontent.com/u/7074?v=4"},"body":"El 23/10/2007, a las 8:41, Jeff King escribió:\n\n> On Tue, Oct 23, 2007 at 08:28:28AM +0200, Wincent Colaiuta wrote:\n>\n>> I did too, where you add a third, optional \"trailer\" parameter to the\n>> function where you pass the newline if there is one (following the  \n>> style of\n>> the functions in color.c). Pasting it below.\n>\n> The problem with that approach is that you can only send in a single\n> line at a time (with the newline detached!), so it makes life  \n> harder for\n> the caller. E.g., there is at least one spot that uses a here-doc with\n> many lines; splitting that into a bunch of print_ansi_color calls  \n> would\n> be unnecessarily ugly.\n\nYes, I agree that it complicates things for the caller. I was just  \ncopying the model found in color.c; but seeing as this is Perl  \nsplitting into lines inside the printing function would be  \nstraightforward.\n\nCheers,\nWincent\n"},{"id":"56991","messageId":"20071023035221.66ea537f@danzwell.com","threadId":"10263","inReplyTo":"20071023042702.GB28312@coredump.intra.peff.net","subject":"Re: [PATCH 2/2] Let git-add--interactive read colors from git-config","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-10-23T08:52:21Z","receivedAt":"2007-10-23T08:52:21Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"On Tue, 23 Oct 2007 00:27:02 -0400\nJeff King <peff@peff.net> wrote:\n\n> On Mon, Oct 22, 2007 at 04:40:48PM -0500, Dan Zwell wrote:\n> \n> > Note: the code to parse git-style color strings to perl-style color\n> > strings should eventually be added to Git.pm so that other (perl)\n> > parts of git can be configured to read colors from .gitconfig in\n> > a nicer way. A git-style string is \"ul red black\", while perl \n> > likes strings like \"underline red on_black\".\n> \n> Why not do it as part of this patch, then?\nWill do. I didn't include it in the patch because I need to learn more\nabout perl before I can make this change, though I can probably just\nfind enough examples in the other scripts that use Git.pm.\n\n> \n> > +\t# Sane (visible) defaults:\n> > +\tif (! @git_prompt_color) {\n> > +\t\t@git_prompt_color = (\"blue\", \"bold\");\n> > +\t}\n> \n> I think it might be a bit more readable to keep the assignment and\n> defaults together:\n> \n>   my @git_prompt_color = split /\\s+/,\n>     qx(git config --get color.interactive.prompt) || 'blue bold';\n> \n> Though I wonder why we are splitting here at all, since we just end up\n> converting the list into a scalar below. And if we just turned that\n> into a function, we could get a nice:\n> \n>   my $prompt_color = git_color_to_ansicolor(\n>     qx(git config --get color.interactive.prompt) || 'blue bold');\nI agree, now that you mention it. Eventually the string must be split\n(parsing it left to right by word makes more sense than trying to\nmutate it with regular expressions, if only because it's a lot harder\nto make mistakes), but there's no reason not to split the string inside\nthe loop, where it would look nicer/more contained. I will make this\nchange.\n\nDan\n"},{"id":"58067","messageId":"20071102224100.71665182@paradox.zwell.net","threadId":"10263","inReplyTo":"20071023035221.66ea537f@danzwell.com","subject":"[PATCH 1/2] Added basic color support to git add --interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-03T03:41:00Z","receivedAt":"2007-11-03T03:41:00Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"From 29b34bb32846921c9432bf1b74c93d06a0667a44 Mon Sep 17 00:00:00 2001\nFrom: Dan Zwell <dzwell@zwell.net>\nDate: Mon, 22 Oct 2007 15:55:20 -0500\nSubject: [PATCH] Added basic color support to git add --interactive\n\nAdded function \"print_colored\" that prints text with a color that\nis passed in. Converted many calls to \"print\" to being calls to\n\"print_colored\".\n\nThe prompt, the header, and the help output are the 3 types of\ncolorized output, and each has its own color.\n\nColorization is done through Term::ANSIColor, which is included\nwith modern versions of perl. This is optional, and should not\nneed to be present if color.interactive is not turned on.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\nI believe this version takes care of the complaints people had\nwith this patch. I hope this is helpful.\n\n Documentation/config.txt  |    6 ++++++\n git-add--interactive.perl |   42 ++++++++++++++++++++++++++++++++++++------\n 2 files changed, 42 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex edf50cd..2fd783f 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -382,6 +382,12 @@ color.diff.<slot>::\n \twhitespace).  The values of these variables may be specified as\n \tin color.branch.<slot>.\n \n+color.interactive::\n+\tWhen true (or `always`), always use colors in `git add\n+\t--interactive`.  When false (or `never`), never.  When set to\n+\t`auto`, use colors only when the output is to the\n+\tterminal. Defaults to false.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex ac598f8..16dc7b0 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -2,6 +2,36 @@\n \n use strict;\n \n+my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n+my $color_config = qx(git config --get color.interactive);\n+if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n+\trequire Term::ANSIColor;\n+\n+\t$use_color = \"true\";\n+\t# Sane (visible) defaults:\n+\t$prompt_color = Term::ANSIColor::color(\"blue bold\");\n+\t$header_color = Term::ANSIColor::color(\"bold\");\n+\t$help_color   = Term::ANSIColor::color(\"red bold\");\n+\t$normal_color = Term::ANSIColor::color(\"reset\");\n+}\n+\n+sub print_colored {\n+\tmy $color = shift;\n+\tmy $string = join(\"\", @_);\n+\n+\tif ($use_color) {\n+\t\t# Put a color code at the beginning of each line, a reset at the end\n+\t\t# color after newlines that are not at the end of the string\n+\t\t$string =~ s/(\\n+)(.)/$1$color$2/g;\n+\t\t# reset before newlines\n+\t\t$string =~ s/(\\n+)/$normal_color$1/g;\n+\t\t# codes at beginning and end (if necessary):\n+\t\t$string =~ s/^/$color/;\n+\t\t$string =~ s/$/$normal_color/ unless $string =~ /\\n$/;\n+\t}\n+\tprint $string;\n+}\n+\n sub run_cmd_pipe {\n \tif ($^O eq 'MSWin32') {\n \t\tmy @invalid = grep {m/[\":*]/} @_;\n@@ -175,7 +205,7 @@ sub list_and_choose {\n \t\t\tif (!$opts->{LIST_FLAT}) {\n \t\t\t\tprint \"     \";\n \t\t\t}\n-\t\t\tprint \"$opts->{HEADER}\\n\";\n+\t\t\tprint_colored $header_color, \"$opts->{HEADER}\\n\";\n \t\t}\n \t\tfor ($i = 0; $i < @stuff; $i++) {\n \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n@@ -205,7 +235,7 @@ sub list_and_choose {\n \n \t\treturn if ($opts->{LIST_ONLY});\n \n-\t\tprint $opts->{PROMPT};\n+\t\tprint_colored $prompt_color, $opts->{PROMPT};\n \t\tif ($opts->{SINGLETON}) {\n \t\t\tprint \"> \";\n \t\t}\n@@ -544,7 +574,7 @@ sub coalesce_overlapping_hunks {\n }\n \n sub help_patch_cmd {\n-\tprint <<\\EOF ;\n+\tprint_colored $help_color, <<\\EOF ;\n y - stage this hunk\n n - do not stage this hunk\n a - stage this and all the remaining hunks\n@@ -619,7 +649,7 @@ sub patch_update_cmd {\n \t\tfor (@{$hunk[$ix]{TEXT}}) {\n \t\t\tprint;\n \t\t}\n-\t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n+\t\tprint_colored $prompt_color, \"Stage this hunk [y/n/a/d$other/?]? \";\n \t\tmy $line = <STDIN>;\n \t\tif ($line) {\n \t\t\tif ($line =~ /^y/i) {\n@@ -673,7 +703,7 @@ sub patch_update_cmd {\n \t\t\telsif ($other =~ /s/ && $line =~ /^s/) {\n \t\t\t\tmy @split = split_hunk($hunk[$ix]{TEXT});\n \t\t\t\tif (1 < @split) {\n-\t\t\t\t\tprint \"Split into \",\n+\t\t\t\t\tprint_colored $header_color, \"Split into \",\n \t\t\t\t\tscalar(@split), \" hunks.\\n\";\n \t\t\t\t}\n \t\t\t\tsplice(@hunk, $ix, 1,\n@@ -766,7 +796,7 @@ sub quit_cmd {\n }\n \n sub help_cmd {\n-\tprint <<\\EOF ;\n+\tprint_colored $help_color, <<\\EOF ;\n status        - show paths with changes\n update        - add working tree state to the staged set of changes\n revert        - revert staged set of changes back to the HEAD version\n-- \n1.5.3.5.474.g3e4bb\n\n\n\n>From 29b34bb32846921c9432bf1b74c93d06a0667a44 Mon Sep 17 00:00:00 2001\nFrom: Dan Zwell <dzwell@zwell.net>\nDate: Mon, 22 Oct 2007 15:55:20 -0500\nSubject: [PATCH] Added basic color support to git add --interactive\n\nAdded function \"print_colored\" that prints text with a color that\nis passed in. Converted many calls to \"print\" to being calls to\n\"print_colored\".\n\nThe prompt, the header, and the help output are the 3 types of\ncolorized output, and each has its own color.\n\nColorization is done through Term::ANSIColor, which is included\nwith modern versions of perl. This is optional, and should not\nneed to be present if color.interactive is not turned on.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\n Documentation/config.txt  |    6 ++++++\n git-add--interactive.perl |   42 ++++++++++++++++++++++++++++++++++++------\n 2 files changed, 42 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex edf50cd..2fd783f 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -382,6 +382,12 @@ color.diff.<slot>::\n \twhitespace).  The values of these variables may be specified as\n \tin color.branch.<slot>.\n \n+color.interactive::\n+\tWhen true (or `always`), always use colors in `git add\n+\t--interactive`.  When false (or `never`), never.  When set to\n+\t`auto`, use colors only when the output is to the\n+\tterminal. Defaults to false.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex ac598f8..16dc7b0 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -2,6 +2,36 @@\n \n use strict;\n \n+my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n+my $color_config = qx(git config --get color.interactive);\n+if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n+\trequire Term::ANSIColor;\n+\n+\t$use_color = \"true\";\n+\t# Sane (visible) defaults:\n+\t$prompt_color = Term::ANSIColor::color(\"blue bold\");\n+\t$header_color = Term::ANSIColor::color(\"bold\");\n+\t$help_color   = Term::ANSIColor::color(\"red bold\");\n+\t$normal_color = Term::ANSIColor::color(\"reset\");\n+}\n+\n+sub print_colored {\n+\tmy $color = shift;\n+\tmy $string = join(\"\", @_);\n+\n+\tif ($use_color) {\n+\t\t# Put a color code at the beginning of each line, a reset at the end\n+\t\t# color after newlines that are not at the end of the string\n+\t\t$string =~ s/(\\n+)(.)/$1$color$2/g;\n+\t\t# reset before newlines\n+\t\t$string =~ s/(\\n+)/$normal_color$1/g;\n+\t\t# codes at beginning and end (if necessary):\n+\t\t$string =~ s/^/$color/;\n+\t\t$string =~ s/$/$normal_color/ unless $string =~ /\\n$/;\n+\t}\n+\tprint $string;\n+}\n+\n sub run_cmd_pipe {\n \tif ($^O eq 'MSWin32') {\n \t\tmy @invalid = grep {m/[\":*]/} @_;\n@@ -175,7 +205,7 @@ sub list_and_choose {\n \t\t\tif (!$opts->{LIST_FLAT}) {\n \t\t\t\tprint \"     \";\n \t\t\t}\n-\t\t\tprint \"$opts->{HEADER}\\n\";\n+\t\t\tprint_colored $header_color, \"$opts->{HEADER}\\n\";\n \t\t}\n \t\tfor ($i = 0; $i < @stuff; $i++) {\n \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n@@ -205,7 +235,7 @@ sub list_and_choose {\n \n \t\treturn if ($opts->{LIST_ONLY});\n \n-\t\tprint $opts->{PROMPT};\n+\t\tprint_colored $prompt_color, $opts->{PROMPT};\n \t\tif ($opts->{SINGLETON}) {\n \t\t\tprint \"> \";\n \t\t}\n@@ -544,7 +574,7 @@ sub coalesce_overlapping_hunks {\n }\n \n sub help_patch_cmd {\n-\tprint <<\\EOF ;\n+\tprint_colored $help_color, <<\\EOF ;\n y - stage this hunk\n n - do not stage this hunk\n a - stage this and all the remaining hunks\n@@ -619,7 +649,7 @@ sub patch_update_cmd {\n \t\tfor (@{$hunk[$ix]{TEXT}}) {\n \t\t\tprint;\n \t\t}\n-\t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n+\t\tprint_colored $prompt_color, \"Stage this hunk [y/n/a/d$other/?]? \";\n \t\tmy $line = <STDIN>;\n \t\tif ($line) {\n \t\t\tif ($line =~ /^y/i) {\n@@ -673,7 +703,7 @@ sub patch_update_cmd {\n \t\t\telsif ($other =~ /s/ && $line =~ /^s/) {\n \t\t\t\tmy @split = split_hunk($hunk[$ix]{TEXT});\n \t\t\t\tif (1 < @split) {\n-\t\t\t\t\tprint \"Split into \",\n+\t\t\t\t\tprint_colored $header_color, \"Split into \",\n \t\t\t\t\tscalar(@split), \" hunks.\\n\";\n \t\t\t\t}\n \t\t\t\tsplice(@hunk, $ix, 1,\n@@ -766,7 +796,7 @@ sub quit_cmd {\n }\n \n sub help_cmd {\n-\tprint <<\\EOF ;\n+\tprint_colored $help_color, <<\\EOF ;\n status        - show paths with changes\n update        - add working tree state to the staged set of changes\n revert        - revert staged set of changes back to the HEAD version\n-- \n1.5.3.5.474.g3e4bb\n\n"},{"id":"58066","messageId":"20071102224111.7f7e165c@paradox.zwell.net","threadId":"10263","inReplyTo":"20071023035221.66ea537f@danzwell.com","subject":"[PATCH 2/2] Let git-add--interactive read colors from .gitconfig","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-03T03:41:11Z","receivedAt":"2007-11-03T03:41:11Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":">From ad3c6a2f015197a72d85039783a63a24c19f7017 Mon Sep 17 00:00:00 2001\nFrom: Dan Zwell <dzwell@zwell.net>\nDate: Mon, 22 Oct 2007 16:08:01 -0500\nSubject: [PATCH] Let git-add--interactive read colors from .gitconfig\n\nColors are specified in color.interactive.{prompt,header,help}.\nThey are specified as git color strings as described in the\ndocumentation. The method color_to_ansi_string() in Git.pm parses\nthese strings and returns ANSI color codes (using\nTerm::ANSIColor).\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\nOne thought is that is seems a bit sloppy to call \"require Term::ANSIColor\"\nwithin color_to_ansi_code(), but I can't really see a better way. After all,\nthat is where the methods from that library are really needed. And I don't\nknow why Git.pm should need to know whether color will end up being used.\n\n Documentation/config.txt  |    7 +++++\n git-add--interactive.perl |   22 ++++++++++++-----\n perl/Git.pm               |   56 ++++++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 77 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 2fd783f..ade3399 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -388,6 +388,13 @@ color.interactive::\n \t`auto`, use colors only when the output is to the\n \tterminal. Defaults to false.\n \n+color.interactive.<slot>::\n+\tUse customized color for `git add --interactive`\n+\toutput. `<slot>` may be `prompt`, `header`, or `help`, for\n+\tthree distinct types of normal output from interactive\n+\tprograms.  The values of these variables may be specified as\n+\tin color.branch.<slot>.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 16dc7b0..2bce5a1 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -1,18 +1,26 @@\n #!/usr/bin/perl -w\n \n use strict;\n+use Git;\n \n my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n my $color_config = qx(git config --get color.interactive);\n if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n-\trequire Term::ANSIColor;\n-\n \t$use_color = \"true\";\n-\t# Sane (visible) defaults:\n-\t$prompt_color = Term::ANSIColor::color(\"blue bold\");\n-\t$header_color = Term::ANSIColor::color(\"bold\");\n-\t$help_color   = Term::ANSIColor::color(\"red bold\");\n-\t$normal_color = Term::ANSIColor::color(\"reset\");\n+\t# Grab the 3 main colors in git color string format, with sane\n+\t# (visible) defaults:\n+\tmy $repo = Git->repository();\n+\tmy $git_prompt_color =\n+\t\tGit::config($repo, \"color.interactive.prompt\")||\"bold blue\";\n+\tmy $git_header_color =\n+\t\tGit::config($repo, \"color.interactive.header\")||\"bold\";\n+\tmy $git_help_color =\n+\t\tGit::config($repo, \"color.interactive.help\")||\"red bold\";\n+\n+\t$prompt_color = Git::color_to_ansi_code($git_prompt_color);\n+\t$header_color = Git::color_to_ansi_code($git_header_color);\n+\t$help_color   = Git::color_to_ansi_code($git_help_color);\n+\t$normal_color = Git::color_to_ansi_code(\"normal\");\n }\n \n sub print_colored {\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex 3f4080c..9100e0b 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -515,7 +515,6 @@ sub config {\n \t};\n }\n \n-\n =item config_bool ( VARIABLE )\n \n Retrieve the bool configuration C<VARIABLE>. The return value\n@@ -550,6 +549,61 @@ sub config_bool {\n }\n \n \n+=item color_to_ansi_code ( COLOR )\n+\n+Converts a git-style color string, like \"underline blue white\" to\n+an ANSI color code. The code is generated by Term::ANSIColor,\n+after the string is parsed into the format that is accepted by\n+that module. Used as follows:\n+\n+\tprint color_to_ansi_code(\"underline blue white\");\n+\tprint \"some text\";\n+\tprint color_to_ansi_code(\"normal\");\n+\n+=cut\n+\n+sub color_to_ansi_code {\n+\tmy ($git_string) = @_;\n+\tmy @ansi_words;\n+\tmy %attrib_mappings = (\n+\t\t\"bold\"    => \"bold\",\n+\t\t\"ul\"      => \"underline\",\n+\t\t\"blink\"   => \"blink\",\n+\t\t# not supported:\n+\t\t#\"dim\"     => \"\",\n+\t\t\"reverse\" => \"reverse\"\n+\t);\n+\tmy ($fg_done, $word);\n+\n+\tforeach $word (split /\\s+/, $git_string) {\n+\t\tif ($word =~ /normal/) {\n+\t\t\t$fg_done = \"true\";\n+\t\t}\n+\t\telsif ($word =~ /black|red|green|yellow/ ||\n+\t\t\t   $word =~ /blue|magenta|cyan|white/) {\n+\t\t\t# is a color.\n+\t\t\tif ($fg_done) {\n+\t\t\t\t# this is the background\n+\t\t\t\tpush @ansi_words, \"on_\" . $word;\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\t# this is foreground\n+\t\t\t\t$fg_done = \"true\";\n+\t\t\t\tpush @ansi_words, $word;\n+\t\t\t}\n+\t\t}\n+\t\telse {\n+\t\t\t# this is an attribute, not a color.\n+\t\t\tif ($attrib_mappings{$word}) {\n+\t\t\t\tpush(@ansi_words,\n+\t\t\t\t\t $attrib_mappings{$word});\n+\t\t\t}\n+\t\t}\n+\t}\n+\trequire Term::ANSIColor;\n+\treturn Term::ANSIColor::color(join(\" \", @ansi_words)||\"reset\");\n+}\n+\n =item ident ( TYPE | IDENTSTR )\n \n =item ident_person ( TYPE | IDENTSTR | IDENTARRAY )\n-- \n1.5.3.5.474.g3e4bb\n"},{"id":"58068","messageId":"7vy7dfyl33.fsf_-_@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071102224111.7f7e165c@paradox.zwell.net","subject":"Re: *[PATCH 2/2] Let git-add--interactive read colors from .gitconfig","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-03T05:06:08Z","receivedAt":"2007-11-03T05:06:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Zwell <dzwell@zwell.net> writes:\n\n> One thought is that is seems a bit sloppy to call \"require Term::ANSIColor\"\n> within color_to_ansi_code(), but I can't really see a better way. After all,\n> that is where the methods from that library are really needed. And I don't\n> know why Git.pm should need to know whether color will end up being used.\n\nHow big is Term::ANSIColor, and how universally available is it?\nImplementing the ANSI \"ESC [ %d m\" arithmetic color.c in Perl\nourselves does not feel too much effort, compared to the\npotential hassle of dealing with extra dependencies and\npotential drift between scripts and C implementation.\n\nWe may later want to update the C side to take colors from\nterminfo, but that is a separate topic ;-)\n\nSince your 2/2 updates on your 1/2, the diff is difficult to\ncomment on, so I'll comment on the combined effects.\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex ac598f8..2bce5a1 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -1,6 +1,44 @@\n #!/usr/bin/perl -w\n \n use strict;\n+use Git;\n+\n+my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n+my $color_config = qx(git config --get color.interactive);\n+if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n+\t$use_color = \"true\";\n+\t# Grab the 3 main colors in git color string format, with sane\n+\t# (visible) defaults:\n+\tmy $repo = Git->repository();\n+\tmy $git_prompt_color =\n+\t\tGit::config($repo, \"color.interactive.prompt\")||\"bold blue\";\n+\tmy $git_header_color =\n+\t\tGit::config($repo, \"color.interactive.header\")||\"bold\";\n+\tmy $git_help_color =\n+\t\tGit::config($repo, \"color.interactive.help\")||\"red bold\";\n+\n+\t$prompt_color = Git::color_to_ansi_code($git_prompt_color);\n+\t$header_color = Git::color_to_ansi_code($git_header_color);\n+\t$help_color   = Git::color_to_ansi_code($git_help_color);\n+\t$normal_color = Git::color_to_ansi_code(\"normal\");\n+}\n\nIf we are to still use Term::ANSIColor, then we might want to\nprotect ourselves from a broken installation:\n\n        if ($color_config =~ /true|always/ ||\n            -t STDOUT && $color_config =~ /auto/) {\n                eval { require Term::ANSIColor; };\n                if (!$@) {\n                        $use_color = 1;\n                        ... set up the colors ...\n                }\n                else {\n                        $use_color = 0;\n                }\n        }\n\nThen you can remove the require from Git::color_to_ansi_code().\nYour current calling convention is to require the calling site\nto be sure the module is availble; the suggested change merely\nmakes it responsible to also make sure the module is loaded.\n\nHmm?\n\nBy the way, coloring the diff text itself may be just the matter\nof doing something like this (except that you now need to snarf\nOLD, NEW, METAINFO and FRAGINFO colors for diff configuration as\nwell.\n\nIn addition to a small matter of testing, a more practical issue\nwould be to add PAGER support there, I think.\n\n---\n\n git-add--interactive.perl |   32 ++++++++++++++++++++++++--------\n 1 files changed, 24 insertions(+), 8 deletions(-)\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 2bce5a1..1063a34 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -388,6 +388,27 @@ sub parse_diff {\n \treturn @hunk;\n }\n \n+sub print_diff_hunk {\n+\tmy ($text) = @_;\n+\tfor (@$text) {\n+\t\tif (!$use_color) {\n+\t\t\tprint;\n+\t\t\tnext;\n+\t\t}\n+\t\tif (/^\\+/) {\n+\t\t\tprint_colored $new_color, $_;\n+\t\t} elsif (/^\\-/) {\n+\t\t\tprint_colored $old_color, $_;\n+\t\t} elsif (/^\\@/) {\n+\t\t\tprint_colored $fraginfo_color, $_;\n+\t\t} elsif (/^ /) {\n+\t\t\tprint_colored $normal_color, $_;\n+\t\t} else {\n+\t\t\tprint_colored $metainfo_color, $_;\n+\t\t}\n+\t}\n+}\n+\n sub hunk_splittable {\n \tmy ($text) = @_;\n \n@@ -610,9 +631,7 @@ sub patch_update_cmd {\n \tmy ($ix, $num);\n \tmy $path = $it->{VALUE};\n \tmy ($head, @hunk) = parse_diff($path);\n-\tfor (@{$head->{TEXT}}) {\n-\t\tprint;\n-\t}\n+\tprint_diff_hunk($head->{TEXT});\n \t$num = scalar @hunk;\n \t$ix = 0;\n \n@@ -654,9 +673,7 @@ sub patch_update_cmd {\n \t\tif (hunk_splittable($hunk[$ix]{TEXT})) {\n \t\t\t$other .= '/s';\n \t\t}\n-\t\tfor (@{$hunk[$ix]{TEXT}}) {\n-\t\t\tprint;\n-\t\t}\n+\t\tprint_diff_hunk($hunk[$ix]{TEXT});\n \t\tprint_colored $prompt_color, \"Stage this hunk [y/n/a/d$other/?]? \";\n \t\tmy $line = <STDIN>;\n \t\tif ($line) {\n@@ -794,8 +811,7 @@ sub diff_cmd {\n \t\t\t\t     HEADER => $status_head, },\n \t\t\t\t   @mods);\n \treturn if (!@them);\n-\tsystem(qw(git diff-index -p --cached HEAD --),\n-\t       map { $_->{VALUE} } @them);\n+\tsystem(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);\n }\n \n sub quit_cmd {\n"},{"id":"58076","messageId":"20071103022626.253dcd93@paradox.zwell.net","threadId":"10263","inReplyTo":"7vy7dfyl33.fsf_-_@gitster.siamese.dyndns.org","subject":"Re: *[PATCH 2/2] Let git-add--interactive read colors from .gitconfig","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-03T07:26:26Z","receivedAt":"2007-11-03T07:26:26Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"On Fri, 02 Nov 2007 22:06:08 -0700\nJunio C Hamano <gitster@pobox.com> wrote:\n\n> Dan Zwell <dzwell@zwell.net> writes:\n> \n> How big is Term::ANSIColor, and how universally available is it?\n> Implementing the ANSI \"ESC [ %d m\" arithmetic color.c in Perl\n> ourselves does not feel too much effort, compared to the\n> potential hassle of dealing with extra dependencies and\n> potential drift between scripts and C implementation.\n20K on my machine, and part of the core library since Perl 5.6.0.\nThis was released in 2000. With your addition (the eval check to make\nsure the module is loaded), nobody should be harmed if they don't have a\nmodern perl, either. My vote would be to reimplement the coloring if we\nactually notice these problems.\n\n<snip>\n> \n> By the way, coloring the diff text itself may be just the matter\n> of doing something like this (except that you now need to snarf\n> OLD, NEW, METAINFO and FRAGINFO colors for diff configuration as\n> well.\n> \n> In addition to a small matter of testing, a more practical issue\n> would be to add PAGER support there, I think.\nYou mean in general, so that users can view a hunk in the PAGER, then\nbe prompted for what to do with it? (Because it doesn't solve the color\nproblems, because calling \"diff --color\" here creates other problems.)\n\n> \n> ---\n> \n>  git-add--interactive.perl |   32 ++++++++++++++++++++++++--------\n>  1 files changed, 24 insertions(+), 8 deletions(-)\n> \n> diff --git a/git-add--interactive.perl b/git-add--interactive.perl\n> index 2bce5a1..1063a34 100755\n> --- a/git-add--interactive.perl\n> +++ b/git-add--interactive.perl\n> @@ -388,6 +388,27 @@ sub parse_diff {\n>  \treturn @hunk;\n>  }\n>  \n> +sub print_diff_hunk {\n> +\tmy ($text) = @_;\n> +\tfor (@$text) {\n> +\t\tif (!$use_color) {\n> +\t\t\tprint;\n> +\t\t\tnext;\n> +\t\t}\n> +\t\tif (/^\\+/) {\n> +\t\t\tprint_colored $new_color, $_;\n> +\t\t} elsif (/^\\-/) {\n> +\t\t\tprint_colored $old_color, $_;\n> +\t\t} elsif (/^\\@/) {\n> +\t\t\tprint_colored $fraginfo_color, $_;\n> +\t\t} elsif (/^ /) {\n> +\t\t\tprint_colored $normal_color, $_;\n> +\t\t} else {\n> +\t\t\tprint_colored $metainfo_color, $_;\n> +\t\t}\n> +\t}\n> +}\n> +\n>  sub hunk_splittable {\n>  \tmy ($text) = @_;\n>  \n> @@ -610,9 +631,7 @@ sub patch_update_cmd {\n>  \tmy ($ix, $num);\n>  \tmy $path = $it->{VALUE};\n>  \tmy ($head, @hunk) = parse_diff($path);\n> -\tfor (@{$head->{TEXT}}) {\n> -\t\tprint;\n> -\t}\n> +\tprint_diff_hunk($head->{TEXT});\n>  \t$num = scalar @hunk;\n>  \t$ix = 0;\n>  \n> @@ -654,9 +673,7 @@ sub patch_update_cmd {\n>  \t\tif (hunk_splittable($hunk[$ix]{TEXT})) {\n>  \t\t\t$other .= '/s';\n>  \t\t}\n> -\t\tfor (@{$hunk[$ix]{TEXT}}) {\n> -\t\t\tprint;\n> -\t\t}\n> +\t\tprint_diff_hunk($hunk[$ix]{TEXT});\n>  \t\tprint_colored $prompt_color, \"Stage this hunk\n> [y/n/a/d$other/?]? \"; my $line = <STDIN>;\n>  \t\tif ($line) {\n> @@ -794,8 +811,7 @@ sub diff_cmd {\n>  \t\t\t\t     HEADER => $status_head, },\n>  \t\t\t\t   @mods);\n>  \treturn if (!@them);\n> -\tsystem(qw(git diff-index -p --cached HEAD --),\n> -\t       map { $_->{VALUE} } @them);\n> +\tsystem(qw(git diff -p --cached HEAD --), map { $_->{VALUE} }\n> @them); }\n>  \n>  sub quit_cmd {\n> \nIn a previous incantation of this thread, coloring the diff output was\ndiscussed. Your patch works, I tested it, but it does not highlight\nwhitespace at the end of lines or space/tab errors. If this is the only\ncase that more than one color may appear per line, it should not be\nhard to match it as a special case (assuming this check isn't disabled\nin .gitconfig), and print the rest of the line as we otherwise would.\n\nDan\n"},{"id":"58159","messageId":"7vpryrxkqm.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071103022626.253dcd93@paradox.zwell.net","subject":"Re: *[PATCH 2/2] Let git-add--interactive read colors from .gitconfig","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-03T18:11:13Z","receivedAt":"2007-11-03T18:11:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Zwell <dzwell@zwell.net> writes:\n\n> Junio C Hamano <gitster@pobox.com> wrote:\n> ...\n>> In addition to a small matter of testing, a more practical issue\n>> would be to add PAGER support there, I think.\n>\n> You mean in general, so that users can view a hunk in the PAGER, then\n> be prompted for what to do with it? (Because it doesn't solve the color\n> problems, because calling \"diff --color\" here creates other problems.)\n\nYes.  I see it a much bigger problem that we let a long hunk\nscroll off the top of the screen then ask the user what to do\nwith it, than any coloring of diff.\n\n> ... but it does not highlight\n> whitespace at the end of lines or space/tab errors.\n\nNo, but you can make it so if you want.\n\nPersonally, I think it is not so useful for \"add -i\" to do so,\nas it is too late in the workflow, unless you add it ways to let\nyou edit and fix the whitespace errors.\n"},{"id":"58211","messageId":"20071104045735.GA12359@segfault.peff.net","threadId":"10263","inReplyTo":"20071102224100.71665182@paradox.zwell.net","subject":"Re: [PATCH 1/2] Added basic color support to git add --interactive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-04T04:57:35Z","receivedAt":"2007-11-04T04:57:35Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Nov 02, 2007 at 10:41:00PM -0500, Dan Zwell wrote:\n\n> +sub print_colored {\n> +\tmy $color = shift;\n> +\tmy $string = join(\"\", @_);\n> +\n> +\tif ($use_color) {\n> +\t\t# Put a color code at the beginning of each line, a reset at the end\n> +\t\t# color after newlines that are not at the end of the string\n> +\t\t$string =~ s/(\\n+)(.)/$1$color$2/g;\n> +\t\t# reset before newlines\n> +\t\t$string =~ s/(\\n+)/$normal_color$1/g;\n> +\t\t# codes at beginning and end (if necessary):\n> +\t\t$string =~ s/^/$color/;\n> +\t\t$string =~ s/$/$normal_color/ unless $string =~ /\\n$/;\n> +\t}\n> +\tprint $string;\n> +}\n\nThis would probably be a bit more readable by marking the regex as\nmultline using /m. Something like:\n\n  $string =~ s/^/$color/mg;\n  $string =~ s/.$/$&$normal_color/mg;\n\nwhich covers both the \"start/end of line\" and \"start/end\" of string\ncases.\n\nAlso, if there is to be pager support for showing diffs, perhaps\nprint_colored needs to take a filehandle argument (or, even simpler,\nchange \"print_colored(...)\" to \"print color(...), so the caller can use\nprint as usual).\n\n-Peff\n"},{"id":"58215","messageId":"7v640ivagv.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071104045735.GA12359@segfault.peff.net","subject":"Re: [PATCH 1/2] Added basic color support to git add --interactive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-04T05:36:00Z","receivedAt":"2007-11-04T05:36:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Fri, Nov 02, 2007 at 10:41:00PM -0500, Dan Zwell wrote:\n>\n>> +sub print_colored {\n>> +\tmy $color = shift;\n>> +\tmy $string = join(\"\", @_);\n>> +\n>> +\tif ($use_color) {\n>> +\t\t# Put a color code at the beginning of each line, a reset at the end\n>> +\t\t# color after newlines that are not at the end of the string\n>> +\t\t$string =~ s/(\\n+)(.)/$1$color$2/g;\n>> +\t\t# reset before newlines\n>> +\t\t$string =~ s/(\\n+)/$normal_color$1/g;\n>> +\t\t# codes at beginning and end (if necessary):\n>> +\t\t$string =~ s/^/$color/;\n>> +\t\t$string =~ s/$/$normal_color/ unless $string =~ /\\n$/;\n>> +\t}\n>> +\tprint $string;\n>> +}\n>\n> This would probably be a bit more readable by marking the regex as\n> multline using /m. Something like:\n>\n>   $string =~ s/^/$color/mg;\n>   $string =~ s/.$/$&$normal_color/mg;\n>\n> which covers both the \"start/end of line\" and \"start/end\" of string\n> cases.\n\nI think you would end up spitting out:\n\n        COLOR something RESET LF COLOR RESET LF\n\ninstead of:\n\n\tCOLOR something RESET LF LF\n\nwhen you get \"something\\n\\n\" if you did that.  Not a big deal,\nthough, as at this point we would be human I/O bound.\n\n> Also, if there is to be pager support for showing diffs, perhaps\n> print_colored needs to take a filehandle argument (or, even simpler,\n> change \"print_colored(...)\" to \"print color(...), so the caller can use\n> print as usual).\n\nMaking it take a FH would be useful.  With that, my\nproof-of-concept patch to add print_diff_hunk would become:\n\n\tsub print_diff_hunk {\n        \tmy ($text) = @_;\n\t\tmy $pager;\n\n                if ($use_pager) {\n\t                open($pager, \"| less\");\n\t\t} else {\n                \t$pager = \\*STDOUT;\n\t\t}\n                for (@$text) {\n\t\t\tprint_colored $pager $color ...\n\t\t}\n                close($pager);\n\t}\n"},{"id":"58217","messageId":"20071104054305.GA13929@sigill.intra.peff.net","threadId":"10263","inReplyTo":"7v640ivagv.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 1/2] Added basic color support to git add --interactive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-04T05:43:06Z","receivedAt":"2007-11-04T05:43:06Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Nov 03, 2007 at 10:36:00PM -0700, Junio C Hamano wrote:\n\n> I think you would end up spitting out:\n> \n>         COLOR something RESET LF COLOR RESET LF\n> \n> instead of:\n> \n> \tCOLOR something RESET LF LF\n> \n> when you get \"something\\n\\n\" if you did that.  Not a big deal,\n> though, as at this point we would be human I/O bound.\n\nYes, though I wonder if the former is \"more correct\" in the sense that\nwe don't know what the attributes are doing, and maybe it matters for\nthem to apply to each line, whether it has text or not.\n\nBut I don't think it's possible for a blank line to actually do anything\nwith the attributes we're currently allowing, and we don't have any\nplans to allow arbitrary terminal control codes in the color specs, so\nit probably doesn't matter.\n\n-Peff\n"},{"id":"59268","messageId":"20071110180109.34febc3f@paradox.zwell.net","threadId":"10263","inReplyTo":"20071104054305.GA13929@sigill.intra.peff.net","subject":"[PATCH 0/3] Adding colors to git-add--interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-11T00:01:09Z","receivedAt":"2007-11-11T00:01:09Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"A bit of a recap--this feature was requested by a user a few weeks\nago, and I wrote a short patch that implemented partial coloring. The\nmain criticisms of this patch were:\n- The name of the configuration key to turn on interactive coloring\nwas not well chosen.\n- The color attribute synonyms \"clear\" and \"reset\" were used\ninterchangeably, though \"reset\" is what the rest of git uses.\n- The colors were not user-settable.\n\nWhen the above were fixed, the new patch garnered the following\ncriticism:\n- The color names accepted in .gitconfig were perl color names (to be\nfed to Term::ANSIColor), and this was not consistent with the rest\nof git. For example, \"red blue ul\" would have to be written, \"red\non_blue underline\".\n\nFixing this (the colors could not be converted by a regex, but had to\nbe parsed) was very libraryish, and also a little confusing. I was\ngiven a suggestion or two about how to make it more readable. This\nparsing also needed to be added to Git.pm instead of\ngit-add--interactive.perl.\n\nIn the next iteration, all of the above were fixed, but as Jeff King\npointed out, I was printing $color before the beginning of a string,\nand printing $clear at the end, which allowed ${COLOR}text\\n${RESET},\nwhich looks bad on some terminals.\n\nLast iteration, it was pointed out that print_colored must take a\nfile handle to pave the way for pager support, and Junio Hamano and Jeff\nKing both gave suggestions as to how, and Junio sent me few changes\nthat allow printing colored diffs in addition to prompts. I ended up\nmaking changes so that the two color functions can be used with perl's\nprint():\nprint colored($color, \"some text\")\nprint color_diff_hunk($hunk)\n\nThis way, file handles can be added directly to the print calls, when\nsupport for $PAGER is added.\n\nLet me know if other things need correction.\n\nDan\n"},{"id":"59270","messageId":"20071110180152.78483719@paradox.zwell.net","threadId":"10263","inReplyTo":"20071104054305.GA13929@sigill.intra.peff.net","subject":"[PATCH 1/3] Added basic color support to git add --interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-11T00:01:52Z","receivedAt":"2007-11-11T00:01:52Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Added function \"colored()\" that prints text with a color that\nis passed in. Converted many calls to \"print\" to being calls to\n\"print colored\".\n\nThe prompt, the header, and the help output are the 3 types of\ncolorized output, and each has its own color.\n\nColorization is done through Term::ANSIColor, which is included\nwith modern versions of perl. This is optional, and should not\nneed to be present if color.interactive is not turned on.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\n Documentation/config.txt  |    6 ++++++\n git-add--interactive.perl |   44\n++++++++++++++++++++++++++++++++++++++------ 2 files changed, 44\ninsertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 8d5d200..3712d6a 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -382,6 +382,12 @@ color.diff.<slot>::\n \twhitespace).  The values of these variables may be specified as\n \tin color.branch.<slot>.\n \n+color.interactive::\n+\tWhen true (or `always`), always use colors in `git add\n+\t--interactive`.  When false (or `never`), never.  When set to\n+\t`auto`, use colors only when the output is to the\n+\tterminal. Defaults to false.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex ac598f8..f2b0e56 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -2,6 +2,38 @@\n \n use strict;\n \n+my ($use_color, $prompt_color, $header_color, $help_color,\n$normal_color); +my $color_config = qx(git config --get\ncolor.interactive); +if ($color_config=~/true|always/ || -t STDOUT &&\n$color_config=~/auto/) {\n+\teval { require Term::ANSIColor; };\n+\tif (!$@) {\n+\t\t$use_color = 1;\n+\n+\t\t# Sane (visible) defaults:\n+\t\t$prompt_color = Term::ANSIColor::color(\"blue bold\");\n+\t\t$header_color = Term::ANSIColor::color(\"bold\");\n+\t\t$help_color   = Term::ANSIColor::color(\"red bold\");\n+\t\t$normal_color = Term::ANSIColor::color(\"reset\");\n+\t}\n+}\n+\n+sub colored {\n+\tmy $color = shift;\n+\tmy $string = join(\"\", @_);\n+\n+\tif ($use_color) {\n+\t\t# Put a color code at the beginning of each line, a\nreset at the end\n+\t\t# color after newlines that are not at the end of the\nstring\n+\t\t$string =~ s/(\\n+)(.)/$1$color$2/g;\n+\t\t# reset before newlines\n+\t\t$string =~ s/(\\n+)/$normal_color$1/g;\n+\t\t# codes at beginning and end (if necessary):\n+\t\t$string =~ s/^/$color/;\n+\t\t$string =~ s/$/$normal_color/ unless $string =~ /\\n$/;\n+\t}\n+\treturn $string;\n+}\n+\n sub run_cmd_pipe {\n \tif ($^O eq 'MSWin32') {\n \t\tmy @invalid = grep {m/[\":*]/} @_;\n@@ -175,7 +207,7 @@ sub list_and_choose {\n \t\t\tif (!$opts->{LIST_FLAT}) {\n \t\t\t\tprint \"     \";\n \t\t\t}\n-\t\t\tprint \"$opts->{HEADER}\\n\";\n+\t\t\tprint colored $header_color,\n\"$opts->{HEADER}\\n\"; }\n \t\tfor ($i = 0; $i < @stuff; $i++) {\n \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n@@ -205,7 +237,7 @@ sub list_and_choose {\n \n \t\treturn if ($opts->{LIST_ONLY});\n \n-\t\tprint $opts->{PROMPT};\n+\t\tprint colored $prompt_color, $opts->{PROMPT};\n \t\tif ($opts->{SINGLETON}) {\n \t\t\tprint \"> \";\n \t\t}\n@@ -544,7 +576,7 @@ sub coalesce_overlapping_hunks {\n }\n \n sub help_patch_cmd {\n-\tprint <<\\EOF ;\n+\tprint colored $help_color, <<\\EOF ;\n y - stage this hunk\n n - do not stage this hunk\n a - stage this and all the remaining hunks\n@@ -619,7 +651,7 @@ sub patch_update_cmd {\n \t\tfor (@{$hunk[$ix]{TEXT}}) {\n \t\t\tprint;\n \t\t}\n-\t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n+\t\tprint colored $prompt_color, \"Stage this hunk\n[y/n/a/d$other/?]? \"; my $line = <STDIN>;\n \t\tif ($line) {\n \t\t\tif ($line =~ /^y/i) {\n@@ -673,7 +705,7 @@ sub patch_update_cmd {\n \t\t\telsif ($other =~ /s/ && $line =~ /^s/) {\n \t\t\t\tmy @split =\nsplit_hunk($hunk[$ix]{TEXT}); if (1 < @split) {\n-\t\t\t\t\tprint \"Split into \",\n+\t\t\t\t\tprint colored $header_color,\n\"Split into \", scalar(@split), \" hunks.\\n\";\n \t\t\t\t}\n \t\t\t\tsplice(@hunk, $ix, 1,\n@@ -766,7 +798,7 @@ sub quit_cmd {\n }\n \n sub help_cmd {\n-\tprint <<\\EOF ;\n+\tprint colored $help_color, <<\\EOF ;\n status        - show paths with changes\n update        - add working tree state to the staged set of changes\n revert        - revert staged set of changes back to the HEAD version\n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"59258","messageId":"20071110180233.3b2b73f8@paradox.zwell.net","threadId":"10263","inReplyTo":"20071104054305.GA13929@sigill.intra.peff.net","subject":"[PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-11T00:02:33Z","receivedAt":"2007-11-11T00:02:33Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Colors are specified in color.interactive.{prompt,header,help}.\nThey are specified as git color strings as described in the\ndocumentation. The method color_to_ansi_string() in Git.pm parses\nthese strings and returns ANSI color codes (using\nTerm::ANSIColor).\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\n Documentation/config.txt  |    7 +++++\n git-add--interactive.perl |   19 ++++++++++-----\n perl/Git.pm               |   55\n++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 74\ninsertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 3712d6a..47c1ab2 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -388,6 +388,13 @@ color.interactive::\n \t`auto`, use colors only when the output is to the\n \tterminal. Defaults to false.\n \n+color.interactive.<slot>::\n+\tUse customized color for `git add --interactive`\n+\toutput. `<slot>` may be `prompt`, `header`, or `help`, for\n+\tthree distinct types of normal output from interactive\n+\tprograms.  The values of these variables may be specified as\n+\tin color.branch.<slot>.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex f2b0e56..508531f 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -1,6 +1,7 @@\n #!/usr/bin/perl -w\n \n use strict;\n+use Git;\n \n my ($use_color, $prompt_color, $header_color, $help_color,\n$normal_color); my $color_config = qx(git config --get\ncolor.interactive); @@ -8,12 +9,18 @@ if ($color_config=~/true|always/\n|| -t STDOUT && $color_config=~/auto/) { eval { require\nTerm::ANSIColor; }; if (!$@) {\n \t\t$use_color = 1;\n-\n-\t\t# Sane (visible) defaults:\n-\t\t$prompt_color = Term::ANSIColor::color(\"blue bold\");\n-\t\t$header_color = Term::ANSIColor::color(\"bold\");\n-\t\t$help_color   = Term::ANSIColor::color(\"red bold\");\n-\t\t$normal_color = Term::ANSIColor::color(\"reset\");\n+\t\t# Set interactive colors:\n+\n+\t\t# Grab the 3 main colors in git color string format,\nwith sane\n+\t\t# (visible) defaults:\n+\t\tmy $repo = Git->repository();\n+\t\t$prompt_color = Git::color_to_ansi_code(\n+\t\t\tGit::config($repo, \"color.interactive.prompt\")\n|| \"bold blue\");\n+\t\t$header_color = Git::color_to_ansi_code(\n+\t\t\tGit::config($repo, \"color.interactive.header\")\n|| \"bold\");\n+\t\t$help_color = Git::color_to_ansi_code(\n+\t\t\tGit::config($repo, \"color.interactive.help\")\n|| \"red bold\");\n+\t\t$normal_color = Git::color_to_ansi_code(\"normal\");\n \t}\n }\n \ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex dca92c8..c9e661a 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -515,7 +515,6 @@ sub config {\n \t};\n }\n \n-\n =item config_bool ( VARIABLE )\n \n Retrieve the bool configuration C<VARIABLE>. The return value\n@@ -550,6 +549,60 @@ sub config_bool {\n }\n \n \n+=item color_to_ansi_code ( COLOR )\n+\n+Converts a git-style color string, like \"underline blue white\" to\n+an ANSI color code. The code is generated by Term::ANSIColor,\n+after the string is parsed into the format that is accepted by\n+that module. Used as follows:\n+\n+\tprint color_to_ansi_code(\"underline blue white\");\n+\tprint \"some text\";\n+\tprint color_to_ansi_code(\"normal\");\n+\n+=cut\n+\n+sub color_to_ansi_code {\n+\tmy ($git_string) = @_;\n+\tmy @ansi_words;\n+\tmy %attrib_mappings = (\n+\t\t\"bold\"    => \"bold\",\n+\t\t\"ul\"      => \"underline\",\n+\t\t\"blink\"   => \"blink\",\n+\t\t# not supported:\n+\t\t#\"dim\"     => \"\",\n+\t\t\"reverse\" => \"reverse\"\n+\t);\n+\tmy ($fg_done, $word);\n+\n+\tforeach $word (split /\\s+/, $git_string) {\n+\t\tif ($word =~ /normal/) {\n+\t\t\t$fg_done = \"true\";\n+\t\t}\n+\t\telsif ($word =~ /black|red|green|yellow/ ||\n+\t\t\t   $word =~ /blue|magenta|cyan|white/) {\n+\t\t\t# is a color.\n+\t\t\tif ($fg_done) {\n+\t\t\t\t# this is the background\n+\t\t\t\tpush @ansi_words, \"on_\" . $word;\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\t# this is foreground\n+\t\t\t\t$fg_done = \"true\";\n+\t\t\t\tpush @ansi_words, $word;\n+\t\t\t}\n+\t\t}\n+\t\telse {\n+\t\t\t# this is an attribute, not a color.\n+\t\t\tif ($attrib_mappings{$word}) {\n+\t\t\t\tpush(@ansi_words,\n+\t\t\t\t\t $attrib_mappings{$word});\n+\t\t\t}\n+\t\t}\n+\t}\n+\treturn Term::ANSIColor::color(join(\" \", @ansi_words)||\"reset\");\n+}\n+\n =item ident ( TYPE | IDENTSTR )\n \n =item ident_person ( TYPE | IDENTSTR | IDENTARRAY )\n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"59255","messageId":"20071110180344.05a81497@paradox.zwell.net","threadId":"10263","inReplyTo":"20071104054305.GA13929@sigill.intra.peff.net","subject":"[PATCH 3/3] Added diff hunk coloring to git-add--interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-11T00:03:44Z","receivedAt":"2007-11-11T00:03:44Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Added and integrated method \"color_diff_hunk\", which colors\nlines, and returns them in an array. Coloring bad whitespace is\nnot yet supported.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\n git-add--interactive.perl |   58 ++++++++++++++++++++++++++++++++++++++------\n 1 files changed, 50 insertions(+), 8 deletions(-)\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 508531f..d92e8ed 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -3,7 +3,11 @@\n use strict;\n use Git;\n \n+# Prompt colors:\n my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n+# Diff colors:\n+my ($diff_use_color, $new_color, $old_color, $fraginfo_color,\n+    $metainfo_color, $whitespace_color);\n my $color_config = qx(git config --get color.interactive);\n if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n \teval { require Term::ANSIColor; };\n@@ -21,6 +25,24 @@ if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n \t\t$help_color = Git::color_to_ansi_code(\n \t\t\tGit::config($repo, \"color.interactive.help\") || \"red bold\");\n \t\t$normal_color = Git::color_to_ansi_code(\"normal\");\n+\n+\t\t# Do we also set diff colors?\n+\t\tmy $diff_colors = Git::config($repo, \"color.diff\");\n+\t\tif ($diff_colors=~/true/ ||\n+\t\t\t-t STDOUT && $diff_colors=~/auto/) {\n+\t\t\t$diff_use_color = 1;\n+\t\t\t$new_color = Git::color_to_ansi_code(\n+\t\t\t\tGit::config($repo, \"color.diff.new\") || \"green\");\n+\t\t\t$old_color = Git::color_to_ansi_code(\n+\t\t\t\tGit::config($repo, \"color.diff.old\") || \"red\");\n+\t\t\t$fraginfo_color = Git::color_to_ansi_code(\n+\t\t\t\tGit::config($repo, \"color.diff.frag\") || \"cyan\");\n+\t\t\t$metainfo_color = Git::color_to_ansi_code(\n+\t\t\t\tGit::config($repo, \"color.diff.meta\") || \"bold\");\n+\t\t\t# Not implemented:\n+\t\t\t#$whitespace_color = Git::color_to_ansi_code(\n+\t\t\t\t#Git::config($repo, \"color.diff.whitespace\") || \"normal red\");\n+\t\t}\n \t}\n }\n \n@@ -389,6 +411,31 @@ sub parse_diff {\n \treturn @hunk;\n }\n \n+sub colored_diff_hunk {\n+\tmy ($text) = @_;\n+\t# return the text, so that it can be passed to print()\n+\tmy @ret;\n+\tfor (@$text) {\n+\t\tif (!$diff_use_color) {\n+\t\t\tpush @ret, $_;\n+\t\t\tnext;\n+\t\t}\n+\n+\t\tif (/^\\+/) {\n+\t\t\tpush @ret, colored($new_color, $_);\n+\t\t} elsif (/^\\-/) {\n+\t\t\tpush @ret, colored($old_color, $_);\n+\t\t} elsif (/^\\@/) {\n+\t\t\tpush @ret, colored($fraginfo_color, $_);\n+\t\t} elsif (/^ /) {\n+\t\t\tpush @ret, colored($normal_color, $_);\n+\t\t} else {\n+\t\t\tpush @ret, colored($metainfo_color, $_);\n+\t\t}\n+\t}\n+\treturn @ret;\n+}\n+\n sub hunk_splittable {\n \tmy ($text) = @_;\n \n@@ -611,9 +658,7 @@ sub patch_update_cmd {\n \tmy ($ix, $num);\n \tmy $path = $it->{VALUE};\n \tmy ($head, @hunk) = parse_diff($path);\n-\tfor (@{$head->{TEXT}}) {\n-\t\tprint;\n-\t}\n+\tprint colored_diff_hunk($head->{TEXT});\n \t$num = scalar @hunk;\n \t$ix = 0;\n \n@@ -655,9 +700,7 @@ sub patch_update_cmd {\n \t\tif (hunk_splittable($hunk[$ix]{TEXT})) {\n \t\t\t$other .= '/s';\n \t\t}\n-\t\tfor (@{$hunk[$ix]{TEXT}}) {\n-\t\t\tprint;\n-\t\t}\n+\t\tprint colored_diff_hunk($hunk[$ix]{TEXT});\n \t\tprint colored $prompt_color, \"Stage this hunk [y/n/a/d$other/?]? \";\n \t\tmy $line = <STDIN>;\n \t\tif ($line) {\n@@ -795,8 +838,7 @@ sub diff_cmd {\n \t\t\t\t     HEADER => $status_head, },\n \t\t\t\t   @mods);\n \treturn if (!@them);\n-\tsystem(qw(git diff-index -p --cached HEAD --),\n-\t       map { $_->{VALUE} } @them);\n+\tsystem(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);\n }\n \n sub quit_cmd {\n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"59284","messageId":"20071110202155.0cc3c401@paradox.zwell.net","threadId":"10263","inReplyTo":"20071104054305.GA13929@sigill.intra.peff.net","subject":"[PATCH 0/3] Adding colors to git-add--interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-11T02:21:55Z","receivedAt":"2007-11-11T02:21:55Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"[Note: I'm resending this because it looks like this e-mail didn't go\nout properly. Sorry for duplicates.]\n\nA bit of a recap--this feature was\nrequested by a user a few weeks ago, and I wrote a short patch that\nimplemented partial coloring. The main criticisms of this patch were:\n- The name of the configuration key to turn on interactive coloring\nwas not well chosen.\n- The color attribute synonyms \"clear\" and \"reset\" were used\ninterchangeably, though \"reset\" is what the rest of git uses.\n- The colors were not user-settable.\n\nWhen the above were fixed, the new patch garnered the following\ncriticism:\n- The color names accepted in .gitconfig were perl color names (to be\nfed to Term::ANSIColor), and this was not consistent with the rest\nof git. For example, \"red blue ul\" would have to be written, \"red\non_blue underline\".\n\nFixing this (the colors could not be converted by a regex, but had to\nbe parsed) was very libraryish, and also a little confusing. I was\ngiven a suggestion or two about how to make it more readable. This\nparsing also needed to be added to Git.pm instead of\ngit-add--interactive.perl.\n\nIn the next iteration, all of the above were fixed, but as Jeff King\npointed out, I was printing $color before the beginning of a string,\nand printing $clear at the end, which allowed ${COLOR}text\\n${RESET},\nwhich looks bad on some terminals.\n\nLast iteration, it was pointed out that print_colored must take a\nfile handle to pave the way for pager support, and Junio Hamano and Jeff\nKing both gave suggestions as to how, and Junio sent me few changes\nthat allow printing colored diffs in addition to prompts. I ended up\nmaking changes so that the two color functions can be used with perl's\nprint():\nprint colored($color, \"some text\")\nprint color_diff_hunk($hunk)\n\nThis way, file handles can be added directly to the print calls, when\nsupport for $PAGER is added.\n\nLet me know if other things need correction.\n\nDan\n"},{"id":"59262","messageId":"20071110202319.1f89a755@paradox.zwell.net","threadId":"10263","inReplyTo":"20071104054305.GA13929@sigill.intra.peff.net","subject":"Subject: [PATCH 1/3] Added basic color support to git add --interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-11T02:23:19Z","receivedAt":"2007-11-11T02:23:19Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Added function \"colored()\" that prints text with a color that\nis passed in. Converted many calls to \"print\" to being calls to\n\"print colored\".\n\nThe prompt, the header, and the help output are the 3 types of\ncolorized output, and each has its own color.\n\nColorization is done through Term::ANSIColor, which is included\nwith modern versions of perl. This is optional, and should not\nneed to be present if color.interactive is not turned on.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\nThe last version of this e-mail was line wrapped, if it was \nsuccessfully sent at all...\n Documentation/config.txt  |    6 ++++++\n git-add--interactive.perl |   44 ++++++++++++++++++++++++++++++++++++++------\n 2 files changed, 44 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 8d5d200..3712d6a 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -382,6 +382,12 @@ color.diff.<slot>::\n \twhitespace).  The values of these variables may be specified as\n \tin color.branch.<slot>.\n \n+color.interactive::\n+\tWhen true (or `always`), always use colors in `git add\n+\t--interactive`.  When false (or `never`), never.  When set to\n+\t`auto`, use colors only when the output is to the\n+\tterminal. Defaults to false.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex ac598f8..f2b0e56 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -2,6 +2,38 @@\n \n use strict;\n \n+my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n+my $color_config = qx(git config --get color.interactive);\n+if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n+\teval { require Term::ANSIColor; };\n+\tif (!$@) {\n+\t\t$use_color = 1;\n+\n+\t\t# Sane (visible) defaults:\n+\t\t$prompt_color = Term::ANSIColor::color(\"blue bold\");\n+\t\t$header_color = Term::ANSIColor::color(\"bold\");\n+\t\t$help_color   = Term::ANSIColor::color(\"red bold\");\n+\t\t$normal_color = Term::ANSIColor::color(\"reset\");\n+\t}\n+}\n+\n+sub colored {\n+\tmy $color = shift;\n+\tmy $string = join(\"\", @_);\n+\n+\tif ($use_color) {\n+\t\t# Put a color code at the beginning of each line, a reset at the end\n+\t\t# color after newlines that are not at the end of the string\n+\t\t$string =~ s/(\\n+)(.)/$1$color$2/g;\n+\t\t# reset before newlines\n+\t\t$string =~ s/(\\n+)/$normal_color$1/g;\n+\t\t# codes at beginning and end (if necessary):\n+\t\t$string =~ s/^/$color/;\n+\t\t$string =~ s/$/$normal_color/ unless $string =~ /\\n$/;\n+\t}\n+\treturn $string;\n+}\n+\n sub run_cmd_pipe {\n \tif ($^O eq 'MSWin32') {\n \t\tmy @invalid = grep {m/[\":*]/} @_;\n@@ -175,7 +207,7 @@ sub list_and_choose {\n \t\t\tif (!$opts->{LIST_FLAT}) {\n \t\t\t\tprint \"     \";\n \t\t\t}\n-\t\t\tprint \"$opts->{HEADER}\\n\";\n+\t\t\tprint colored $header_color, \"$opts->{HEADER}\\n\";\n \t\t}\n \t\tfor ($i = 0; $i < @stuff; $i++) {\n \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n@@ -205,7 +237,7 @@ sub list_and_choose {\n \n \t\treturn if ($opts->{LIST_ONLY});\n \n-\t\tprint $opts->{PROMPT};\n+\t\tprint colored $prompt_color, $opts->{PROMPT};\n \t\tif ($opts->{SINGLETON}) {\n \t\t\tprint \"> \";\n \t\t}\n@@ -544,7 +576,7 @@ sub coalesce_overlapping_hunks {\n }\n \n sub help_patch_cmd {\n-\tprint <<\\EOF ;\n+\tprint colored $help_color, <<\\EOF ;\n y - stage this hunk\n n - do not stage this hunk\n a - stage this and all the remaining hunks\n@@ -619,7 +651,7 @@ sub patch_update_cmd {\n \t\tfor (@{$hunk[$ix]{TEXT}}) {\n \t\t\tprint;\n \t\t}\n-\t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n+\t\tprint colored $prompt_color, \"Stage this hunk [y/n/a/d$other/?]? \";\n \t\tmy $line = <STDIN>;\n \t\tif ($line) {\n \t\t\tif ($line =~ /^y/i) {\n@@ -673,7 +705,7 @@ sub patch_update_cmd {\n \t\t\telsif ($other =~ /s/ && $line =~ /^s/) {\n \t\t\t\tmy @split = split_hunk($hunk[$ix]{TEXT});\n \t\t\t\tif (1 < @split) {\n-\t\t\t\t\tprint \"Split into \",\n+\t\t\t\t\tprint colored $header_color, \"Split into \",\n \t\t\t\t\tscalar(@split), \" hunks.\\n\";\n \t\t\t\t}\n \t\t\t\tsplice(@hunk, $ix, 1,\n@@ -766,7 +798,7 @@ sub quit_cmd {\n }\n \n sub help_cmd {\n-\tprint <<\\EOF ;\n+\tprint colored $help_color, <<\\EOF ;\n status        - show paths with changes\n update        - add working tree state to the staged set of changes\n revert        - revert staged set of changes back to the HEAD version\n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"59263","messageId":"20071110202351.7b4544aa@paradox.zwell.net","threadId":"10263","inReplyTo":"20071104054305.GA13929@sigill.intra.peff.net","subject":"Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-11T02:23:51Z","receivedAt":"2007-11-11T02:23:51Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Colors are specified in color.interactive.{prompt,header,help}.\nThey are specified as git color strings as described in the\ndocumentation. The method color_to_ansi_string() in Git.pm parses\nthese strings and returns ANSI color codes (using\nTerm::ANSIColor).\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\nThe last version of this e-mail was line wrapped, if it was \nsuccessfully sent at all.\n\n Documentation/config.txt  |    7 +++++\n git-add--interactive.perl |   19 ++++++++++-----\n perl/Git.pm               |   55 ++++++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 74 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 3712d6a..47c1ab2 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -388,6 +388,13 @@ color.interactive::\n \t`auto`, use colors only when the output is to the\n \tterminal. Defaults to false.\n \n+color.interactive.<slot>::\n+\tUse customized color for `git add --interactive`\n+\toutput. `<slot>` may be `prompt`, `header`, or `help`, for\n+\tthree distinct types of normal output from interactive\n+\tprograms.  The values of these variables may be specified as\n+\tin color.branch.<slot>.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex f2b0e56..508531f 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -1,6 +1,7 @@\n #!/usr/bin/perl -w\n \n use strict;\n+use Git;\n \n my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n my $color_config = qx(git config --get color.interactive);\n@@ -8,12 +9,18 @@ if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n \teval { require Term::ANSIColor; };\n \tif (!$@) {\n \t\t$use_color = 1;\n-\n-\t\t# Sane (visible) defaults:\n-\t\t$prompt_color = Term::ANSIColor::color(\"blue bold\");\n-\t\t$header_color = Term::ANSIColor::color(\"bold\");\n-\t\t$help_color   = Term::ANSIColor::color(\"red bold\");\n-\t\t$normal_color = Term::ANSIColor::color(\"reset\");\n+\t\t# Set interactive colors:\n+\n+\t\t# Grab the 3 main colors in git color string format, with sane\n+\t\t# (visible) defaults:\n+\t\tmy $repo = Git->repository();\n+\t\t$prompt_color = Git::color_to_ansi_code(\n+\t\t\tGit::config($repo, \"color.interactive.prompt\") || \"bold blue\");\n+\t\t$header_color = Git::color_to_ansi_code(\n+\t\t\tGit::config($repo, \"color.interactive.header\") || \"bold\");\n+\t\t$help_color = Git::color_to_ansi_code(\n+\t\t\tGit::config($repo, \"color.interactive.help\") || \"red bold\");\n+\t\t$normal_color = Git::color_to_ansi_code(\"normal\");\n \t}\n }\n \ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex dca92c8..c9e661a 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -515,7 +515,6 @@ sub config {\n \t};\n }\n \n-\n =item config_bool ( VARIABLE )\n \n Retrieve the bool configuration C<VARIABLE>. The return value\n@@ -550,6 +549,60 @@ sub config_bool {\n }\n \n \n+=item color_to_ansi_code ( COLOR )\n+\n+Converts a git-style color string, like \"underline blue white\" to\n+an ANSI color code. The code is generated by Term::ANSIColor,\n+after the string is parsed into the format that is accepted by\n+that module. Used as follows:\n+\n+\tprint color_to_ansi_code(\"underline blue white\");\n+\tprint \"some text\";\n+\tprint color_to_ansi_code(\"normal\");\n+\n+=cut\n+\n+sub color_to_ansi_code {\n+\tmy ($git_string) = @_;\n+\tmy @ansi_words;\n+\tmy %attrib_mappings = (\n+\t\t\"bold\"    => \"bold\",\n+\t\t\"ul\"      => \"underline\",\n+\t\t\"blink\"   => \"blink\",\n+\t\t# not supported:\n+\t\t#\"dim\"     => \"\",\n+\t\t\"reverse\" => \"reverse\"\n+\t);\n+\tmy ($fg_done, $word);\n+\n+\tforeach $word (split /\\s+/, $git_string) {\n+\t\tif ($word =~ /normal/) {\n+\t\t\t$fg_done = \"true\";\n+\t\t}\n+\t\telsif ($word =~ /black|red|green|yellow/ ||\n+\t\t\t   $word =~ /blue|magenta|cyan|white/) {\n+\t\t\t# is a color.\n+\t\t\tif ($fg_done) {\n+\t\t\t\t# this is the background\n+\t\t\t\tpush @ansi_words, \"on_\" . $word;\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\t# this is foreground\n+\t\t\t\t$fg_done = \"true\";\n+\t\t\t\tpush @ansi_words, $word;\n+\t\t\t}\n+\t\t}\n+\t\telse {\n+\t\t\t# this is an attribute, not a color.\n+\t\t\tif ($attrib_mappings{$word}) {\n+\t\t\t\tpush(@ansi_words,\n+\t\t\t\t\t $attrib_mappings{$word});\n+\t\t\t}\n+\t\t}\n+\t}\n+\treturn Term::ANSIColor::color(join(\" \", @ansi_words)||\"reset\");\n+}\n+\n =item ident ( TYPE | IDENTSTR )\n \n =item ident_person ( TYPE | IDENTSTR | IDENTARRAY )\n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"59285","messageId":"20071111075446.GA26985@sigill.intra.peff.net","threadId":"10263","inReplyTo":"20071110180109.34febc3f@paradox.zwell.net","subject":"Re: [PATCH 0/3] Adding colors to git-add--interactive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-11T07:54:47Z","receivedAt":"2007-11-11T07:54:47Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Nov 10, 2007 at 06:01:09PM -0600, Dan Zwell wrote:\n\n> A bit of a recap--this feature was requested by a user a few weeks\n\nThanks for the recap; there have been enough iterations of this series\nthat at least I forgot what was going on. The patches look reasonable,\nbut I have a few comments (hopefully you have enough \"umph\" for one more\niteration). I'll just inline them here.\n\n[patch 1/3]:\n> +my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n> +my $color_config = qx(git config --get color.interactive);\n\nWhy call git config here manually, but Git::config later (I think the\nanswer is \"because we don't call Git::config until a later patch\", but it\nis probably best to remain consistent).\n\n> +sub colored {\n> +\tmy $color = shift;\n> +\tmy $string = join(\"\", @_);\n> +\n> +\tif ($use_color) {\n> +\t\t# Put a color code at the beginning of each line, a reset at the end\n> +\t\t# color after newlines that are not at the end of the string\n> +\t\t$string =~ s/(\\n+)(.)/$1$color$2/g;\n> +\t\t# reset before newlines\n> +\t\t$string =~ s/(\\n+)/$normal_color$1/g;\n> +\t\t# codes at beginning and end (if necessary):\n> +\t\t$string =~ s/^/$color/;\n> +\t\t$string =~ s/$/$normal_color/ unless $string =~ /\\n$/;\n> +\t}\n> +\treturn $string;\n> +}\n\nThis also seems like a candidate for lib-ification in Git.pm, alongside\ncolor_to_ansi_code.\n\n> -\t\t\tprint \"$opts->{HEADER}\\n\";\n> +\t\t\tprint colored $header_color, \"$opts->{HEADER}\\n\";\n\nI don't know if we have a style policy on calling\n\n  user_defined_function $foo, $bar;\n\nrather than\n\n  user_defined_function($foo, $bar);\n\nIn fact, I don't know that we have much perl style policy at all. But I\ntend to shy away from the former because then the syntax requires that\n\"colored\" is always defined before the calling spot.\n\n[patch 2/3]:\n> +\t\t# Grab the 3 main colors in git color string format, with sane\n> +\t\t# (visible) defaults:\n> +\t\tmy $repo = Git->repository();\n> +\t\t$prompt_color = Git::color_to_ansi_code(\n> +\t\t\tGit::config($repo, \"color.interactive.prompt\") || \"bold blue\");\n> +\t\t$header_color = Git::color_to_ansi_code(\n> +\t\t\tGit::config($repo, \"color.interactive.header\") || \"bold\");\n> +\t\t$help_color = Git::color_to_ansi_code(\n> +\t\t\tGit::config($repo, \"color.interactive.help\") || \"red bold\");\n> +\t\t$normal_color = Git::color_to_ansi_code(\"normal\");\n\nIt is much more common (and proper OO, in the face of inheritance) to\nuse\n\n   $repo->config(\"color.interactive.prompt\")\n\n> +=item color_to_ansi_code ( COLOR )\n> +\n> +Converts a git-style color string, like \"underline blue white\" to\n> +an ANSI color code. The code is generated by Term::ANSIColor,\n> +after the string is parsed into the format that is accepted by\n> +that module. Used as follows:\n> +\n> +\tprint color_to_ansi_code(\"underline blue white\");\n> +\tprint \"some text\";\n> +\tprint color_to_ansi_code(\"normal\");\n\nYay, documentation!  It would also be nice to have a test script that\nruns this through a few more complex git color specs.\n\n> +\tmy %attrib_mappings = (\n> +\t\t\"bold\"    => \"bold\",\n> +\t\t\"ul\"      => \"underline\",\n> +\t\t\"blink\"   => \"blink\",\n> +\t\t# not supported:\n> +\t\t#\"dim\"     => \"\",\n\nWhy not? I don't especially care about \"dim\" support, but if there is a\ngood reason, then you should note it.\n\n> +\tforeach $word (split /\\s+/, $git_string) {\n> +\t\tif ($word =~ /normal/) {\n> +\t\t\t$fg_done = \"true\";\n> +\t\t}\n\nWhy a regex instead of 'eq'? Also, should this be case insensitive?\n\n> +\t\telsif ($word =~ /black|red|green|yellow/ ||\n> +\t\t\t   $word =~ /blue|magenta|cyan|white/) {\n\nIt looks like you are doing two regexes here just to meet whitespace\nguidelines. Look into the '/x' modifier to make your regex prettier (but\nagain, consider 'eq').\n\n> +\treturn Term::ANSIColor::color(join(\" \", @ansi_words)||\"reset\");\n\nStyle: whitespace around ||\n\n[patch 3/3]:\n> +\t\t\t# Not implemented:\n> +\t\t\t#$whitespace_color = Git::color_to_ansi_code(\n> +\t\t\t\t#Git::config($repo, \"color.diff.whitespace\") || \"normal red\");\n\nPersonally I would have just excluded the parsing, since it isn't\nimplemented, but I don't think it matters.\n\n> +sub colored_diff_hunk {\n\nPerhaps this should also go in Git.pm? Though right now I don't know\nwhich other perl scripts would actually want to colorize a diff, so I\ndon't think it matters.\n\n> -\tsystem(qw(git diff-index -p --cached HEAD --),\n> -\t       map { $_->{VALUE} } @them);\n> +\tsystem(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);\n\nNow this was a surprise after reading the commit message.\n\n-Peff\n"},{"id":"59288","messageId":"7vzlxlgpgt.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071111075446.GA26985@sigill.intra.peff.net","subject":"Re: [PATCH 0/3] Adding colors to git-add--interactive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-11T08:23:46Z","receivedAt":"2007-11-11T08:23:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n>> -\tsystem(qw(git diff-index -p --cached HEAD --),\n>> -\t       map { $_->{VALUE} } @them);\n>> +\tsystem(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);\n>\n> Now this was a surprise after reading the commit message.\n\nThis hunk makes the \"show diff\" subcommand honor user's external\ndiff viewer if specified, which is a good change.  But it does\nnot belong to the \"colored add -i\" series.\n\nI mildly suspect that this change might have been my fault, but\nI think it should be treated in an independent patch anyway.\n"},{"id":"59296","messageId":"4736BFB6.7050505@zwell.net","threadId":"10263","inReplyTo":"7vzlxlgpgt.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 0/3] Adding colors to git-add--interactive","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-11-11T08:39:18Z","receivedAt":"2007-11-11T08:39:18Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"Junio C Hamano wrote:\n> This hunk makes the \"show diff\" subcommand honor user's external\n> diff viewer if specified, which is a good change.  But it does\n> not belong to the \"colored add -i\" series.\n> \n> I mildly suspect that this change might have been my fault, but\n> I think it should be treated in an independent patch anyway.\n> \n\nYep, that change was part of Junio's hunk coloring patch that he sent in \nreply to my last set of patches. When I revise this, I'll drop that change.\n\nDan\n"},{"id":"59302","messageId":"7vve89f6qy.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071110202351.7b4544aa@paradox.zwell.net","subject":"Re: Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-11T09:53:25Z","receivedAt":"2007-11-11T09:53:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Zwell <dzwell@zwell.net> writes:\n\n> @@ -8,12 +9,18 @@ if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {\n>  \teval { require Term::ANSIColor; };\n>  \tif (!$@) {\n>  \t\t$use_color = 1;\n> +\t\t# Set interactive colors:\n> +\n> +\t\t# Grab the 3 main colors in git color string format, with sane\n> +\t\t# (visible) defaults:\n> +\t\tmy $repo = Git->repository();\n> +\t\t$prompt_color = Git::color_to_ansi_code(\n> +\t\t\tGit::config($repo, \"color.interactive.prompt\") || \"bold blue\");\n> +\t\t$header_color = Git::color_to_ansi_code(\n> +\t\t\tGit::config($repo, \"color.interactive.header\") || \"bold\");\n> +\t\t$help_color = Git::color_to_ansi_code(\n> +\t\t\tGit::config($repo, \"color.interactive.help\") || \"red bold\");\n> +\t\t$normal_color = Git::color_to_ansi_code(\"normal\");\n\nMakes me wonder if you are better off with two new helper\nfunctions defined in Git.pm, as in:\n\n\t$prompt_color = $repo->config_color(\"interactive.prompt\") || \"bold blue\")\n\t$normal_color = Git::color_to_ansi_code(\"normal\");\n\n> +sub color_to_ansi_code {\n> +\tmy ($git_string) = @_;\n> +\tmy @ansi_words;\n> +\tmy %attrib_mappings = (\n> +\t\t\"bold\"    => \"bold\",\n> +\t\t\"ul\"      => \"underline\",\n> +\t\t\"blink\"   => \"blink\",\n> +\t\t# not supported:\n> +\t\t#\"dim\"     => \"\",\n> +\t\t\"reverse\" => \"reverse\"\n> +\t);\n\nI do not like a hash variable name that says it is a \"mapping\".\nIt being a hash is enough indication that it is a mapping.\n\nYou are better off naming such a mapping as if it is a function\nthat takes one parameter (in this case, git name) and returns a\nsingle value (perl name).  So I'd probably say:\n\n\tmy %perl_attrib = ( ... );\n\n(or \"git_attrib_to_perl\").  A use site of such a hash would look\nlike this:\n\n\tpush @perl_words, $perl_attrib{'ul'};\n        push @perl_names, $git_attrib_to_perl{'blink'};\n\nMaybe it is just me, but aren't these easier to read?\n\n> +\tmy ($fg_done, $word);\n> +\n> +\tforeach $word (split /\\s+/, $git_string) {\n> +\t\tif ($word =~ /normal/) {\n\n\t$word eq 'normal' ?\n\n> +\t\t\t$fg_done = \"true\";\n> +\t\t}\n> +\t\telsif ($word =~ /black|red|green|yellow/ ||\n> +\t\t\t   $word =~ /blue|magenta|cyan|white/) {\n\n\texists $color_name{$word}\n\nwith\n\n\tmy %color_name = map { $_ => 1 } qw(black red ... white);\n\nat the beginning?\n\n> +\t\t\t# is a color.\n> +\t\t\tif ($fg_done) {\n> +\t\t\t\t# this is the background\n> +\t\t\t\tpush @ansi_words, \"on_\" . $word;\n> +\t\t\t}\n> +\t\t\telse {\n> +\t\t\t\t# this is foreground\n> +\t\t\t\t$fg_done = \"true\";\n> +\t\t\t\tpush @ansi_words, $word;\n> +\t\t\t}\n> +\t\t}\n> +\t\telse {\n> +\t\t\t# this is an attribute, not a color.\n> +\t\t\tif ($attrib_mappings{$word}) {\n\n\texists $git_attrib_to_perl{$word}\n\n?\n"},{"id":"59303","messageId":"7vlk95f6fb.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071110180344.05a81497@paradox.zwell.net","subject":"Re: [PATCH 3/3] Added diff hunk coloring to git-add--interactive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-11T10:00:24Z","receivedAt":"2007-11-11T10:00:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Zwell <dzwell@zwell.net> writes:\n\n> +sub colored_diff_hunk {\n> +\tmy ($text) = @_;\n> +\t# return the text, so that it can be passed to print()\n> +\tmy @ret;\n> +\tfor (@$text) {\n> +\t\tif (!$diff_use_color) {\n> +\t\t\tpush @ret, $_;\n> +\t\t\tnext;\n> +\t\t}\n\nIt would be better to do the \"if (!$diff_use_color)\" part\nupfront before entering the loop, wouldn't it?\n\n\tsub colored_diff_hunk {\n        \tmy ($text) = @_;\n\t\tif (!$diff_use_color) {\n\t                return @$text;\n\t\t}\n\n                my @ret;\n                for (@$text) {\n                \t...\n\t\t}\n\t}\n"},{"id":"59305","messageId":"7vabplf4ug.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"7vve89f6qy.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-11T10:34:31Z","receivedAt":"2007-11-11T10:34:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Makes me wonder if you are better off with two new helper\n> functions defined in Git.pm, as in:\n>\n> \t$prompt_color = $repo->config_color(\"interactive.prompt\") || \"bold blue\")\n> \t$normal_color = Git::color_to_ansi_code(\"normal\");\n\nSorry, but please disregard.  \"bold blue\" part was also\nparameter to the string-to-ansi-color-escape function, so the\nabove does not make much sense.\n"},{"id":"59370","messageId":"7vve88d09e.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071110202319.1f89a755@paradox.zwell.net","subject":"Re: Subject: [PATCH 1/3] Added basic color support to git add --interactive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-11T19:56:29Z","receivedAt":"2007-11-11T19:56:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Zwell <dzwell@zwell.net> writes:\n\n> Added function \"colored()\" that prints text with a color that\n> is passed in. Converted many calls to \"print\" to being calls to\n> \"print colored\".\n\nYou said \"Let me know if other things need correction.\"  I think\nmost of the comments you recieved were about improvements not\ncorrection, and I think I am going to say in this message will\nalso mostly fall into that category.\n\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index 8d5d200..3712d6a 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -382,6 +382,12 @@ color.diff.<slot>::\n>  \twhitespace).  The values of these variables may be specified as\n>  \tin color.branch.<slot>.\n>  \n> +color.interactive::\n> +\tWhen true (or `always`), always use colors in `git add\n> +\t--interactive`.  When false (or `never`), never.  When set to\n> +\t`auto`, use colors only when the output is to the\n> +\tterminal. Defaults to false.\n> +\n\nI think \"auto\" should disable colors even when the output is \"-t\nSTDOUT\" if $TERM eq \"dumb\" (see color.c::git_config_colorbool()).\n\n> @@ -175,7 +207,7 @@ sub list_and_choose {\n>  \t\t\tif (!$opts->{LIST_FLAT}) {\n>  \t\t\t\tprint \"     \";\n>  \t\t\t}\n> -\t\t\tprint \"$opts->{HEADER}\\n\";\n> +\t\t\tprint colored $header_color, \"$opts->{HEADER}\\n\";\n\nI agree with Jeff's suggestion to stick to more C-ish style to\nalways use parentheses around function arguments.\n"},{"id":"59605","messageId":"47390050.1020907@zwell.net","threadId":"10263","inReplyTo":"7vve89f6qy.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-11-13T01:39:28Z","receivedAt":"2007-11-13T01:39:28Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"Junio C Hamano wrote:\n>> +\t\t\t$fg_done = \"true\";\n>> +\t\t}\n>> +\t\telsif ($word =~ /black|red|green|yellow/ ||\n>> +\t\t\t   $word =~ /blue|magenta|cyan|white/) {\n> \n> \texists $color_name{$word}\n> \n> with\n> \n> \tmy %color_name = map { $_ => 1 } qw(black red ... white);\n> \n> at the beginning?\n> \nI don't see the advantage of doing it that way. After all, we're pattern \nmatching. Does using a hash, an array, and a call to map() gain us \nsomething? I think a regular expression is clearer. Of course, as Jeff \npointed out, I should have used a whitespace-agnostic regular expression.\n+\t\telsif ($word =~ /black|red|green|yellow|\n+\t\t\tblue|magenta|cyan|white/x ) {\n\nI agreed with the rest of your suggestions, and will implement them in \nthe next round of changes, later this week.\n\nDan\n"},{"id":"59606","messageId":"7v4pfq27tx.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"47390050.1020907@zwell.net","subject":"Re: Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-13T02:32:58Z","receivedAt":"2007-11-13T02:32:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Zwell <dzwell@gmail.com> writes:\n\n> Junio C Hamano wrote:\n>>> +\t\t\t$fg_done = \"true\";\n>>> +\t\t}\n>>> +\t\telsif ($word =~ /black|red|green|yellow/ ||\n>>> +\t\t\t   $word =~ /blue|magenta|cyan|white/) {\n>>\n>> \texists $color_name{$word}\n>>\n>> with\n>>\n>> \tmy %color_name = map { $_ => 1 } qw(black red ... white);\n>>\n>> at the beginning?\n>>\n> I don't see the advantage of doing it that way. After all, we're\n> pattern matching. Does using a hash, an array, and a call to map()\n> gain us something? I think a regular expression is clearer. Of course,\n> as Jeff pointed out, I should have used a whitespace-agnostic regular\n> expression.\n\nI suggested the hash approach only because (1) it is easier to\nread than two regexp matches that are split only to keep the\nline less than 80-chars long, and (2) a misconfiguration like\n\"color.foo = fred\" can be caught more easily.\n\nI do not quite understand the \"after all, we're pattern\nmatching\" part, though.  Are you talking about \"split(/\\s+/, $str)\" \nyour for-loop iterates over?\n"},{"id":"59608","messageId":"47391211.5000606@zwell.net","threadId":"10263","inReplyTo":"7v4pfq27tx.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-11-13T02:55:13Z","receivedAt":"2007-11-13T02:55:13Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"Junio C Hamano wrote:\n> I suggested the hash approach only because (1) it is easier to\n> read than two regexp matches that are split only to keep the\n> line less than 80-chars long, and (2) a misconfiguration like\n> \"color.foo = fred\" can be caught more easily.\n> \n> I do not quite understand the \"after all, we're pattern\n> matching\" part, though.  Are you talking about \"split(/\\s+/, $str)\" \n> your for-loop iterates over?\n> \n\nI think we're talking about the same thing. I was referring to the split \nregular expression, and the question is, \"for the current element of \nsplit(/\\s+/, $str), does it match a color?\"\n\nAnyway, I preferred the regex version for readability, though I should \nhave used the /x modifier--it would still take two lines, but it would \nnot need to attempt two matches. As for misconfigured color \nconfigurations, should we catch that? I wrote this with the intent that \nit should ignore invalid color names, but it would probably be more \nuseful to print a warning.\n\nDan\n"},{"id":"59622","messageId":"20071113072629.GA21769@sigill.intra.peff.net","threadId":"10263","inReplyTo":"47391211.5000606@zwell.net","subject":"Re: Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-13T07:26:29Z","receivedAt":"2007-11-13T07:26:29Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Nov 12, 2007 at 08:55:13PM -0600, Dan Zwell wrote:\n\n> Anyway, I preferred the regex version for readability, though I should have \n> used the /x modifier--it would still take two lines, but it would not need \n\nYour regex is wrong, because it doesn't anchor at the beginning and end\nof the string (so /red/ will match \"supercaliredfragilistic\", which is\nprobably not what you want). So you probably want /^red$/, which is\nequivalent to using 'eq' with 'red'. Or, as Junio noted, you are overall\ntrying to say \"is element $word in this list\"; the canonical perl way of\ndoing that is to make the list a hash for quick lookup.\n\n> to attempt two matches. As for misconfigured color configurations, should we \n> catch that? I wrote this with the intent that it should ignore invalid color \n> names, but it would probably be more useful to print a warning.\n\nYour patch doesn't just ignore; sometimes it accidentally matches\ninvalid input (the example above is obviously silly, but consider what\naccidentally omitting the space in \"blinkblack\" would do).\n\n-Peff\n"},{"id":"59624","messageId":"7v4pfqwqln.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"47391211.5000606@zwell.net","subject":"Re: Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-13T07:29:24Z","receivedAt":"2007-11-13T07:29:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Zwell <dzwell@gmail.com> writes:\n\n> ... I wrote this with the intent\n> that it should ignore invalid color names, but it would probably be\n> more useful to print a warning.\n\nBut the point is, that you are not ignoring invalid color names\nbut instead giving back a random match aren't you?\n"},{"id":"59632","messageId":"47395F63.8040306@zwell.net","threadId":"10263","inReplyTo":"7v4pfqwqln.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-11-13T08:25:07Z","receivedAt":"2007-11-13T08:25:07Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"Junio C Hamano wrote:\n> But the point is, that you are not ignoring invalid color names\n> but instead giving back a random match aren't you?\n\nNo, if there's no match, the token is ignored. False matches are \npossible in some cases (the bogus config option \"colored\" would match \n\"red\", for example), so I will follow your suggestion with the hash, \nafter all. I'll send out the next revised patches in a day or two--I've \nmade most of the changes you and Jeff suggested, but I need to double check.\n\nDan\n"},{"id":"59640","messageId":"fhbrpp$ceq$2@ger.gmane.org","threadId":"10263","inReplyTo":"47395F63.8040306@zwell.net","subject":"Re: Subject: [PATCH 2/3] Let git-add--interactive read colors from .gitconfig","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-11-13T09:46:38Z","receivedAt":"2007-11-13T09:46:38Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Dan Zwell wrote:\n\n> Junio C Hamano wrote:\n>> But the point is, that you are not ignoring invalid color names\n>> but instead giving back a random match aren't you?\n> \n> No, if there's no match, the token is ignored. False matches are \n> possible in some cases (the bogus config option \"colored\" would match \n> \"red\", for example),\n\nMatch /\\b(?:red|...)\\b/ then\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"60693","messageId":"20071122045437.46ee4638@paradox.zwell.net","threadId":"10263","inReplyTo":"20071110180109.34febc3f@paradox.zwell.net","subject":"[PATCH 0/5] Colors for git-add--interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-22T10:54:37Z","receivedAt":"2007-11-22T10:54:37Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"There are several changes since the last iteration of the\n\"colors for git-add--interactive\" patch set:\n\n- Added parentheses around arguments to all user-defined functions.\n- Reading the configuration is done in a more organized, robust, and\ncleaner way.\n- Fixed bug where color keys could inappropriately match (\"colored\"\nshould not match \"red\", for example).\n- Users can now set a particular color key to the empty string, and\nthis is equivalent to setting it to \"normal\". (This is the behavior\nexhibited by git-diff.)\n- Color configuration information is case insensitive.\n- Added warnings when color configuration keys contain invalid tokens.\n- Refactored a few variables for stylistic reasons.\n\n\nIssues:\n\n- Does not always properly color the output of git-diff --cc, because\n  the diff-coloring regular expressions do not match every diff line.\n  I'm not sure that git-add--interactive normally gets used in the same\nsituations as git-diff --cc. They don't seem to work well, together,\nfrom the little that I tested (without the color patches applied).\nThere are a few solutions, but I haven't thought of one that's both\nreliable and clean. My impression is that diff --cc is called any time\nthat HEAD has two parents. Is this correct?\n\nDan\n"},{"id":"60657","messageId":"20071122045446.4b904632@paradox.zwell.net","threadId":"10263","inReplyTo":"20071110180109.34febc3f@paradox.zwell.net","subject":"[PATCH 1/5] Added basic color support to git add --interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-22T10:54:46Z","receivedAt":"2007-11-22T10:54:46Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Added function \"colored()\" that prints text with a color that\nis passed in. Converted many calls to \"print\" to being calls to\n\"print colored()\".\n\nThe prompt, the header, and the help output are the 3 types of\ncolorized output, and each has its own color.\n\nColorization is done through Term::ANSIColor, which is included\nwith modern versions of perl. This is optional, and should not\nneed to be present if color.interactive is not turned on.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\n Documentation/config.txt  |    6 ++++\n git-add--interactive.perl |   66 ++++++++++++++++++++++++++++++++++++++++-----\n 2 files changed, 65 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 8d5d200..3712d6a 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -382,6 +382,12 @@ color.diff.<slot>::\n \twhitespace).  The values of these variables may be specified as\n \tin color.branch.<slot>.\n \n+color.interactive::\n+\tWhen true (or `always`), always use colors in `git add\n+\t--interactive`.  When false (or `never`), never.  When set to\n+\t`auto`, use colors only when the output is to the\n+\tterminal. Defaults to false.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex ac598f8..2b5559f 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -1,6 +1,58 @@\n #!/usr/bin/perl -w\n \n use strict;\n+use Git;\n+\n+my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n+\n+{\n+\t# set color options:\n+\tmy $repo = Git->repository();\n+\tmy $color_config = $repo->config('color.interactive');\n+\t$use_color = 0;\n+\tif (!defined $color_config) {\n+\t\t$use_color = 0;\n+\t}\n+\telsif ($color_config =~ /true|always/) {\n+\t\t$use_color = 1;\n+\t}\n+\telsif ($color_config eq 'auto' && -t STDOUT &&\n+\t\t   $ENV{'TERM'} ne 'dumb') {\n+\t\t$use_color = 1;\n+\t}\n+\n+\tif ($use_color) {\n+\t\teval { require Term::ANSIColor; };\n+\t\tif ($@) {\n+\t\t\t# library did not load.\n+\t\t\t$use_color = 0;\n+\t\t}\n+\t\telse { # set up colors\n+\t\t\t# Sane (visible) defaults:\n+\t\t\t$prompt_color = Term::ANSIColor::color('blue bold');\n+\t\t\t$header_color = Term::ANSIColor::color('bold');\n+\t\t\t$help_color   = Term::ANSIColor::color('red bold');\n+\t\t\t$normal_color = Term::ANSIColor::color('reset');\n+\t\t}\n+\t}\n+}\n+\n+sub colored {\n+\tmy $color = shift;\n+\tmy $string = join('', @_);\n+\n+\tif ($use_color) {\n+\t\t# Put a color code at the beginning of each line, a reset at the end\n+\t\t# color after newlines that are not at the end of the string\n+\t\t$string =~ s/(\\n+)(.)/$1$color$2/g;\n+\t\t# reset before newlines\n+\t\t$string =~ s/(\\n+)/$normal_color$1/g;\n+\t\t# codes at beginning and end (if necessary):\n+\t\t$string =~ s/^/$color/;\n+\t\t$string =~ s/$/$normal_color/ unless $string =~ /\\n$/;\n+\t}\n+\treturn $string;\n+}\n \n sub run_cmd_pipe {\n \tif ($^O eq 'MSWin32') {\n@@ -175,7 +227,7 @@ sub list_and_choose {\n \t\t\tif (!$opts->{LIST_FLAT}) {\n \t\t\t\tprint \"     \";\n \t\t\t}\n-\t\t\tprint \"$opts->{HEADER}\\n\";\n+\t\t\tprint colored($header_color, \"$opts->{HEADER}\\n\");\n \t\t}\n \t\tfor ($i = 0; $i < @stuff; $i++) {\n \t\t\tmy $chosen = $chosen[$i] ? '*' : ' ';\n@@ -205,7 +257,7 @@ sub list_and_choose {\n \n \t\treturn if ($opts->{LIST_ONLY});\n \n-\t\tprint $opts->{PROMPT};\n+\t\tprint colored($prompt_color, $opts->{PROMPT});\n \t\tif ($opts->{SINGLETON}) {\n \t\t\tprint \"> \";\n \t\t}\n@@ -544,7 +596,7 @@ sub coalesce_overlapping_hunks {\n }\n \n sub help_patch_cmd {\n-\tprint <<\\EOF ;\n+\tprint colored($help_color, <<\\EOF );\n y - stage this hunk\n n - do not stage this hunk\n a - stage this and all the remaining hunks\n@@ -619,7 +671,7 @@ sub patch_update_cmd {\n \t\tfor (@{$hunk[$ix]{TEXT}}) {\n \t\t\tprint;\n \t\t}\n-\t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n+\t\tprint colored($prompt_color, \"Stage this hunk [y/n/a/d$other/?]? \");\n \t\tmy $line = <STDIN>;\n \t\tif ($line) {\n \t\t\tif ($line =~ /^y/i) {\n@@ -673,8 +725,8 @@ sub patch_update_cmd {\n \t\t\telsif ($other =~ /s/ && $line =~ /^s/) {\n \t\t\t\tmy @split = split_hunk($hunk[$ix]{TEXT});\n \t\t\t\tif (1 < @split) {\n-\t\t\t\t\tprint \"Split into \",\n-\t\t\t\t\tscalar(@split), \" hunks.\\n\";\n+\t\t\t\t\tprint colored($header_color, \"Split into \",\n+\t\t\t\t\t\tscalar(@split), \" hunks.\\n\");\n \t\t\t\t}\n \t\t\t\tsplice(@hunk, $ix, 1,\n \t\t\t\t       map { +{ TEXT => $_, USE => undef } }\n@@ -766,7 +818,7 @@ sub quit_cmd {\n }\n \n sub help_cmd {\n-\tprint <<\\EOF ;\n+\tprint colored($help_color, <<\\EOF );\n status        - show paths with changes\n update        - add working tree state to the staged set of changes\n revert        - revert staged set of changes back to the HEAD version\n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"60658","messageId":"20071122045534.435f01bb@paradox.zwell.net","threadId":"10263","inReplyTo":"20071110180109.34febc3f@paradox.zwell.net","subject":"[PATCH 2/5] Don't return 'undef' in case called in a vector context.","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-22T10:55:34Z","receivedAt":"2007-11-22T10:55:34Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Previously, the Git->repository()->config('non-existent.key')\nevaluated to as true in a vector context. Call 'return' with\nno argument, instead.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\nThis isn't color related, but the next change I make to Git.pm\ndepends on this.\n\n perl/Git.pm |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex dca92c8..6603762 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -508,7 +508,7 @@ sub config {\n \t\tmy $E = shift;\n \t\tif ($E->value() == 1) {\n \t\t\t# Key not found.\n-\t\t\treturn undef;\n+\t\t\treturn;\n \t\t} else {\n \t\t\tthrow $E;\n \t\t}\n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"60660","messageId":"20071122045552.30ca55c2@paradox.zwell.net","threadId":"10263","inReplyTo":"20071110180109.34febc3f@paradox.zwell.net","subject":"[PATCH 3/5] Added config_default($key, $default) to Git.pm","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-22T10:55:52Z","receivedAt":"2007-11-22T10:55:52Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Method returns a configuration value if defined, or the default\nvalue that was passed in, otherwise.\n\nThe main purpose of this method is to allow the empty string to\nbe a valid configuration option, and to replace the following\nconstruct:\n\n$val = $repo->config('my.key') || $default_val\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\n perl/Git.pm |   28 ++++++++++++++++++++++++++++\n 1 files changed, 28 insertions(+), 0 deletions(-)\n\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex 6603762..7327300 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -549,6 +549,34 @@ sub config_bool {\n \t};\n }\n \n+=item config_default ( VARIABLE, DEFAULT )\n+\n+Fetches a configuration option C<VARIABLE>, returning its\n+value if it is defined (it is valid to return the empty string,\n+if that is its value). Otherwise, C<DEFAULT>, a default\n+value, is returned. This method may be a replacement for\n+\n+\tmy $value = $repo->config('my.key') || 'default val';\n+\n+in situations where the empty string is an acceptable return value.\n+This method may also be called in a vector context, when expecting\n+multivars.\n+\n+\tmy @value = $repo->config_default('my.multivar', \\@default_vals);\n+\n+=cut\n+\n+sub config_default {\n+\tmy ($self, $var, $default) = @_;\n+\tif (wantarray) {\n+\t\tmy @value = $self->config($var);\n+\t\treturn @value ? @value : @$default;\n+\t}\n+\telse {\n+\t\tmy $value = $self->config($var);\n+\t\treturn (defined $value) ? $value : $default;\n+\t}\n+}\n \n =item ident ( TYPE | IDENTSTR )\n \n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"60649","messageId":"20071122045606.0232fc2d@paradox.zwell.net","threadId":"10263","inReplyTo":"20071110180109.34febc3f@paradox.zwell.net","subject":"[PATCH 4/5] Let git-add--interactive read colors from configuration","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-22T10:56:06Z","receivedAt":"2007-11-22T10:56:06Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Colors are specified in color.interactive.{prompt,header,help}.\nThey are specified as git color strings as described in the\ndocumentation. The method color_to_ansi_code() in Git.pm parses\nthese strings and returns ANSI color codes (using\nTerm::ANSIColor).\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\n Documentation/config.txt  |    7 ++++\n git-add--interactive.perl |   20 ++++++++---\n perl/Git.pm               |   80 ++++++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 100 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 3712d6a..47c1ab2 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -388,6 +388,13 @@ color.interactive::\n \t`auto`, use colors only when the output is to the\n \tterminal. Defaults to false.\n \n+color.interactive.<slot>::\n+\tUse customized color for `git add --interactive`\n+\toutput. `<slot>` may be `prompt`, `header`, or `help`, for\n+\tthree distinct types of normal output from interactive\n+\tprograms.  The values of these variables may be specified as\n+\tin color.branch.<slot>.\n+\n color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 2b5559f..f76f008 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -6,8 +6,8 @@ use Git;\n my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n \n {\n-\t# set color options:\n \tmy $repo = Git->repository();\n+\t# set interactive color options:\n \tmy $color_config = $repo->config('color.interactive');\n \t$use_color = 0;\n \tif (!defined $color_config) {\n@@ -28,11 +28,19 @@ my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n \t\t\t$use_color = 0;\n \t\t}\n \t\telse { # set up colors\n-\t\t\t# Sane (visible) defaults:\n-\t\t\t$prompt_color = Term::ANSIColor::color('blue bold');\n-\t\t\t$header_color = Term::ANSIColor::color('bold');\n-\t\t\t$help_color   = Term::ANSIColor::color('red bold');\n-\t\t\t$normal_color = Term::ANSIColor::color('reset');\n+\t\t\t# Grab the 3 main colors in git color string format, with sane\n+\t\t\t# (visible) defaults:\n+\t\t\t$prompt_color = Git::color_to_ansi_code(\n+\t\t\t\tscalar $repo->config_default('color.interactive.prompt',\n+\t\t\t\t\t'bold blue'));\n+\t\t\t$header_color = Git::color_to_ansi_code(\n+\t\t\t\tscalar $repo->config_default('color.interactive.header',\n+\t\t\t\t\t'bold'));\n+\t\t\t$help_color = Git::color_to_ansi_code(\n+\t\t\t\tscalar $repo->config_default('color.interactive.help',\n+\t\t\t\t\t'red bold'));\n+\n+\t\t\t$normal_color = Git::color_to_ansi_code('normal');\n \t\t}\n \t}\n }\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex 7327300..18ef6b4 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -515,7 +515,6 @@ sub config {\n \t};\n }\n \n-\n =item config_bool ( VARIABLE )\n \n Retrieve the bool configuration C<VARIABLE>. The return value\n@@ -578,6 +577,85 @@ sub config_default {\n \t}\n }\n \n+=item color_to_ansi_code ( COLOR )\n+\n+Converts a git-style color string, like \"underline blue white\" to\n+an ANSI color code. The code is generated by Term::ANSIColor,\n+after the string is parsed into the format that is accepted by\n+that module. Used as follows:\n+\n+\tprint color_to_ansi_code(\"underline blue white\");\n+\tprint \"some text\";\n+\tprint color_to_ansi_code(\"normal\");\n+\n+color_to_ansi_code('') returns the empty string, and should do\n+nothing when printed.\n+\n+=cut\n+\n+sub color_to_ansi_code {\n+\tmy ($git_string) = @_;\n+\tmy @ansi_words;\n+\tmy %git_to_perl_color = (\n+\t\t'bold'    => 'bold',\n+\t\t'ul'      => 'underline',\n+\t\t'blink'   => 'blink',\n+\t\t'reverse' => 'reverse'\n+\t\t# not supported by Term::ANSIColor:\n+\t\t#'dim'     => ''\n+\t);\n+\tmy %valid_color = map { $_ => 1 } qw(black red green yellow\n+\t\t\t\t\t    blue magenta cyan white);\n+\n+\tmy ($fg_done, $token);\n+\tforeach $token (split /\\s+/, $git_string) {\n+\t\t$token = lc($token);\n+\n+\t\tif ($token eq 'normal') {\n+\t\t\t$fg_done = 1;\n+\t\t}\n+\t\telsif (exists $valid_color{$token}) {\n+\t\t\t# is a color.\n+\t\t\tif ($fg_done) {\n+\t\t\t\t# this is the background\n+\t\t\t\tpush @ansi_words, 'on_' . $token;\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\t# this is foreground\n+\t\t\t\t$fg_done = 1;\n+\t\t\t\tpush @ansi_words, $token;\n+\t\t\t}\n+\t\t}\n+\t\telse {\n+\t\t\t# this is an attribute, not a color.\n+\t\t\tif ($git_to_perl_color{$token}) {\n+\t\t\t\tpush(@ansi_words,\n+\t\t\t\t\t $git_to_perl_color{$token});\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\tprint STDERR 'Warning: bad color or attribute: ';\n+\t\t\t\tprint STDERR \"\\\"$token\\\". Check git configuration.\\n\";\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t# decide what to return--return color codes, 'clear' code, or\n+\t# the empty string, depending on the input we were passed /\n+\t# what we have processed:\n+\tif (@ansi_words) {\n+\t\treturn Term::ANSIColor::color(join(' ', @ansi_words));\n+\t}\n+\telse {\n+\t\tif ($fg_done) {\n+\t\t\t# the git attrib 'normal' was processed\n+\t\t\treturn Term::ANSIColor::color('clear');\n+\t\t}\n+\t\telse {\n+\t\t\treturn '';\n+\t\t}\n+\t}\n+}\n+\n =item ident ( TYPE | IDENTSTR )\n \n =item ident_person ( TYPE | IDENTSTR | IDENTARRAY )\n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"60646","messageId":"20071122045624.405e2b2b@paradox.zwell.net","threadId":"10263","inReplyTo":"20071110180109.34febc3f@paradox.zwell.net","subject":"[PATCH 5/5] Added diff hunk coloring to git-add--interactive","fromName":"Dan Zwell","fromEmail":"dzwell@zwell.net","sentAt":"2007-11-22T10:56:24Z","receivedAt":"2007-11-22T10:56:24Z","isPatch":true,"sender":{"key":"dzwell@zwell.net","avatar":null},"body":"Added and integrated method \"color_diff_hunk\", which colors\nlines, and returns them in an array. Coloring bad whitespace is\nnot yet supported.\n\nSigned-off-by: Dan Zwell <dzwell@zwell.net>\n---\n git-add--interactive.perl |   93 ++++++++++++++++++++++++++++++++++----------\n 1 files changed, 72 insertions(+), 21 deletions(-)\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex f76f008..ba9430c 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -4,9 +4,12 @@ use strict;\n use Git;\n \n my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n+my ($diff_use_color, $new_color, $old_color, $fraginfo_color,\n+\t$metainfo_color, $whitespace_color);\n \n {\n \tmy $repo = Git->repository();\n+\n \t# set interactive color options:\n \tmy $color_config = $repo->config('color.interactive');\n \t$use_color = 0;\n@@ -21,27 +24,55 @@ my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);\n \t\t$use_color = 1;\n \t}\n \n-\tif ($use_color) {\n+\t# set diff color options\n+\tmy $diff_color_config = $repo->config('color.diff');\n+\tif (!defined $diff_color_config) {\n+\t\t$diff_use_color = 0;\n+\t}\n+\telsif ($diff_color_config =~ /true|always/) {\n+\t\t$diff_use_color = 1;\n+\t}\n+\telsif ($diff_color_config eq 'auto' && -t STDOUT &&\n+\t\t   $ENV{'TERM'} ne 'dumb') {\n+\t\t$diff_use_color = 1;\n+\t}\n+\n+\t# load color library if needed\n+\tif ($use_color || $diff_use_color) {\n \t\teval { require Term::ANSIColor; };\n \t\tif ($@) {\n \t\t\t# library did not load.\n \t\t\t$use_color = 0;\n+\t\t\t$diff_use_color = 0;\n \t\t}\n-\t\telse { # set up colors\n-\t\t\t# Grab the 3 main colors in git color string format, with sane\n-\t\t\t# (visible) defaults:\n-\t\t\t$prompt_color = Git::color_to_ansi_code(\n-\t\t\t\tscalar $repo->config_default('color.interactive.prompt',\n-\t\t\t\t\t'bold blue'));\n-\t\t\t$header_color = Git::color_to_ansi_code(\n-\t\t\t\tscalar $repo->config_default('color.interactive.header',\n-\t\t\t\t\t'bold'));\n-\t\t\t$help_color = Git::color_to_ansi_code(\n-\t\t\t\tscalar $repo->config_default('color.interactive.help',\n-\t\t\t\t\t'red bold'));\n+\t}\n \n-\t\t\t$normal_color = Git::color_to_ansi_code('normal');\n-\t\t}\n+\t# convenience function:\n+\tsub get_color {\n+\t\tmy ($key, $default) = @_;\n+\t\treturn Git::color_to_ansi_code(\n+\t\t\tscalar $repo->config_default($key, $default));\n+\t}\n+\t# set interactive colors\n+\tif ($use_color) {\n+\t\t# Grab the 3 main colors in git color string format, with sane\n+\t\t# (visible) defaults:\n+\t\t$prompt_color = get_color('color.interactive.prompt', 'bold blue');\n+\t\t$header_color = get_color('color.interactive.header', 'bold');\n+\t\t$help_color = get_color('color.interactive.help', 'red bold');\n+\t\t$normal_color = Git::color_to_ansi_code('normal');\n+\t}\n+\n+\t# set diff colors\n+\tif ($diff_use_color) {\n+\t\t$new_color = get_color('color.diff.new', 'green');\n+\t\t$old_color = get_color('color.diff.old', 'red');\n+\t\t$fraginfo_color = get_color('color.diff.frag', 'cyan');\n+\t\t$metainfo_color = get_color('color.diff.meta', 'bold');\n+\t\t$normal_color = Git::color_to_ansi_code('normal');\n+\t\t# Not implemented:\n+\t\t#$whitespace_color = get_color('color.diff.whitespace',\n+\t\t\t#'normal red');\n \t}\n }\n \n@@ -410,6 +441,30 @@ sub parse_diff {\n \treturn @hunk;\n }\n \n+sub color_diff_hunk {\n+\t# return the colored text, so that it can be passed to print()\n+\tmy ($text) = @_;\n+\tif (!$diff_use_color) {\n+\t\treturn @$text;\n+\t}\n+\n+\tmy @ret;\n+\tfor (@$text) {\n+\t\tif (/^\\+/) {\n+\t\t\tpush @ret, colored($new_color, $_);\n+\t\t} elsif (/^\\-/) {\n+\t\t\tpush @ret, colored($old_color, $_);\n+\t\t} elsif (/^\\@/) {\n+\t\t\tpush @ret, colored($fraginfo_color, $_);\n+\t\t} elsif (/^ /) {\n+\t\t\tpush @ret, colored($normal_color, $_);\n+\t\t} else {\n+\t\t\tpush @ret, colored($metainfo_color, $_);\n+\t\t}\n+\t}\n+\treturn @ret;\n+}\n+\n sub hunk_splittable {\n \tmy ($text) = @_;\n \n@@ -632,9 +687,7 @@ sub patch_update_cmd {\n \tmy ($ix, $num);\n \tmy $path = $it->{VALUE};\n \tmy ($head, @hunk) = parse_diff($path);\n-\tfor (@{$head->{TEXT}}) {\n-\t\tprint;\n-\t}\n+\tprint color_diff_hunk($head->{TEXT});\n \t$num = scalar @hunk;\n \t$ix = 0;\n \n@@ -676,9 +729,7 @@ sub patch_update_cmd {\n \t\tif (hunk_splittable($hunk[$ix]{TEXT})) {\n \t\t\t$other .= '/s';\n \t\t}\n-\t\tfor (@{$hunk[$ix]{TEXT}}) {\n-\t\t\tprint;\n-\t\t}\n+\t\tprint color_diff_hunk($hunk[$ix]{TEXT});\n \t\tprint colored($prompt_color, \"Stage this hunk [y/n/a/d$other/?]? \");\n \t\tmy $line = <STDIN>;\n \t\tif ($line) {\n-- \n1.5.3.5.565.gf0b83-dirty\n"},{"id":"60673","messageId":"20071122115728.GD12913@sigill.intra.peff.net","threadId":"10263","inReplyTo":"20071122045437.46ee4638@paradox.zwell.net","subject":"Re: [PATCH 0/5] Colors for git-add--interactive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-22T11:57:28Z","receivedAt":"2007-11-22T11:57:28Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 22, 2007 at 04:54:37AM -0600, Dan Zwell wrote:\n\n> - Does not always properly color the output of git-diff --cc, because\n>   the diff-coloring regular expressions do not match every diff line.\n>   I'm not sure that git-add--interactive normally gets used in the same\n> situations as git-diff --cc. They don't seem to work well, together,\n> from the little that I tested (without the color patches applied).\n> There are a few solutions, but I haven't thought of one that's both\n> reliable and clean. My impression is that diff --cc is called any time\n> that HEAD has two parents. Is this correct?\n\nI think the only time that git-add--interactive is likely to see a\ncombined diff is when you have unmerged entries in the index. Something\nlike:\n\n  $ mkdir foo && cd foo && git init\n  $ touch file && git add file && git commit -m added\n  $ echo master >file && git commit -a -m master\n  $ git checkout -b other HEAD^\n  $ echo other >file && git commit -a -m other\n  $ git merge master\n  $ git diff\n\n-Peff\n"},{"id":"60676","messageId":"20071122120619.GE12913@sigill.intra.peff.net","threadId":"10263","inReplyTo":"20071122045534.435f01bb@paradox.zwell.net","subject":"Re: [PATCH 2/5] Don't return 'undef' in case called in a vector context.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-22T12:06:19Z","receivedAt":"2007-11-22T12:06:19Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 22, 2007 at 04:55:34AM -0600, Dan Zwell wrote:\n\n> Previously, the Git->repository()->config('non-existent.key')\n> evaluated to as true in a vector context. Call 'return' with\n> no argument, instead.\n\nI think the reason this works is a subtle issue (well, I had to look it\nup, anyway): return without an argument automatically checks the calling\ncontext and returns the empty list in a list context. So we are\nreturning an empty list now, instead of a list containing a single\nundef. I think it might be useful to explain this a bit better in the\ncommit message.\n\n-Peff\n"},{"id":"60677","messageId":"20071122121402.GF12913@sigill.intra.peff.net","threadId":"10263","inReplyTo":"20071122045552.30ca55c2@paradox.zwell.net","subject":"Re: [PATCH 3/5] Added config_default($key, $default) to Git.pm","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-22T12:14:02Z","receivedAt":"2007-11-22T12:14:02Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 22, 2007 at 04:55:52AM -0600, Dan Zwell wrote:\n\n> Method returns a configuration value if defined, or the default\n> value that was passed in, otherwise.\n> \n> The main purpose of this method is to allow the empty string to\n> be a valid configuration option, and to replace the following\n> construct:\n> \n> $val = $repo->config('my.key') || $default_val\n\nThe config subroutine does not currently take a third argument. Is there\na particular reason not to make $repo->config('my.key', $default_val)\nthe equivalent of config_default?\n\n> +in situations where the empty string is an acceptable return value.\n> +This method may also be called in a vector context, when expecting\n\nThe term \"vector context\" is not commonly used. Most of the perl\ndocumentation calls it \"list context\" (try googling for each and seeing\nthe hit numbers).\n\n-Peff\n"},{"id":"60678","messageId":"20071122121836.GG12913@sigill.intra.peff.net","threadId":"10263","inReplyTo":"20071122045606.0232fc2d@paradox.zwell.net","subject":"Re: [PATCH 4/5] Let git-add--interactive read colors from configuration","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-22T12:18:36Z","receivedAt":"2007-11-22T12:18:36Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 22, 2007 at 04:56:06AM -0600, Dan Zwell wrote:\n\n> +\t\t\t# Grab the 3 main colors in git color string format, with sane\n> +\t\t\t# (visible) defaults:\n> +\t\t\t$prompt_color = Git::color_to_ansi_code(\n> +\t\t\t\tscalar $repo->config_default('color.interactive.prompt',\n> +\t\t\t\t\t'bold blue'));\n\nAnd by the same token as the last message, given that config_* take only\ntwo arguments, is there a reason not to extend them so that\n\n  $repo->config_bool('my.key', 0);\n\nhandles the default. Then I think you could simplify this to just:\n\n  $repo->config_color('color.interactive.prompt', 'bold blue');\n\nand hide the color_to_ansi_code messiness from the script altogether.\n\n-Peff\n"},{"id":"60680","messageId":"20071122122540.GH12913@sigill.intra.peff.net","threadId":"10263","inReplyTo":"20071122045624.405e2b2b@paradox.zwell.net","subject":"Re: [PATCH 5/5] Added diff hunk coloring to git-add--interactive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-22T12:25:41Z","receivedAt":"2007-11-22T12:25:41Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 22, 2007 at 04:56:24AM -0600, Dan Zwell wrote:\n\n> -\t\telse { # set up colors\n> -\t\t\t# Grab the 3 main colors in git color string format, with sane\n> -\t\t\t# (visible) defaults:\n> -\t\t\t$prompt_color = Git::color_to_ansi_code(\n> -\t\t\t\tscalar $repo->config_default('color.interactive.prompt',\n> -\t\t\t\t\t'bold blue'));\n\nThese were just added in the last patch. I know sometimes it is worth\nshowing the progression of work as the patches go, but in this case, I\nthink it is simpler for the reviewers if the first patch which adds a\nchunk of code does it in the final way (even if you need to just say \"I\ndid it this way because there will be reasons later on.\").\n\n> +\tsub get_color {\n> +\t\tmy ($key, $default) = @_;\n> +\t\treturn Git::color_to_ansi_code(\n> +\t\t\tscalar $repo->config_default($key, $default));\n> +\t}\n\nAh, so you agree that this is a good route. I think this should probably\nbe Git::config_color.\n\nThere is also a subtle issue, which is that it pulls the \"$repo\"\nvariable from the outer lexical scope (as Git::config_color, it would\ntake it as the first parameter).\n\n> +\t\t$prompt_color = get_color('color.interactive.prompt', 'bold blue');\n> +\t\t$header_color = get_color('color.interactive.header', 'bold');\n> +\t\t$help_color = get_color('color.interactive.help', 'red bold');\n> +\t\t$normal_color = Git::color_to_ansi_code('normal');\n\nYeah, much nicer to read.\n\n> +\tif ($diff_use_color) {\n> +\t\t$new_color = get_color('color.diff.new', 'green');\n> +\t\t$old_color = get_color('color.diff.old', 'red');\n> +\t\t$fraginfo_color = get_color('color.diff.frag', 'cyan');\n> +\t\t$metainfo_color = get_color('color.diff.meta', 'bold');\n> +\t\t$normal_color = Git::color_to_ansi_code('normal');\n> +\t\t# Not implemented:\n> +\t\t#$whitespace_color = get_color('color.diff.whitespace',\n> +\t\t\t#'normal red');\n\nUnfortunately, there is a historical wart that probably still needs\nsupporting, which is that the original names were diff.color.*. Or have\nwe officially removed support for that yet?\n\n-Peff\n"},{"id":"60700","messageId":"7vve7u3x4g.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071122045437.46ee4638@paradox.zwell.net","subject":"Re: [PATCH 0/5] Colors for git-add--interactive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-22T19:20:47Z","receivedAt":"2007-11-22T19:20:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Zwell <dzwell@zwell.net> writes:\n\n> My impression is that diff --cc is called any time\n> that HEAD has two parents. Is this correct?\n\nYou get combined output when your index is unmerged.\n\nShowing combined output to the user to examine may make sense,\nbut I think you would want to have the user pick from diff\nbetween stage#2 and the work tree for an unmerged entry, if you\nallow to pick hunks during a conflicted merge.\n"},{"id":"60709","messageId":"7vd4u23rpg.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071122045534.435f01bb@paradox.zwell.net","subject":"Re: [PATCH 2/5] Don't return 'undef' in case called in a vector context.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-22T21:17:47Z","receivedAt":"2007-11-22T21:17:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dan Zwell <dzwell@zwell.net> writes:\n\n> diff --git a/perl/Git.pm b/perl/Git.pm\n> index dca92c8..6603762 100644\n> --- a/perl/Git.pm\n> +++ b/perl/Git.pm\n> @@ -508,7 +508,7 @@ sub config {\n>  \t\tmy $E = shift;\n>  \t\tif ($E->value() == 1) {\n>  \t\t\t# Key not found.\n> -\t\t\treturn undef;\n> +\t\t\treturn;\n>  \t\t} else {\n>  \t\t\tthrow $E;\n>  \t\t}\n\nShouldn't the same fix made to config_bool as well?\n"},{"id":"60711","messageId":"7v63zu3r7h.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071122121836.GG12913@sigill.intra.peff.net","subject":"Re: [PATCH 4/5] Let git-add--interactive read colors from configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-22T21:28:34Z","receivedAt":"2007-11-22T21:28:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Thu, Nov 22, 2007 at 04:56:06AM -0600, Dan Zwell wrote:\n>\n>> +\t\t\t# Grab the 3 main colors in git color string format, with sane\n>> +\t\t\t# (visible) defaults:\n>> +\t\t\t$prompt_color = Git::color_to_ansi_code(\n>> +\t\t\t\tscalar $repo->config_default('color.interactive.prompt',\n>> +\t\t\t\t\t'bold blue'));\n>\n> And by the same token as the last message, given that config_* take only\n> two arguments, is there a reason not to extend them so that\n>\n>   $repo->config_bool('my.key', 0);\n>\n> handles the default. Then I think you could simplify this to just:\n>\n>   $repo->config_color('color.interactive.prompt', 'bold blue');\n>\n> and hide the color_to_ansi_code messiness from the script altogether.\n\nI like the config_color() method.\n\nI think the \"config_bool with default\" also makes sense but it\nneeds to be coded a bit carefully.  Issues to consider:\n\n (1) Non default form \"$r->config_bool('key')\" should keep the\n     original semantics; missing key in the configuration is the\n     same as false (i.e. \"undef\" in scalar, () in list context).\n\n (2) What should be the second parameter in the form to default\n     to true?  '1'?  'true'?  Any kind of \"true\" value in Perl\n     should be accepted?\n\n (3) Same question as (2) but for defaulting to false.  Any kind\n     of \"false\"?\n"},{"id":"60713","messageId":"7v1wai3qrw.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071122122540.GH12913@sigill.intra.peff.net","subject":"Re: [PATCH 5/5] Added diff hunk coloring to git-add--interactive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-22T21:37:55Z","receivedAt":"2007-11-22T21:37:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n>> +\tif ($diff_use_color) {\n>> +\t\t$new_color = get_color('color.diff.new', 'green');\n>> +\t\t$old_color = get_color('color.diff.old', 'red');\n>> +\t\t$fraginfo_color = get_color('color.diff.frag', 'cyan');\n>> +\t\t$metainfo_color = get_color('color.diff.meta', 'bold');\n>> +\t\t$normal_color = Git::color_to_ansi_code('normal');\n>> +\t\t# Not implemented:\n>> +\t\t#$whitespace_color = get_color('color.diff.whitespace',\n>> +\t\t\t#'normal red');\n>\n> Unfortunately, there is a historical wart that probably still needs\n> supporting, which is that the original names were diff.color.*. Or have\n> we officially removed support for that yet?\n\nNeither officially or unofficially yet, but we can start the\nprocess of making it official with an early announcement.  I do\nnot think we would hurt people as long as a long enough advance\nnotice is given.\n\nI however am wondering if we need to have so many \"enable color\nsupport\" switches.  color.status, color.diff, and now yet\nanother color.interactive?  Who sets color.status and/or\ncolor.interactive to auto without setting color.diff to auto as\nwell?\n\nIt may be good that they _can_ be individually controlled, but I\nstrongly suspect that most people would just want to set a\nsingle variable color.ui to \"auto\", and have it give the default\nvalue for all the color.$cmd configuration variable that are not\nexplicitly defined.\n"},{"id":"60718","messageId":"20071122223050.GC3620@sigill.intra.peff.net","threadId":"10263","inReplyTo":"7v63zu3r7h.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 4/5] Let git-add--interactive read colors from configuration","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-22T22:30:50Z","receivedAt":"2007-11-22T22:30:50Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 22, 2007 at 01:28:34PM -0800, Junio C Hamano wrote:\n\n> I think the \"config_bool with default\" also makes sense but it\n> needs to be coded a bit carefully.  Issues to consider:\n\nYes. It is not strictly necessary for this patch series, but I think it\nis nice to stake out a claim on the third argument of config_* functions\nfor consistency sake. But perhaps in the name of avoiding regression, it\nshould come later, when somebody actually wants to use it.\n\n>  (1) Non default form \"$r->config_bool('key')\" should keep the\n>      original semantics; missing key in the configuration is the\n>      same as false (i.e. \"undef\" in scalar, () in list context).\n\nYes, this is obviously the most important thing.\n\n>  (2) What should be the second parameter in the form to default\n>      to true?  '1'?  'true'?  Any kind of \"true\" value in Perl\n>      should be accepted?\n> \n>  (3) Same question as (2) but for defaulting to false.  Any kind\n>      of \"false\"?\n\nHmm. I am tempted to say \"yes, any true or any false value\" in that the\npoint of config_* is to convert git config values to native perl\nrepresentations. OTOH, the moral equivalent of\n\n  config_color('my.key', 'bold red');\n\nis probably more appropriately\n\n  config_bool('my.key', 'true');\n\nso I am fine doing it that way, as well (though I think it makes us\nduplicate the \"translate these strings into bools\" code into perl).\n\n-Peff\n"},{"id":"60719","messageId":"7v1wah3o3w.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071122122540.GH12913@sigill.intra.peff.net","subject":"Re: [PATCH 5/5] Added diff hunk coloring to git-add--interactive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-22T22:35:31Z","receivedAt":"2007-11-22T22:35:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Thu, Nov 22, 2007 at 04:56:24AM -0600, Dan Zwell wrote:\n>\n>> -\t\telse { # set up colors\n>> -\t\t\t# Grab the 3 main colors in git color string format, with sane\n>> -\t\t\t# (visible) defaults:\n>> -\t\t\t$prompt_color = Git::color_to_ansi_code(\n>> -\t\t\t\tscalar $repo->config_default('color.interactive.prompt',\n>> -\t\t\t\t\t'bold blue'));\n>\n> These were just added in the last patch. I know sometimes it is worth\n> showing the progression of work as the patches go, but in this case, I\n> think it is simpler for the reviewers if the first patch which adds a\n> chunk of code does it in the final way (even if you need to just say \"I\n> did it this way because there will be reasons later on.\").\n\nIf you are suggesting to reorganize the series like this:\n\n 1/5 Fix to Git.pm for list context;\n\n 2/5 Enhance Git.pm to allow config() methods to take default values;\n\n 3/5 Enhance Git.pm with get_color() method;\n\n 4/5 Teach git-add--interactive to read color settings from the\n     config;\n\n 5/5 Paint output from git-add--interactive in colors, including\n     prompt, help and diff hunks.\n\nI think that makes a very good sense.  The earlier part of the\nseries would be independent from colorization of \"add -i\" and\ncan go in before everything else to allow other potential users,\ne.g. \"git remote --color\" ;-).  I do not see a strong reason to\nhave the separate \"Basic color support with hardcoded color\" at\nthe beginning, either.\n\nI think it is a matter of taste to either:\n\n (1) Squash 4 and 5 in the above list into one; or\n\n (2) Split 5 into separate commits to color different parts.\n\nPerhaps the former would be simpler and more appropriate for\nthis series.\n"},{"id":"60734","messageId":"474653F6.2060803@zwell.net","threadId":"10263","inReplyTo":"7vd4u23rpg.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/5] Don't return 'undef' in case called in a vector context.","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-11-23T04:15:50Z","receivedAt":"2007-11-23T04:15:50Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"Junio C Hamano wrote:\n> Dan Zwell <dzwell@zwell.net> writes:\n> \n>> diff --git a/perl/Git.pm b/perl/Git.pm\n>> index dca92c8..6603762 100644\n>> --- a/perl/Git.pm\n>> +++ b/perl/Git.pm\n>> @@ -508,7 +508,7 @@ sub config {\n>>  \t\tmy $E = shift;\n>>  \t\tif ($E->value() == 1) {\n>>  \t\t\t# Key not found.\n>> -\t\t\treturn undef;\n>> +\t\t\treturn;\n>>  \t\t} else {\n>>  \t\t\tthrow $E;\n>>  \t\t}\n> \n> Shouldn't the same fix made to config_bool as well?\n> \n\nI didn't realize it at the time, but yes, config_bool needs this (though \nthe only time config_bool is evaluated in a list context should be when \nit is evaluated as an argument to another function). I'll make the change.\n\nDan\n"},{"id":"60735","messageId":"474665E0.1010104@zwell.net","threadId":"10263","inReplyTo":"20071122223050.GC3620@sigill.intra.peff.net","subject":"Re: [PATCH 4/5] Let git-add--interactive read colors from configuration","fromName":"Dan Zwell","fromEmail":"dzwell@gmail.com","sentAt":"2007-11-23T05:32:16Z","receivedAt":"2007-11-23T05:32:16Z","isPatch":true,"sender":{"key":"dzwell@gmail.com","avatar":null},"body":"Jeff King wrote:\n>>  (2) What should be the second parameter in the form to default\n>>      to true?  '1'?  'true'?  Any kind of \"true\" value in Perl\n>>      should be accepted?\n>>\n>>  (3) Same question as (2) but for defaulting to false.  Any kind\n>>      of \"false\"?\n> \n> Hmm. I am tempted to say \"yes, any true or any false value\" in that the\n> point of config_* is to convert git config values to native perl\n> representations. OTOH, the moral equivalent of\n> \n>   config_color('my.key', 'bold red');\n> \n> is probably more appropriately\n> \n>   config_bool('my.key', 'true');\n> \n> so I am fine doing it that way, as well (though I think it makes us\n> duplicate the \"translate these strings into bools\" code into perl).\n> \n\nAs you said, config_* converts git values to perl values. However, that \nconversion needs only be done for strings in .gitconfig. Is there any \nreason why the caller of the function would need to pass a string \n\"false\"? I just don't see the need for conversion of any kind.\n\nFurther, I think that we could return the default variable directly, \nwithout parsing it at all. It would be much simpler, and there would \nneed to be no special cases for dealing with undef or 'false'. It's a \nperl function, being called with perl arguments, so a user should not be \nthat surprised when 'false' does what perl says it should do.\n\nDan\n"},{"id":"60741","messageId":"20071123090918.GC5196@sigill.intra.peff.net","threadId":"10263","inReplyTo":"474665E0.1010104@zwell.net","subject":"Re: [PATCH 4/5] Let git-add--interactive read colors from configuration","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-23T09:09:18Z","receivedAt":"2007-11-23T09:09:18Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 22, 2007 at 11:32:16PM -0600, Dan Zwell wrote:\n\n> Further, I think that we could return the default variable directly, without \n> parsing it at all. It would be much simpler, and there would need to be no \n> special cases for dealing with undef or 'false'. It's a perl function, being \n> called with perl arguments, so a user should not be that surprised when \n> 'false' does what perl says it should do.\n\nI think that is more elegant for config_bool, but it means that\nconfig_bool and config_color have slightly different behaviors (the\ndifference being that it is easy to feed a native perl value as the\ndefault to config_bool, but to get the same behavior for config_color,\nyou would call Git::color_to_ansi_code manually, which is a pain).\n\nIn this instance, I am inclined to sacrifice consistency for convenience\nand make it:\n\n   my $bool = config_bool('my.key', 0);\n   my $color = config_color('my.key', 'bold red');\n\nNote that there is one tricky part of config_bool, which is what\nconfig_bool('my.key', undef) should do (is it \"default false\" or \"no\ndefault\"?).\n\n-Peff\n"},{"id":"60742","messageId":"7vk5o9uxqq.fsf@gitster.siamese.dyndns.org","threadId":"10263","inReplyTo":"20071123090918.GC5196@sigill.intra.peff.net","subject":"Re: [PATCH 4/5] Let git-add--interactive read colors from configuration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-23T09:17:33Z","receivedAt":"2007-11-23T09:17:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Note that there is one tricky part of config_bool, which is what\n> config_bool('my.key', undef) should do (is it \"default false\" or \"no\n> default\"?).\n\nI am glad somebody finally got to the trick question I posed\nearlier ;-)\n\nBut config_bool('key') and config_bool('key', undef) would both\nreturn undef to say \"The value is false\" when key does not\nexist, so it was not much of a trick.  It does not make a\ndifference if the undef came because the default parameter was\nundef, or because there was no default parameter given and the\nbuilt-in behaviour of config_bool() was to return undef for a\nmissing key.\n"},{"id":"60754","messageId":"20071123102156.GA6754@sigill.intra.peff.net","threadId":"10263","inReplyTo":"7v1wai3qrw.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 5/5] Added diff hunk coloring to git-add--interactive","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-23T10:21:57Z","receivedAt":"2007-11-23T10:21:57Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 22, 2007 at 01:37:55PM -0800, Junio C Hamano wrote:\n\n> > Unfortunately, there is a historical wart that probably still needs\n> > supporting, which is that the original names were diff.color.*. Or have\n> > we officially removed support for that yet?\n> \n> Neither officially or unofficially yet, but we can start the\n> process of making it official with an early announcement.  I do\n> not think we would hurt people as long as a long enough advance\n> notice is given.\n\nAndy Parkins added color.* (and removed documentation for *.color)\nalmost a year ago (in a159ca0c). But I don't think there has been an\nofficial deprecation notice.\n\n> I however am wondering if we need to have so many \"enable color\n> support\" switches.  color.status, color.diff, and now yet\n> another color.interactive?  Who sets color.status and/or\n> color.interactive to auto without setting color.diff to auto as\n> well?\n\nYes, I have often thought this, as well, and a \"color.all\" would\nprobably be convenient.\n\n-Peff\n"}]}