snapshot of eee7b5cfc0776c68816d7fdaa8af9d7a0e0da2e6 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/janpuc/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.StatusMoved: 1,
24 anchor.StatusAmbiguous: 2,
25 anchor.StatusDrifted: 3,
26 anchor.StatusOrphaned: 4,
27 }
28
29 func buildTree(files []entry, current string) ([]treeNode, []entry) {
30 root := &treeNode{}
31 for _, file := range files {
32 directory := findOrCreateDirectory(root, path.Dir(file.Path))
33 directory.Files = append(directory.Files, file)
34 }
35
36 collapse(root)
37 summariseTree(root, current)
38 return root.Dirs, root.Files
39 }
40
41 func findOrCreateDirectory(root *treeNode, directory string) *treeNode {
42 if directory == "." || directory == "" {
43 return root
44 }
45
46 at := root
47 for _, segment := range strings.Split(directory, "/") {
48 next := (*treeNode)(nil)
49 for i := range at.Dirs {
50 if at.Dirs[i].Name == segment {
51 next = &at.Dirs[i]
52 break
53 }
54 }
55 if next == nil {
56 at.Dirs = append(at.Dirs, treeNode{Name: segment, Path: path.Join(at.Path, segment)})
57 next = &at.Dirs[len(at.Dirs)-1]
58 }
59 at = next
60 }
61 return at
62 }
63
64 func collapse(at *treeNode) {
65 for i := range at.Dirs {
66 collapse(&at.Dirs[i])
67 }
68
69 if at.Path == "" {
70 return
71 }
72 for len(at.Files) == 0 && len(at.Dirs) == 1 {
73 only := at.Dirs[0]
74 at.Name = at.Name + "/" + only.Name
75 at.Path = only.Path
76 at.Files = only.Files
77 at.Dirs = only.Dirs
78 }
79 }
80
81 func summariseTree(at *treeNode, current string) {
82 sort.Slice(at.Dirs, func(i, j int) bool { return at.Dirs[i].Name < at.Dirs[j].Name })
83 sort.Slice(at.Files, func(i, j int) bool { return at.Files[i].Name < at.Files[j].Name })
84
85 for _, file := range at.Files {
86 at.Count += file.Count
87 if statusSeverity[file.Worst] > statusSeverity[at.Worst] {
88 at.Worst = file.Worst
89 }
90 if file.Path == current {
91 at.Open = true
92 }
93 }
94
95 for i := range at.Dirs {
96 child := &at.Dirs[i]
97 summariseTree(child, current)
98
99 at.Count += child.Count
100 if statusSeverity[child.Worst] > statusSeverity[at.Worst] {
101 at.Worst = child.Worst
102 }
103 if child.Open {
104 at.Open = true
105 }
106 }
107 }

Find an annotation

Search file paths, rationale, kinds, and authors.

moveEnter openEsc close