From cee3aa323ea144a5a3a378ff766d2f925897624d Mon Sep 17 00:00:00 2001 From: ruinivist Date: Sat, 3 Jan 2026 21:49:14 +0000 Subject: [PATCH] add scrollable functionality for fstree --- fstree/fstree.go | 33 ++++++++++++++++++++++++++++++++- main.go | 12 ++++++++++-- sample/test/new_file.txt | 0 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 sample/test/new_file.txt diff --git a/fstree/fstree.go b/fstree/fstree.go index 6ad805e..bd84814 100644 --- a/fstree/fstree.go +++ b/fstree/fstree.go @@ -52,6 +52,8 @@ type FsTree struct { selectedNode *FsNode hoveredNode *FsNode errMsg string + height int + width int } // ==================== Bubble Tea Interface Implementation ==================== @@ -61,6 +63,9 @@ func (t *FsTree) Init() tea.Cmd { func (t *FsTree) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch m := msg.(type) { + case tea.WindowSizeMsg: + t.width = m.Width + t.height = m.Height case tea.KeyMsg: t.errMsg = "" switch m.String() { @@ -117,7 +122,33 @@ func (t *FsTree) View() string { builder := &strings.Builder{} t.renderNode(t.root, 0, builder) - return builder.String() + rendered := builder.String() + + // clamp to height around selected node + if t.selectedNode != nil { + lines := strings.Split(rendered, "\n") + totalLines := len(lines) + selectedLine := t.selectedNode.line + + halfHeight := t.height / 2 + startLine := selectedLine - halfHeight + if startLine < 0 { + startLine = 0 + } + endLine := startLine + t.height + if endLine > totalLines { + endLine = totalLines + startLine = endLine - t.height + if startLine < 0 { + startLine = 0 + } + } + + clampedLines := lines[startLine:endLine] + rendered = strings.Join(clampedLines, "\n") + } + + return rendered } // ==================== FsTree helper methods ==================== diff --git a/main.go b/main.go index b1130d3..b2d6639 100644 --- a/main.go +++ b/main.go @@ -98,12 +98,20 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.WindowSizeMsg: m.terminalWidth = msg.Width m.terminalHeight = msg.Height - m.viewport.Width = msg.Width - m.width - 1 - m.viewport.Height = msg.Height + if m.tree != nil { + m.tree.Update(tea.WindowSizeMsg{ + Height: m.terminalHeight, + Width: m.terminalWidth, + }) + } return m, nil case treeLoadedMsg: m.tree = msg.tree m.loading = false + m.tree.Update(tea.WindowSizeMsg{ + Height: m.terminalHeight, + Width: m.terminalWidth, + }) return m, nil case spinner.TickMsg: var cmd tea.Cmd diff --git a/sample/test/new_file.txt b/sample/test/new_file.txt new file mode 100644 index 0000000..e69de29