@@ -155,6 +155,7 @@ type Model struct {
155155 treeMode bool // True when in tree view
156156 currentNode * types.TreeNode // Current tree node
157157 nodeStack []* types.TreeNode // Breadcrumb trail
158+ cursorStack []int // Cursor positions for each level
158159 maxDepth int // Max depth limit
159160 treeSelected map [string ]bool // Selected items in tree
160161 scanning bool // True while scanning
@@ -217,7 +218,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
217218 // Handle based on current state
218219 switch m .state {
219220 case StateDone :
220- return m , tea .Quit
221+ // 'q' to quit, any other key to rescan and continue
222+ if msg .String () == "q" || msg .String () == "ctrl+c" {
223+ m .quitting = true
224+ return m , tea .Quit
225+ }
226+ // Rescan and return to selection
227+ return m , m .rescanItems ()
221228
222229 case StateConfirming :
223230 switch msg .String () {
@@ -346,6 +353,20 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
346353 }
347354 m .cursor = 0
348355 return m , nil
356+
357+ case rescanItemsMsg :
358+ if msg .err != nil {
359+ m .err = msg .err
360+ return m , nil
361+ }
362+ // Reset state and show new items
363+ m .items = msg .items
364+ m .selected = make (map [int ]bool )
365+ m .cursor = 0
366+ m .state = StateSelecting
367+ m .results = nil
368+ m .err = nil
369+ return m , nil
349370 }
350371
351372 return m , nil
@@ -368,6 +389,45 @@ type scanNodeMsg struct {
368389 err error
369390}
370391
392+ // rescanItemsMsg is sent when items rescan completes
393+ type rescanItemsMsg struct {
394+ items []types.ScanResult
395+ err error
396+ }
397+
398+ // rescanItems rescans all items and returns to selection
399+ func (m Model ) rescanItems () tea.Cmd {
400+ return func () tea.Msg {
401+ s , err := scanner .New ()
402+ if err != nil {
403+ return rescanItemsMsg {err : err }
404+ }
405+
406+ opts := types.ScanOptions {
407+ MaxDepth : 3 ,
408+ IncludeXcode : true ,
409+ IncludeAndroid : true ,
410+ IncludeNode : true ,
411+ }
412+
413+ results , err := s .ScanAll (opts )
414+ if err != nil {
415+ return rescanItemsMsg {err : err }
416+ }
417+
418+ // Sort by size
419+ for i := 0 ; i < len (results )- 1 ; i ++ {
420+ for j := i + 1 ; j < len (results ); j ++ {
421+ if results [j ].Size > results [i ].Size {
422+ results [i ], results [j ] = results [j ], results [i ]
423+ }
424+ }
425+ }
426+
427+ return rescanItemsMsg {items : results }
428+ }
429+ }
430+
371431// enterTreeMode transitions from flat list to tree view
372432func (m Model ) enterTreeMode () tea.Cmd {
373433 return func () tea.Msg {
@@ -409,9 +469,17 @@ func (m *Model) goBackInTree() {
409469 return
410470 }
411471
472+ // Pop node and cursor from stacks
412473 m .currentNode = m .nodeStack [len (m .nodeStack )- 1 ]
413474 m .nodeStack = m .nodeStack [:len (m .nodeStack )- 1 ]
414- m .cursor = 0
475+
476+ // Restore cursor position
477+ if len (m .cursorStack ) > 0 {
478+ m .cursor = m .cursorStack [len (m .cursorStack )- 1 ]
479+ m .cursorStack = m .cursorStack [:len (m .cursorStack )- 1 ]
480+ } else {
481+ m .cursor = 0
482+ }
415483}
416484
417485// drillDownInTree navigates into child node
@@ -436,9 +504,13 @@ func (m *Model) drillDownInTree() tea.Cmd {
436504
437505 if selectedNode .NeedsScanning () {
438506 m .scanning = true
507+ // Save cursor position before scanning
508+ m .cursorStack = append (m .cursorStack , m .cursor )
439509 return m .scanNode (selectedNode )
440510 }
441511
512+ // Save cursor position before navigating
513+ m .cursorStack = append (m .cursorStack , m .cursor )
442514 m .nodeStack = append (m .nodeStack , m .currentNode )
443515 m .currentNode = selectedNode
444516 m .cursor = 0
@@ -759,7 +831,7 @@ func (m Model) renderSelection(b *strings.Builder) string {
759831func (m Model ) renderResults (b * strings.Builder ) string {
760832 if m .err != nil {
761833 b .WriteString (errorStyle .Render (fmt .Sprintf ("Error: %v" , m .err )))
762- b .WriteString ("\n \n Press any key to exit ." )
834+ b .WriteString ("\n \n Press any key to rescan, q to quit ." )
763835 return b .String ()
764836 }
765837
@@ -786,7 +858,7 @@ func (m Model) renderResults(b *strings.Builder) string {
786858 summary += fmt .Sprintf (" (%s freed)" , ui .FormatSize (freedSize ))
787859 }
788860 b .WriteString (successStyle .Render (summary ))
789- b .WriteString ("\n \n Press any key to exit ." )
861+ b .WriteString ("\n \n Press any key to rescan, q to quit ." )
790862
791863 return b .String ()
792864}
0 commit comments