Skip to content

Commit 8699f49

Browse files
committed
WIP: file tree v2
1 parent 2ca04b3 commit 8699f49

File tree

5 files changed

+128
-10
lines changed

5 files changed

+128
-10
lines changed

go.mod

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ go 1.22.6
44

55
require (
66
github.com/bluekeyes/go-gitdiff v0.8.0
7-
github.com/charmbracelet/bubbles v0.20.0
8-
github.com/charmbracelet/bubbletea v1.1.0
7+
github.com/charmbracelet/bubbles v0.0.0-unpublished
8+
github.com/charmbracelet/bubbletea v1.1.1
99
github.com/charmbracelet/lipgloss v0.13.0
1010
github.com/charmbracelet/log v0.4.0
1111
github.com/charmbracelet/x/ansi v0.3.2
1212
github.com/muesli/reflow v0.3.0
13+
github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a
1314
)
1415

1516
require (
@@ -24,10 +25,11 @@ require (
2425
github.com/mattn/go-runewidth v0.0.16 // indirect
2526
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
2627
github.com/muesli/cancelreader v0.2.2 // indirect
27-
github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a // indirect
2828
github.com/rivo/uniseg v0.4.7 // indirect
2929
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
3030
golang.org/x/sync v0.8.0 // indirect
3131
golang.org/x/sys v0.25.0 // indirect
3232
golang.org/x/text v0.18.0 // indirect
3333
)
34+
35+
replace github.com/charmbracelet/bubbles v0.0.0-unpublished => /Users/dlvhdr/code/playground/bubbles

go.sum

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,16 @@ github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWp
66
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
77
github.com/bluekeyes/go-gitdiff v0.8.0 h1:Nn1wfw3/XeKoc3lWk+2bEXGUHIx36kj80FM1gVcBk+o=
88
github.com/bluekeyes/go-gitdiff v0.8.0/go.mod h1:WWAk1Mc6EgWarCrPFO+xeYlujPu98VuLW3Tu+B/85AE=
9-
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
10-
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
11-
github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c=
12-
github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
9+
github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY=
10+
github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
1311
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
1412
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
1513
github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM=
1614
github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM=
1715
github.com/charmbracelet/x/ansi v0.3.2 h1:wsEwgAN+C9U06l9dCVMX0/L3x7ptvY1qmjMwyfE6USY=
1816
github.com/charmbracelet/x/ansi v0.3.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
19-
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q=
20-
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
17+
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
18+
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
2119
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
2220
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
2321
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

pkg/constants/constants.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ package constants
22

33
const (
44
SearchingFileTreeWidth = 50
5-
OpenFileTreeWidth = 26
5+
OpenFileTreeWidth = 50
66
)

pkg/ui/mainModel.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ui
22

33
import (
44
"fmt"
5+
"os"
56
"strings"
67

78
"github.com/bluekeyes/go-gitdiff/gitdiff"
@@ -18,6 +19,7 @@ import (
1819
"github.com/dlvhdr/diffnav/pkg/ui/common"
1920
"github.com/dlvhdr/diffnav/pkg/ui/panes/diffviewer"
2021
"github.com/dlvhdr/diffnav/pkg/ui/panes/filetree"
22+
"github.com/dlvhdr/diffnav/pkg/ui/panes/filetreev2"
2123
"github.com/dlvhdr/diffnav/pkg/utils"
2224
)
2325

@@ -32,6 +34,7 @@ type mainModel struct {
3234
files []*gitdiff.File
3335
cursor int
3436
fileTree filetree.Model
37+
fileTreeV2 filetreev2.Model
3538
diffViewer diffviewer.Model
3639
width int
3740
height int
@@ -47,6 +50,7 @@ type mainModel struct {
4750
func New(input string) mainModel {
4851
m := mainModel{input: input, isShowingFileTree: true}
4952
m.fileTree = filetree.New()
53+
m.fileTreeV2 = filetreev2.New()
5054
m.diffViewer = diffviewer.New()
5155

5256
m.help = help.New()
@@ -132,6 +136,7 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
132136
return m, tea.Quit
133137
}
134138
m.fileTree = m.fileTree.SetFiles(m.files)
139+
m.fileTreeV2 = m.fileTreeV2.SetFiles(m.files)
135140
cmd = m.setCursor(0)
136141
cmds = append(cmds, cmd)
137142

@@ -230,6 +235,8 @@ func (m mainModel) View() string {
230235
width := m.sidebarWidth()
231236
if m.searching {
232237
content = m.resultsVp.View()
238+
} else if os.Getenv("DIFFNAV_FILETREE") == "v2" {
239+
content = m.fileTreeV2.View()
233240
} else {
234241
content = m.fileTree.View()
235242
}

pkg/ui/panes/filetreev2/filetree.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package filetreev2
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"strings"
7+
8+
"github.com/bluekeyes/go-gitdiff/gitdiff"
9+
"github.com/charmbracelet/bubbles/tree"
10+
tea "github.com/charmbracelet/bubbletea"
11+
ltree "github.com/charmbracelet/lipgloss/tree"
12+
13+
"github.com/dlvhdr/diffnav/pkg/constants"
14+
"github.com/dlvhdr/diffnav/pkg/filenode"
15+
)
16+
17+
type Model struct {
18+
t tree.Model
19+
files []*gitdiff.File
20+
}
21+
22+
func New() Model {
23+
return Model{
24+
t: tree.New(nil, constants.OpenFileTreeWidth, 50),
25+
}
26+
}
27+
28+
func (m Model) Init() tea.Cmd {
29+
return nil
30+
}
31+
32+
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
33+
return m, nil
34+
}
35+
36+
func (m Model) View() string {
37+
return m.t.View()
38+
}
39+
40+
func (m Model) SetFiles(files []*gitdiff.File) Model {
41+
m.files = files
42+
t := buildFullFileTree(files)
43+
m.t.SetNodes(t)
44+
return m
45+
}
46+
47+
func (m Model) SetCursor(cursor int) Model {
48+
return m
49+
}
50+
51+
func buildFullFileTree(files []*gitdiff.File) *tree.Node {
52+
t := tree.Root(".")
53+
for _, file := range files {
54+
subTree := t
55+
56+
name := filenode.GetFileName(file)
57+
dir := filepath.Dir(name)
58+
parts := strings.Split(dir, string(os.PathSeparator))
59+
path := ""
60+
61+
// walk the tree to find existing path
62+
for _, part := range parts {
63+
found := false
64+
children := subTree.ChildNodes()
65+
for j := 0; j < len(children); j++ {
66+
child := children[j]
67+
if child.Value() == part {
68+
subTree = child
69+
path = path + part + string(os.PathSeparator)
70+
found = true
71+
break
72+
}
73+
}
74+
if !found {
75+
break
76+
}
77+
}
78+
79+
// path does not exist from this point, need to creat it
80+
leftover := strings.TrimPrefix(name, path)
81+
parts = strings.Split(leftover, string(os.PathSeparator))
82+
for i, part := range parts {
83+
var c *tree.Node
84+
if i == len(parts)-1 {
85+
subTree.Child(filenode.FileNode{File: file})
86+
} else {
87+
c = tree.Root(part)
88+
subTree.Child(c)
89+
subTree = c
90+
}
91+
}
92+
}
93+
94+
return t
95+
}
96+
97+
var enumerator = func(children ltree.Children, index int) string {
98+
return "│"
99+
}
100+
101+
var indenter = func(children ltree.Children, index int) string {
102+
if children.Length()-1 == index {
103+
return " "
104+
}
105+
return "│"
106+
}
107+
108+
// SetSize implements the Component interface.
109+
func (m *Model) SetSize(width, height int) tea.Cmd {
110+
return nil
111+
}

0 commit comments

Comments
 (0)