feat: side-panel navigation and expansion

main
Francesco Minnocci 9 months ago
parent fe45414521
commit a0e069e9c9

@ -31,8 +31,9 @@ type model struct {
leftWidth int
treeRoot *TreeNode
textarea textarea.Model
treeRoot *TreeNode
treeCursor int
textarea textarea.Model
commands []Command
viewport viewport.Model
@ -71,8 +72,10 @@ func main() {
}
}
func flattenTree(n *TreeNode, depth int) []string {
var out []string
// returns both the string representation and corresponding nodes
func flattenTreeWithNodes(n *TreeNode, depth int) ([]string, []*TreeNode) {
var lines []string
var nodes []*TreeNode
prefix := strings.Repeat(" ", depth)
icon := "▸"
if n.Expanded && len(n.Children) > 0 {
@ -80,13 +83,28 @@ func flattenTree(n *TreeNode, depth int) []string {
} else if len(n.Children) == 0 {
icon = " "
}
out = append(out, fmt.Sprintf("%s%s %s", prefix, icon, n.Label))
lines = append(lines, fmt.Sprintf("%s%s %s", prefix, icon, n.Label))
nodes = append(nodes, n)
if n.Expanded {
for _, c := range n.Children {
out = append(out, flattenTree(c, depth+1)...)
childLines, childNodes := flattenTreeWithNodes(c, depth+1)
lines = append(lines, childLines...)
nodes = append(nodes, childNodes...)
}
}
return out
return lines, nodes
}
func flattenTree(n *TreeNode, depth int) []string {
lines, _ := flattenTreeWithNodes(n, depth)
return lines
}
// toggleNodeExpansion toggles the expanded state of a node if it has children
func (m *model) toggleNodeExpansion(node *TreeNode) {
if len(node.Children) > 0 {
node.Expanded = !node.Expanded
}
}
func (m *model) renderCommandsContent() string {
@ -225,6 +243,37 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.focusPane == "fileview" {
// fileview tree behaviour (navigation, expand/collapse)
_, nodes := flattenTreeWithNodes(m.treeRoot, 0)
switch msg.String() {
case "up", "k":
if m.treeCursor > 0 {
m.treeCursor--
}
case "down", "j":
if m.treeCursor < len(nodes)-1 {
m.treeCursor++
}
case "left", "h":
if m.treeCursor < len(nodes) {
node := nodes[m.treeCursor]
if node.Expanded && len(node.Children) > 0 {
node.Expanded = false
}
}
case "right", "l":
if m.treeCursor < len(nodes) {
node := nodes[m.treeCursor]
if !node.Expanded && len(node.Children) > 0 {
node.Expanded = true
}
}
case "enter", " ":
// toggle
if m.treeCursor < len(nodes) {
m.toggleNodeExpansion(nodes[m.treeCursor])
}
}
return m, nil
}
@ -292,6 +341,14 @@ func (m model) View() string {
treeLines := flattenTree(m.treeRoot, 0)
// highlight the current selection when fileview is focused
if m.focusPane == "fileview" && m.treeCursor < len(treeLines) {
selectedStyle := lipgloss.NewStyle().
Background(lipgloss.Color("6")).
Foreground(lipgloss.Color("0"))
treeLines[m.treeCursor] = selectedStyle.Render(treeLines[m.treeCursor])
}
// show the tree view content
fileviewRows = append(fileviewRows, treeLines...)

Loading…
Cancel
Save