List for cgit developers and users
 help / color / mirror / Atom feed
* Display of directories that contain only one subdirectory
@ 2016-07-13 17:57 erik.brangs
  2016-07-13 19:49 ` john
  0 siblings, 1 reply; 8+ messages in thread
From: erik.brangs @ 2016-07-13 17:57 UTC (permalink / raw)


Hi,

I use cgit via websites that use it to provide a repository browser, i.e. I don't have my own deployment. IMHO it would be nice to get a more comfortable navigation for directories that only contain one subdirectory. For example, for a path like "contrib/hooks" at https://git.zx2c4.com/cgit/tree/ , you first need to click on "contrib" and then again on "hooks". Navigation could be simplified by providing a link for "contrib/hooks" that points directly to the "contrib/hooks" path.

GitHub's repository browser implements this feature. For example, at https://github.com/torvalds/linux/tree/master/tools , there's a link for "kvm/kvm_stat" that points directly to "https://github.com/torvalds/linux/tree/master/tools/kvm/kvm_stat" .

I looked at cgitrc.5.txt and didn't find any evidence that this feature was already implemented for cgit. Assuming I didn't miss anything, would someone be interested in implementing it?


Kind regards,

Erik Brangs






^ permalink raw reply	[flat|nested] 8+ messages in thread

* Display of directories that contain only one subdirectory
  2016-07-13 17:57 Display of directories that contain only one subdirectory erik.brangs
@ 2016-07-13 19:49 ` john
  2016-07-13 22:12   ` jamie.couture
  2016-07-14 18:12   ` erik.brangs
  0 siblings, 2 replies; 8+ messages in thread
From: john @ 2016-07-13 19:49 UTC (permalink / raw)


On Wed, Jul 13, 2016 at 07:57:23PM +0200, Erik Brangs wrote:
> I use cgit via websites that use it to provide a repository browser,
> i.e. I don't have my own deployment. IMHO it would be nice to get a
> more comfortable navigation for directories that only contain one
> subdirectory. For example, for a path like "contrib/hooks" at
> https://git.zx2c4.com/cgit/tree/ , you first need to click on
> "contrib" and then again on "hooks". Navigation could be simplified by
> providing a link for "contrib/hooks" that points directly to the
> "contrib/hooks" path.
> 
> GitHub's repository browser implements this feature. For example, at
> https://github.com/torvalds/linux/tree/master/tools , there's a link
> for "kvm/kvm_stat" that points directly to
> "https://github.com/torvalds/linux/tree/master/tools/kvm/kvm_stat" .
> 
> I looked at cgitrc.5.txt and didn't find any evidence that this
> feature was already implemented for cgit. Assuming I didn't miss
> anything, would someone be interested in implementing it?

It turns out it's not too difficult, patch below.  This is slightly
different from Github's behaviour because it allows clicking on
intermediate directories; it wouldn't be hard to collect the full path
instead but I actually prefer this way of doing things.

-- >8 --
Subject: [PATCH] tree: allow skipping through single-child trees

If we have only a single element in a directory (for example in Java
package paths), display multiple directories in one go so that it is
possible to navigate directly to the first directory that contains
either files or multiple directories.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 ui-tree.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 68 insertions(+), 2 deletions(-)

diff --git a/ui-tree.c b/ui-tree.c
index 120066c..2252490 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -155,6 +155,72 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
 		print_text_buffer(basename, buf, size);
 }
 
+struct single_tree_ctx {
+	struct strbuf *path;
+	unsigned char sha1[GIT_SHA1_RAWSZ];
+	char *name;
+	size_t count;
+};
+
+static int single_tree_cb(const unsigned char *sha1, struct strbuf *base,
+			  const char *pathname, unsigned mode, int stage,
+			  void *cbdata)
+{
+	struct single_tree_ctx *ctx = cbdata;
+
+	if (++ctx->count > 1)
+		return -1;
+
+	if (!S_ISDIR(mode)) {
+		ctx->count = 2;
+		return -1;
+	}
+
+	ctx->name = xstrdup(pathname);
+	memcpy(ctx->sha1, sha1, GIT_SHA1_RAWSZ);
+	strbuf_addf(ctx->path, "/%s", pathname);
+	return 0;
+}
+
+static void write_tree_link(const unsigned char *sha1, char *name,
+			    char *rev, struct strbuf *fullpath)
+{
+	size_t initial_length = fullpath->len;
+	struct tree *tree;
+	struct single_tree_ctx tree_ctx = {
+		.path = fullpath,
+		.count = 1,
+	};
+	struct pathspec paths = {
+		.nr = 0
+	};
+
+	memcpy(tree_ctx.sha1, sha1, GIT_SHA1_RAWSZ);
+
+	while (tree_ctx.count == 1) {
+		cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, rev,
+			       fullpath->buf);
+
+		tree = lookup_tree(tree_ctx.sha1);
+		if (!tree)
+			return;
+
+		free(tree_ctx.name);
+		tree_ctx.name = NULL;
+		tree_ctx.count = 0;
+
+		read_tree_recursive(tree, "", 0, 1, &paths, single_tree_cb,
+				    &tree_ctx);
+
+		if (tree_ctx.count != 1)
+			break;
+
+		html(" / ");
+		name = tree_ctx.name;
+	}
+
+	strbuf_setlen(fullpath, initial_length);
+}
 
 static int ls_item(const unsigned char *sha1, struct strbuf *base,
 		const char *pathname, unsigned mode, int stage, void *cbdata)
@@ -187,8 +253,8 @@ static int ls_item(const unsigned char *sha1, struct strbuf *base,
 	if (S_ISGITLINK(mode)) {
 		cgit_submodule_link("ls-mod", fullpath.buf, sha1_to_hex(sha1));
 	} else if (S_ISDIR(mode)) {
-		cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head,
-			       walk_tree_ctx->curr_rev, fullpath.buf);
+		write_tree_link(sha1, name, walk_tree_ctx->curr_rev,
+				&fullpath);
 	} else {
 		char *ext = strrchr(name, '.');
 		strbuf_addstr(&class, "ls-blob");
-- 
2.9.0.465.g8850cbc



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Display of directories that contain only one subdirectory
  2016-07-13 19:49 ` john
@ 2016-07-13 22:12   ` jamie.couture
  2016-07-13 22:43     ` jamie.couture
  2016-07-14 18:12   ` erik.brangs
  1 sibling, 1 reply; 8+ messages in thread
From: jamie.couture @ 2016-07-13 22:12 UTC (permalink / raw)


Was working on a solution when this came in.  However, this looks much
better than what I was trying to attempt.

Gave it a spin. Works great.

On Wednesday, 13 July 2016, John Keeping <john at keeping.me.uk> wrote:

> On Wed, Jul 13, 2016 at 07:57:23PM +0200, Erik Brangs wrote:
> > I use cgit via websites that use it to provide a repository browser,
> > i.e. I don't have my own deployment. IMHO it would be nice to get a
> > more comfortable navigation for directories that only contain one
> > subdirectory. For example, for a path like "contrib/hooks" at
> > https://git.zx2c4.com/cgit/tree/ , you first need to click on
> > "contrib" and then again on "hooks". Navigation could be simplified by
> > providing a link for "contrib/hooks" that points directly to the
> > "contrib/hooks" path.
> >
> > GitHub's repository browser implements this feature. For example, at
> > https://github.com/torvalds/linux/tree/master/tools , there's a link
> > for "kvm/kvm_stat" that points directly to
> > "https://github.com/torvalds/linux/tree/master/tools/kvm/kvm_stat" .
> >
> > I looked at cgitrc.5.txt and didn't find any evidence that this
> > feature was already implemented for cgit. Assuming I didn't miss
> > anything, would someone be interested in implementing it?
>
> It turns out it's not too difficult, patch below.  This is slightly
> different from Github's behaviour because it allows clicking on
> intermediate directories; it wouldn't be hard to collect the full path
> instead but I actually prefer this way of doing things.
>
> -- >8 --
> Subject: [PATCH] tree: allow skipping through single-child trees
>
> If we have only a single element in a directory (for example in Java
> package paths), display multiple directories in one go so that it is
> possible to navigate directly to the first directory that contains
> either files or multiple directories.
>
> Signed-off-by: John Keeping <john at keeping.me.uk <javascript:;>>
> ---
>  ui-tree.c | 70
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 68 insertions(+), 2 deletions(-)
>
> diff --git a/ui-tree.c b/ui-tree.c
> index 120066c..2252490 100644
> --- a/ui-tree.c
> +++ b/ui-tree.c
> @@ -155,6 +155,72 @@ static void print_object(const unsigned char *sha1,
> char *path, const char *base
>                 print_text_buffer(basename, buf, size);
>  }
>
> +struct single_tree_ctx {
> +       struct strbuf *path;
> +       unsigned char sha1[GIT_SHA1_RAWSZ];
> +       char *name;
> +       size_t count;
> +};
> +
> +static int single_tree_cb(const unsigned char *sha1, struct strbuf *base,
> +                         const char *pathname, unsigned mode, int stage,
> +                         void *cbdata)
> +{
> +       struct single_tree_ctx *ctx = cbdata;
> +
> +       if (++ctx->count > 1)
> +               return -1;
> +
> +       if (!S_ISDIR(mode)) {
> +               ctx->count = 2;
> +               return -1;
> +       }
> +
> +       ctx->name = xstrdup(pathname);
> +       memcpy(ctx->sha1, sha1, GIT_SHA1_RAWSZ);
> +       strbuf_addf(ctx->path, "/%s", pathname);
> +       return 0;
> +}
> +
> +static void write_tree_link(const unsigned char *sha1, char *name,
> +                           char *rev, struct strbuf *fullpath)
> +{
> +       size_t initial_length = fullpath->len;
> +       struct tree *tree;
> +       struct single_tree_ctx tree_ctx = {
> +               .path = fullpath,
> +               .count = 1,
> +       };
> +       struct pathspec paths = {
> +               .nr = 0
> +       };
> +
> +       memcpy(tree_ctx.sha1, sha1, GIT_SHA1_RAWSZ);
> +
> +       while (tree_ctx.count == 1) {
> +               cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, rev,
> +                              fullpath->buf);
> +
> +               tree = lookup_tree(tree_ctx.sha1);
> +               if (!tree)
> +                       return;
> +
> +               free(tree_ctx.name);
> +               tree_ctx.name = NULL;
> +               tree_ctx.count = 0;
> +
> +               read_tree_recursive(tree, "", 0, 1, &paths, single_tree_cb,
> +                                   &tree_ctx);
> +
> +               if (tree_ctx.count != 1)
> +                       break;
> +
> +               html(" / ");
> +               name = tree_ctx.name;
> +       }
> +
> +       strbuf_setlen(fullpath, initial_length);
> +}
>
>  static int ls_item(const unsigned char *sha1, struct strbuf *base,
>                 const char *pathname, unsigned mode, int stage, void
> *cbdata)
> @@ -187,8 +253,8 @@ static int ls_item(const unsigned char *sha1, struct
> strbuf *base,
>         if (S_ISGITLINK(mode)) {
>                 cgit_submodule_link("ls-mod", fullpath.buf,
> sha1_to_hex(sha1));
>         } else if (S_ISDIR(mode)) {
> -               cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head,
> -                              walk_tree_ctx->curr_rev, fullpath.buf);
> +               write_tree_link(sha1, name, walk_tree_ctx->curr_rev,
> +                               &fullpath);
>         } else {
>                 char *ext = strrchr(name, '.');
>                 strbuf_addstr(&class, "ls-blob");
> --
> 2.9.0.465.g8850cbc
>
> _______________________________________________
> CGit mailing list
> CGit at lists.zx2c4.com <javascript:;>
> http://lists.zx2c4.com/mailman/listinfo/cgit
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20160713/e6744fde/attachment.html>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Display of directories that contain only one subdirectory
  2016-07-13 22:12   ` jamie.couture
@ 2016-07-13 22:43     ` jamie.couture
  2016-08-07 15:09       ` john
  0 siblings, 1 reply; 8+ messages in thread
From: jamie.couture @ 2016-07-13 22:43 UTC (permalink / raw)



Ugh, hit enter too fast:

So what I was initially wasting my time worrying about was an insane situation 
where there are many empty directories with only one file at the end of the 
tunnel.

mkdir -p why/would/anyone/do/this/what/possible/reason/would/justify/such/a/deep/structure/with/nothing/of/value/come/on
touch why/would/anyone/do/this/what/possible/reason/would/justify/such/a/deep/structure/with/nothing/of/value/come/on/hi.txt

Where we might end up with something that does not word wrap, but our css does 
take care of it: so moot point.  The other consideration I was worrying about 
was skipping all the in-between folders since there's nothing of value, 
display some ellipsis:

some / path / ... / end 

I'm not sure if there's much value in truncating that scenario.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Display of directories that contain only one subdirectory
  2016-07-13 19:49 ` john
  2016-07-13 22:12   ` jamie.couture
@ 2016-07-14 18:12   ` erik.brangs
  2016-08-07 15:12     ` john
  1 sibling, 1 reply; 8+ messages in thread
From: erik.brangs @ 2016-07-14 18:12 UTC (permalink / raw)


Hi,

On 13.07.2016 21:49, John Keeping wrote:
> It turns out it's not too difficult, patch below.  This is slightly
> different from Github's behaviour because it allows clicking on
> intermediate directories; it wouldn't be hard to collect the full path
> instead but I actually prefer this way of doing things.
Sounds great to me. Thanks.

Will this feature be part of the next cgit release?


Kind regards,

Erik Brangs


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Display of directories that contain only one subdirectory
  2016-07-13 22:43     ` jamie.couture
@ 2016-08-07 15:09       ` john
  0 siblings, 0 replies; 8+ messages in thread
From: john @ 2016-08-07 15:09 UTC (permalink / raw)


On Wed, Jul 13, 2016 at 06:43:06PM -0400, Jamie Couture wrote:
> So what I was initially wasting my time worrying about was an insane situation 
> where there are many empty directories with only one file at the end of the 
> tunnel.
> 
> mkdir -p why/would/anyone/do/this/what/possible/reason/would/justify/such/a/deep/structure/with/nothing/of/value/come/on
> touch why/would/anyone/do/this/what/possible/reason/would/justify/such/a/deep/structure/with/nothing/of/value/come/on/hi.txt
> 
> Where we might end up with something that does not word wrap, but our css does 
> take care of it: so moot point.  The other consideration I was worrying about 
> was skipping all the in-between folders since there's nothing of value, 
> display some ellipsis:
> 
> some / path / ... / end 
> 
> I'm not sure if there's much value in truncating that scenario.

(I finally have some time to look at this again.)

I don't think it's worth the extra complexity to handle putting in
ellipses for this case.  I tried a long path with a very narrow browser
window and it wraps sensibly, which I think is acceptable.

Note that the patch here won't display the file at the end of your
second example above - it explicitly checks for directories, which is a
conscious choice so that we don't have to go back and correct the mode
bits in the first column.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Display of directories that contain only one subdirectory
  2016-07-14 18:12   ` erik.brangs
@ 2016-08-07 15:12     ` john
  2016-08-08 22:48       ` Jason
  0 siblings, 1 reply; 8+ messages in thread
From: john @ 2016-08-07 15:12 UTC (permalink / raw)


On Thu, Jul 14, 2016 at 08:12:09PM +0200, Erik Brangs wrote:
> On 13.07.2016 21:49, John Keeping wrote:
> > It turns out it's not too difficult, patch below.  This is slightly
> > different from Github's behaviour because it allows clicking on
> > intermediate directories; it wouldn't be hard to collect the full path
> > instead but I actually prefer this way of doing things.
> Sounds great to me. Thanks.
> 
> Will this feature be part of the next cgit release?

Jason, I think this is a nice feature to have and it's quite nicely
contained.  What do you think about picking up this patch?

(Patch is here in case you don't have the thread in your mailbox:
<https://lists.zx2c4.com/pipermail/cgit/2016-July/003163.html>)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Display of directories that contain only one subdirectory
  2016-08-07 15:12     ` john
@ 2016-08-08 22:48       ` Jason
  0 siblings, 0 replies; 8+ messages in thread
From: Jason @ 2016-08-08 22:48 UTC (permalink / raw)


On Sun, Aug 7, 2016 at 5:12 PM, John Keeping <john at keeping.me.uk> wrote:
> Jason, I think this is a nice feature to have and it's quite nicely
> contained.  What do you think about picking up this patch?

Sure, will pick it up.

>
> (Patch is here in case you don't have the thread in your mailbox:
> <https://lists.zx2c4.com/pipermail/cgit/2016-July/003163.html>)

Haha no worries -- cgit emails are delivered to my inbox :)


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-08-08 22:48 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-13 17:57 Display of directories that contain only one subdirectory erik.brangs
2016-07-13 19:49 ` john
2016-07-13 22:12   ` jamie.couture
2016-07-13 22:43     ` jamie.couture
2016-08-07 15:09       ` john
2016-07-14 18:12   ` erik.brangs
2016-08-07 15:12     ` john
2016-08-08 22:48       ` Jason

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).