From ac5ee42a1fdd8fd07168784585c3ce3c2a2c74ba Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Tue, 4 Aug 2026 10:35:29 +0200 Subject: [PATCH 1/3] add support to dynamically adjust file tree width --- pkg/ui/keys.go | 12 ++++++++++++ pkg/ui/panes/filetree/filetree.go | 23 ++++++++++++++++++----- pkg/ui/panes/filetree/keys.go | 16 +++++++++++++--- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/pkg/ui/keys.go b/pkg/ui/keys.go index bad9e15..c629168 100644 --- a/pkg/ui/keys.go +++ b/pkg/ui/keys.go @@ -33,6 +33,8 @@ type KeyMap struct { ToggleHelp key.Binding ToggleMessage key.Binding ToggleSelection key.Binding + IncreaseFileTreeWidth key.Binding + DecreaseFileTreeWidth key.Binding } var keys = &KeyMap{ @@ -156,6 +158,14 @@ var keys = &KeyMap{ key.WithKeys("v"), key.WithHelp("v", "toggle selection"), ), + IncreaseFileTreeWidth: key.NewBinding( + key.WithKeys(">"), + key.WithHelp(">", "increase file tree width"), + ), + DecreaseFileTreeWidth: key.NewBinding( + key.WithKeys("<"), + key.WithHelp("<", "decrease file tree width"), + ), } func KeyGroups() [][]key.Binding { @@ -171,6 +181,8 @@ func KeyGroups() [][]key.Binding { keys.CtrlU, keys.ScrollLeft, keys.ScrollRight, + keys.IncreaseFileTreeWidth, + keys.DecreaseFileTreeWidth, }, { keys.ToggleFileTree, keys.SearchFiles, diff --git a/pkg/ui/panes/filetree/filetree.go b/pkg/ui/panes/filetree/filetree.go index ce6e2f9..a240f69 100644 --- a/pkg/ui/panes/filetree/filetree.go +++ b/pkg/ui/panes/filetree/filetree.go @@ -21,10 +21,15 @@ import ( "github.com/dlvhdr/diffnav/pkg/utils" ) +const ( + widthStep = 5 +) + type Model struct { - t tree.Model - files []*gitdiff.File - cfg config.Config + t tree.Model + files []*gitdiff.File + cfg config.Config + currentWidth int } func New(cfg config.Config) Model { @@ -59,6 +64,12 @@ func (m *Model) Update(msg tea.Msg) (*Model, tea.Cmd) { case key.Matches(msg, keys.ToggleNode): m.t.ToggleCurrentNode() + + case key.Matches(msg, keys.IncreaseFileTreeWidth): + m.SetSize(m.Width()+widthStep, 0) + + case key.Matches(msg, keys.DecreaseFileTreeWidth): + m.SetSize(m.Width()-widthStep, 0) } } return m, nil @@ -411,8 +422,10 @@ var indenter = func(children ltree.Children, index int) string { // SetSize implements the Component interface. func (m *Model) SetSize(width, height int) { - m.t.SetSize(width, height) - m.rebuildTree() + if width > 0 { + m.t.SetSize(width, height) + m.rebuildTree() + } } func (m *Model) Width() int { diff --git a/pkg/ui/panes/filetree/keys.go b/pkg/ui/panes/filetree/keys.go index f7a171f..f6ee3d1 100644 --- a/pkg/ui/panes/filetree/keys.go +++ b/pkg/ui/panes/filetree/keys.go @@ -3,9 +3,11 @@ package filetree import "charm.land/bubbles/v2/key" type KeyMap struct { - ExpandNode key.Binding - CollapseNode key.Binding - ToggleNode key.Binding + ExpandNode key.Binding + CollapseNode key.Binding + ToggleNode key.Binding + IncreaseFileTreeWidth key.Binding + DecreaseFileTreeWidth key.Binding } var keys = &KeyMap{ @@ -21,4 +23,12 @@ var keys = &KeyMap{ key.WithKeys("enter"), key.WithHelp("enter", "toggle"), ), + IncreaseFileTreeWidth: key.NewBinding( + key.WithKeys(">"), + key.WithHelp(">", "increase file tree width"), + ), + DecreaseFileTreeWidth: key.NewBinding( + key.WithKeys("<"), + key.WithHelp("<", "decrease file tree width"), + ), } From 7b987f9806e699d75855c9c35f763cc67c8addcd Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Tue, 11 Aug 2026 20:34:53 +0200 Subject: [PATCH 2/3] Revert "add support to dynamically adjust file tree width" This reverts commit ac5ee42a1fdd8fd07168784585c3ce3c2a2c74ba. --- pkg/ui/keys.go | 12 ------------ pkg/ui/panes/filetree/filetree.go | 23 +++++------------------ pkg/ui/panes/filetree/keys.go | 16 +++------------- 3 files changed, 8 insertions(+), 43 deletions(-) diff --git a/pkg/ui/keys.go b/pkg/ui/keys.go index c629168..bad9e15 100644 --- a/pkg/ui/keys.go +++ b/pkg/ui/keys.go @@ -33,8 +33,6 @@ type KeyMap struct { ToggleHelp key.Binding ToggleMessage key.Binding ToggleSelection key.Binding - IncreaseFileTreeWidth key.Binding - DecreaseFileTreeWidth key.Binding } var keys = &KeyMap{ @@ -158,14 +156,6 @@ var keys = &KeyMap{ key.WithKeys("v"), key.WithHelp("v", "toggle selection"), ), - IncreaseFileTreeWidth: key.NewBinding( - key.WithKeys(">"), - key.WithHelp(">", "increase file tree width"), - ), - DecreaseFileTreeWidth: key.NewBinding( - key.WithKeys("<"), - key.WithHelp("<", "decrease file tree width"), - ), } func KeyGroups() [][]key.Binding { @@ -181,8 +171,6 @@ func KeyGroups() [][]key.Binding { keys.CtrlU, keys.ScrollLeft, keys.ScrollRight, - keys.IncreaseFileTreeWidth, - keys.DecreaseFileTreeWidth, }, { keys.ToggleFileTree, keys.SearchFiles, diff --git a/pkg/ui/panes/filetree/filetree.go b/pkg/ui/panes/filetree/filetree.go index a240f69..ce6e2f9 100644 --- a/pkg/ui/panes/filetree/filetree.go +++ b/pkg/ui/panes/filetree/filetree.go @@ -21,15 +21,10 @@ import ( "github.com/dlvhdr/diffnav/pkg/utils" ) -const ( - widthStep = 5 -) - type Model struct { - t tree.Model - files []*gitdiff.File - cfg config.Config - currentWidth int + t tree.Model + files []*gitdiff.File + cfg config.Config } func New(cfg config.Config) Model { @@ -64,12 +59,6 @@ func (m *Model) Update(msg tea.Msg) (*Model, tea.Cmd) { case key.Matches(msg, keys.ToggleNode): m.t.ToggleCurrentNode() - - case key.Matches(msg, keys.IncreaseFileTreeWidth): - m.SetSize(m.Width()+widthStep, 0) - - case key.Matches(msg, keys.DecreaseFileTreeWidth): - m.SetSize(m.Width()-widthStep, 0) } } return m, nil @@ -422,10 +411,8 @@ var indenter = func(children ltree.Children, index int) string { // SetSize implements the Component interface. func (m *Model) SetSize(width, height int) { - if width > 0 { - m.t.SetSize(width, height) - m.rebuildTree() - } + m.t.SetSize(width, height) + m.rebuildTree() } func (m *Model) Width() int { diff --git a/pkg/ui/panes/filetree/keys.go b/pkg/ui/panes/filetree/keys.go index f6ee3d1..f7a171f 100644 --- a/pkg/ui/panes/filetree/keys.go +++ b/pkg/ui/panes/filetree/keys.go @@ -3,11 +3,9 @@ package filetree import "charm.land/bubbles/v2/key" type KeyMap struct { - ExpandNode key.Binding - CollapseNode key.Binding - ToggleNode key.Binding - IncreaseFileTreeWidth key.Binding - DecreaseFileTreeWidth key.Binding + ExpandNode key.Binding + CollapseNode key.Binding + ToggleNode key.Binding } var keys = &KeyMap{ @@ -23,12 +21,4 @@ var keys = &KeyMap{ key.WithKeys("enter"), key.WithHelp("enter", "toggle"), ), - IncreaseFileTreeWidth: key.NewBinding( - key.WithKeys(">"), - key.WithHelp(">", "increase file tree width"), - ), - DecreaseFileTreeWidth: key.NewBinding( - key.WithKeys("<"), - key.WithHelp("<", "decrease file tree width"), - ), } From 8d2474c9aadb84de3a396b3cca2a171a65d3ecf0 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Tue, 11 Aug 2026 21:18:40 +0200 Subject: [PATCH 3/3] fix key based resizing --- pkg/ui/keys.go | 12 ++++++++++++ pkg/ui/tui.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/pkg/ui/keys.go b/pkg/ui/keys.go index bad9e15..8bbedda 100644 --- a/pkg/ui/keys.go +++ b/pkg/ui/keys.go @@ -33,6 +33,8 @@ type KeyMap struct { ToggleHelp key.Binding ToggleMessage key.Binding ToggleSelection key.Binding + IncreaseFileTreeWidth key.Binding + DecreaseFileTreeWidth key.Binding } var keys = &KeyMap{ @@ -156,6 +158,14 @@ var keys = &KeyMap{ key.WithKeys("v"), key.WithHelp("v", "toggle selection"), ), + IncreaseFileTreeWidth: key.NewBinding( + key.WithKeys(">"), + key.WithHelp(">", "increase file tree width"), + ), + DecreaseFileTreeWidth: key.NewBinding( + key.WithKeys("<"), + key.WithHelp("<", "decrease file tree width"), + ), } func KeyGroups() [][]key.Binding { @@ -171,6 +181,7 @@ func KeyGroups() [][]key.Binding { keys.CtrlU, keys.ScrollLeft, keys.ScrollRight, + keys.IncreaseFileTreeWidth, }, { keys.ToggleFileTree, keys.SearchFiles, @@ -183,6 +194,7 @@ func KeyGroups() [][]key.Binding { keys.ToggleDiffView, keys.ToggleIconStyle, keys.ToggleSelection, + keys.DecreaseFileTreeWidth, }, { keys.ToggleMessage, keys.ToggleHelp, diff --git a/pkg/ui/tui.go b/pkg/ui/tui.go index 6e71f36..4a11cc3 100644 --- a/pkg/ui/tui.go +++ b/pkg/ui/tui.go @@ -361,6 +361,15 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case key.Matches(msg, keys.CtrlD, keys.CtrlU, keys.CtrlE, keys.CtrlY): m.diffViewer, cmd = m.diffViewer.Update(msg) cmds = append(cmds, cmd) + + case key.Matches(msg, keys.IncreaseFileTreeWidth): + m, cmd = m.handleSidebarResize(minResizeStep) + cmds = append(cmds, cmd) + + case key.Matches(msg, keys.DecreaseFileTreeWidth): + m, cmd = m.handleSidebarResize(-minResizeStep) + cmds = append(cmds, cmd) + default: if m.activePanel == DiffViewerPanel { m.diffViewer, cmd = m.diffViewer.Update(msg) @@ -1324,6 +1333,38 @@ func (m mainModel) handleSidebarDrag(msg tea.MouseMsg) (tea.Model, tea.Cmd) { return m, tea.Batch(cmds...) } +func (m mainModel) handleSidebarResize(resize int) (mainModel, tea.Cmd) { + if m.searchingFiles { + return m, nil + } + + // Clamp to reasonable bounds. + minWidth := sidebarMinWidth + maxWidth := m.width / 2 + newWidth := max(minWidth, min(maxWidth, m.sidebarWidth()+resize)) + + // Hide sidebar if resized below threshold. + if newWidth < sidebarHideWidth { + m.isShowingFileTree = false + cmd := m.diffViewer.SetSize(m.width, m.mainContentHeight()) + return m, cmd + } + + // TODO: for some reason setting a value smaller than minResizeStep + // will garble up the output when resizing. I have no idea why. + if abs(newWidth-m.sidebarWidth()) < minResizeStep { + return m, nil + } + + // Resize components. + cmds := []tea.Cmd{} + + cmds = append(cmds, m.diffViewer.SetSize(m.width-newWidth, m.mainContentHeight())) + m.fileTree.SetSize(newWidth-1, m.mainContentHeight()-searchHeight-1) + + return m, tea.Batch(cmds...) +} + func abs(x int) int { if x < 0 { return -x