From 733a517036bc5ad3327b41f494b0d09cd2470262 Mon Sep 17 00:00:00 2001 From: gennyble Date: Sat, 16 Dec 2023 07:43:48 -0600 Subject: allow ordering sections with scan-path --- ui-repolist.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 98 insertions(+), 7 deletions(-) (limited to 'ui-repolist.c') diff --git a/ui-repolist.c b/ui-repolist.c index 97b11c5..a46df0e 100644 --- a/ui-repolist.c +++ b/ui-repolist.c @@ -236,6 +236,64 @@ static int sort_section(const void *a, const void *b) return result; } +static int string_list_index(const struct string_list *list, const char *str) +{ + for (int i = 0; i < list->nr; ++i) { + if (strcmp(list->items[i].string, str) == 0) + return i; + } + + return -1; +} + +static int strempty(const char *str) { + if (str == NULL) + return 1; + + return str[0] == 0; +} + +static int sort_section_order(const void *a, const void *b) +{ + const struct cgit_repo *r1 = a; + const struct cgit_repo *r2 = b; + int result; + + int sec1_idx = string_list_index(&ctx.cfg.section_order, r1->section); + int sec2_idx = string_list_index(&ctx.cfg.section_order, r2->section); + int both_unordered = sec1_idx == -1 && sec2_idx == -1; + int both_empty = strempty(r1->section) && strempty(r2->section); + + if (both_empty) { + // both sections empty, sort within the emptiness + result = 0; + } else if (strempty(r1->section)) { + return -1; + } else if (strempty(r2->section)) { + return 1; + } else if (both_unordered) { + // Both are unordered, compare lexigraphically + result = cmp(r1->section, r2->section); + } else if (sec1_idx == -1) { + return 1; + } else if (sec2_idx == -1) { + return -1; + } else { + result = sec1_idx - sec2_idx; + } + + if (result == 0) { + // sections are equal, sort within them + if (strcmp(ctx.cfg.repository_sort, "age") == 0) + result = sort_idle(r1, r2); + + if (result == 0) + result = cmp(r1->name, r2->name); + } + + return result; +} + struct sortcolumn { const char *name; int (*fn)(const void *a, const void *b); @@ -243,6 +301,7 @@ struct sortcolumn { static const struct sortcolumn sortcolumn[] = { {"section", sort_section}, + {"section_order", sort_section_order}, {"name", sort_name}, {"desc", sort_desc}, {"owner", sort_owner}, @@ -253,12 +312,13 @@ static const struct sortcolumn sortcolumn[] = { static int sort_repolist(char *field) { const struct sortcolumn *column; - for (column = &sortcolumn[0]; column->name; column++) { if (strcmp(field, column->name)) continue; + qsort(cgit_repolist.repos, cgit_repolist.count, sizeof(struct cgit_repo), column->fn); + return 1; } return 0; @@ -290,46 +350,71 @@ void cgit_print_repolist(void) if (ctx.qry.sort) sorted = sort_repolist(ctx.qry.sort); - else if (ctx.cfg.section_sort) + else if (strcmp(ctx.cfg.section_sort, "name") == 0) sort_repolist("section"); + else if (strcmp(ctx.cfg.section_sort, "order") == 0) + sort_repolist("section_order"); html(""); for (i = 0; i < cgit_repolist.count; i++) { ctx.repo = &cgit_repolist.repos[i]; + if (!is_visible(ctx.repo)) continue; + hits++; if (hits <= ctx.qry.ofs) continue; + if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count) continue; + if (!header++) print_header(); + section = ctx.repo->section; if (section && !strcmp(section, "")) section = NULL; - if (!sorted && - ((last_section == NULL && section != NULL) || - (last_section != NULL && section == NULL) || - (last_section != NULL && section != NULL && - strcmp(section, last_section)))) { + + // condition: + // - not sorted AND + // - one of them exist, but not both OR + // - both exist and are not equal + // + // ( one of them exists, but not both ) + // (!last && section) || (last && !section) || (both exist and are not equal) + if (!sorted && ( + (last_section == NULL && section != NULL) || + (last_section != NULL && section == NULL) || + (last_section != NULL && section != NULL && strcmp(section, last_section)) + )) { htmlf(""); last_section = section; } + htmlf(""); + if (ctx.cfg.enable_index_links) { html(""); } + html("\n"); } + html("
", columns); html_txt(section); html("
", !sorted && section ? "sublevel-repo" : "toplevel-repo"); + cgit_summary_link(ctx.repo->name, NULL, NULL, NULL); + html(""); + repourl = cgit_repourl(ctx.repo->url); + html_link_open(repourl, NULL, NULL); + free(repourl); + if (html_ntxt(ctx.repo->desc, ctx.cfg.max_repodesc_len) < 0) html("..."); + html_link_close(); + html(""); + if (ctx.cfg.enable_index_owner) { if (ctx.repo->owner_filter) { cgit_open_filter(ctx.repo->owner_filter); @@ -348,8 +433,10 @@ void cgit_print_repolist(void) } html(""); } + print_modtime(ctx.repo); html(""); cgit_summary_link("summary", NULL, "button", NULL); @@ -360,11 +447,15 @@ void cgit_print_repolist(void) cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL); html("
"); + if (hits > ctx.cfg.max_repo_count) print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search, ctx.qry.sort); + cgit_print_docend(); } -- cgit 1.4.1-3-g733a5