From: Tom Tobin <korpios@korpios.com>
To: Git Mailing List <git@vger.kernel.org>
Subject: [PATCH] Add color to git-add--interactive diffs (Take 2: now without spurious line break!)
Date: Sun, 14 Oct 2007 03:44:54 -0500 [thread overview]
Message-ID: <1192351494.7226.18.camel@athena> (raw)
(This is repost; my damned mail client wrapped a line in the patch last
time, and now I've got that under control. My apologies!) :(
Seeing the recent discussion and code regarding adding color to
git-add--interactive, I thought I'd throw in my recent attempt at
colorizing the diffs. (This doesn't handle anything else, such as the
prompts.)
After banging my head against parsing colorized output of git-add-files,
I gave up and implemented internal colorization keying off of the
color.diff configuration.
Hopefully this can be of some use towards fully colorizing
git-add--interactive; I'll admit up front that Perl isn't my primary
language, so I apologize in advance for whatever stupidities I've
introduced. ;)
Signed-off-by: Tom Tobin <korpios@korpios.com>
---
git-add--interactive.perl | 111 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index be68814..eeb38e6 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -1,5 +1,6 @@
#!/usr/bin/perl -w
+use List::Util qw(first);
use strict;
sub run_cmd_pipe {
@@ -22,6 +23,112 @@ if (!defined $GIT_DIR) {
}
chomp($GIT_DIR);
+my ($use_color) = 0;
+my (%term_color_codes) = (
+ "normal", "", "black", "0", "red", "1",
+ "green", "2", "yellow", "3", "blue", "4",
+ "magenta", "5", "cyan", "6", "white", "7"
+);
+my (%term_attr_codes) = (
+ "bold", "1", "dim", "2", "ul", "4", "blink", "5", "reverse", "7"
+);
+my %colorconfig = (
+ 'color.diff' => 'never',
+ 'color.diff.plain' => '',
+ 'color.diff.meta' => 'bold',
+ 'color.diff.frag' => 'cyan',
+ 'color.diff.old' => 'red',
+ 'color.diff.new' => 'green',
+ 'color.diff.commit' => 'yellow',
+ 'color.diff.whitespace' => 'normal red'
+ );
+for (split("\n", `git-config --get-regexp '^color\.diff'`)) {
+ my ($var, $val) = $_ =~ /^([^\s]+)\s(.*)$/;
+ $colorconfig{$var} = $val;
+}
+if (first { $_ eq $colorconfig{'color.diff'} } ("true", "always", "auto")) {
+ $use_color = 1;
+}
+
+sub parse_color {
+ my ($fg, $bg, $attr, $lookup);
+ my ($fg_code, $bg_code, $attr_code, $output_code) = ("", "", "", "");
+ my (@color) = @_;
+ my (@colorvals) = defined($color[0]) ? split(" ", $color[0]) : ();
+
+ for (@colorvals) {
+ $lookup = $term_color_codes{$_};
+ if (defined($lookup)) {
+ if (!defined($fg)) {
+ $fg = 1;
+ $fg_code = "3$lookup";
+ } elsif (!defined($bg)) {
+ $bg = 1;
+ $bg_code = "4$lookup";
+ } else {
+ die("Color slots only take up to two colors!");
+ }
+ next;
+ }
+ $lookup = $term_attr_codes{$_};
+ if (defined($lookup)) {
+ if (!defined($attr)) {
+ $attr = 1;
+ $attr_code = $lookup;
+ } else {
+ die("Color slots only take a single attribute!");
+ }
+ } else {
+ die("Unrecognized value for color slot!");
+ }
+ }
+ for ($fg_code, $bg_code, $attr_code) {
+ if ($_ eq "") {
+ next;
+ }
+ if ($output_code ne "") {
+ $output_code = $output_code . ";";
+ }
+ $output_code = $output_code . $_;
+ }
+ if (length($output_code)) {
+ return "\e[${output_code}m";
+ } else {
+ return "";
+ }
+}
+
+sub colorize_head_line {
+ my $line = shift @_;
+ if ($use_color) {
+ # git doesn't colorize these by default, soooo
+ # if ($line =~ /^\+/) {
+ # return parse_color($colorconfig{'color.diff.new'}) . "$line\e[m";
+ # }
+ # if ($line =~ /^-/) {
+ # return parse_color($colorconfig{'color.diff.old'}) . "$line\e[m";
+ # }
+ return parse_color($colorconfig{'color.diff.meta'}) . "$line\e[m";
+ }
+ return $line;
+}
+
+sub colorize_hunk_line {
+ my $line = shift @_;
+ if ($use_color) {
+ if ($line =~ /^\+/) {
+ return parse_color($colorconfig{'color.diff.new'}) . "$line\e[m";
+ }
+ if ($line =~ /^-/) {
+ return parse_color($colorconfig{'color.diff.old'}) . "$line\e[m";
+ }
+ if ($line =~ /^@@ /) {
+ return parse_color($colorconfig{'color.diff.frag'}) . "$line\e[m";
+ }
+ }
+ return $line;
+}
+
sub refresh {
my $fh;
open $fh, 'git update-index --refresh |'
@@ -573,7 +680,7 @@ sub patch_update_cmd {
my $path = $it->{VALUE};
my ($head, @hunk) = parse_diff($path);
for (@{$head->{TEXT}}) {
- print;
+ print colorize_head_line($_);
}
$num = scalar @hunk;
$ix = 0;
@@ -617,7 +724,7 @@ sub patch_update_cmd {
$other .= '/s';
}
for (@{$hunk[$ix]{TEXT}}) {
- print;
+ print colorize_hunk_line($_);
}
print "Stage this hunk [y/n/a/d$other/?]? ";
my $line = <STDIN>;
--
1.5.3.4
next reply other threads:[~2007-10-14 8:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-14 8:44 Tom Tobin [this message]
2007-10-14 11:36 ` [PATCH] Add color to git-add--interactive diffs (Take 2: now without spurious line break!) Wincent Colaiuta
2007-10-14 17:15 ` Johannes Schindelin
2007-10-14 17:55 ` Andreas Ericsson
2007-10-14 21:01 ` Wincent Colaiuta
2007-10-22 20:47 ` [PATCH] Add color to git-add--interactive diffs (Total different idea to solve the problem) Peter Baumann
2007-10-22 23:55 ` Johannes Schindelin
2007-10-23 5:34 ` Peter Baumann
2007-10-23 11:13 ` Johannes Schindelin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1192351494.7226.18.camel@athena \
--to=korpios@korpios.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).