@@ -169,7 +169,8 @@ func calculateMaxDepth(nodes []*TreeNode) int {
169169}
170170
171171// RenderTree renders the tree as an ASCII tree with styled columns.
172- func RenderTree (nodes []* TreeNode , cfg * config.Config , maxIDWidth int , hasTags bool ) string {
172+ // termWidth is used to calculate responsive column widths.
173+ func RenderTree (nodes []* TreeNode , cfg * config.Config , maxIDWidth int , hasTags bool , termWidth int ) string {
173174 var sb strings.Builder
174175
175176 // Calculate max depth to determine ID column width
@@ -184,48 +185,79 @@ func RenderTree(nodes []*TreeNode, cfg *config.Config, maxIDWidth int, hasTags b
184185 treeColWidth = maxIDWidth + maxDepth * treeIndent
185186 }
186187
188+ // Calculate responsive columns based on terminal width
189+ // Adjust for tree column width vs default ID column width
190+ adjustedWidth := termWidth - treeColWidth + ColWidthID
191+ cols := CalculateResponsiveColumns (adjustedWidth , hasTags )
192+
193+ // Calculate title width from remaining space
194+ // Account for: tree/ID col, type col, status col, priority symbol (2), space before tags (1)
195+ titleWidth := termWidth - treeColWidth - ColWidthType - ColWidthStatus - 3
196+ if cols .ShowTags {
197+ titleWidth -= cols .Tags
198+ }
199+ if titleWidth < 20 {
200+ titleWidth = 20
201+ }
202+
187203 // Header with manual padding (lipgloss Width doesn't handle styled strings well)
188204 headerCol := lipgloss .NewStyle ().Foreground (ColorMuted )
189205 idHeader := headerCol .Render ("ID" ) + strings .Repeat (" " , treeColWidth - 2 )
190- typeHeader := headerCol .Render ("TYPE" ) + strings .Repeat (" " , 12 - 4 )
191- statusHeader := headerCol .Render ("STATUS" ) + strings .Repeat (" " , 14 - 6 )
206+ typeHeader := headerCol .Render ("TYPE" ) + strings .Repeat (" " , ColWidthType - 4 )
207+ statusHeader := headerCol .Render ("STATUS" ) + strings .Repeat (" " , ColWidthStatus - 6 )
192208
193209 header := idHeader + typeHeader + statusHeader + headerCol .Render ("TITLE" )
194- dividerWidth := treeColWidth + 12 + 14 + 50
210+ if cols .ShowTags && titleWidth > 5 {
211+ header += strings .Repeat (" " , titleWidth - 5 + 3 ) + headerCol .Render ("TAGS" ) // +3 for priority/spacing
212+ }
213+ dividerWidth := termWidth - 1 // -1 to avoid wrapping on exact terminal width
195214 sb .WriteString (header )
196215 sb .WriteString ("\n " )
197216 sb .WriteString (Muted .Render (strings .Repeat ("─" , dividerWidth )))
198217 sb .WriteString ("\n " )
199218
219+ // Build render config from responsive columns
220+ renderCfg := treeRenderConfig {
221+ treeColWidth : treeColWidth ,
222+ titleWidth : titleWidth ,
223+ cols : cols ,
224+ }
225+
200226 // Render nodes (depth 0 = root level, no ancestry yet)
201- renderNodes (& sb , nodes , 0 , nil , cfg , treeColWidth , hasTags )
227+ renderNodes (& sb , nodes , 0 , nil , cfg , renderCfg )
202228
203229 return sb .String ()
204230}
205231
232+ // treeRenderConfig holds computed rendering configuration for tree output
233+ type treeRenderConfig struct {
234+ treeColWidth int
235+ titleWidth int
236+ cols ResponsiveColumns
237+ }
238+
206239// renderNodes recursively renders tree nodes with proper indentation.
207240// depth 0 = root level (no connector), depth 1+ = nested (has connector)
208241// ancestry tracks whether each parent level was a last child (true = last, no continuation line needed)
209- func renderNodes (sb * strings.Builder , nodes []* TreeNode , depth int , ancestry []bool , cfg * config.Config , treeColWidth int , hasTags bool ) {
242+ func renderNodes (sb * strings.Builder , nodes []* TreeNode , depth int , ancestry []bool , cfg * config.Config , renderCfg treeRenderConfig ) {
210243 for i , node := range nodes {
211244 isLast := i == len (nodes )- 1
212- renderNode (sb , node , depth , isLast , ancestry , cfg , treeColWidth , hasTags )
245+ renderNode (sb , node , depth , isLast , ancestry , cfg , renderCfg )
213246 // Only add to ancestry when depth > 0 (roots have no connectors to continue)
214247 if len (node .Children ) > 0 {
215248 var newAncestry []bool
216249 if depth > 0 {
217250 newAncestry = append (ancestry , isLast )
218251 }
219- renderNodes (sb , node .Children , depth + 1 , newAncestry , cfg , treeColWidth , hasTags )
252+ renderNodes (sb , node .Children , depth + 1 , newAncestry , cfg , renderCfg )
220253 }
221254 }
222255}
223256
224257// renderNode renders a single tree node with tree connectors.
225- // treeColWidth is the fixed width of the ID column (includes space for tree connectors).
226258// depth 0 = root (no connector), depth 1+ = nested (has connector)
227259// ancestry tracks whether each parent level was a last child (true = last, no continuation line needed)
228- func renderNode (sb * strings.Builder , node * TreeNode , depth int , isLast bool , ancestry []bool , cfg * config.Config , treeColWidth int , hasTags bool ) {
260+ func renderNode (sb * strings.Builder , node * TreeNode , depth int , isLast bool , ancestry []bool , cfg * config.Config , renderCfg treeRenderConfig ) {
229261 b := node .Bean
230262
231263 // Build tree prefix from ancestry
@@ -248,21 +280,22 @@ func renderNode(sb *strings.Builder, node *TreeNode, depth int, isLast bool, anc
248280 // Get colors from config
249281 colors := cfg .GetBeanColors (b .Status , b .Type , b .Priority )
250282
251- // Use shared RenderBeanRow function
283+ // Use shared RenderBeanRow function with responsive columns
252284 row := RenderBeanRow (b .ID , b .Status , b .Type , b .Title , BeanRowConfig {
253285 StatusColor : colors .StatusColor ,
254286 TypeColor : colors .TypeColor ,
255287 PriorityColor : colors .PriorityColor ,
256288 Priority : b .Priority ,
257289 IsArchive : colors .IsArchive ,
258- MaxTitleWidth : 50 ,
290+ MaxTitleWidth : renderCfg . titleWidth ,
259291 ShowCursor : false ,
260292 Tags : b .Tags ,
261- ShowTags : hasTags ,
262- MaxTags : 1 ,
293+ ShowTags : renderCfg .cols .ShowTags ,
294+ TagsColWidth : renderCfg .cols .Tags ,
295+ MaxTags : renderCfg .cols .MaxTags ,
263296 TreePrefix : prefix ,
264297 Dimmed : ! node .Matched ,
265- IDColWidth : treeColWidth ,
298+ IDColWidth : renderCfg . treeColWidth ,
266299 })
267300
268301 sb .WriteString (row )
0 commit comments