From accb61dad1f2b4c253c083f1a4a31ff3e1ffabbc Mon Sep 17 00:00:00 2001 From: Gokcehan Date: Sat, 18 Nov 2017 22:06:30 +0300 Subject: [PATCH] eliminate redundant renews for sort changes Mentioned in #92. --- eval.go | 14 ++++++------ nav.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/eval.go b/eval.go index 846c452..dcf2afc 100644 --- a/eval.go +++ b/eval.go @@ -19,13 +19,13 @@ func (e *setExpr) eval(app *app, args []string) { gOpts.dircounts = !gOpts.dircounts case "dirfirst": gOpts.dirfirst = true - app.nav.renew(app.nav.height) + app.nav.sort() case "nodirfirst": gOpts.dirfirst = false - app.nav.renew(app.nav.height) + app.nav.sort() case "dirfirst!": gOpts.dirfirst = !gOpts.dirfirst - app.nav.renew(app.nav.height) + app.nav.sort() case "globsearch": gOpts.globsearch = true case "noglobsearch": @@ -55,13 +55,13 @@ func (e *setExpr) eval(app *app, args []string) { gOpts.preview = !gOpts.preview case "reverse": gOpts.reverse = true - app.nav.renew(app.nav.height) + app.nav.sort() case "noreverse": gOpts.reverse = false - app.nav.renew(app.nav.height) + app.nav.sort() case "reverse!": gOpts.reverse = !gOpts.reverse - app.nav.renew(app.nav.height) + app.nav.sort() case "smartcase": gOpts.smartcase = true case "nosmartcase": @@ -124,7 +124,7 @@ func (e *setExpr) eval(app *app, args []string) { return } gOpts.sortby = e.val - app.nav.renew(app.nav.height) + app.nav.sort() case "timefmt": gOpts.timefmt = e.val case "ratios": diff --git a/nav.go b/nav.go index 87a3958..335c98c 100644 --- a/nav.go +++ b/nav.go @@ -140,10 +140,19 @@ type dir struct { } func newDir(path string) *dir { - return &dir{ - path: path, - fi: getFilesSorted(path), + fi, err := readdir(path) + if err != nil { + log.Printf("reading directory: %s", err) } + + dir := &dir{ + path: path, + fi: fi, + } + + dir.sort() + + return dir } func (dir *dir) renew(height int) { @@ -152,11 +161,56 @@ func (dir *dir) renew(height int) { name = dir.fi[dir.ind].Name() } - dir.fi = getFilesSorted(dir.path) + fi, err := readdir(dir.path) + if err != nil { + log.Printf("reading directory: %s", err) + } + + dir.fi = fi + + dir.sort() dir.load(dir.ind, dir.pos, height, name) } +func (dir *dir) sort() { + switch gOpts.sortby { + case "natural": + sortFilesStable(dir.fi, func(i, j int) bool { + return naturalLess(strings.ToLower(dir.fi[i].Name()), strings.ToLower(dir.fi[j].Name())) + }) + case "name": + sortFilesStable(dir.fi, func(i, j int) bool { + return strings.ToLower(dir.fi[i].Name()) < strings.ToLower(dir.fi[j].Name()) + }) + case "size": + sortFilesStable(dir.fi, func(i, j int) bool { + return dir.fi[i].Size() < dir.fi[j].Size() + }) + case "time": + sortFilesStable(dir.fi, func(i, j int) bool { + return dir.fi[i].ModTime().Before(dir.fi[j].ModTime()) + }) + default: + log.Printf("unknown sorting type: %s", gOpts.sortby) + } + + if gOpts.reverse { + for i, j := 0, len(dir.fi)-1; i < j; i, j = i+1, j-1 { + dir.fi[i], dir.fi[j] = dir.fi[j], dir.fi[i] + } + } + + if gOpts.dirfirst { + sortFilesStable(dir.fi, func(i, j int) bool { + if dir.fi[i].IsDir() == dir.fi[j].IsDir() { + return i < j + } + return dir.fi[i].IsDir() + }) + } +} + func (dir *dir) load(ind, pos, height int, name string) { if len(dir.fi) == 0 { dir.ind, dir.pos = 0, 0 @@ -252,6 +306,12 @@ func (nav *nav) renew(height int) { } } +func (nav *nav) sort() { + for _, d := range nav.dirs { + d.sort() + } +} + func (nav *nav) up(dist int) { dir := nav.currDir()