Sort by file extensions (#230)
- preserve natural ordering of filenames if extensions are the same or are missing - files without extensions rank higher on ascending sort and lower on descending sort
This commit is contained in:
parent
41339a9e5a
commit
9991a40e87
@ -179,6 +179,7 @@ The following additional keybindings are provided by default:
|
|||||||
map st :set sortby time; set info time
|
map st :set sortby time; set info time
|
||||||
map sa :set sortby atime; set info atime
|
map sa :set sortby atime; set info atime
|
||||||
map sc :set sortby ctime; set info ctime
|
map sc :set sortby ctime; set info ctime
|
||||||
|
map se :set sortby ext; set info
|
||||||
map gh cd ~
|
map gh cd ~
|
||||||
|
|
||||||
The following keybindings to applications are provided by default:
|
The following keybindings to applications are provided by default:
|
||||||
|
4
eval.go
4
eval.go
@ -251,8 +251,10 @@ func (e *setExpr) eval(app *app, args []string) {
|
|||||||
gOpts.sortType.method = ctimeSort
|
gOpts.sortType.method = ctimeSort
|
||||||
case "atime":
|
case "atime":
|
||||||
gOpts.sortType.method = atimeSort
|
gOpts.sortType.method = atimeSort
|
||||||
|
case "ext":
|
||||||
|
gOpts.sortType.method = extSort
|
||||||
default:
|
default:
|
||||||
app.ui.echoerr("sortby: value should either be 'natural', 'name', 'size', 'time', 'atime' or 'ctime'")
|
app.ui.echoerr("sortby: value should either be 'natural', 'name', 'size', 'time', 'atime', 'ctime' or 'ext'")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.nav.sort()
|
app.nav.sort()
|
||||||
|
26
nav.go
26
nav.go
@ -32,6 +32,7 @@ type file struct {
|
|||||||
dirCount int
|
dirCount int
|
||||||
accessTime time.Time
|
accessTime time.Time
|
||||||
changeTime time.Time
|
changeTime time.Time
|
||||||
|
ext string
|
||||||
}
|
}
|
||||||
|
|
||||||
func readdir(path string) ([]*file, error) {
|
func readdir(path string) ([]*file, error) {
|
||||||
@ -77,6 +78,10 @@ func readdir(path string) ([]*file, error) {
|
|||||||
ct = lstat.ModTime()
|
ct = lstat.ModTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns an empty string if extension could not be determined
|
||||||
|
// i.e. directories, filenames without extensions
|
||||||
|
ext := filepath.Ext(fpath)
|
||||||
|
|
||||||
files = append(files, &file{
|
files = append(files, &file{
|
||||||
FileInfo: lstat,
|
FileInfo: lstat,
|
||||||
linkState: linkState,
|
linkState: linkState,
|
||||||
@ -84,6 +89,7 @@ func readdir(path string) ([]*file, error) {
|
|||||||
dirCount: -1,
|
dirCount: -1,
|
||||||
accessTime: at,
|
accessTime: at,
|
||||||
changeTime: ct,
|
changeTime: ct,
|
||||||
|
ext: ext,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +155,26 @@ func (dir *dir) sort() {
|
|||||||
sort.SliceStable(dir.files, func(i, j int) bool {
|
sort.SliceStable(dir.files, func(i, j int) bool {
|
||||||
return dir.files[i].changeTime.Before(dir.files[j].changeTime)
|
return dir.files[i].changeTime.Before(dir.files[j].changeTime)
|
||||||
})
|
})
|
||||||
|
case extSort:
|
||||||
|
sort.SliceStable(dir.files, func(i, j int) bool {
|
||||||
|
leftExt := strings.ToLower(dir.files[i].ext)
|
||||||
|
rightExt := strings.ToLower(dir.files[j].ext)
|
||||||
|
|
||||||
|
// if the extension could not be determined (directories, files without)
|
||||||
|
// use a zero byte so that these files can be ranked higher
|
||||||
|
if leftExt == "" {
|
||||||
|
leftExt = "\x00"
|
||||||
|
}
|
||||||
|
if rightExt == "" {
|
||||||
|
rightExt = "\x00"
|
||||||
|
}
|
||||||
|
|
||||||
|
// in order to also have natural sorting with the filenames
|
||||||
|
// combine the name with the ext but have the ext at the front
|
||||||
|
left := leftExt + strings.ToLower(dir.files[i].Name())
|
||||||
|
right := rightExt + strings.ToLower(dir.files[j].Name())
|
||||||
|
return left < right
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if gOpts.sortType.option&reverseSort != 0 {
|
if gOpts.sortType.option&reverseSort != 0 {
|
||||||
|
2
opts.go
2
opts.go
@ -11,6 +11,7 @@ const (
|
|||||||
timeSort
|
timeSort
|
||||||
atimeSort
|
atimeSort
|
||||||
ctimeSort
|
ctimeSort
|
||||||
|
extSort
|
||||||
)
|
)
|
||||||
|
|
||||||
type sortOption byte
|
type sortOption byte
|
||||||
@ -157,6 +158,7 @@ func init() {
|
|||||||
gOpts.keys["st"] = &listExpr{[]expr{&setExpr{"sortby", "time"}, &setExpr{"info", "time"}}}
|
gOpts.keys["st"] = &listExpr{[]expr{&setExpr{"sortby", "time"}, &setExpr{"info", "time"}}}
|
||||||
gOpts.keys["sa"] = &listExpr{[]expr{&setExpr{"sortby", "atime"}, &setExpr{"info", "atime"}}}
|
gOpts.keys["sa"] = &listExpr{[]expr{&setExpr{"sortby", "atime"}, &setExpr{"info", "atime"}}}
|
||||||
gOpts.keys["sc"] = &listExpr{[]expr{&setExpr{"sortby", "ctime"}, &setExpr{"info", "ctime"}}}
|
gOpts.keys["sc"] = &listExpr{[]expr{&setExpr{"sortby", "ctime"}, &setExpr{"info", "ctime"}}}
|
||||||
|
gOpts.keys["se"] = &listExpr{[]expr{&setExpr{"sortby", "ext"}, &setExpr{"info", ""}}}
|
||||||
gOpts.keys["gh"] = &callExpr{"cd", []string{"~"}, 1}
|
gOpts.keys["gh"] = &callExpr{"cd", []string{"~"}, 1}
|
||||||
|
|
||||||
gOpts.cmdkeys = make(map[string]expr)
|
gOpts.cmdkeys = make(map[string]expr)
|
||||||
|
Loading…
Reference in New Issue
Block a user