diff options
-rw-r--r-- | cgit.css | 10 | ||||
-rwxr-xr-x | filters/syntax-highlighting.py | 2 | ||||
-rw-r--r-- | ui-blame.c | 63 |
3 files changed, 62 insertions, 13 deletions
@@ -353,6 +353,16 @@ div#cgit table.blame div.alt:nth-child(odd) { | |||
353 | background: white; | 353 | background: white; |
354 | } | 354 | } |
355 | 355 | ||
356 | div#cgit table.blame td.lines > div { | ||
357 | position: relative; | ||
358 | } | ||
359 | |||
360 | div#cgit table.blame td.lines > div > pre { | ||
361 | padding: 0 0 0 0.5em; | ||
362 | position: absolute; | ||
363 | top: 0; | ||
364 | } | ||
365 | |||
356 | div#cgit table.bin-blob { | 366 | div#cgit table.bin-blob { |
357 | margin-top: 0.5em; | 367 | margin-top: 0.5em; |
358 | border: solid 1px black; | 368 | 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 | |||
34 | sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') | 34 | sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') |
35 | data = sys.stdin.read() | 35 | data = sys.stdin.read() |
36 | filename = sys.argv[1] | 36 | filename = sys.argv[1] |
37 | formatter = HtmlFormatter(style='pastie') | 37 | formatter = HtmlFormatter(style='pastie', nobackground=True) |
38 | 38 | ||
39 | try: | 39 | try: |
40 | lexer = guess_lexer_for_filename(filename, data) | 40 | lexer = guess_lexer_for_filename(filename, data) |
@@ -67,15 +67,29 @@ static void emit_blame_entry_linenumber(struct blame_entry *ent) | |||
67 | htmlf(numberfmt, ++lineno); | 67 | htmlf(numberfmt, ++lineno); |
68 | } | 68 | } |
69 | 69 | ||
70 | static void emit_blame_entry_line(struct blame_scoreboard *sb, | 70 | static void emit_blame_entry_line_background(struct blame_scoreboard *sb, |
71 | struct blame_entry *ent) | 71 | struct blame_entry *ent) |
72 | { | 72 | { |
73 | const char *cp, *cpend; | 73 | unsigned long line; |
74 | size_t len, maxlen = 2; | ||
75 | const char* pos, *endpos; | ||
74 | 76 | ||
75 | cp = blame_nth_line(sb, ent->lno); | 77 | for (line = ent->lno; line < ent->lno + ent->num_lines; line++) { |
76 | cpend = blame_nth_line(sb, ent->lno + ent->num_lines); | 78 | html("\n"); |
79 | pos = blame_nth_line(sb, line); | ||
80 | endpos = blame_nth_line(sb, line + 1); | ||
81 | len = 0; | ||
82 | while (pos < endpos) { | ||
83 | len++; | ||
84 | if (*pos++ == '\t') | ||
85 | len = (len + 7) & ~7; | ||
86 | } | ||
87 | if (len > maxlen) | ||
88 | maxlen = len; | ||
89 | } | ||
77 | 90 | ||
78 | html_ntxt(cp, cpend - cp); | 91 | for (len = 0; len < maxlen - 1; len++) |
92 | html(" "); | ||
79 | } | 93 | } |
80 | 94 | ||
81 | struct walk_tree_context { | 95 | struct walk_tree_context { |
@@ -88,6 +102,7 @@ static void print_object(const unsigned char *sha1, const char *path, | |||
88 | const char *basename, const char *rev) | 102 | const char *basename, const char *rev) |
89 | { | 103 | { |
90 | enum object_type type; | 104 | enum object_type type; |
105 | char *buf; | ||
91 | unsigned long size; | 106 | unsigned long size; |
92 | struct argv_array rev_argv = ARGV_ARRAY_INIT; | 107 | struct argv_array rev_argv = ARGV_ARRAY_INIT; |
93 | struct rev_info revs; | 108 | struct rev_info revs; |
@@ -102,6 +117,13 @@ static void print_object(const unsigned char *sha1, const char *path, | |||
102 | return; | 117 | return; |
103 | } | 118 | } |
104 | 119 | ||
120 | buf = read_sha1_file(sha1, &type, &size); | ||
121 | if (!buf) { | ||
122 | cgit_print_error_page(500, "Internal server error", | ||
123 | "Error reading object %s", sha1_to_hex(sha1)); | ||
124 | return; | ||
125 | } | ||
126 | |||
105 | argv_array_push(&rev_argv, "blame"); | 127 | argv_array_push(&rev_argv, "blame"); |
106 | argv_array_push(&rev_argv, rev); | 128 | argv_array_push(&rev_argv, rev); |
107 | init_revisions(&revs, NULL); | 129 | init_revisions(&revs, NULL); |
@@ -157,20 +179,37 @@ static void print_object(const unsigned char *sha1, const char *path, | |||
157 | html("</td>\n"); | 179 | html("</td>\n"); |
158 | } | 180 | } |
159 | 181 | ||
160 | /* Lines */ | 182 | html("<td class='lines'><div>"); |
161 | html("<td class='lines'>"); | 183 | |
184 | /* Colored bars behind lines */ | ||
185 | html("<div>"); | ||
162 | for (ent = sb.ent; ent; ) { | 186 | for (ent = sb.ent; ent; ) { |
163 | struct blame_entry *e = ent->next; | 187 | struct blame_entry *e = ent->next; |
164 | html("<div class='alt'><pre><code>"); | 188 | html("<div class='alt'><pre>"); |
165 | emit_blame_entry_line(&sb, ent); | 189 | emit_blame_entry_line_background(&sb, ent); |
166 | html("</code></pre></div>"); | 190 | html("</pre></div>"); |
167 | free(ent); | 191 | free(ent); |
168 | ent = e; | 192 | ent = e; |
169 | } | 193 | } |
170 | html("</td>\n"); | 194 | html("</div>"); |
171 | 195 | ||
172 | free((void *)sb.final_buf); | 196 | free((void *)sb.final_buf); |
173 | 197 | ||
198 | /* Lines */ | ||
199 | html("<pre><code>"); | ||
200 | if (ctx.repo->source_filter) { | ||
201 | char *filter_arg = xstrdup(basename); | ||
202 | cgit_open_filter(ctx.repo->source_filter, filter_arg); | ||
203 | html_raw(buf, size); | ||
204 | cgit_close_filter(ctx.repo->source_filter); | ||
205 | free(filter_arg); | ||
206 | } else { | ||
207 | html_txt(buf); | ||
208 | } | ||
209 | html("</code></pre>"); | ||
210 | |||
211 | html("</div></td>\n"); | ||
212 | |||
174 | html("</tr>\n</table>\n"); | 213 | html("</tr>\n</table>\n"); |
175 | 214 | ||
176 | cgit_print_layout_end(); | 215 | cgit_print_layout_end(); |