summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--cgit.c8
-rw-r--r--cgit.css10
-rw-r--r--cgit.h4
-rw-r--r--cgitrc.5.txt2
-rw-r--r--cmd.c46
-rw-r--r--cmd.h3
-rw-r--r--shared.c6
-rw-r--r--ui-commit.c20
-rw-r--r--ui-commit.h2
-rw-r--r--ui-diff.c22
-rw-r--r--ui-log.c29
-rw-r--r--ui-patch.c8
-rw-r--r--ui-patch.h2
-rw-r--r--ui-refs.c2
-rw-r--r--ui-shared.c230
-rw-r--r--ui-shared.h70
-rw-r--r--ui-tree.c15
17 files changed, 308 insertions, 171 deletions
diff --git a/cgit.c b/cgit.c
index 38bc136..ab25b6a 100644
--- a/cgit.c
+++ b/cgit.c
@@ -260,2 +260,4 @@ static void querystring_cb(const char *name, const char *value)
260 ctx.qry.show_all = atoi(value); 260 ctx.qry.show_all = atoi(value);
261 } else if (!strcmp(name, "context")) {
262 ctx.qry.context = atoi(value);
261 } 263 }
@@ -435,2 +437,8 @@ static void process_request(void *cbdata)
435 437
438 /* If cmd->want_vpath is set, assume ctx->qry.path contains a "virtual"
439 * in-project path limit to be made available at ctx->qry.vpath.
440 * Otherwise, no path limit is in effect (ctx->qry.vpath = NULL).
441 */
442 ctx->qry.vpath = cmd->want_vpath ? ctx->qry.path : NULL;
443
436 if (cmd->want_repo && !ctx->repo) { 444 if (cmd->want_repo && !ctx->repo) {
diff --git a/cgit.css b/cgit.css
index 6198403..6e47eb3 100644
--- a/cgit.css
+++ b/cgit.css
@@ -66,3 +66,3 @@ table#header td.sub {
66table.tabs { 66table.tabs {
67 /* border-bottom: solid 2px #ccc; */ 67 border-bottom: solid 3px #ccc;
68 border-collapse: collapse; 68 border-collapse: collapse;
@@ -104,2 +104,9 @@ table.tabs td.form select {
104 104
105div.path {
106 margin: 0px;
107 padding: 5px 2em 2px 2em;
108 color: #000;
109 background-color: #eee;
110}
111
105div.content { 112div.content {
@@ -107,3 +114,2 @@ div.content {
107 padding: 2em; 114 padding: 2em;
108 border-top: solid 3px #ccc;
109 border-bottom: solid 3px #ccc; 115 border-bottom: solid 3px #ccc;
diff --git a/cgit.h b/cgit.h
index 8884f9e..2b28d63 100644
--- a/cgit.h
+++ b/cgit.h
@@ -149,2 +149,4 @@ struct cgit_query {
149 int show_all; 149 int show_all;
150 int context;
151 char *vpath;
150}; 152};
@@ -279,3 +281,3 @@ extern int cgit_diff_files(const unsigned char *old_sha1,
279 unsigned long *old_size, unsigned long *new_size, 281 unsigned long *old_size, unsigned long *new_size,
280 int *binary, linediff_fn fn); 282 int *binary, int context, linediff_fn fn);
281 283
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 5c24381..a853522 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -446,3 +446,3 @@ snapshots=tar.gz tar.bz2 zip
446 446
447mimetype.git=image/git 447mimetype.gif=image/gif
448mimetype.html=text/html 448mimetype.html=text/html
diff --git a/cmd.c b/cmd.c
index ad784fc..6dc9f5e 100644
--- a/cmd.c
+++ b/cmd.c
@@ -53,3 +53,3 @@ static void commit_fn(struct cgit_context *ctx)
53{ 53{
54 cgit_print_commit(ctx->qry.sha1); 54 cgit_print_commit(ctx->qry.sha1, ctx->qry.path);
55} 55}
@@ -92,3 +92,3 @@ static void patch_fn(struct cgit_context *ctx)
92{ 92{
93 cgit_print_patch(ctx->qry.sha1); 93 cgit_print_patch(ctx->qry.sha1, ctx->qry.path);
94} 94}
@@ -131,4 +131,4 @@ static void tree_fn(struct cgit_context *ctx)
131 131
132#define def_cmd(name, want_repo, want_layout) \ 132#define def_cmd(name, want_repo, want_layout, want_vpath) \
133 {#name, name##_fn, want_repo, want_layout} 133 {#name, name##_fn, want_repo, want_layout, want_vpath}
134 134
@@ -137,21 +137,21 @@ struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx)
137 static struct cgit_cmd cmds[] = { 137 static struct cgit_cmd cmds[] = {
138 def_cmd(HEAD, 1, 0), 138 def_cmd(HEAD, 1, 0, 0),
139 def_cmd(atom, 1, 0), 139 def_cmd(atom, 1, 0, 0),
140 def_cmd(about, 0, 1), 140 def_cmd(about, 0, 1, 0),
141 def_cmd(blob, 1, 0), 141 def_cmd(blob, 1, 0, 0),
142 def_cmd(commit, 1, 1), 142 def_cmd(commit, 1, 1, 1),
143 def_cmd(diff, 1, 1), 143 def_cmd(diff, 1, 1, 1),
144 def_cmd(info, 1, 0), 144 def_cmd(info, 1, 0, 0),
145 def_cmd(log, 1, 1), 145 def_cmd(log, 1, 1, 1),
146 def_cmd(ls_cache, 0, 0), 146 def_cmd(ls_cache, 0, 0, 0),
147 def_cmd(objects, 1, 0), 147 def_cmd(objects, 1, 0, 0),
148 def_cmd(patch, 1, 0), 148 def_cmd(patch, 1, 0, 1),
149 def_cmd(plain, 1, 0), 149 def_cmd(plain, 1, 0, 0),
150 def_cmd(refs, 1, 1), 150 def_cmd(refs, 1, 1, 0),
151 def_cmd(repolist, 0, 0), 151 def_cmd(repolist, 0, 0, 0),
152 def_cmd(snapshot, 1, 0), 152 def_cmd(snapshot, 1, 0, 0),
153 def_cmd(stats, 1, 1), 153 def_cmd(stats, 1, 1, 1),
154 def_cmd(summary, 1, 1), 154 def_cmd(summary, 1, 1, 0),
155 def_cmd(tag, 1, 1), 155 def_cmd(tag, 1, 1, 0),
156 def_cmd(tree, 1, 1), 156 def_cmd(tree, 1, 1, 1),
157 }; 157 };
diff --git a/cmd.h b/cmd.h
index ec9e691..8dc01bd 100644
--- a/cmd.h
+++ b/cmd.h
@@ -9,3 +9,4 @@ struct cgit_cmd {
9 unsigned int want_repo:1, 9 unsigned int want_repo:1,
10 want_layout:1; 10 want_layout:1,
11 want_vpath:1;
11}; 12};
diff --git a/shared.c b/shared.c
index 8b3a045..06f70bb 100644
--- a/shared.c
+++ b/shared.c
@@ -12,3 +12,2 @@ struct cgit_repolist cgit_repolist;
12struct cgit_context ctx; 12struct cgit_context ctx;
13int cgit_cmd;
14 13
@@ -266,3 +265,4 @@ int cgit_diff_files(const unsigned char *old_sha1,
266 const unsigned char *new_sha1, unsigned long *old_size, 265 const unsigned char *new_sha1, unsigned long *old_size,
267 unsigned long *new_size, int *binary, linediff_fn fn) 266 unsigned long *new_size, int *binary, int context,
267 linediff_fn fn)
268{ 268{
@@ -293,3 +293,3 @@ int cgit_diff_files(const unsigned char *old_sha1,
293 diff_params.flags = XDF_NEED_MINIMAL; 293 diff_params.flags = XDF_NEED_MINIMAL;
294 emit_params.ctxlen = 3; 294 emit_params.ctxlen = context > 0 ? context : 3;
295 emit_params.flags = XDL_EMIT_FUNCNAMES; 295 emit_params.flags = XDL_EMIT_FUNCNAMES;
diff --git a/ui-commit.c b/ui-commit.c
index 41313b9..a11bc5f 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -14,3 +14,3 @@
14 14
15void cgit_print_commit(char *hex) 15void cgit_print_commit(char *hex, const char *prefix)
16{ 16{
@@ -60,10 +60,10 @@ void cgit_print_commit(char *hex)
60 tmp = sha1_to_hex(commit->object.sha1); 60 tmp = sha1_to_hex(commit->object.sha1);
61 cgit_commit_link(tmp, NULL, NULL, ctx.qry.head, tmp, 0); 61 cgit_commit_link(tmp, NULL, NULL, ctx.qry.head, tmp, prefix, 0);
62 html(" ("); 62 html(" (");
63 cgit_patch_link("patch", NULL, NULL, NULL, tmp); 63 cgit_patch_link("patch", NULL, NULL, NULL, tmp, prefix);
64 html(") ("); 64 html(") (");
65 if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff)) 65 if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff))
66 cgit_commit_link("unidiff", NULL, NULL, ctx.qry.head, tmp, 1); 66 cgit_commit_link("unidiff", NULL, NULL, ctx.qry.head, tmp, prefix, 1);
67 else 67 else
68 cgit_commit_link("side-by-side diff", NULL, NULL, ctx.qry.head, tmp, 1); 68 cgit_commit_link("side-by-side diff", NULL, NULL, ctx.qry.head, tmp, prefix, 1);
69 html(")</td></tr>\n"); 69 html(")</td></tr>\n");
@@ -73,2 +73,6 @@ void cgit_print_commit(char *hex)
73 ctx.qry.head, tmp, NULL); 73 ctx.qry.head, tmp, NULL);
74 if (prefix) {
75 html(" /");
76 cgit_tree_link(prefix, NULL, NULL, ctx.qry.head, tmp, prefix);
77 }
74 html("</td></tr>\n"); 78 html("</td></tr>\n");
@@ -89,6 +93,6 @@ void cgit_print_commit(char *hex)
89 } 93 }
90 cgit_commit_link(tmp2, NULL, NULL, ctx.qry.head, tmp, 0); 94 cgit_commit_link(tmp2, NULL, NULL, ctx.qry.head, tmp, prefix, 0);
91 html(" ("); 95 html(" (");
92 cgit_diff_link("diff", NULL, NULL, ctx.qry.head, hex, 96 cgit_diff_link("diff", NULL, NULL, ctx.qry.head, hex,
93 sha1_to_hex(p->item->object.sha1), NULL, 0); 97 sha1_to_hex(p->item->object.sha1), prefix, 0);
94 html(")</td></tr>"); 98 html(")</td></tr>");
@@ -123,3 +127,3 @@ void cgit_print_commit(char *hex)
123 tmp = NULL; 127 tmp = NULL;
124 cgit_print_diff(ctx.qry.sha1, tmp, NULL); 128 cgit_print_diff(ctx.qry.sha1, tmp, prefix);
125 } 129 }
diff --git a/ui-commit.h b/ui-commit.h
index 40bcb31..8198b4b 100644
--- a/ui-commit.h
+++ b/ui-commit.h
@@ -3,3 +3,3 @@
3 3
4extern void cgit_print_commit(char *hex); 4extern void cgit_print_commit(char *hex, const char *prefix);
5 5
diff --git a/ui-diff.c b/ui-diff.c
index a92a768..e0a72f7 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -129,3 +129,3 @@ static void inspect_filepair(struct diff_filepair *pair)
129 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, &new_size, 129 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, &new_size,
130 &binary, count_diff_lines); 130 &binary, 0, count_diff_lines);
131 if (files >= slots) { 131 if (files >= slots) {
@@ -156,5 +156,5 @@ static void inspect_filepair(struct diff_filepair *pair)
156void cgit_print_diffstat(const unsigned char *old_sha1, 156void cgit_print_diffstat(const unsigned char *old_sha1,
157 const unsigned char *new_sha1) 157 const unsigned char *new_sha1, const char *prefix)
158{ 158{
159 int i; 159 int i, save_context = ctx.qry.context;
160 160
@@ -163,2 +163,12 @@ void cgit_print_diffstat(const unsigned char *old_sha1,
163 ctx.qry.sha2, NULL, 0); 163 ctx.qry.sha2, NULL, 0);
164 if (prefix)
165 htmlf(" (limited to '%s')", prefix);
166 html(" (");
167 ctx.qry.context = (save_context > 0 ? save_context : 3) << 1;
168 cgit_self_link("more", NULL, NULL, &ctx);
169 html("/");
170 ctx.qry.context = (save_context > 3 ? save_context : 3) >> 1;
171 cgit_self_link("less", NULL, NULL, &ctx);
172 ctx.qry.context = save_context;
173 html(" context)");
164 html("</div>"); 174 html("</div>");
@@ -166,3 +176,3 @@ void cgit_print_diffstat(const unsigned char *old_sha1,
166 max_changes = 0; 176 max_changes = 0;
167 cgit_diff_tree(old_sha1, new_sha1, inspect_filepair, NULL); 177 cgit_diff_tree(old_sha1, new_sha1, inspect_filepair, prefix);
168 for(i = 0; i<files; i++) 178 for(i = 0; i<files; i++)
@@ -288,3 +298,3 @@ static void filepair_cb(struct diff_filepair *pair)
288 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, 298 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
289 &new_size, &binary, print_line_fn)) 299 &new_size, &binary, ctx.qry.context, print_line_fn))
290 cgit_print_error("Error running diff"); 300 cgit_print_error("Error running diff");
@@ -340,3 +350,3 @@ void cgit_print_diff(const char *new_rev, const char *old_rev, const char *prefi
340 print_ssdiff_link(); 350 print_ssdiff_link();
341 cgit_print_diffstat(old_rev_sha1, new_rev_sha1); 351 cgit_print_diffstat(old_rev_sha1, new_rev_sha1, prefix);
342 352
diff --git a/ui-log.c b/ui-log.c
index 4441d1d..33ec8a9 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -35,3 +35,3 @@ void inspect_files(struct diff_filepair *pair)
35 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, 35 cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
36 &new_size, &binary, count_lines); 36 &new_size, &binary, 0, count_lines);
37} 37}
@@ -48,4 +48,5 @@ void show_commit_decorations(struct commit *commit)
48 strncpy(buf, deco->name + 11, sizeof(buf) - 1); 48 strncpy(buf, deco->name + 11, sizeof(buf) - 1);
49 cgit_log_link(buf, NULL, "branch-deco", buf, NULL, NULL, 49 cgit_log_link(buf, NULL, "branch-deco", buf, NULL,
50 0, NULL, NULL, ctx.qry.showmsg); 50 ctx.qry.vpath, 0, NULL, NULL,
51 ctx.qry.showmsg);
51 } 52 }
@@ -62,4 +63,5 @@ void show_commit_decorations(struct commit *commit)
62 cgit_log_link(buf, NULL, "remote-deco", NULL, 63 cgit_log_link(buf, NULL, "remote-deco", NULL,
63 sha1_to_hex(commit->object.sha1), NULL, 64 sha1_to_hex(commit->object.sha1),
64 0, NULL, NULL, ctx.qry.showmsg); 65 ctx.qry.vpath, 0, NULL, NULL,
66 ctx.qry.showmsg);
65 } 67 }
@@ -68,3 +70,4 @@ void show_commit_decorations(struct commit *commit)
68 cgit_commit_link(buf, NULL, "deco", ctx.qry.head, 70 cgit_commit_link(buf, NULL, "deco", ctx.qry.head,
69 sha1_to_hex(commit->object.sha1), 0); 71 sha1_to_hex(commit->object.sha1),
72 ctx.qry.vpath, 0);
70 } 73 }
@@ -84,3 +87,3 @@ void print_commit(struct commit *commit)
84 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1)); 87 tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1));
85 tmp = cgit_pageurl(ctx.repo->url, "commit", tmp); 88 tmp = cgit_fileurl(ctx.repo->url, "commit", ctx.qry.vpath, tmp);
86 html_link_open(tmp, NULL, NULL); 89 html_link_open(tmp, NULL, NULL);
@@ -91,3 +94,3 @@ void print_commit(struct commit *commit)
91 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, 94 cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head,
92 sha1_to_hex(commit->object.sha1), 0); 95 sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0);
93 show_commit_decorations(commit); 96 show_commit_decorations(commit);
@@ -181,3 +184,3 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
181 NULL, ctx.qry.head, ctx.qry.sha1, 184 NULL, ctx.qry.head, ctx.qry.sha1,
182 ctx.qry.path, ctx.qry.ofs, ctx.qry.grep, 185 ctx.qry.vpath, ctx.qry.ofs, ctx.qry.grep,
183 ctx.qry.search, ctx.qry.showmsg ? 0 : 1); 186 ctx.qry.search, ctx.qry.showmsg ? 0 : 1);
@@ -218,3 +221,3 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
218 cgit_log_link("[prev]", NULL, NULL, ctx.qry.head, 221 cgit_log_link("[prev]", NULL, NULL, ctx.qry.head,
219 ctx.qry.sha1, ctx.qry.path, 222 ctx.qry.sha1, ctx.qry.vpath,
220 ofs - cnt, ctx.qry.grep, 223 ofs - cnt, ctx.qry.grep,
@@ -225,3 +228,3 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
225 cgit_log_link("[next]", NULL, NULL, ctx.qry.head, 228 cgit_log_link("[next]", NULL, NULL, ctx.qry.head,
226 ctx.qry.sha1, ctx.qry.path, 229 ctx.qry.sha1, ctx.qry.vpath,
227 ofs + cnt, ctx.qry.grep, 230 ofs + cnt, ctx.qry.grep,
@@ -232,4 +235,4 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern
232 html("<tr class='nohover'><td colspan='3'>"); 235 html("<tr class='nohover'><td colspan='3'>");
233 cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL, NULL, 0, 236 cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL,
234 NULL, NULL, ctx.qry.showmsg); 237 ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg);
235 html("</td></tr>\n"); 238 html("</td></tr>\n");
diff --git a/ui-patch.c b/ui-patch.c
index 2a8f7a5..d13104c 100644
--- a/ui-patch.c
+++ b/ui-patch.c
@@ -73,3 +73,3 @@ static void filepair_cb(struct diff_filepair *pair)
73 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, 73 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
74 &new_size, &binary, print_line)) 74 &new_size, &binary, 0, print_line))
75 html("Error running diff"); 75 html("Error running diff");
@@ -79,3 +79,3 @@ static void filepair_cb(struct diff_filepair *pair)
79 79
80void cgit_print_patch(char *hex) 80void cgit_print_patch(char *hex, const char *prefix)
81{ 81{
@@ -124,3 +124,5 @@ void cgit_print_patch(char *hex)
124 html("---\n"); 124 html("---\n");
125 cgit_diff_tree(old_sha1, sha1, filepair_cb, NULL); 125 if (prefix)
126 htmlf("(limited to '%s')\n\n", prefix);
127 cgit_diff_tree(old_sha1, sha1, filepair_cb, prefix);
126 html("--\n"); 128 html("--\n");
diff --git a/ui-patch.h b/ui-patch.h
index 9f68212..1641cea 100644
--- a/ui-patch.h
+++ b/ui-patch.h
@@ -3,3 +3,3 @@
3 3
4extern void cgit_print_patch(char *hex); 4extern void cgit_print_patch(char *hex, const char *prefix);
5 5
diff --git a/ui-refs.c b/ui-refs.c
index 98738db..94ff6be 100644
--- a/ui-refs.c
+++ b/ui-refs.c
@@ -76,3 +76,3 @@ static int print_branch(struct refinfo *ref)
76 if (ref->object->type == OBJ_COMMIT) { 76 if (ref->object->type == OBJ_COMMIT) {
77 cgit_commit_link(info->subject, NULL, NULL, name, NULL, 0); 77 cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
78 html("</td><td>"); 78 html("</td><td>");
diff --git a/ui-shared.c b/ui-shared.c
index 0f65474..c398d7a 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -29,3 +29,3 @@ static char *http_date(time_t t)
29 29
30void cgit_print_error(char *msg) 30void cgit_print_error(const char *msg)
31{ 31{
@@ -135,3 +135,3 @@ char *cgit_currurl()
135 135
136static void site_url(char *page, char *search, int ofs) 136static void site_url(const char *page, const char *search, int ofs)
137{ 137{
@@ -162,4 +162,4 @@ static void site_url(char *page, char *search, int ofs)
162 162
163static void site_link(char *page, char *name, char *title, char *class, 163static void site_link(const char *page, const char *name, const char *title,
164 char *search, int ofs) 164 const char *class, const char *search, int ofs)
165{ 165{
@@ -183,4 +183,4 @@ static void site_link(char *page, char *name, char *title, char *class,
183 183
184void cgit_index_link(char *name, char *title, char *class, char *pattern, 184void cgit_index_link(const char *name, const char *title, const char *class,
185 int ofs) 185 const char *pattern, int ofs)
186{ 186{
@@ -189,4 +189,4 @@ void cgit_index_link(char *name, char *title, char *class, char *pattern,
189 189
190static char *repolink(char *title, char *class, char *page, char *head, 190static char *repolink(const char *title, const char *class, const char *page,
191 char *path) 191 const char *head, const char *path)
192{ 192{
@@ -242,4 +242,5 @@ static char *repolink(char *title, char *class, char *page, char *head,
242 242
243static void reporevlink(char *page, char *name, char *title, char *class, 243static void reporevlink(const char *page, const char *name, const char *title,
244 char *head, char *rev, char *path) 244 const char *class, const char *head, const char *rev,
245 const char *path)
245{ 246{
@@ -258,3 +259,4 @@ static void reporevlink(char *page, char *name, char *title, char *class,
258 259
259void cgit_summary_link(char *name, char *title, char *class, char *head) 260void cgit_summary_link(const char *name, const char *title, const char *class,
261 const char *head)
260{ 262{
@@ -263,4 +265,4 @@ void cgit_summary_link(char *name, char *title, char *class, char *head)
263 265
264void cgit_tag_link(char *name, char *title, char *class, char *head, 266void cgit_tag_link(const char *name, const char *title, const char *class,
265 char *rev) 267 const char *head, const char *rev)
266{ 268{
@@ -269,4 +271,4 @@ void cgit_tag_link(char *name, char *title, char *class, char *head,
269 271
270void cgit_tree_link(char *name, char *title, char *class, char *head, 272void cgit_tree_link(const char *name, const char *title, const char *class,
271 char *rev, char *path) 273 const char *head, const char *rev, const char *path)
272{ 274{
@@ -275,4 +277,4 @@ void cgit_tree_link(char *name, char *title, char *class, char *head,
275 277
276void cgit_plain_link(char *name, char *title, char *class, char *head, 278void cgit_plain_link(const char *name, const char *title, const char *class,
277 char *rev, char *path) 279 const char *head, const char *rev, const char *path)
278{ 280{
@@ -281,5 +283,5 @@ void cgit_plain_link(char *name, char *title, char *class, char *head,
281 283
282void cgit_log_link(char *name, char *title, char *class, char *head, 284void cgit_log_link(const char *name, const char *title, const char *class,
283 char *rev, char *path, int ofs, char *grep, char *pattern, 285 const char *head, const char *rev, const char *path,
284 int showmsg) 286 int ofs, const char *grep, const char *pattern, int showmsg)
285{ 287{
@@ -318,4 +320,5 @@ void cgit_log_link(char *name, char *title, char *class, char *head,
318 320
319void cgit_commit_link(char *name, char *title, char *class, char *head, 321void cgit_commit_link(char *name, const char *title, const char *class,
320 char *rev, int toggle_ssdiff) 322 const char *head, const char *rev, const char *path,
323 int toggle_ssdiff)
321{ 324{
@@ -330,3 +333,3 @@ void cgit_commit_link(char *name, char *title, char *class, char *head,
330 333
331 delim = repolink(title, class, "commit", head, NULL); 334 delim = repolink(title, class, "commit", head, path);
332 if (rev && strcmp(rev, ctx.qry.head)) { 335 if (rev && strcmp(rev, ctx.qry.head)) {
@@ -340,2 +343,9 @@ void cgit_commit_link(char *name, char *title, char *class, char *head,
340 html("ss=1"); 343 html("ss=1");
344 delim = "&amp;";
345 }
346 if (ctx.qry.context > 0 && ctx.qry.context != 3) {
347 html(delim);
348 html("context=");
349 htmlf("%d", ctx.qry.context);
350 delim = "&amp;";
341 } 351 }
@@ -346,4 +356,4 @@ void cgit_commit_link(char *name, char *title, char *class, char *head,
346 356
347void cgit_refs_link(char *name, char *title, char *class, char *head, 357void cgit_refs_link(const char *name, const char *title, const char *class,
348 char *rev, char *path) 358 const char *head, const char *rev, const char *path)
349{ 359{
@@ -352,4 +362,5 @@ void cgit_refs_link(char *name, char *title, char *class, char *head,
352 362
353void cgit_snapshot_link(char *name, char *title, char *class, char *head, 363void cgit_snapshot_link(const char *name, const char *title, const char *class,
354 char *rev, char *archivename) 364 const char *head, const char *rev,
365 const char *archivename)
355{ 366{
@@ -358,5 +369,5 @@ void cgit_snapshot_link(char *name, char *title, char *class, char *head,
358 369
359void cgit_diff_link(char *name, char *title, char *class, char *head, 370void cgit_diff_link(const char *name, const char *title, const char *class,
360 char *new_rev, char *old_rev, char *path, 371 const char *head, const char *new_rev, const char *old_rev,
361 int toggle_ssdiff) 372 const char *path, int toggle_ssdiff)
362{ 373{
@@ -380,2 +391,9 @@ void cgit_diff_link(char *name, char *title, char *class, char *head,
380 html("ss=1"); 391 html("ss=1");
392 delim = "&amp;";
393 }
394 if (ctx.qry.context > 0 && ctx.qry.context != 3) {
395 html(delim);
396 html("context=");
397 htmlf("%d", ctx.qry.context);
398 delim = "&amp;";
381 } 399 }
@@ -386,10 +404,10 @@ void cgit_diff_link(char *name, char *title, char *class, char *head,
386 404
387void cgit_patch_link(char *name, char *title, char *class, char *head, 405void cgit_patch_link(const char *name, const char *title, const char *class,
388 char *rev) 406 const char *head, const char *rev, const char *path)
389{ 407{
390 reporevlink("patch", name, title, class, head, rev, NULL); 408 reporevlink("patch", name, title, class, head, rev, path);
391} 409}
392 410
393void cgit_stats_link(char *name, char *title, char *class, char *head, 411void cgit_stats_link(const char *name, const char *title, const char *class,
394 char *path) 412 const char *head, const char *path)
395{ 413{
@@ -398,2 +416,60 @@ void cgit_stats_link(char *name, char *title, char *class, char *head,
398 416
417void cgit_self_link(char *name, const char *title, const char *class,
418 struct cgit_context *ctx)
419{
420 if (!strcmp(ctx->qry.page, "repolist"))
421 return cgit_index_link(name, title, class, ctx->qry.search,
422 ctx->qry.ofs);
423 else if (!strcmp(ctx->qry.page, "summary"))
424 return cgit_summary_link(name, title, class, ctx->qry.head);
425 else if (!strcmp(ctx->qry.page, "tag"))
426 return cgit_tag_link(name, title, class, ctx->qry.head,
427 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL);
428 else if (!strcmp(ctx->qry.page, "tree"))
429 return cgit_tree_link(name, title, class, ctx->qry.head,
430 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
431 ctx->qry.path);
432 else if (!strcmp(ctx->qry.page, "plain"))
433 return cgit_plain_link(name, title, class, ctx->qry.head,
434 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
435 ctx->qry.path);
436 else if (!strcmp(ctx->qry.page, "log"))
437 return cgit_log_link(name, title, class, ctx->qry.head,
438 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
439 ctx->qry.path, ctx->qry.ofs,
440 ctx->qry.grep, ctx->qry.search,
441 ctx->qry.showmsg);
442 else if (!strcmp(ctx->qry.page, "commit"))
443 return cgit_commit_link(name, title, class, ctx->qry.head,
444 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
445 ctx->qry.path, 0);
446 else if (!strcmp(ctx->qry.page, "patch"))
447 return cgit_patch_link(name, title, class, ctx->qry.head,
448 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
449 ctx->qry.path);
450 else if (!strcmp(ctx->qry.page, "refs"))
451 return cgit_refs_link(name, title, class, ctx->qry.head,
452 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
453 ctx->qry.path);
454 else if (!strcmp(ctx->qry.page, "snapshot"))
455 return cgit_snapshot_link(name, title, class, ctx->qry.head,
456 ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,
457 ctx->qry.path);
458 else if (!strcmp(ctx->qry.page, "diff"))
459 return cgit_diff_link(name, title, class, ctx->qry.head,
460 ctx->qry.sha1, ctx->qry.sha2,
461 ctx->qry.path, 0);
462 else if (!strcmp(ctx->qry.page, "stats"))
463 return cgit_stats_link(name, title, class, ctx->qry.head,
464 ctx->qry.path);
465
466 /* Don't known how to make link for this page */
467 repolink(title, class, ctx->qry.page, ctx->qry.head, ctx->qry.path);
468 html("><!-- cgit_self_link() doesn't know how to make link for page '");
469 html_txt(ctx->qry.page);
470 html("' -->");
471 html_txt(name);
472 html("</a>");
473}
474
399void cgit_object_link(struct object *obj) 475void cgit_object_link(struct object *obj)
@@ -407,3 +483,3 @@ void cgit_object_link(struct object *obj)
407 cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL, 483 cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL,
408 ctx.qry.head, fullrev, 0); 484 ctx.qry.head, fullrev, NULL, 0);
409 return; 485 return;
@@ -419,3 +495,3 @@ void cgit_object_link(struct object *obj)
419 495
420void cgit_print_date(time_t secs, char *format, int local_time) 496void cgit_print_date(time_t secs, const char *format, int local_time)
421{ 497{
@@ -434,3 +510,3 @@ void cgit_print_date(time_t secs, char *format, int local_time)
434 510
435void cgit_print_age(time_t t, time_t max_relative, char *format) 511void cgit_print_age(time_t t, time_t max_relative, const char *format)
436{ 512{
@@ -533,3 +609,3 @@ void cgit_print_docstart(struct cgit_context *ctx)
533 html_attr(cgit_hosturl()); 609 html_attr(cgit_hosturl());
534 html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.path, 610 html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.vpath,
535 fmt("h=%s", ctx->qry.head))); 611 fmt("h=%s", ctx->qry.head)));
@@ -613,3 +689,4 @@ int print_archive_ref(const char *refname, const unsigned char *sha1,
613 689
614void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page) 690void cgit_add_hidden_formfields(int incl_head, int incl_search,
691 const char *page)
615{ 692{
@@ -619,4 +696,4 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page)
619 url = fmt("%s/%s", ctx.qry.repo, page); 696 url = fmt("%s/%s", ctx.qry.repo, page);
620 if (ctx.qry.path) 697 if (ctx.qry.vpath)
621 url = fmt("%s/%s", url, ctx.qry.path); 698 url = fmt("%s/%s", url, ctx.qry.vpath);
622 html_hidden("url", url); 699 html_hidden("url", url);
@@ -643,7 +720,26 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page)
643 720
644const char *fallback_cmd = "repolist"; 721static const char *hc(struct cgit_context *ctx, const char *page)
722{
723 return strcmp(ctx->qry.page, page) ? NULL : "active";
724}
645 725
646char *hc(struct cgit_cmd *cmd, const char *page) 726static void cgit_print_path_crumbs(struct cgit_context *ctx, char *path)
647{ 727{
648 return (strcmp(cmd ? cmd->name : fallback_cmd, page) ? NULL : "active"); 728 char *old_path = ctx->qry.path;
729 char *p = path, *q, *end = path + strlen(path);
730
731 ctx->qry.path = NULL;
732 cgit_self_link("root", NULL, NULL, ctx);
733 ctx->qry.path = p = path;
734 while (p < end) {
735 if (!(q = strchr(p, '/')))
736 q = end;
737 *q = '\0';
738 html_txt("/");
739 cgit_self_link(p, NULL, NULL, ctx);
740 if (q < end)
741 *q = '/';
742 p = q + 1;
743 }
744 ctx->qry.path = old_path;
649} 745}
@@ -699,7 +795,2 @@ void cgit_print_pageheader(struct cgit_context *ctx)
699{ 795{
700 struct cgit_cmd *cmd = cgit_get_cmd(ctx);
701
702 if (!cmd && ctx->repo)
703 fallback_cmd = "summary";
704
705 html("<div id='cgit'>"); 796 html("<div id='cgit'>");
@@ -710,20 +801,21 @@ void cgit_print_pageheader(struct cgit_context *ctx)
710 if (ctx->repo) { 801 if (ctx->repo) {
711 cgit_summary_link("summary", NULL, hc(cmd, "summary"), 802 cgit_summary_link("summary", NULL, hc(ctx, "summary"),
712 ctx->qry.head); 803 ctx->qry.head);
713 cgit_refs_link("refs", NULL, hc(cmd, "refs"), ctx->qry.head, 804 cgit_refs_link("refs", NULL, hc(ctx, "refs"), ctx->qry.head,
714 ctx->qry.sha1, NULL); 805 ctx->qry.sha1, NULL);
715 cgit_log_link("log", NULL, hc(cmd, "log"), ctx->qry.head, 806 cgit_log_link("log", NULL, hc(ctx, "log"), ctx->qry.head,
716 NULL, NULL, 0, NULL, NULL, ctx->qry.showmsg); 807 NULL, ctx->qry.vpath, 0, NULL, NULL,
717 cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head, 808 ctx->qry.showmsg);
718 ctx->qry.sha1, NULL); 809 cgit_tree_link("tree", NULL, hc(ctx, "tree"), ctx->qry.head,
719 cgit_commit_link("commit", NULL, hc(cmd, "commit"), 810 ctx->qry.sha1, ctx->qry.vpath);
720 ctx->qry.head, ctx->qry.sha1, 0); 811 cgit_commit_link("commit", NULL, hc(ctx, "commit"),
721 cgit_diff_link("diff", NULL, hc(cmd, "diff"), ctx->qry.head, 812 ctx->qry.head, ctx->qry.sha1, ctx->qry.vpath, 0);
722 ctx->qry.sha1, ctx->qry.sha2, NULL, 0); 813 cgit_diff_link("diff", NULL, hc(ctx, "diff"), ctx->qry.head,
814 ctx->qry.sha1, ctx->qry.sha2, ctx->qry.vpath, 0);
723 if (ctx->repo->max_stats) 815 if (ctx->repo->max_stats)
724 cgit_stats_link("stats", NULL, hc(cmd, "stats"), 816 cgit_stats_link("stats", NULL, hc(ctx, "stats"),
725 ctx->qry.head, NULL); 817 ctx->qry.head, ctx->qry.vpath);
726 if (ctx->repo->readme) 818 if (ctx->repo->readme)
727 reporevlink("about", "about", NULL, 819 reporevlink("about", "about", NULL,
728 hc(cmd, "about"), ctx->qry.head, NULL, 820 hc(ctx, "about"), ctx->qry.head, NULL,
729 NULL); 821 NULL);
@@ -733,3 +825,3 @@ void cgit_print_pageheader(struct cgit_context *ctx)
733 html_url_path(cgit_fileurl(ctx->qry.repo, "log", 825 html_url_path(cgit_fileurl(ctx->qry.repo, "log",
734 ctx->qry.path, NULL)); 826 ctx->qry.vpath, NULL));
735 html("'>\n"); 827 html("'>\n");
@@ -748,5 +840,5 @@ void cgit_print_pageheader(struct cgit_context *ctx)
748 } else { 840 } else {
749 site_link(NULL, "index", NULL, hc(cmd, "repolist"), NULL, 0); 841 site_link(NULL, "index", NULL, hc(ctx, "repolist"), NULL, 0);
750 if (ctx->cfg.root_readme) 842 if (ctx->cfg.root_readme)
751 site_link("about", "about", NULL, hc(cmd, "about"), 843 site_link("about", "about", NULL, hc(ctx, "about"),
752 NULL, 0); 844 NULL, 0);
@@ -763,2 +855,8 @@ void cgit_print_pageheader(struct cgit_context *ctx)
763 html("</td></tr></table>\n"); 855 html("</td></tr></table>\n");
856 if (ctx->qry.vpath) {
857 html("<div class='path'>");
858 html("path: ");
859 cgit_print_path_crumbs(ctx, ctx->qry.vpath);
860 html("</div>");
861 }
764 html("<div class='content'>"); 862 html("<div class='content'>");
diff --git a/ui-shared.h b/ui-shared.h
index 9ebc1f9..3cc1258 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -12,32 +12,46 @@ extern char *cgit_pageurl(const char *reponame, const char *pagename,
12 12
13extern void cgit_index_link(char *name, char *title, char *class, 13extern void cgit_index_link(const char *name, const char *title,
14 char *pattern, int ofs); 14 const char *class, const char *pattern, int ofs);
15extern void cgit_summary_link(char *name, char *title, char *class, char *head); 15extern void cgit_summary_link(const char *name, const char *title,
16extern void cgit_tag_link(char *name, char *title, char *class, char *head, 16 const char *class, const char *head);
17 char *rev); 17extern void cgit_tag_link(const char *name, const char *title,
18extern void cgit_tree_link(char *name, char *title, char *class, char *head, 18 const char *class, const char *head,
19 char *rev, char *path); 19 const char *rev);
20extern void cgit_plain_link(char *name, char *title, char *class, char *head, 20extern void cgit_tree_link(const char *name, const char *title,
21 char *rev, char *path); 21 const char *class, const char *head,
22extern void cgit_log_link(char *name, char *title, char *class, char *head, 22 const char *rev, const char *path);
23 char *rev, char *path, int ofs, char *grep, 23extern void cgit_plain_link(const char *name, const char *title,
24 char *pattern, int showmsg); 24 const char *class, const char *head,
25extern void cgit_commit_link(char *name, char *title, char *class, char *head, 25 const char *rev, const char *path);
26 char *rev, int toggle_ssdiff); 26extern void cgit_log_link(const char *name, const char *title,
27extern void cgit_patch_link(char *name, char *title, char *class, char *head, 27 const char *class, const char *head, const char *rev,
28 char *rev); 28 const char *path, int ofs, const char *grep,
29extern void cgit_refs_link(char *name, char *title, char *class, char *head, 29 const char *pattern, int showmsg);
30 char *rev, char *path); 30extern void cgit_commit_link(char *name, const char *title,
31extern void cgit_snapshot_link(char *name, char *title, char *class, 31 const char *class, const char *head,
32 char *head, char *rev, char *archivename); 32 const char *rev, const char *path,
33extern void cgit_diff_link(char *name, char *title, char *class, char *head,
34 char *new_rev, char *old_rev, char *path,
35 int toggle_ssdiff); 33 int toggle_ssdiff);
36extern void cgit_stats_link(char *name, char *title, char *class, char *head, 34extern void cgit_patch_link(const char *name, const char *title,
37 char *path); 35 const char *class, const char *head,
36 const char *rev, const char *path);
37extern void cgit_refs_link(const char *name, const char *title,
38 const char *class, const char *head,
39 const char *rev, const char *path);
40extern void cgit_snapshot_link(const char *name, const char *title,
41 const char *class, const char *head,
42 const char *rev, const char *archivename);
43extern void cgit_diff_link(const char *name, const char *title,
44 const char *class, const char *head,
45 const char *new_rev, const char *old_rev,
46 const char *path, int toggle_ssdiff);
47extern void cgit_stats_link(const char *name, const char *title,
48 const char *class, const char *head,
49 const char *path);
50extern void cgit_self_link(char *name, const char *title,
51 const char *class, struct cgit_context *ctx);
38extern void cgit_object_link(struct object *obj); 52extern void cgit_object_link(struct object *obj);
39 53
40extern void cgit_print_error(char *msg); 54extern void cgit_print_error(const char *msg);
41extern void cgit_print_date(time_t secs, char *format, int local_time); 55extern void cgit_print_date(time_t secs, const char *format, int local_time);
42extern void cgit_print_age(time_t t, time_t max_relative, char *format); 56extern void cgit_print_age(time_t t, time_t max_relative, const char *format);
43extern void cgit_print_http_headers(struct cgit_context *ctx); 57extern void cgit_print_http_headers(struct cgit_context *ctx);
@@ -50,3 +64,3 @@ extern void cgit_print_snapshot_links(const char *repo, const char *head,
50extern void cgit_add_hidden_formfields(int incl_head, int incl_search, 64extern void cgit_add_hidden_formfields(int incl_head, int incl_search,
51 char *page); 65 const char *page);
52#endif /* UI_SHARED_H */ 66#endif /* UI_SHARED_H */
diff --git a/ui-tree.c b/ui-tree.c
index 0ee38f2..75ec9cb 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -104,6 +104,6 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
104 104
105 html(" ("); 105 htmlf("blob: %s (", sha1_to_hex(sha1));
106 cgit_plain_link("plain", NULL, NULL, ctx.qry.head, 106 cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
107 curr_rev, path); 107 curr_rev, path);
108 htmlf(")<br/>blob: %s\n", sha1_to_hex(sha1)); 108 html(")\n");
109 109
@@ -227,3 +227,2 @@ static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
227 static char buffer[PATH_MAX]; 227 static char buffer[PATH_MAX];
228 char *url;
229 228
@@ -232,8 +231,2 @@ static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
232 strcpy(buffer+baselen, pathname); 231 strcpy(buffer+baselen, pathname);
233 url = cgit_pageurl(ctx.qry.repo, "tree",
234 fmt("h=%s&amp;path=%s", curr_rev, buffer));
235 html("/");
236 cgit_tree_link(xstrdup(pathname), NULL, NULL, ctx.qry.head,
237 curr_rev, buffer);
238
239 if (strcmp(match_path, buffer)) 232 if (strcmp(match_path, buffer))
@@ -280,6 +273,2 @@ void cgit_print_tree(const char *rev, char *path)
280 273
281 html("path: <a href='");
282 html_attr(cgit_pageurl(ctx.qry.repo, "tree", fmt("h=%s", rev)));
283 html("'>root</a>");
284
285 if (path == NULL) { 274 if (path == NULL) {