{"thread":{"id":"10269","subject":"[PATCH] Add color to git-add--interactive diffs","startedAt":"2007-10-14T08:23:56Z","lastAt":"2007-10-14T08:38:54Z","messageCount":2,"participants":["Tom Tobin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"55672","messageId":"1192350236.7226.6.camel@athena","threadId":"10269","inReplyTo":null,"subject":"[PATCH] Add color to git-add--interactive diffs","fromName":"Tom Tobin","fromEmail":"korpios@korpios.com","sentAt":"2007-10-14T08:23:56Z","receivedAt":"2007-10-14T08:23:56Z","isPatch":true,"sender":{"key":"korpios@korpios.com","avatar":null},"body":"Seeing the recent discussion and code regarding adding color to\ngit-add--interactive, I thought I'd throw in my recent attempt at\ncolorizing the diffs.  (This doesn't handle anything else, such as the\nprompts.)\n\nAfter banging my head against parsing colorized output of git-add-files,\nI gave up and implemented internal colorization keying off of the\ncolor.diff configuration.\n\nHopefully this can be of some use towards fully colorizing\ngit-add--interactive; I'll admit up front that Perl isn't my primary\nlanguage, so I apologize in advance for whatever stupidities I've\nintroduced.  ;)\n\nSigned-off-by: Tom Tobin <korpios@korpios.com>\n---\n git-add--interactive.perl |  111\n++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 109 insertions(+), 2 deletions(-)\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex be68814..eeb38e6 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -1,5 +1,6 @@\n #!/usr/bin/perl -w\n \n+use List::Util qw(first);\n use strict;\n \n sub run_cmd_pipe {\n@@ -22,6 +23,112 @@ if (!defined $GIT_DIR) {\n }\n chomp($GIT_DIR);\n \n+my ($use_color) = 0;\n+my (%term_color_codes) = (\n+\t\"normal\", \"\", \"black\", \"0\", \"red\", \"1\",\n+\t\"green\", \"2\", \"yellow\", \"3\", \"blue\", \"4\",\n+\t\"magenta\", \"5\", \"cyan\", \"6\", \"white\", \"7\"\n+);\n+my (%term_attr_codes) = (\n+\t\"bold\", \"1\", \"dim\", \"2\", \"ul\", \"4\", \"blink\", \"5\", \"reverse\", \"7\"\n+);\n+my %colorconfig = (\n+\t'color.diff' => 'never',\n+\t'color.diff.plain' => '',\n+\t'color.diff.meta' => 'bold',\n+\t'color.diff.frag' => 'cyan',\n+\t'color.diff.old' => 'red',\n+\t'color.diff.new' => 'green',\n+\t'color.diff.commit' => 'yellow',\n+\t'color.diff.whitespace' => 'normal red'\n+\t);\n+for (split(\"\\n\", `git-config --get-regexp '^color\\.diff'`)) {\n+\tmy ($var, $val) = $_ =~ /^([^\\s]+)\\s(.*)$/;\n+\t$colorconfig{$var} = $val;\n+}\n+if (first { $_ eq $colorconfig{'color.diff'} } (\"true\", \"always\",\n\"auto\")) {\n+\t$use_color = 1;\n+}\n+\n+sub parse_color {\n+\tmy ($fg, $bg, $attr, $lookup);\n+\tmy ($fg_code, $bg_code, $attr_code, $output_code) = (\"\", \"\", \"\", \"\");\n+\tmy (@color) = @_;\n+\tmy (@colorvals) = defined($color[0]) ? split(\" \", $color[0]) : ();\n+\n+\tfor (@colorvals) {\n+\t\t$lookup = $term_color_codes{$_};\n+\t\tif (defined($lookup)) {\n+\t\t\tif (!defined($fg)) {\n+\t\t\t\t$fg = 1;\n+\t\t\t\t$fg_code = \"3$lookup\";\n+\t\t\t} elsif (!defined($bg)) {\n+\t\t\t\t$bg = 1;\n+\t\t\t\t$bg_code = \"4$lookup\";\n+\t\t\t} else {\n+\t\t\t\tdie(\"Color slots only take up to two colors!\");\n+\t\t\t}\n+\t\t\tnext;\n+\t\t}\n+\t\t$lookup = $term_attr_codes{$_};\n+\t\tif (defined($lookup)) {\n+\t\t\tif (!defined($attr)) {\n+\t\t\t\t$attr = 1;\n+\t\t\t\t$attr_code = $lookup;\n+\t\t\t} else {\n+\t\t\t\tdie(\"Color slots only take a single attribute!\");\n+\t\t\t}\n+\t\t} else {\n+\t\t\tdie(\"Unrecognized value for color slot!\");\n+\t\t}\n+\t}\n+\tfor ($fg_code, $bg_code, $attr_code) {\n+\t\tif ($_ eq \"\") {\n+\t\t\tnext;\n+\t\t}\n+\t\tif ($output_code ne \"\") {\n+\t\t\t$output_code = $output_code . \";\";\n+\t\t}\n+\t\t$output_code = $output_code . $_;\n+\t}\n+\tif (length($output_code)) {\n+\t\treturn \"\\e[${output_code}m\";\n+\t} else {\n+\t\treturn \"\";\n+\t}\n+}\n+\n+sub colorize_head_line {\n+\tmy $line = shift @_;\n+\tif ($use_color) {\n+\t\t# git doesn't colorize these by default, soooo\n+\t\t# if ($line =~ /^\\+/) {\n+\t\t#\t return parse_color($colorconfig{'color.diff.new'}) . \"$line\\e[m\";\n+\t\t# }\n+\t\t# if ($line =~ /^-/) {\n+\t\t#\t return parse_color($colorconfig{'color.diff.old'}) . \"$line\\e[m\";\n+\t\t# }\n+\t\treturn parse_color($colorconfig{'color.diff.meta'}) . \"$line\\e[m\";\n+\t}\n+\treturn $line;\n+}\n+\n+sub colorize_hunk_line {\n+\tmy $line = shift @_;\n+\tif ($use_color) {\n+\t\tif ($line =~ /^\\+/) {\n+\t\t\treturn parse_color($colorconfig{'color.diff.new'}) . \"$line\\e[m\";\n+\t\t}\n+\t\tif ($line =~ /^-/) {\n+\t\t\treturn parse_color($colorconfig{'color.diff.old'}) . \"$line\\e[m\";\n+\t\t}\n+\t\tif ($line =~ /^@@ /) {\n+\t\t\treturn parse_color($colorconfig{'color.diff.frag'}) . \"$line\\e[m\";\n+\t\t}\n+\t}\n+\treturn $line;\n+}\n+\n sub refresh {\n \tmy $fh;\n \topen $fh, 'git update-index --refresh |'\n@@ -573,7 +680,7 @@ sub patch_update_cmd {\n \tmy $path = $it->{VALUE};\n \tmy ($head, @hunk) = parse_diff($path);\n \tfor (@{$head->{TEXT}}) {\n-\t\tprint;\n+\t\tprint colorize_head_line($_);\n \t}\n \t$num = scalar @hunk;\n \t$ix = 0;\n@@ -617,7 +724,7 @@ sub patch_update_cmd {\n \t\t\t$other .= '/s';\n \t\t}\n \t\tfor (@{$hunk[$ix]{TEXT}}) {\n-\t\t\tprint;\n+\t\t\tprint colorize_hunk_line($_);\n \t\t}\n \t\tprint \"Stage this hunk [y/n/a/d$other/?]? \";\n \t\tmy $line = <STDIN>;\n-- \n1.5.3.4\n"},{"id":"55673","messageId":"1192351134.7226.11.camel@athena","threadId":"10269","inReplyTo":"1192350236.7226.6.camel@athena","subject":"Re: [PATCH] Add color to git-add--interactive diffs","fromName":"Tom Tobin","fromEmail":"korpios@korpios.com","sentAt":"2007-10-14T08:38:54Z","receivedAt":"2007-10-14T08:38:54Z","isPatch":true,"sender":{"key":"korpios@korpios.com","avatar":null},"body":"On Sun, 2007-10-14 at 03:24 -0500, Tom Tobin wrote:\n> Seeing the recent discussion and code regarding adding color to\n> git-add--interactive, I thought I'd throw in my recent attempt at\n> colorizing the diffs.  (This doesn't handle anything else, such as the\n> prompts.)\n\nCrap, my apologies; Evolution inserted a spurious line break in there.\n\nI'll repost the patch.\n"}]}