breadcrumbs icon indicating copy to clipboard operation
breadcrumbs copied to clipboard

v4: Sort by next

Open soulsynapse opened this issue 11 months ago • 1 comments

This might already be possible in breadcrumbs, I'm not sure.

There could also be a better way to do it that is already baked in.

Is your feature request related to a problem? Please describe. Sort order is a pain to manage, but I already have next relationships. Functionally this is a linked list and can be used for sort order. The problem is that maintaining sort order and defining it in breadcrumbs is difficult.

Describe the solution you'd like For code blocks, sorting by the next relationships would be great. That way I don't have to define a numerical order or have it included in the name.

Describe alternatives you've considered Originally I wanted to do this with dataview and the breadcrumbs API. I guess sort by creation date could work and be useful.

Additional context I've been messing with the codeblocks and this occurred to me.

I set up an example vault to show this.

The files are linked by next sequentially image

They all have 1 common parent image

Ideally I could set the sort to be next and it would split out a flattened 'next' list while showing the hierarchy from down.

soulsynapse avatar Mar 02 '24 18:03 soulsynapse

As a similar ask, it would be nice to be able to do something like

type: tree
dir: down
depth: -1
order-by: next

(with the order-by an imagined extra feature), so that I can see the immediate children of this node, but ordered by those children's own next/prev property.

tsbertalan avatar Mar 04 '24 03:03 tsbertalan

Tried writing the logic for this and it's a nightmare, both in terms of resources and how things need to be assessed.

soulsynapse avatar Mar 07 '24 07:03 soulsynapse

Hey, thanks for giving it a try, I appreciate the effort. I was going to take a look sometime. Perhaps there's a way to acheive this. Will keep it in mind

SkepticMystic avatar Mar 07 '24 07:03 SkepticMystic

The logic for building the tree is here, right? What are the nest objects that get mentioned there--nodes in the tree?

Once you have a particular, limited tree in hand in abstract form, but haven't yet generated an HTML representation, it seems to me that any numerical operations on that tree are nicely limited in scope. You can recurse from the root, at each point considering the small list of children X, (1a) determining the order of children at each point by building (from the next/prev metadata) a new doubly linked list Y from them and following it's pointers to its head, (1b) following the pointers the other way to reorder X, (2) then recurse into each of X.

tsbertalan avatar Mar 07 '24 15:03 tsbertalan

Hey, thanks for your input. I've been thinking about this a bit, and I think a simple option is to pass the graph into the sort function, then for each node, fetch the first "next" neighbour, and set that as its sort key. It's a little inefficient to be fetching it more than once for each node. So perhaps the "nexts" can be memoised, but this should work

SkepticMystic avatar Mar 12 '24 06:03 SkepticMystic

@SkepticMystic So, you mean you sort all the nodes in the graph? It's a tree, though--there is no single chain of next across everyone; just within a set of siblings.

tsbertalan avatar Mar 12 '24 22:03 tsbertalan

No, not for all nodes, just the ones in a given list - like it is now when sorting by file path, for example. So say you've set up a code block to show a tree of edges going down from the current note. The traversal will run as normal, getting the nested list of edges. Then we can sort them, doing something like the following (pseudo-codey for now):

const sort_by_field(graph: Graph, edges: Edge[], field: string) => edges.sort((a, b) => {
    const neighbours_a = graph.neighbours(a).filter(e => a.field === field)
    const neighbours_b = graph.neighbours(b).filter(e => b.field === field)

    if (!neighbours_a.length || !neighbours_b.length) {
        return 0
    } else {
        return neighbours_a[0].path - neighbours_b[0].path
    }
})

This achieves the same result as precomputing a next traversal. But the key here is that we don't need a chain, it can be done for each node in isolation.

If a node doesn't have outgoing neighbours for a given field, the traversal would have ended anyway. If a node has multiple outgoing neighbours for a given field, there would have been ambiguity in the traversal method as well, so we just take the first.

What do you think? I believe this should work

SkepticMystic avatar Mar 13 '24 05:03 SkepticMystic

@soulsynapse @tsbertalan I believe I've got this working! In 4.0.22-beta, you can now sort by the neighbour of some field using the following syntax:

sort: neighbour:<field> desc

Let me know if it does what you're looking for, or if you run into any issues

SkepticMystic avatar Mar 13 '24 13:03 SkepticMystic

WOW!! Works great!!

The reason I was hoping for this is that there's an entire subset of zettelkasten called folgezettel. There isn't really a solution for this in Obsidian right now.

But this makes it possible. What a game-changer!

soulsynapse avatar Mar 13 '24 14:03 soulsynapse

Glad to hear it :) I'll close this out for now then, thanks!

SkepticMystic avatar Mar 13 '24 14:03 SkepticMystic

@SkepticMystic Do you mean something like this?

type: tree
title: false
dir: down
depth: -1
sort: neighbour:next desc

This seems to still be sorting by path or basename for me.

tsbertalan avatar Aug 07 '24 21:08 tsbertalan