From 2b4c0f913b4e3402629650096ec363dc505d108a Mon Sep 17 00:00:00 2001 From: Gokcehan Date: Thu, 11 Jan 2018 19:25:48 +0300 Subject: [PATCH] load directories asynchronously Mentioned in #92. --- app.go | 22 ++++++++++++++++++++++ nav.go | 43 ++++++++++++++++++++++++++++++++----------- ui.go | 6 ++++++ 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/app.go b/app.go index e38b483..b99df64 100644 --- a/app.go +++ b/app.go @@ -80,6 +80,28 @@ func (app *app) loop() { } return + case d := <-app.nav.dirChan: + app.nav.dirCache[d.path] = d + + for i := range app.nav.dirs { + if app.nav.dirs[i].path == d.path { + app.nav.dirs[i] = d + } + } + + app.nav.position() + + curr, err := app.nav.currFile() + if err == nil { + if d.path == app.nav.currDir().path { + app.nav.load(curr.path) + } + if d.path == curr.path { + app.ui.dirPrev = d + } + } + + app.ui.draw(app.nav) case e := <-clientChan: for i := 0; i < e.count; i++ { e.expr.eval(app, nil) diff --git a/nav.go b/nav.go index 76e2ba3..073b1ff 100644 --- a/nav.go +++ b/nav.go @@ -85,11 +85,12 @@ func readdir(path string) ([]*file, error) { } type dir struct { - ind int // index of current entry in fi - pos int // position of current entry in ui - path string // full path of directory - fi []*file // displayed files in directory including or excluding hidden ones - all []*file // all files in directory including hidden ones (same array as fi) + loading bool // directory is loading from disk + ind int // index of current entry in fi + pos int // position of current entry in ui + path string // full path of directory + fi []*file // displayed files in directory including or excluding hidden ones + all []*file // all files in directory including hidden ones (same array as fi) } func newDir(path string) *dir { @@ -205,6 +206,7 @@ func (dir *dir) find(name string, height int) { type nav struct { dirs []*dir dirCache map[string]*dir + dirChan chan *dir saves map[string]bool marks map[string]int markInd int @@ -220,6 +222,7 @@ func newNav(height int) *nav { nav := &nav{ dirCache: make(map[string]*dir), + dirChan: make(chan *dir), marks: make(map[string]int), saves: make(map[string]bool), markInd: 0, @@ -231,6 +234,19 @@ func newNav(height int) *nav { return nav } +func (nav *nav) position() { + curr, err := nav.currFile() + if err == nil { + nav.dirs[len(nav.dirs)-1].find(filepath.Base(curr.path), nav.height) + } + + path := nav.currDir().path + for i := len(nav.dirs) - 2; i >= 0; i-- { + nav.dirs[i].find(filepath.Base(path), nav.height) + path = filepath.Dir(path) + } +} + func (nav *nav) getDirs(wd string) { var dirs []*dir @@ -276,14 +292,19 @@ func (nav *nav) renew(height int) { } func (nav *nav) load(path string) *dir { - dir, ok := nav.dirCache[path] + d, ok := nav.dirCache[path] if !ok { - dir = newDir(path) - dir.sort() - dir.ind, dir.pos = 0, 0 - nav.dirCache[path] = dir + go func() { + d := newDir(path) + d.sort() + d.ind, d.pos = 0, 0 + nav.dirChan <- d + }() + d := &dir{loading: true, path: path} + nav.dirCache[path] = d + return d } - return dir + return d } func (nav *nav) sort() { diff --git a/ui.go b/ui.go index 08bafaa..d440dac 100644 --- a/ui.go +++ b/ui.go @@ -246,6 +246,12 @@ func (win *win) printDir(dir *dir, marks map[string]int, saves map[string]bool) fg, bg := termbox.ColorDefault, termbox.ColorDefault + if dir.loading { + fg = termbox.AttrBold + win.print(2, 0, fg, bg, "loading...") + return + } + if len(dir.fi) == 0 { fg = termbox.AttrBold win.print(2, 0, fg, bg, "empty")