@@ -64,6 +64,10 @@ def __init__(self):
6464 self .is_fetching_data = False
6565 self .current_task_thread : Optional [threading .Thread ] = None
6666
67+ # Sorting state for analyze tab
68+ self .sort_column = None
69+ self .sort_reverse = False
70+
6771 # Setup GUI
6872 self .setup_styles ()
6973 self .create_widgets ()
@@ -303,14 +307,14 @@ def create_scan_tab(self):
303307 columns = ('name' , 'language' , 'stars' , 'forks' , 'size' , 'updated' )
304308 self .repo_tree = ttk .Treeview (repos_frame , columns = columns , show = 'tree headings' , height = 15 )
305309
306- # Define column headings
310+ # Define column headings with sort commands
307311 self .repo_tree .heading ('#0' , text = 'Repository' )
308- self .repo_tree .heading ('name' , text = 'Name' )
309- self .repo_tree .heading ('language' , text = 'Language' )
310- self .repo_tree .heading ('stars' , text = 'Stars' )
311- self .repo_tree .heading ('forks' , text = 'Forks' )
312- self .repo_tree .heading ('size' , text = 'Size (KB)' )
313- self .repo_tree .heading ('updated' , text = 'Updated' )
312+ self .repo_tree .heading ('name' , text = 'Name ↕' , command = lambda : self . sort_repositories ( 'name' ) )
313+ self .repo_tree .heading ('language' , text = 'Language ↕' , command = lambda : self . sort_repositories ( 'language' ) )
314+ self .repo_tree .heading ('stars' , text = 'Stars ↕' , command = lambda : self . sort_repositories ( 'stars' ) )
315+ self .repo_tree .heading ('forks' , text = 'Forks ↕' , command = lambda : self . sort_repositories ( 'forks' ) )
316+ self .repo_tree .heading ('size' , text = 'Size (KB) ↕' , command = lambda : self . sort_repositories ( 'size' ) )
317+ self .repo_tree .heading ('updated' , text = 'Updated ↕' , command = lambda : self . sort_repositories ( 'updated' ) )
314318
315319 # Column widths
316320 self .repo_tree .column ('#0' , width = 50 )
@@ -343,6 +347,70 @@ def create_scan_tab(self):
343347 # Bind tree selection
344348 self .repo_tree .bind ('<<TreeviewSelect>>' , self .on_repo_select )
345349
350+ def sort_repositories (self , column ):
351+ """Sort repositories by the specified column."""
352+ if not self .current_user_data or not self .current_user_data .repositories :
353+ return
354+
355+ # Toggle sort direction if same column, otherwise start with ascending
356+ if self .sort_column == column :
357+ self .sort_reverse = not self .sort_reverse
358+ else :
359+ self .sort_column = column
360+ self .sort_reverse = False
361+
362+ # Update column headers to show sort direction
363+ self ._update_sort_headers ()
364+
365+ # Sort repositories
366+ repos = self .current_user_data .repositories .copy ()
367+
368+ if column == 'name' :
369+ repos .sort (key = lambda r : r .name .lower (), reverse = self .sort_reverse )
370+ elif column == 'language' :
371+ repos .sort (key = lambda r : (r .language or '' ).lower (), reverse = self .sort_reverse )
372+ elif column == 'stars' :
373+ repos .sort (key = lambda r : r .stars or 0 , reverse = self .sort_reverse )
374+ elif column == 'forks' :
375+ repos .sort (key = lambda r : r .forks or 0 , reverse = self .sort_reverse )
376+ elif column == 'size' :
377+ repos .sort (key = lambda r : r .size or 0 , reverse = self .sort_reverse )
378+ elif column == 'updated' :
379+ repos .sort (key = lambda r : r .updated_at or '' , reverse = self .sort_reverse )
380+
381+ # Clear and repopulate tree with sorted data
382+ for item in self .repo_tree .get_children ():
383+ self .repo_tree .delete (item )
384+
385+ for i , repo in enumerate (repos ):
386+ updated_date = repo .updated_at [:10 ] if repo .updated_at else 'Unknown'
387+ self .repo_tree .insert ('' , 'end' , iid = str (i ), text = str (i + 1 ),
388+ values = (repo .name , repo .language , repo .stars ,
389+ repo .forks , repo .size , updated_date ))
390+
391+ # Store sorted repositories for selection handling
392+ self .current_user_data .repositories = repos
393+
394+ def _update_sort_headers (self ):
395+ """Update column headers to show current sort direction."""
396+ # Base headers without sort indicators
397+ headers = {
398+ 'name' : 'Name' ,
399+ 'language' : 'Language' ,
400+ 'stars' : 'Stars' ,
401+ 'forks' : 'Forks' ,
402+ 'size' : 'Size (KB)' ,
403+ 'updated' : 'Updated'
404+ }
405+
406+ # Update each header
407+ for col , base_text in headers .items ():
408+ if col == self .sort_column :
409+ arrow = ' ↓' if self .sort_reverse else ' ↑'
410+ self .repo_tree .heading (col , text = base_text + arrow )
411+ else :
412+ self .repo_tree .heading (col , text = base_text + ' ↕' )
413+
346414 def create_readme_tab (self ):
347415 """Create the README generation tab."""
348416 readme_frame = ttk .Frame (self .notebook )
@@ -1072,8 +1140,28 @@ def _update_scan_tab(self):
10721140 for item in self .repo_tree .get_children ():
10731141 self .repo_tree .delete (item )
10741142
1143+ # Apply current sort if one exists
1144+ repos = user_data .repositories .copy ()
1145+ if self .sort_column :
1146+ if self .sort_column == 'name' :
1147+ repos .sort (key = lambda r : r .name .lower (), reverse = self .sort_reverse )
1148+ elif self .sort_column == 'language' :
1149+ repos .sort (key = lambda r : (r .language or '' ).lower (), reverse = self .sort_reverse )
1150+ elif self .sort_column == 'stars' :
1151+ repos .sort (key = lambda r : r .stars or 0 , reverse = self .sort_reverse )
1152+ elif self .sort_column == 'forks' :
1153+ repos .sort (key = lambda r : r .forks or 0 , reverse = self .sort_reverse )
1154+ elif self .sort_column == 'size' :
1155+ repos .sort (key = lambda r : r .size or 0 , reverse = self .sort_reverse )
1156+ elif self .sort_column == 'updated' :
1157+ repos .sort (key = lambda r : r .updated_at or '' , reverse = self .sort_reverse )
1158+ # Update the original data with sorted order
1159+ user_data .repositories = repos
1160+ # Update headers to show sort direction
1161+ self ._update_sort_headers ()
1162+
10751163 # Populate repository tree
1076- for i , repo in enumerate (user_data . repositories ):
1164+ for i , repo in enumerate (repos ):
10771165 updated_date = repo .updated_at [:10 ] if repo .updated_at else 'Unknown'
10781166
10791167 self .repo_tree .insert ('' , 'end' , iid = str (i ), text = str (i + 1 ),
0 commit comments