ncdu: add sort by average size in directory

Add keyboard shortcut 'A' which sort by average size in directory.

If files/folders have same avgSize sort by actual size

Fixes: #4699
This commit is contained in:
Adam Plánský 2020-10-27 14:28:38 +01:00 committed by GitHub
parent 605f2b819a
commit e00bf3d723
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -71,7 +71,7 @@ func helpText() (tr []string) {
" ←,h to return", " ←,h to return",
" c toggle counts", " c toggle counts",
" g toggle graph", " g toggle graph",
" n,s,C sort by name,size,count", " n,s,C,A sort by name,size,count,average size",
" d delete file/directory", " d delete file/directory",
} }
if !clipboard.Unsupported { if !clipboard.Unsupported {
@ -88,27 +88,28 @@ func helpText() (tr []string) {
// UI contains the state of the user interface // UI contains the state of the user interface
type UI struct { type UI struct {
f fs.Fs // fs being displayed f fs.Fs // fs being displayed
fsName string // human name of Fs fsName string // human name of Fs
root *scan.Dir // root directory root *scan.Dir // root directory
d *scan.Dir // current directory being displayed d *scan.Dir // current directory being displayed
path string // path of current directory path string // path of current directory
showBox bool // whether to show a box showBox bool // whether to show a box
boxText []string // text to show in box boxText []string // text to show in box
boxMenu []string // box menu options boxMenu []string // box menu options
boxMenuButton int boxMenuButton int
boxMenuHandler func(fs fs.Fs, path string, option int) (string, error) boxMenuHandler func(fs fs.Fs, path string, option int) (string, error)
entries fs.DirEntries // entries of current directory entries fs.DirEntries // entries of current directory
sortPerm []int // order to display entries in after sorting sortPerm []int // order to display entries in after sorting
invSortPerm []int // inverse order invSortPerm []int // inverse order
dirListHeight int // height of listing dirListHeight int // height of listing
listing bool // whether listing is in progress listing bool // whether listing is in progress
showGraph bool // toggle showing graph showGraph bool // toggle showing graph
showCounts bool // toggle showing counts showCounts bool // toggle showing counts
sortByName int8 // +1 for normal, 0 for off, -1 for reverse sortByName int8 // +1 for normal, 0 for off, -1 for reverse
sortBySize int8 sortBySize int8
sortByCount int8 sortByCount int8
dirPosMap map[string]dirPos // store for directory positions sortByAverageSize int8
dirPosMap map[string]dirPos // store for directory positions
} }
// Where we have got to in the directory listing // Where we have got to in the directory listing
@ -496,9 +497,17 @@ type ncduSort struct {
// Less is part of sort.Interface. // Less is part of sort.Interface.
func (ds *ncduSort) Less(i, j int) bool { func (ds *ncduSort) Less(i, j int) bool {
var iAvgSize, jAvgSize float64
isize, icount, _, _ := ds.d.AttrI(ds.sortPerm[i]) isize, icount, _, _ := ds.d.AttrI(ds.sortPerm[i])
jsize, jcount, _, _ := ds.d.AttrI(ds.sortPerm[j]) jsize, jcount, _, _ := ds.d.AttrI(ds.sortPerm[j])
iname, jname := ds.entries[ds.sortPerm[i]].Remote(), ds.entries[ds.sortPerm[j]].Remote() iname, jname := ds.entries[ds.sortPerm[i]].Remote(), ds.entries[ds.sortPerm[j]].Remote()
if icount > 0 {
iAvgSize = float64(isize / icount)
}
if jcount > 0 {
jAvgSize = float64(jsize / jcount)
}
switch { switch {
case ds.u.sortByName < 0: case ds.u.sortByName < 0:
return iname > jname return iname > jname
@ -520,6 +529,18 @@ func (ds *ncduSort) Less(i, j int) bool {
if icount != jcount { if icount != jcount {
return icount > jcount return icount > jcount
} }
case ds.u.sortByAverageSize < 0:
if iAvgSize != jAvgSize {
return iAvgSize < jAvgSize
}
// if avgSize is equal, sort by size
return isize < jsize
case ds.u.sortByAverageSize > 0:
if iAvgSize != jAvgSize {
return iAvgSize > jAvgSize
}
// if avgSize is equal, sort by size
return isize > jsize
} }
// if everything equal, sort by name // if everything equal, sort by name
return iname < jname return iname < jname
@ -628,6 +649,7 @@ func (u *UI) toggleSort(sortType *int8) {
u.sortBySize = 0 u.sortBySize = 0
u.sortByCount = 0 u.sortByCount = 0
u.sortByName = 0 u.sortByName = 0
u.sortByAverageSize = 0
if old == 0 { if old == 0 {
*sortType = 1 *sortType = 1
} else { } else {
@ -742,6 +764,8 @@ outer:
u.toggleSort(&u.sortBySize) u.toggleSort(&u.sortBySize)
case 'C': case 'C':
u.toggleSort(&u.sortByCount) u.toggleSort(&u.sortByCount)
case 'A':
u.toggleSort(&u.sortByAverageSize)
case 'y': case 'y':
u.copyPath() u.copyPath()
case 'Y': case 'Y':