about summary refs log tree commit diff
path: root/ui-blame.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui-blame.c')
-rw-r--r--ui-blame.c63
1 files changed, 51 insertions, 12 deletions
diff --git a/ui-blame.c b/ui-blame.c
index d565fff..17e2d60 100644
--- a/ui-blame.c
+++ b/ui-blame.c
@@ -67,15 +67,29 @@ static void emit_blame_entry_linenumber(struct blame_entry *ent)
 		htmlf(numberfmt, ++lineno);
 }
 
-static void emit_blame_entry_line(struct blame_scoreboard *sb,
-				  struct blame_entry *ent)
+static void emit_blame_entry_line_background(struct blame_scoreboard *sb,
+					     struct blame_entry *ent)
 {
-	const char *cp, *cpend;
+	unsigned long line;
+	size_t len, maxlen = 2;
+	const char* pos, *endpos;
 
-	cp = blame_nth_line(sb, ent->lno);
-	cpend = blame_nth_line(sb, ent->lno + ent->num_lines);
+	for (line = ent->lno; line < ent->lno + ent->num_lines; line++) {
+		html("\n");
+		pos = blame_nth_line(sb, line);
+		endpos = blame_nth_line(sb, line + 1);
+		len = 0;
+		while (pos < endpos) {
+			len++;
+			if (*pos++ == '\t')
+				len = (len + 7) & ~7;
+		}
+		if (len > maxlen)
+			maxlen = len;
+	}
 
-	html_ntxt(cp, cpend - cp);
+	for (len = 0; len < maxlen - 1; len++)
+		html(" ");
 }
 
 struct walk_tree_context {
@@ -88,6 +102,7 @@ static void print_object(const unsigned char *sha1, const char *path,
 			 const char *basename, const char *rev)
 {
 	enum object_type type;
+	char *buf;
 	unsigned long size;
 	struct argv_array rev_argv = ARGV_ARRAY_INIT;
 	struct rev_info revs;
@@ -102,6 +117,13 @@ static void print_object(const unsigned char *sha1, const char *path,
 		return;
 	}
 
+	buf = read_sha1_file(sha1, &type, &size);
+	if (!buf) {
+		cgit_print_error_page(500, "Internal server error",
+			"Error reading object %s", sha1_to_hex(sha1));
+		return;
+	}
+
 	argv_array_push(&rev_argv, "blame");
 	argv_array_push(&rev_argv, rev);
 	init_revisions(&revs, NULL);
@@ -157,20 +179,37 @@ static void print_object(const unsigned char *sha1, const char *path,
 		html("</td>\n");
 	}
 
-	/* Lines */
-	html("<td class='lines'>");
+	html("<td class='lines'><div>");
+
+	/* Colored bars behind lines */
+	html("<div>");
 	for (ent = sb.ent; ent; ) {
 		struct blame_entry *e = ent->next;
-		html("<div class='alt'><pre><code>");
-		emit_blame_entry_line(&sb, ent);
-		html("</code></pre></div>");
+		html("<div class='alt'><pre>");
+		emit_blame_entry_line_background(&sb, ent);
+		html("</pre></div>");
 		free(ent);
 		ent = e;
 	}
-	html("</td>\n");
+	html("</div>");
 
 	free((void *)sb.final_buf);
 
+	/* Lines */
+	html("<pre><code>");
+	if (ctx.repo->source_filter) {
+		char *filter_arg = xstrdup(basename);
+		cgit_open_filter(ctx.repo->source_filter, filter_arg);
+		html_raw(buf, size);
+		cgit_close_filter(ctx.repo->source_filter);
+		free(filter_arg);
+	} else {
+		html_txt(buf);
+	}
+	html("</code></pre>");
+
+	html("</div></td>\n");
+
 	html("</tr>\n</table>\n");
 
 	cgit_print_layout_end();