snapshot of 8b9e9fcfc8b13c2d29024f6f756b28bc6851512b Annotations about the code that implements koment.

internal/ui/tree.go

1 package ui
2
3 import (
4 "path"
5 "sort"
6 "strings"
7
8 "github.com/koment-dev/koment/internal/anchor"
9 )
10
11 type treeNode struct {
12 Name string
13 Path string
14 Dirs []treeNode
15 Files []entry
16 Count int
17 Worst anchor.Status
18 Open bool
19 }
20
21 var statusSeverity = map[anchor.Status]int{
22 anchor.StatusOK: 0,
23 anchor.StatusAmbiguous: 2,
24 anchor.StatusDrifted: 3,
25 anchor.StatusOrphaned: 4,
26 }
27
28 func buildTree(files []entry, current string) ([]treeNode, []entry) {
29 root := &treeNode{}
30 for _, file := range files {
31 directory := findOrCreateDirectory(root, path.Dir(file.Path))
32 directory.Files = append(directory.Files, file)
33 }
34
35 collapse(root)
36 summariseTree(root, current)
37 return root.Dirs, root.Files
38 }
39
40 func findOrCreateDirectory(root *treeNode, directory string) *treeNode {
41 if directory == "." || directory == "" {
42 return root
43 }
44
45 at := root
46 for _, segment := range strings.Split(directory, "/") {
47 next := (*treeNode)(nil)
48 for i := range at.Dirs {
49 if at.Dirs[i].Name == segment {
50 next = &at.Dirs[i]
51 break
52 }
53 }
54 if next == nil {
55 at.Dirs = append(at.Dirs, treeNode{Name: segment, Path: path.Join(at.Path, segment)})
56 next = &at.Dirs[len(at.Dirs)-1]
57 }
58 at = next
59 }
60 return at
61 }
62
63 func collapse(at *treeNode) {
64 for i := range at.Dirs {
65 collapse(&at.Dirs[i])
66 }
67
68 if at.Path == "" {
69 return
70 }
71 for len(at.Files) == 0 && len(at.Dirs) == 1 {
72 only := at.Dirs[0]
73 at.Name = at.Name + "/" + only.Name
74 at.Path = only.Path
75 at.Files = only.Files
76 at.Dirs = only.Dirs
77 }
78 }
79
80 func summariseTree(at *treeNode, current string) {
81 sort.Slice(at.Dirs, func(i, j int) bool { return at.Dirs[i].Name < at.Dirs[j].Name })
82 sort.Slice(at.Files, func(i, j int) bool { return at.Files[i].Name < at.Files[j].Name })
83
84 for _, file := range at.Files {
85 at.Count += file.Count
86 if statusSeverity[file.Worst] > statusSeverity[at.Worst] {
87 at.Worst = file.Worst
88 }
89 if file.Path == current {
90 at.Open = true
91 }
92 }
93
94 for i := range at.Dirs {
95 child := &at.Dirs[i]
96 summariseTree(child, current)
97
98 at.Count += child.Count
99 if statusSeverity[child.Worst] > statusSeverity[at.Worst] {
100 at.Worst = child.Worst
101 }
102 if child.Open {
103 at.Open = true
104 }
105 }
106 }

Find an annotation

Search file paths, rationale, kinds, and authors.

moveEnter openEsc close