Skip to content

GH-99: expand and collapse folders in the tree - #100

Merged
blainemotsinger merged 1 commit into
mainfrom
GH-99
Nov 7, 2026
Merged

blainemotsinger merged 1 commit into
mainfrom
GH-99

Conversation

@blainemotsinger

Copy link
Copy Markdown
Member

Summary

The folder pane draws the listing as a tree. Folders with subfolders show a + when
folded and - when expanded, in the shape imap-notes uses: the marker leads the row and
the cursor is the bold row, so the selection never displaces the marker. Folded is the
default, and which folders are open is remembered per account.

Owner rulings applied:

  • enter expands a collapsed folder first; the next enter loads it, exactly as before.
  • right expands without opening, left folds. Both are folder-pane actions only.
  • A folder absent from the state file is folded, so a fresh install shows the top level.
  • No invented mailboxes: a parent is the nearest ancestor the server actually listed.
  • imap-notes' marker shape, not a > cursor glyph.

Folder tree

tui/foldertree.go derives the visible rows on demand from the listing and an expansion
set keyed by mailbox name, so there is no cached second tree to go stale. Every cursor,
scroll, clamp and render path indexes the visible rows instead of m.folders.

listedParent walks the whole path and uses the nearest ancestor the listing contains.
A server that lists Work/Projects/2025 without Work/Projects gets the grandchild under
a listed Work and no synthetic row; a folder with no listed ancestor renders as a root.
Indent is tree depth, not delimiter count.

The folders overlay (\) and the move picker (m) stay flat, so a folded folder is still
reachable; both convert between their flat index and the tree cursor when they open a
folder.

enter on a folder with children expands it; enter on an expanded folder or a leaf
opens it. right calls the same expansion without opening, left folds. z remains
thread-collapse only and is still inert in the folder pane.

Persistence

config.State gains Expanded map[string][]string — account name to the folders whose
subfolders were shown. It is written 0600 through the existing temp-file-and-rename, is
still names only, and is written only by an explicit expand or collapse: revealing a path
for a remembered or opened folder happens in memory and does not create or modify the
file. A fresh state file therefore opens the tree folded.

Two presentation changes in the same delivery

  • The footer joins its command keys with two spaces, matching imap-notes
    (tui/view.go:135). The five-hint default is 44 cells against the 54-cell floor at 60
    columns. The visual-range footer at 105 columns now drops its last hint whole rather
    than fitting everything; nothing is truncated mid-hint.
  • PanelGap = 2 columns between panels, so folders/messages and messages/reader have the
    same four blank cells (one of padding on each side plus the gap). The gap is subtracted
    from the pane widths in ComputeLayoutWith and drawn as a real blank block, so the
    visible columns and gaps still sum to the content width and the frame stays exact. At
    120 columns: folders 28, messages 40, reader 42.

Verification

gofmt -l .                     (empty)
go vet ./...                   clean
go test -count=1 ./...         ok github.com/renderorange/chute
                               ok github.com/renderorange/chute/config
                               ok github.com/renderorange/chute/mail
                               ok github.com/renderorange/chute/tui
go test -race -count=1 ./...   ok root 1.0s, config 1.1s, mail 1.3s, tui 2.2s
golangci-lint v2.15.0          0 issues

Behaviour is pinned by tui/foldertree_test.go: folded by default, enter expands then
opens, right/left fold and expand, arrows inert outside the pane, no invented parent,
a persisted expand survives a reload, a remembered Work/2024/Q1 reopens with its path
shown and writes nothing, and the tree keeps the frame exact at 60x20, 105x59 and 140x40.
TestFolderTreeSelectionIsBoldNotAGlyph forces a TrueColor profile because lipgloss packs
bold and colour into one SGR sequence.

Notes

  • The module has no PR template; this body follows the shape of the recent PRs.
  • left and right are folder-pane actions; left in the reader does not mean "back".
    Flagged rather than changed, since esc owns that meaning today.
  • Help gained no rows: the new actions share the existing open / expand and
    collapse thread / folder rows, which matters because the overlay is already at its
    tested height.

Closes #99

The folder pane draws the listing as a tree. A folder with subfolders leads with + (folded) or - (expanded) in the imap-notes shape, and the cursor is the bold row rather than a "> " glyph, so the marker is never displaced. Folders are folded by default; the expanded set is stored per account in state.toml, names only, and only an explicit expand or collapse writes it.

enter expands a collapsed folder before it opens anything: the first press reveals the subfolders, the next loads the folder as before. right expands, left folds, and both are scoped to the folder pane. The folders overlay and the move picker stay flat, so a folded folder is still reachable.

A parent is the nearest ancestor the listing actually contains, so a server that omits an intermediate container gets no invented row; a folder with no listed ancestor is a root.

Two presentation changes ride with the issue on this branch: the footer joins its command keys with two spaces, matching imap-notes (44 cells for the five-hint set, inside the 54-cell floor at 60 columns); and the panels are separated by a two-column layout gap, so folders/messages and messages/reader have the same four blank cells. The gap is subtracted from the pane widths, keeping the frame exact.
@blainemotsinger blainemotsinger self-assigned this Nov 7, 2026
@blainemotsinger
blainemotsinger merged commit ef7f5fa into main Nov 7, 2026
5 checks passed
@blainemotsinger
blainemotsinger deleted the GH-99 branch November 7, 2026 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

expand/collapse folders in folders listing

1 participant