summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Smith <whydoubt@gmail.com>2017-10-28 21:43:26 -0500
committerJason A. Donenfeld <Jason@zx2c4.com>2018-01-19 11:40:58 +0100
commitdbaee2672be14374acb17266477c19294c6155f3 (patch)
treeb9824a153190bab7f0b6e48b922b1b3934666d96
parentaafc42d8089437db5105feb12d540c33fe9f9e16 (diff)
ui-blame: Allow syntax highlighting
Place file contents into a single block so that syntax highlighting can be applied in the usual fashion. Place the alternating color bars behind the file contents. Force the default syntax highlighting background to transparent. Signed-off-by: Jeff Smith <whydoubt@gmail.com> Reviewed-by: John Keeping <john@keeping.me.uk>
-rw-r--r--cgit.css10
-rwxr-xr-xfilters/syntax-highlighting.py2
-rw-r--r--ui-blame.c63
3 files changed, 62 insertions, 13 deletions
diff --git a/cgit.css b/cgit.css
index 20b7e86..217a05a 100644
--- a/cgit.css
+++ b/cgit.css
@@ -353,6 +353,16 @@ div#cgit table.blame div.alt:nth-child(odd) {
background: white;
}
+div#cgit table.blame td.lines > div {
+ position: relative;
+}
+
+div#cgit table.blame td.lines > div > pre {
+ padding: 0 0 0 0.5em;
+ position: absolute;
+ top: 0;
+}
+
div#cgit table.bin-blob {
margin-top: 0.5em;
border: solid 1px black;
diff --git a/filters/syntax-highlighting.py b/filters/syntax-highlighting.py
index 5888b50..e912594 100755
--- a/filters/syntax-highlighting.py
+++ b/filters/syntax-highlighting.py
@@ -34,7 +34,7 @@ sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8', errors='replace
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
data = sys.stdin.read()
filename = sys.argv[1]
-formatter = HtmlFormatter(style='pastie')
+formatter = HtmlFormatter(style='pastie', nobackground=True)
try:
lexer = guess_lexer_for_filename(filename, data)
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();