Subject: [PATCH] blame: add color

From: Chris J Arges <[email-masked]>
Date: Tue, 8 Oct 2013 09:18:49 -0500

Add colorized text for git blame when color.interactive is enabled.
This work is based on the colorization code in builtin/clean.c.

Signed-off-by: Chris J Arges <[email-masked]>
---
 builtin/blame.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 6da7233..fbff437 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -23,6 +23,7 @@
 #include "userdiff.h"
 #include "line-range.h"
 #include "line-log.h"
+#include "color.h"
 
 static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file");
 
@@ -51,6 +52,24 @@ static size_t blame_date_width;
 
 static struct string_list mailmap;
 
+static int blame_use_color = -1;
+static char blame_colors[][COLOR_MAXLEN] = {
+	GIT_COLOR_RESET,
+	GIT_COLOR_NORMAL,	/* PLAIN */
+	GIT_COLOR_YELLOW,	/* COMMIT */
+	GIT_COLOR_BOLD,		/* NAME */
+	GIT_COLOR_CYAN,		/* LINE */
+	GIT_COLOR_GREEN,	/* TIME */
+};
+enum color_blame {
+	BLAME_COLOR_RESET = 0,
+	BLAME_COLOR_PLAIN = 1,
+	BLAME_COLOR_COMMIT = 2,
+	BLAME_COLOR_NAME = 3,
+	BLAME_COLOR_LINE = 4,
+	BLAME_COLOR_TIME = 5,
+};
+
 #ifndef DEBUG
 #define DEBUG 0
 #endif
@@ -1575,6 +1594,18 @@ static void assign_blame(struct scoreboard *sb, int opt)
 	}
 }
 
+static const char *blame_get_color(enum color_blame ix)
+{
+	if (want_color(blame_use_color))
+		return blame_colors[ix];
+	return "";
+}
+
+static void blame_print_color(enum color_blame ix)
+{
+	printf("%s", blame_get_color(ix));
+}
+
 static const char *format_time(unsigned long time, const char *tz_str,
 			       int show_raw_time)
 {
@@ -1680,7 +1711,9 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
 			}
 		}
 
+		blame_print_color(BLAME_COLOR_COMMIT);
 		printf("%.*s", length, hex);
+		blame_print_color(BLAME_COLOR_RESET);
 		if (opt & OUTPUT_ANNOTATE_COMPAT) {
 			const char *name;
 			if (opt & OUTPUT_SHOW_EMAIL)
@@ -1711,14 +1744,22 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
 				else
 					name = ci.author.buf;
 				pad = longest_author - utf8_strwidth(name);
-				printf(" (%s%*s %10s",
-				       name, pad, "",
+				blame_print_color(BLAME_COLOR_NAME);
+				printf(" (%s%*s ",
+				       name, pad, "");
+				blame_print_color(BLAME_COLOR_RESET);
+				blame_print_color(BLAME_COLOR_TIME);
+				printf(" (%10s",
 				       format_time(ci.author_time,
 						   ci.author_tz.buf,
 						   show_raw_time));
+
+				blame_print_color(BLAME_COLOR_RESET);
 			}
+			blame_print_color(BLAME_COLOR_LINE);
 			printf(" %*d) ",
 			       max_digits, ent->lno + 1 + cnt);
+			blame_print_color(BLAME_COLOR_RESET);
 		}
 		do {
 			ch = *cp++;
@@ -1948,6 +1989,12 @@ static int git_blame_config(const char *var, const char *value, void *cb)
 		blame_date_mode = parse_date_format(value);
 		return 0;
 	}
+	/* honors the color.interactive* config variables which also
+	   applied in git-add--interactive and git-stash */
+	if (!strcmp(var, "color.interactive")) {
+		blame_use_color = git_config_colorbool(var, value);
+		return 0;
+	}
 
 	if (userdiff_config(var, value) < 0)
 		return -1;
-- 
1.7.9.5