This repository has been archived on 2026-10-25. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
submarine/internal/tui/tree/rows.go
T
Simon FrankenandClaude Opus 5.5 2212b24fe1 Add submarine TUI prototype with mock data
Bubble Tea prototype for browsing repositories with many nested git
submodules: collapsible tree, pins shown as ref + distance, summarized
issue words with severity levels, detail pane, async loading via a
Provider interface backed by mock data. Includes docs/ with
requirements, state model, UX guide, architecture and decision log,
plus AGENTS.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 14:59:53 +02:00

69 lines
1.5 KiB
Go

package tree
import (
"path"
"submarine/internal/submodule"
)
type rowKind int
const (
rowDir rowKind = iota // non-selectable directory header, e.g. "modules/"
rowNode // a submodule
)
type row struct {
kind rowKind
depth int
label string // directory label for rowDir
node *submodule.Submodule
}
// rows flattens the visible part of the tree.
func (m *Model) rows() []row {
var out []row
m.appendRows(&out, m.roots, 0)
return out
}
// appendRows groups mods by the directory of their RelPath. Each group with a
// directory gets a header row; its submodules are indented one level deeper.
func (m *Model) appendRows(out *[]row, mods []*submodule.Submodule, depth int) {
for _, g := range groupByDir(mods) {
d := depth
if g.dir != "." {
*out = append(*out, row{kind: rowDir, depth: depth, label: g.dir + "/"})
d++
}
for _, s := range g.mods {
*out = append(*out, row{kind: rowNode, depth: d, node: s})
if m.expanded[s.Path] && len(s.Children) > 0 {
m.appendRows(out, s.Children, d+1)
}
}
}
}
type dirGroup struct {
dir string
mods []*submodule.Submodule
}
// groupByDir keeps the order in which directories first appear.
func groupByDir(mods []*submodule.Submodule) []dirGroup {
var groups []dirGroup
idx := map[string]int{}
for _, s := range mods {
dir := path.Dir(s.RelPath)
i, ok := idx[dir]
if !ok {
i = len(groups)
idx[dir] = i
groups = append(groups, dirGroup{dir: dir})
}
groups[i].mods = append(groups[i].mods, s)
}
return groups
}