Documentation
¶
Overview ¶
Package listorder is the ONE order the server puts rows in: a folder's contents (from the catalogue, from the storage driver or merged), the MCP `file_list` tool, and the per-person views (Recent, Starred, Shared with me, a tag).
⚠ Why it exists (filex 0.54, audit Y3). Before it, the same folder came back in three orders depending on which code path answered: the catalogue path said `ORDER BY type DESC, name` (files first, because "file" > "dir"), the merged catalogue-and-driver path put folders first, and `file_list` returned whatever order the storage driver listed in. A CLI user, an MCP agent and the explorer saw one folder three ways, and the explorer's own comment claimed the server "already" answered by name. Every path now sorts through Sort.
The rule, in order:
- Folders before files, in every key and both directions (the explorer's rule, packages/core lib/sortOrder byFoldersFirst). The direction reverses the order INSIDE each group, never the groups. KeyWhen is the exception: "when did I open / star / get this" is one timeline, not two groups.
- The key: name (numbers as numbers, case and the four i's folded by namefold), modified, size, type (the extension), or when (the person's own time on the row).
- Ties: the name, then the path's bytes, so the same rows always come back in the same order.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var Default = Order{Key: KeyName}
Default is a folder's order when nobody asked for one: by name, A to Z.
var Newest = Order{Key: KeyWhen, Desc: true}
Newest is a per-person view's order when nobody asked for one: the person's own time, newest first.
Functions ¶
func CompareNames ¶
CompareNames orders two names the way the Name column does: case and the four Latin i's folded (namefold.String), and a run of digits compared as a number, so "Disk 2" comes before "Disk 10". -1, 0 or 1.
func SortEntries ¶
SortEntries orders projected listing rows in place; whenKey names the row's own-time field ("" when the listing has none).
Types ¶
type Fields ¶
type Fields struct {
Name string
Path string
Dir bool
Size int64
// Modified and When are milliseconds since the epoch; 0 is unknown.
Modified int64
When int64
}
Fields is what the rule reads off one row.
func EntryFields ¶
EntryFields reads a listing row as the manager projects it (`basename`, `path`, `type`, `size`, `last_modified`), with `whenKey` (e.g. "shared_at", "" for none) as the person's own time.
func NodeFields ¶
NodeFields reads a catalogue row. When is left for the caller.
type Key ¶
type Key string
Key is what a listing is ordered by.
const ( KeyName Key = "name" KeyModified Key = "modified" KeySize Key = "size" KeyType Key = "type" // KeyWhen is the person's own time on the row: when they opened it // (Recent), starred it (Starred), were given it (Shared with me). KeyWhen Key = "when" )
The keys. The wire spelling is the constant's value; a leading "-" asks for the descending order (`sort=-modified` is newest first).
type Order ¶
Order is a key and a direction.
func Parse ¶
Parse reads a `sort` parameter: a key, optionally prefixed with "-" for the descending order. "opened", "starred", "shared" and "tagged" are accepted as the name of a view's own time (KeyWhen). An empty value answers fallback; an unknown key answers fallback and false, so a handler can refuse it.