diff options
author | Jason A. Donenfeld | 2012-07-12 19:13:39 +0200 |
---|---|---|
committer | Jason A. Donenfeld | 2012-07-12 20:01:46 +0200 |
commit | 184c5655b2e350dbd0dd8be75d3f370f22aa6dee (patch) | |
tree | bcd4fef53e416f443666ec50f21adef33fc95e76 | |
parent | scan-tree: Support gitweb.category. (diff) | |
download | cgit-184c5655b2e350dbd0dd8be75d3f370f22aa6dee.tar.gz cgit-184c5655b2e350dbd0dd8be75d3f370f22aa6dee.zip |
ui-repolist: Case insensitive sorting and age sort
Add two options, one for doing the ordinary name sorts in a case-insensitive manner, and another for choosing to sort repos in each section by age instead of by name.
-rw-r--r-- | cgit.c | 6 | ||||
-rw-r--r-- | cgit.h | 2 | ||||
-rw-r--r-- | cgitrc.5.txt | 12 | ||||
-rw-r--r-- | ui-repolist.c | 22 |
4 files changed, 37 insertions, 5 deletions
diff --git a/cgit.c b/cgit.c index 4656ed6..24ef8e0 100644 --- a/cgit.c +++ b/cgit.c | |||
@@ -199,6 +199,8 @@ void config_cb(const char *name, const char *value) | |||
199 | ctx.cfg.cache_static_ttl = atoi(value); | 199 | ctx.cfg.cache_static_ttl = atoi(value); |
200 | else if (!strcmp(name, "cache-dynamic-ttl")) | 200 | else if (!strcmp(name, "cache-dynamic-ttl")) |
201 | ctx.cfg.cache_dynamic_ttl = atoi(value); | 201 | ctx.cfg.cache_dynamic_ttl = atoi(value); |
202 | else if (!strcmp(name, "case-sensitive-sort")) | ||
203 | ctx.cfg.case_sensitive_sort = atoi(value); | ||
202 | else if (!strcmp(name, "about-filter")) | 204 | else if (!strcmp(name, "about-filter")) |
203 | ctx.cfg.about_filter = new_filter(value, ABOUT); | 205 | ctx.cfg.about_filter = new_filter(value, ABOUT); |
204 | else if (!strcmp(name, "commit-filter")) | 206 | else if (!strcmp(name, "commit-filter")) |
@@ -231,6 +233,8 @@ void config_cb(const char *name, const char *value) | |||
231 | ctx.cfg.scan_hidden_path = atoi(value); | 233 | ctx.cfg.scan_hidden_path = atoi(value); |
232 | else if (!strcmp(name, "section-from-path")) | 234 | else if (!strcmp(name, "section-from-path")) |
233 | ctx.cfg.section_from_path = atoi(value); | 235 | ctx.cfg.section_from_path = atoi(value); |
236 | else if (!strcmp(name, "section-sort")) | ||
237 | ctx.cfg.section_sort = xstrdup(value); | ||
234 | else if (!strcmp(name, "source-filter")) | 238 | else if (!strcmp(name, "source-filter")) |
235 | ctx.cfg.source_filter = new_filter(value, SOURCE); | 239 | ctx.cfg.source_filter = new_filter(value, SOURCE); |
236 | else if (!strcmp(name, "summary-log")) | 240 | else if (!strcmp(name, "summary-log")) |
@@ -335,6 +339,7 @@ static void prepare_context(struct cgit_context *ctx) | |||
335 | ctx->cfg.cache_root_ttl = 5; | 339 | ctx->cfg.cache_root_ttl = 5; |
336 | ctx->cfg.cache_scanrc_ttl = 15; | 340 | ctx->cfg.cache_scanrc_ttl = 15; |
337 | ctx->cfg.cache_static_ttl = -1; | 341 | ctx->cfg.cache_static_ttl = -1; |
342 | ctx->cfg.case_sensitive_sort = 1; | ||
338 | ctx->cfg.css = "/cgit.css"; | 343 | ctx->cfg.css = "/cgit.css"; |
339 | ctx->cfg.logo = "/cgit.png"; | 344 | ctx->cfg.logo = "/cgit.png"; |
340 | ctx->cfg.local_time = 0; | 345 | ctx->cfg.local_time = 0; |
@@ -359,6 +364,7 @@ static void prepare_context(struct cgit_context *ctx) | |||
359 | ctx->cfg.scan_hidden_path = 0; | 364 | ctx->cfg.scan_hidden_path = 0; |
360 | ctx->cfg.script_name = CGIT_SCRIPT_NAME; | 365 | ctx->cfg.script_name = CGIT_SCRIPT_NAME; |
361 | ctx->cfg.section = ""; | 366 | ctx->cfg.section = ""; |
367 | ctx->cfg.section_sort = "name"; | ||
362 | ctx->cfg.summary_branches = 10; | 368 | ctx->cfg.summary_branches = 10; |
363 | ctx->cfg.summary_log = 10; | 369 | ctx->cfg.summary_log = 10; |
364 | ctx->cfg.summary_tags = 10; | 370 | ctx->cfg.summary_tags = 10; |
diff --git a/cgit.h b/cgit.h index 91b4d72..79ba7ad 100644 --- a/cgit.h +++ b/cgit.h | |||
@@ -187,6 +187,7 @@ struct cgit_config { | |||
187 | char *root_readme; | 187 | char *root_readme; |
188 | char *script_name; | 188 | char *script_name; |
189 | char *section; | 189 | char *section; |
190 | char *section_sort; | ||
190 | char *virtual_root; | 191 | char *virtual_root; |
191 | char *strict_export; | 192 | char *strict_export; |
192 | int cache_size; | 193 | int cache_size; |
@@ -196,6 +197,7 @@ struct cgit_config { | |||
196 | int cache_root_ttl; | 197 | int cache_root_ttl; |
197 | int cache_scanrc_ttl; | 198 | int cache_scanrc_ttl; |
198 | int cache_static_ttl; | 199 | int cache_static_ttl; |
200 | int case_sensitive_sort; | ||
199 | int embedded; | 201 | int embedded; |
200 | int enable_filter_overrides; | 202 | int enable_filter_overrides; |
201 | int enable_gitweb_owner; | 203 | int enable_gitweb_owner; |
diff --git a/cgitrc.5.txt b/cgitrc.5.txt index d1a90c5..902fff3 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt | |||
@@ -70,6 +70,10 @@ cache-static-ttl:: | |||
70 | version of repository pages accessed with a fixed SHA1. Default value: | 70 | version of repository pages accessed with a fixed SHA1. Default value: |
71 | "5". | 71 | "5". |
72 | 72 | ||
73 | case-sensitive-sort:: | ||
74 | Sort items in the repo list case sensitively. Default value: "1". | ||
75 | See also: section-sort. | ||
76 | |||
73 | clone-prefix:: | 77 | clone-prefix:: |
74 | Space-separated list of common prefixes which, when combined with a | 78 | Space-separated list of common prefixes which, when combined with a |
75 | repository url, generates valid clone urls for the repository. This | 79 | repository url, generates valid clone urls for the repository. This |
@@ -333,11 +337,17 @@ section:: | |||
333 | after this option will inherit the current section name. Default value: | 337 | after this option will inherit the current section name. Default value: |
334 | none. | 338 | none. |
335 | 339 | ||
340 | section-sort:: | ||
341 | The way in which repositories in each section are sorted. Valid values | ||
342 | are "name" for sorting by the repo name or "age" for sorting by the | ||
343 | most recently updated repository. Default value: "name". See also: | ||
344 | section, case-sensitive-sort. | ||
345 | |||
336 | section-from-path:: | 346 | section-from-path:: |
337 | A number which, if specified before scan-path, specifies how many | 347 | A number which, if specified before scan-path, specifies how many |
338 | path elements from each repo path to use as a default section name. | 348 | path elements from each repo path to use as a default section name. |
339 | If negative, cgit will discard the specified number of path elements | 349 | If negative, cgit will discard the specified number of path elements |
340 | above the repo directory. Default value: 0. | 350 | above the repo directory. Default value: "0". |
341 | 351 | ||
342 | side-by-side-diffs:: | 352 | side-by-side-diffs:: |
343 | If set to "1" shows side-by-side diffs instead of unidiffs per | 353 | If set to "1" shows side-by-side diffs instead of unidiffs per |
diff --git a/ui-repolist.c b/ui-repolist.c index d946f32..4e2bdf4 100644 --- a/ui-repolist.c +++ b/ui-repolist.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include "cgit.h" | 9 | #include "cgit.h" |
10 | #include "html.h" | 10 | #include "html.h" |
11 | #include "ui-shared.h" | 11 | #include "ui-shared.h" |
12 | #include <strings.h> | ||
12 | 13 | ||
13 | time_t read_agefile(char *path) | 14 | time_t read_agefile(char *path) |
14 | { | 15 | { |
@@ -131,8 +132,12 @@ void print_pager(int items, int pagelen, char *search, char *sort) | |||
131 | 132 | ||
132 | static int cmp(const char *s1, const char *s2) | 133 | static int cmp(const char *s1, const char *s2) |
133 | { | 134 | { |
134 | if (s1 && s2) | 135 | if (s1 && s2) { |
135 | return strcmp(s1, s2); | 136 | if (ctx.cfg.case_sensitive_sort) |
137 | return strcmp(s1, s2); | ||
138 | else | ||
139 | return strcasecmp(s1, s2); | ||
140 | } | ||
136 | if (s1 && !s2) | 141 | if (s1 && !s2) |
137 | return -1; | 142 | return -1; |
138 | if (s2 && !s1) | 143 | if (s2 && !s1) |
@@ -145,10 +150,19 @@ static int sort_section(const void *a, const void *b) | |||
145 | const struct cgit_repo *r1 = a; | 150 | const struct cgit_repo *r1 = a; |
146 | const struct cgit_repo *r2 = b; | 151 | const struct cgit_repo *r2 = b; |
147 | int result; | 152 | int result; |
153 | time_t t; | ||
148 | 154 | ||
149 | result = cmp(r1->section, r2->section); | 155 | result = cmp(r1->section, r2->section); |
150 | if (!result) | 156 | if (!result) { |
151 | result = cmp(r1->name, r2->name); | 157 | if (!strcmp(ctx.cfg.section_sort, "age")) { |
158 | // get_repo_modtime caches the value in r->mtime, so we don't | ||
159 | // have to worry about inefficiencies here. | ||
160 | if (get_repo_modtime(r1, &t) && get_repo_modtime(r2, &t)) | ||
161 | result = r2->mtime - r1->mtime; | ||
162 | } | ||
163 | if (!result) | ||
164 | result = cmp(r1->name, r2->name); | ||
165 | } | ||
152 | return result; | 166 | return result; |
153 | } | 167 | } |
154 | 168 | ||