Repository navigation
Treemap depth and a SpaceSniffer style - #5
Merged
Merged
Conversation
Percentages divided by the filtered total, so with a type filter active a row could read above 100%. They now divide by the sum of the displayed rows, and emptiness is judged from those rows too. The active ext: list normalizes dots and case the way the Rust parser does, so shift-clicking .pdf while ext:.PDF is active removes it instead of adding a duplicate.
Current stable clippy rejects chunks_exact with a constant size.
A treemap that draws every file it can subdivide is a mosaic: on a real drive most of the pixels are specks too small to identify, and finding out what any of them is costs a hover, one block at a time. That is the whole of the "visual overload" complaint, and no depth setting fixes it — the setting the issue asked for decides how much of the tree is drawn, not whether what is drawn can be read. Three changes, all in the layout: Culling is by side, not area. `min_area_px: 3.0` accepted a 40×0.1 sliver because 4 px² cleared the floor; `min_side_px` requires both dimensions, so what survives is something a person can actually see. Culled children keep eating their share of the parent, as before — that contract is what makes the parent's area honest, and the test that pinned it still does. A directory reserves a strip at the top of its interior for its label, and its children tile what is left. The strip is taken from the *children's* frame and never from the directory's own rect: that rect has to stay a function of its own frame alone, or a depth cap that stops recursion early would shift the rects that survive it, and the UI switches depth live. The test that pins that prefix property runs with a strip on. Depth became adaptive. A directory subdivides only while its interior can still hold a legible child — padding, strip and padding again come out of every level, so a branch runs out of room and stops on its own. Big folders go deep because they have the pixels; small ones stay a plate. max_depth is now only an upper bound on top of that, which leaves room for the explicit depth preference to land on top of it without fighting it. The rect carries the text too. Names come from `tree.name(id)` at the DTO boundary rather than through `TreemapRect`, which stays `Copy` and geometry-only for the layout's own tests; one string per visible rect is also far cheaper than the round trip per node it would otherwise take to label a block.
Settings gets Treemap style (Default or SpaceSniffer) and Treemap depth (All, 1, 2 or custom). Default with All is the old treemap. This replaces the fit-based layout from the previous commit, so the default stays as it was. With a depth cap, folders below the cap draw as closed, labelled blocks. In SpaceSniffer style a click opens a folder in place and folds the one opened before; Default still zooms. Changing the view folds everything back to the cap. A clicked folder whose contents are too small to draw zooms instead of opening to nothing. SpaceSniffer has no All, since a map with every level drawn has nothing to open; it reads a stored All as 1 so switching back to Default restores it. The layout takes one node to keep open past the cap and reports which folders had their children drawn, so the UI never infers that from rect order. Opening a folder only adds rects; nothing already drawn moves. Hovering outlines the folder the block sits in. The Export menu shares the depth picker.
This was referenced Nov 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2.
Summary
main.chunks_exactlint on current stable in its own commit.Why
#2 asked for less noise and SpaceSniffer-style drill-down without changing the default. Depth and click behaviour are separate settings so each does one thing.
Selection, view and open folder are three separate pieces of state, and they only flow one way. The selection is a cursor and only highlights. Only commands move the view: map clicks, wheel, keys, breadcrumbs and the sidebar. Moving the view clears the open folder. An earlier version let the selection decide what was open, which made arrowing through the sidebar open and zoom the map. QDirStat, WinDirStat and WizTree also link the selection between the list and the map and only zoom on explicit commands.
Design notes
TreemapOptions.revealkeeps one node visible pastmax_depth;TreemapRect.expandedsays whether a directory's children were laid out. Tests pin that revealing only adds rects.get_treemaptakes an args struct;nameis sent only for folded folders under a depth cap.Review
Reviewed with GPT-6 Astra and GPT-6.1 Sol through opencode over five rounds.
Taken:
expandedflag instead of inferring folded folders from rect order (Sol).Rejected:
record.rshunk out (Sol). It is already its own commit.Several earlier findings (wheel opening and folding, selection-driven reveal races) went away when the design changed to the model above.
Validation
npm run devon WindowsThanks to @Li3age for the issue and the SpaceSniffer pointer.