Version 5 of NeXT-style file browser

Updated 2005-12-04 12:55:48

Kevin Walzer I was trying to create a variation of the standard Tk file browser handled with a listbox, which would emulate the NeXT (now Mac OS X) style of file browsing: navigating horizontally across a file system. I hit a wall and asked for help on comp.lang.tcl. Kaitzschu came to the rescue and did more than add some guidance to my rough initial code; he radically transformed it. Thanks to Kaitzchu for the help.

The result is below, licensed under the standard Tcl BSD-style license. Embellishments and improvements are more than welcome!


 package require Tcl 8.5
 package require Tk

 namespace eval ::nextlist {namespace export nextlist}

 proc ::nextlist::nextlist {wid dir} {
   if {![file isdirectory $dir]} {error "non-directory $dir"}
   nlist [frame $wid] $dir 0
   return $wid
 }

 proc ::nextlist::nlist {base dir cnt} {
   if {![file isdirectory $dir]} {return; # here file-clicketyclicks}
   # check for [file readable]? nah
   # dear santa, let children be in order
   destroy {expand}[lrange [winfo children $base] [expr {2*$cnt}] end]
   # exportselection 0 looks good, but selection gets easily out-of-sync
   set l [listbox "[set b "$base.nl$cnt"]-list" -yscrollcommand [list "$b-scroll" set] -height 20 -exportselection 0]
   pack $l [scrollbar "$b-scroll" -command [list $l yview]] -side left -expand 1 -fill y -anchor w
   # I like my directories first and everything dictionarized, love {expand}
   # could be done with intermediate list and $l insert end {expand}$lst
   foreach item [list {expand}[lsort -dictionary [glob -directory $dir -nocomplain -types {d} -- *]] \
                      {expand}[lsort -dictionary [glob -directory $dir -nocomplain -types {f} -- *]]] \
           {$l insert end "[file tail $item][expr {[file isdirectory $item] ? {/} : {}}]"}
   bind $l <Double-1> [list ::nextlist::navigare $dir [incr cnt] %W %x %y]
 }

 proc ::nextlist::navigare {d c w x y} {
 if {[set subdir [$w get [$w index "@$x,$y"]]] eq {}} {return}
 nlist [winfo parent $w] [file join $d $subdir] $c
 }

 # To test this code, try the following command: 
   pack [::nextlist::nextlist .nl ~/Desktop]

You will see listboxes added and deleted horizontally as you navigate through the file hierarchy.


With all due respect to the author's love of {expand}, the second use of it is rather pointless:

   [list {expand}[lsort ...] {expand}[lsort ...]]

is equivalent to, but not as clear as

   [concat [lsort ...] [lsort ...]]

Kaitzschu Guilty as charged. Use concat, it is also very, very fast once lists get bigger. I wasn't familiar with this command, because it's manual page is confounding wrt use with lists (trimming and spaces, sounds too much like strings).


Category File