#!/bin/sh # Tcl ignores the next line \ exec wish $0 "${1+$@}" set trimcomps 1 set showlim 1 set f [open "|du" "r"] text .t -width 45 -height 30 -cursor top_left_arrow \ -yscrollcommand ".s set" pack .t -side left -fill both -expand y scrollbar .s -command ".t yview" pack .s -side right -fill y proc bclick path { global showsub .t conf -state normal if {$showsub($path)} { hide_children $path } else { show_children $path } .t conf -state disabled } proc ancestors path { set ret {} set elts [split $path /] while {[llength $elts] > 1} { lappend ret [join $elts /] set elts [lrange $elts 0 [expr [llength $elts] - 2]] } return $ret } proc show_line {ppath p mk size} { global chillun visible showsub levspace lineno nextline set path $ppath/$p set visible($path) 1 foreach a [ancestors $ppath] { .t mark gravity em$lineno($a) right } if {![info exists lineno($path)]} { set lineno($path) [incr nextline] } set l $lineno($path) if {[info exists chillun($path)]} { if {$showsub($path)} { set tc + set rel sunken } else { set tc - set rel raised } .t insert $mk "\n$size\t$levspace($path)" {} \ $tc tag$l " $p" {} .t tag conf tag$l -border 1 -relief $rel .t tag bind tag$l "bclick $path" .t mark set sm$l "$mk linestart" .t mark set em$l $mk .t mark set cm$l $mk .t mark gravity cm$l left if {$showsub($path)} { show_children $path } } else { .t insert $mk "\n$size\t$levspace($path) $p" .t mark set sm$l "$mk linestart" .t mark set em$l $mk } .t see em$l .t mark gravity sm$l left .t mark gravity em$l left foreach a [ancestors $path] { .t mark gravity em$lineno($a) left } } proc show_children {path} { global chillun visible showsub lineno if {![info exists chillun($path)] || !$visible($path)} return set l $lineno($path) if {!$showsub($path)} { .t insert tag$l.first + tag$l .t delete "tag$l.last - 1c" .t tag conf tag$l -relief sunken set showsub($path) 1 } foreach cl $chillun($path) { set size [lindex $cl 0] set p [lindex $cl 1] show_line $path $p em$l $size } } proc hide_children {path} { global visible chillun showsub lineno set l $lineno($path) .t delete cm$l em$l if {$showsub($path)} { .t insert tag$l.first - tag$l .t delete "tag$l.last -1c" .t tag conf tag$l -relief raised } .t see em$l update if {$showsub($path)} { unvis_children $path set showsub($path) 0 } } proc unvis_children path { global visible showsub chillun foreach l $chillun($path) { set size [lindex $l 0] set p [lindex $l 1] set pathp $path/$p set visible($pathp) 0 if {$showsub($pathp)} { unvis_children $pathp } } } .t insert 1.0 "\t" {} + tag0 " Total" {} .t tag conf tag0 -border 1 -relief sunken .t tag bind tag0 "bclick {}" set chillun() {} set showsub() [expr $showlim > 0] set visible() 1 set levspace() {} set lineno() 0 set nextline 0 .t mark set sm0 1.0 .t mark gravity sm0 left .t mark set cm0 1.end .t mark gravity cm0 left .t mark set em0 1.end .t mark gravity em0 right while {[gets $f line] && $line != {}} { set size [lindex $line 0] set comps [lrange [split [lindex $line 1] /] $trimcomps end] set nc [llength $comps] set ppath {} set path {} set p {} set ls {} set i 0 if {$nc == 0} { .t insert sm0 $size continue } set pcomps [lrange $comps 0 [expr $nc-2]] foreach p $pcomps { set ppath $path incr i append ls " " append path /$p if {![info exists chillun($path)]} { set showsub($path) [expr $i < $showlim] set chillun($path) {} set levspace($path) $ls } if {$showsub($ppath)} { if {![info exists visible($path)]} { show_line $ppath $p em$lineno($ppath) {} } } } set p [lindex $comps end] set ppath $path append path /$p if {![info exists showsub($path)]} { set showsub($path) [expr $nc < $showlim] } append ls " " set levspace($path) $ls if [info exists lineno($ppath)] { set mk em$lineno($ppath) } set i 0 foreach sib $chillun($ppath) { if {$size > [lindex $sib 0]} { set sibpath $ppath/[lindex $sib 1] if {[info exists lineno($sibpath)]} { set mk "sm$lineno($sibpath) - 1c" } set chillun($ppath) [linsert $chillun($ppath) $i [list $size $p]] set i -999 break } incr i } if {$i != -999} { lappend chillun($ppath) [list $size $p] } if {$showsub($ppath)} { if {[info exists visible($path)] && $visible($path)} { # delete the old line and insert it in the new place set l $lineno($path) .t delete "sm$l -1c" em$l } show_line $ppath $p $mk $size } .t conf -state disabled update .t conf -state normal } close $f .t conf -state disabled