diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Add `enable-tree-group-dirs` to list dirs first
| -rw-r--r-- | cgitrc.5.txt | 6 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/cgit.c | 2 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/cgit.h | 1 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/ui-tree.c | 65 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 files changed, 69 insertions, 5 deletions
diff --git a/cgitrc.5.txt b/cgitrc.5.txt index d9f0b93..7a3e48a 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt @@ -223,6 +223,12 @@ enable-tree-linenumbers:: Flag which, when set to "1", will make cgit generate linenumber links for plaintext blobs printed in the tree view. Default value: "1". +enable-tree-group-dirs:: + Flag which, when set to "1", makes the tree view list all directories + first, sorted, followed by the files. When set to "0", entries appear + in git's own order, with directories and files intermixed by name. + Default value: "0". + favicon:: Url used as link to a shortcut icon for cgit. It is suggested to use the value "/favicon.ico" since certain browsers will ignore other diff --git a/source/cgit.c b/source/cgit.c index 91dd9a7..29b2131 100644 --- a/source/cgit.c +++ b/source/cgit.c @@ -199,6 +199,8 @@ static void config_cb(const char *name, const char *value) ctx.cfg.enable_html_serving = atoi(value); else if (!strcmp(name, "enable-tree-linenumbers")) ctx.cfg.enable_tree_linenumbers = atoi(value); + else if (!strcmp(name, "enable-tree-group-dirs")) + ctx.cfg.enable_tree_group_dirs = atoi(value); else if (!strcmp(name, "enable-git-config")) ctx.cfg.enable_git_config = atoi(value); else if (!strcmp(name, "enable-cache-list")) diff --git a/source/cgit.h b/source/cgit.h index 634d2f5..ab7b284 100644 --- a/source/cgit.h +++ b/source/cgit.h @@ -242,6 +242,7 @@ struct cgit_config { int enable_subject_links; int enable_html_serving; int enable_tree_linenumbers; + int enable_tree_group_dirs; int enable_git_config; int enable_cache_list; int local_time; diff --git a/source/ui-tree.c b/source/ui-tree.c index 5ac8c9a..cbaca38 100644 --- a/source/ui-tree.c +++ b/source/ui-tree.c @@ -13,10 +13,18 @@ #include "html.h" #include "ui-shared.h" +struct tree_ls_entry { + struct object_id oid; + char *name; + unsigned mode; +}; + struct walk_tree_context { char *curr_rev; char *match_path; int state; + struct tree_ls_entry *entries; + size_t entries_nr, entries_alloc; }; static void print_text_buffer(const char *name, char *buf, unsigned long size) @@ -200,10 +208,9 @@ static void write_tree_link(const struct object_id *oid, char *name, strbuf_setlen(fullpath, initial_length); } -static int ls_item(const struct object_id *oid, struct strbuf *base, - const char *pathname, unsigned mode, void *cbdata) +static void render_ls_item(const struct object_id *oid, const char *pathname, + unsigned mode, struct walk_tree_context *walk_tree_ctx) { - struct walk_tree_context *walk_tree_ctx = cbdata; char *name; struct strbuf fullpath = STRBUF_INIT; struct strbuf linkpath = STRBUF_INIT; @@ -278,9 +285,55 @@ cleanup: free(name); strbuf_release(&fullpath); strbuf_release(&class); +} + +static int ls_item(const struct object_id *oid, struct strbuf *base, + const char *pathname, unsigned mode, void *cbdata) +{ + struct walk_tree_context *walk_tree_ctx = cbdata; + + /* When grouping directories first, collect the entries now and render + * them once the whole level has been read (see ls_flush). */ + if (ctx.cfg.enable_tree_group_dirs) { + struct tree_ls_entry *e; + ALLOC_GROW(walk_tree_ctx->entries, walk_tree_ctx->entries_nr + 1, + walk_tree_ctx->entries_alloc); + e = &walk_tree_ctx->entries[walk_tree_ctx->entries_nr++]; + oidcpy(&e->oid, oid); + e->name = xstrdup(pathname); + e->mode = mode; + return 0; + } + + render_ls_item(oid, pathname, mode, walk_tree_ctx); return 0; } +/* Render any entries collected by ls_item, directories first and then the + * rest, keeping git's ordering within each group. A no-op unless directory + * grouping is enabled, in which case nothing was collected. */ +static void ls_flush(struct walk_tree_context *walk_tree_ctx) +{ + size_t i; + + for (i = 0; i < walk_tree_ctx->entries_nr; i++) { + struct tree_ls_entry *e = &walk_tree_ctx->entries[i]; + if (S_ISDIR(e->mode)) + render_ls_item(&e->oid, e->name, e->mode, walk_tree_ctx); + } + for (i = 0; i < walk_tree_ctx->entries_nr; i++) { + struct tree_ls_entry *e = &walk_tree_ctx->entries[i]; + if (!S_ISDIR(e->mode)) + render_ls_item(&e->oid, e->name, e->mode, walk_tree_ctx); + } + + for (i = 0; i < walk_tree_ctx->entries_nr; i++) + free(walk_tree_ctx->entries[i].name); + free(walk_tree_ctx->entries); + walk_tree_ctx->entries = NULL; + walk_tree_ctx->entries_nr = walk_tree_ctx->entries_alloc = 0; +} + static void ls_head(void) { cgit_print_layout_start(); @@ -315,6 +368,7 @@ static void ls_tree(const struct object_id *oid, const char *path, struct walk_t ls_head(); read_tree(the_repository, tree, &paths, ls_item, walk_tree_ctx); + ls_flush(walk_tree_ctx); ls_tail(); } @@ -395,9 +449,10 @@ void cgit_print_tree(const char *rev, char *path) read_tree(the_repository, repo_get_commit_tree(the_repository, commit), &paths, walk_tree, &walk_tree_ctx); - if (walk_tree_ctx.state == 1) + if (walk_tree_ctx.state == 1) { + ls_flush(&walk_tree_ctx); ls_tail(); - else if (walk_tree_ctx.state == 2) + } else if (walk_tree_ctx.state == 2) cgit_print_layout_end(); else cgit_print_error_page(404, "Not found", "Path not found"); |
