Private
Public Access
1
0

Add pkg/util/dirtree

Update dir_tree tool to use it
Update filepicker bubble to use it
This commit is contained in:
2025-01-01 05:06:37 +00:00
parent 3cac7e8e11
commit 8e2991da1a
5 changed files with 340 additions and 346 deletions

View File

@@ -0,0 +1,113 @@
package filepicker
import (
"git.mlow.ca/mlow/lmcli/pkg/util/dirtree"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
type Model struct {
tree *dirtree.Tree
cursor int
displayNodes []*dirtree.Node // Flattened view of visible nodes
}
func New(path string) Model {
m := Model{
tree: dirtree.NewTree(path),
}
m.tree.Root.LoadChildren(false, 0, nil)
m.updateRenderTree()
return m
}
func (m *Model) updateRenderTree() {
m.displayNodes = dirtree.FlattenTree(m.tree.Root, false)
}
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "j":
if m.cursor < len(m.displayNodes)-1 {
m.cursor++
}
case "k":
if m.cursor > 0 {
m.cursor--
}
case "l", "right":
current := m.displayNodes[m.cursor]
if current.IsDir() {
current.Expanded = true
current.LoadChildren(false, 0, nil)
m.updateRenderTree()
}
case "h", "left":
current := m.displayNodes[m.cursor]
if current.IsDir() && current.Expanded {
current.Expanded = false
m.updateRenderTree()
} else {
// Find and collapse parent
if !current.IsRoot() {
current.Parent().Expanded = false
m.updateRenderTree()
// Move cursor to parent
for i, node := range m.displayNodes {
if node == current.Parent() {
m.cursor = i
break
}
}
}
}
case " ":
current := m.displayNodes[m.cursor]
if current.IsSelected() {
current.Deselect(true)
} else {
current.Select(true, 0)
}
m.updateRenderTree()
case "H":
m.tree.ShowHidden = !m.tree.ShowHidden
m.tree.Root.LoadChildren(false, 0, nil)
}
}
return m, nil
}
func (m Model) Init() tea.Cmd {
return nil
}
func (m Model) View() string {
// Define styles
dirStyle := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("12")) // Blue for directories
fileStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("7")) // White for files
selectedStyle := lipgloss.NewStyle().Bold(true)
renderNode := func(node *dirtree.Node) string {
var nodeName string
if node.IsDir() {
caret := "▶ "
if node.Expanded {
caret = "▼ "
}
nodeName = caret + node.Name + "/"
nodeName = dirStyle.Render(nodeName)
} else {
nodeName = fileStyle.Render(node.Name)
}
if node.IsSelected() {
nodeName = selectedStyle.Render(nodeName)
}
return nodeName
}
return dirtree.RenderNodes(m.displayNodes, dirtree.Compact, m.cursor, renderNode)
}