add natural sorting as a sortby option

Closes #21.
This commit is contained in:
Gokcehan 2016-12-03 00:45:04 +03:00
parent 225bd5b49c
commit 721a20269e
5 changed files with 33 additions and 33 deletions

2
doc.go
View File

@ -54,7 +54,7 @@ The following options can be used to customize the behavior of lf.
previewer string (default "") (not filtered if empty) previewer string (default "") (not filtered if empty)
shell string (default "$SHELL") shell string (default "$SHELL")
showinfo string (default "none") showinfo string (default "none")
sortby string (default "name") sortby string (default "natural")
timefmt string (default "Mon Jan _2 15:04:05 2006") timefmt string (default "Mon Jan _2 15:04:05 2006")
ratios string (default "1:2:3") ratios string (default "1:2:3")

View File

@ -58,7 +58,7 @@ The following options can be used to customize the behavior of lf.
previewer string (default "") (not filtered if empty) previewer string (default "") (not filtered if empty)
shell string (default "$SHELL") shell string (default "$SHELL")
showinfo string (default "none") showinfo string (default "none")
sortby string (default "name") sortby string (default "natural")
timefmt string (default "Mon Jan _2 15:04:05 2006") timefmt string (default "Mon Jan _2 15:04:05 2006")
ratios string (default "1:2:3") ratios string (default "1:2:3")

View File

@ -84,8 +84,8 @@ func (e *SetExpr) eval(app *App, args []string) {
} }
gOpts.showinfo = e.val gOpts.showinfo = e.val
case "sortby": case "sortby":
if e.val != "name" && e.val != "size" && e.val != "time" { if e.val != "natural" && e.val != "name" && e.val != "size" && e.val != "time" {
msg := "sortby should either be 'name', 'size' or 'time'" msg := "sortby should either be 'natural', 'name', 'size' or 'time'"
app.ui.message = msg app.ui.message = msg
log.Print(msg) log.Print(msg)
return return

56
nav.go
View File

@ -46,6 +46,34 @@ func getFilesSorted(path string) []*File {
} }
switch gOpts.sortby { switch gOpts.sortby {
case "natural":
sortFilesStable(fi, func(i, j int) bool {
nums1, rest1, numFirst1 := extractNums(fi[i].Name())
nums2, rest2, numFirst2 := extractNums(fi[j].Name())
if numFirst1 != numFirst2 {
return strings.ToLower(fi[i].Name()) < strings.ToLower(fi[j].Name())
}
if numFirst1 {
if nums1[0] != nums2[0] {
return nums1[0] < nums2[0]
}
nums1 = nums1[1:]
nums2 = nums2[1:]
}
for k := 0; k < len(nums1) && k < len(nums2); k++ {
if rest1[k] != rest2[k] {
return strings.ToLower(fi[i].Name()) < strings.ToLower(fi[j].Name())
}
if nums1[k] != nums2[k] {
return nums1[k] < nums2[k]
}
}
return strings.ToLower(fi[i].Name()) < strings.ToLower(fi[j].Name())
})
case "name": case "name":
sortFilesStable(fi, func(i, j int) bool { sortFilesStable(fi, func(i, j int) bool {
return strings.ToLower(fi[i].Name()) < strings.ToLower(fi[j].Name()) return strings.ToLower(fi[i].Name()) < strings.ToLower(fi[j].Name())
@ -70,34 +98,6 @@ func getFilesSorted(path string) []*File {
return fi[i].IsDir() return fi[i].IsDir()
}) })
} }
//TODO this should be optional
sortFilesStable(fi, func(i, j int) bool {
nums1, rest1, numFirst1 := extractNums(fi[i].Name())
nums2, rest2, numFirst2 := extractNums(fi[j].Name())
if numFirst1 != numFirst2 {
return i < j
}
if numFirst1 {
if nums1[0] != nums2[0] {
return nums1[0] < nums2[0]
}
nums1 = nums1[1:]
nums2 = nums2[1:]
}
for k := 0; k < len(nums1) && k < len(nums2); k++ {
if rest1[k] != rest2[k] {
return i < j
}
if nums1[k] != nums2[k] {
return nums1[k] < nums2[k]
}
}
return i < j
})
return fi return fi
} }

View File

@ -27,7 +27,7 @@ func init() {
gOpts.tabstop = 8 gOpts.tabstop = 8
gOpts.shell = envShell gOpts.shell = envShell
gOpts.showinfo = "none" gOpts.showinfo = "none"
gOpts.sortby = "name" gOpts.sortby = "natural"
gOpts.timefmt = time.ANSIC gOpts.timefmt = time.ANSIC
gOpts.ratios = []int{1, 2, 3} gOpts.ratios = []int{1, 2, 3}