When a single file is modified inside a nested directory, the file tree compresses the whole chain of directories into one line, such as "pkg/gui/controllers/helpers". Selecting that line shows the diff of the entire working tree. When a second file is then modified in another subdirectory of pkg/gui, the tree splits the line into "pkg/gui" with "context" and "controllers/helpers" below it, and the refresh moves the selection down to "controllers/helpers". Users who keep the top directory selected to see the diff of everything lose that view and have to move the cursor back up after every such refresh. This happens because the selection is re-found by the node's own path, and a compressed node's path is the deepest directory in its chain. The node stood for every directory in that chain, though, and the topmost piece of the split is the one that stays on the same line. Match a compressed directory node against any new node that stands for at least one of the same directories. The list is in depth-first order, so the topmost piece wins and the cursor stays on its line. Files are never compressed, so their handling doesn't change. The reverse case, where two directories fold back into one compressed line, already selected the merged line and still does. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
FileTree Package
This package handles the representation of file trees. There are two ways to render files: one is to render them flat, so something like this:
dir1/file1
dir1/file2
file3
And the other is to render them as a tree
dir1/
file1
file2
file3
Internally we represent each of the above as a tree, but with the flat approach there's just a single root node and every path is a direct child of that root. Viewing in 'tree' mode (as opposed to 'flat' mode) allows for collapsing and expanding directories, and lets you perform actions on directories e.g. staging a whole directory. But it takes up more vertical space and sometimes you just want to have a flat view where you can go flick through your files one by one to see the diff.
This package is not concerned about rendering the tree: only representing its internal state.