summaryrefslogtreecommitdiffstats
path: root/pkg/commands
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2020-11-15 10:45:55 +1100
committerJesse Duffield <jessedduffield@gmail.com>2021-03-30 21:57:00 +1100
commit45939171ea6537562270975348fe2919c9c60b95 (patch)
treeb9c4138c32b54577a3d6f17acdc0f4132c2ebc9e /pkg/commands
parent049849264e561d2867d0d94940b1f66dcac77e6b (diff)
WIP
start moving to new interface WIP WIP WIP WIP WIP
Diffstat (limited to 'pkg/commands')
-rw-r--r--pkg/commands/loading_files.go1
-rw-r--r--pkg/commands/models/status_line_node.go137
-rw-r--r--pkg/commands/models/status_line_node_test.go76
3 files changed, 214 insertions, 0 deletions
diff --git a/pkg/commands/loading_files.go b/pkg/commands/loading_files.go
index f2a285f58..411c0251a 100644
--- a/pkg/commands/loading_files.go
+++ b/pkg/commands/loading_files.go
@@ -58,6 +58,7 @@ func (c *GitCommand) GetStatusFiles(opts GetStatusFileOptions) []*models.File {
}
files = append(files, file)
}
+
return files
}
diff --git a/pkg/commands/models/status_line_node.go b/pkg/commands/models/status_line_node.go
new file mode 100644
index 000000000..042a0fceb
--- /dev/null
+++ b/pkg/commands/models/status_line_node.go
@@ -0,0 +1,137 @@
+package models
+
+import (
+ "sort"
+)
+
+type StatusLineNode struct {
+ Children []*StatusLineNode
+ File *File
+ Name string
+ Collapsed bool
+}
+
+func (s *StatusLineNode) GetShortStatus() string {
+ // need to see if any child has unstaged changes.
+ if s.IsLeaf() {
+ return s.File.ShortStatus
+ }
+
+ firstChar := " "
+ secondChar := " "
+ if s.HasStagedChanges() {
+ firstChar = "M"
+ }
+ if s.HasUnstagedChanges() {
+ secondChar = "M"
+ }
+
+ return firstChar + secondChar
+}
+
+func (s *StatusLineNode) HasUnstagedChanges() bool {
+ if s.IsLeaf() {
+ return s.File.HasUnstagedChanges
+ }
+
+ for _, child := range s.Children {
+ if child.HasUnstagedChanges() {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (s *StatusLineNode) HasStagedChanges() bool {
+ if s.IsLeaf() {
+ return s.File.HasStagedChanges
+ }
+
+ for _, child := range s.Children {
+ if child.HasStagedChanges() {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (s *StatusLineNode) GetNodeAtIndex(index int) *StatusLineNode {
+ node, _ := s.getNodeAtIndexAux(index)
+
+ return node
+}
+
+func (s *StatusLineNode) getNodeAtIndexAux(index int) (*StatusLineNode, int) {
+ offset := 1
+
+ if index == 0 {
+ return s, offset
+ }
+
+ for _, child := range s.Children {
+ node, offsetChange := child.getNodeAtIndexAux(index - offset)
+ offset += offsetChange
+ if node != nil {
+ return node, offset
+ }
+ }
+
+ return nil, offset
+}
+
+func (s *StatusLineNode) IsLeaf() bool {
+ return len(s.Children) == 0
+}
+
+func (s *StatusLineNode) Size() int {
+ output := 1
+
+ for _, child := range s.Children {
+ output += child.Size()
+ }
+
+ return output
+}
+
+func (s *StatusLineNode) Flatten() []*StatusLineNode {
+ arr := []*StatusLineNode{s}
+
+ for _, child := range s.Children {
+ arr = append(arr, child.Flatten()...)
+ }
+
+ return arr
+}
+
+func (s *StatusLineNode) SortTree() {
+ s.sortChildren()
+
+ for _, child := range s.Children {
+ child.SortTree()
+ }
+}
+
+func (s *StatusLineNode) sortChildren() {
+ if s.IsLeaf() {
+ return
+ }
+
+ sortedChildren := make([]*StatusLineNode, len(s.Children))
+ copy(sortedChildren, s.Children)
+
+ sort.Slice(sortedChildren, func(i, j int) bool {
+ if !sortedChildren[i].IsLeaf() && sortedChildren[j].IsLeaf() {
+ return true
+ }
+ if sortedChildren[i].IsLeaf() && !sortedChildren[j].IsLeaf() {
+ return false
+ }
+
+ return sortedChildren[i].Name < sortedChildren[j].Name
+ })
+
+ // TODO: think about making this in-place
+ s.Children = sortedChildren
+}
diff --git a/pkg/commands/models/status_line_node_test.go b/pkg/commands/models/status_line_node_test.go
new file mode 100644
index 000000000..f8114fcf1
--- /dev/null
+++ b/pkg/commands/models/status_line_node_test.go
@@ -0,0 +1,76 @@
+package models
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRender(t *testing.T) {
+ scenarios := []struct {
+ name string
+ root *StatusLineNode
+ expected []string
+ }{
+ {
+ name: "nil node",
+ root: nil,
+ expected: []string{},
+ },
+ {
+ name: "leaf node",
+ root: &StatusLineNode{
+ Name: "",
+ Children: []*StatusLineNode{
+ {File: &File{Name: "test", ShortStatus: " M", HasStagedChanges: true}, Name: "test"},
+ },
+ },
+ expected: []string{" M test"},
+ },
+ {
+ name: "big example",
+ root: &StatusLineNode{
+ Name: "",
+ Children: []*StatusLineNode{
+ {
+ Name: "dir1",
+ Collapsed: true,
+ Children: []*StatusLineNode{
+ {
+ File: &File{Name: "file2", ShortStatus: "M ", HasUnstagedChanges: true},
+ Name: "file2",
+ },
+ },
+ },
+ {
+ Name: "dir2",
+ Children: []*StatusLineNode{
+ {
+ File: &File{Name: "file3", ShortStatus: " M", HasStagedChanges: true},
+ Name: "file3",
+ },
+ {
+ File: &File{Name: "file4", ShortStatus: "M ", HasUnstagedChanges: true},
+ Name: "file4",
+ },
+ },
+ },
+ {
+ File: &File{Name: "file1", ShortStatus: "M ", HasUnstagedChanges: true},
+ Name: "file1",
+ },
+ },
+ },
+
+ expected: []string{"M dir1 ►", "MM dir2 ▼", " M file3", " M file4", "M file1"},
+ },
+ }
+
+ for _, s := range scenarios {
+ s := s
+ t.Run(s.name, func(t *testing.T) {
+ result := s.root.Render()[1:]
+ assert.EqualValues(t, s.expected, result)
+ })
+ }
+}