load directories asynchronously

Mentioned in #92.
This commit is contained in:
Gokcehan 2018-01-11 19:25:48 +03:00
parent ec8e75ba30
commit 2b4c0f913b
3 changed files with 60 additions and 11 deletions

22
app.go
View File

@ -80,6 +80,28 @@ func (app *app) loop() {
} }
return 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: case e := <-clientChan:
for i := 0; i < e.count; i++ { for i := 0; i < e.count; i++ {
e.expr.eval(app, nil) e.expr.eval(app, nil)

33
nav.go
View File

@ -85,6 +85,7 @@ func readdir(path string) ([]*file, error) {
} }
type dir struct { type dir struct {
loading bool // directory is loading from disk
ind int // index of current entry in fi ind int // index of current entry in fi
pos int // position of current entry in ui pos int // position of current entry in ui
path string // full path of directory path string // full path of directory
@ -205,6 +206,7 @@ func (dir *dir) find(name string, height int) {
type nav struct { type nav struct {
dirs []*dir dirs []*dir
dirCache map[string]*dir dirCache map[string]*dir
dirChan chan *dir
saves map[string]bool saves map[string]bool
marks map[string]int marks map[string]int
markInd int markInd int
@ -220,6 +222,7 @@ func newNav(height int) *nav {
nav := &nav{ nav := &nav{
dirCache: make(map[string]*dir), dirCache: make(map[string]*dir),
dirChan: make(chan *dir),
marks: make(map[string]int), marks: make(map[string]int),
saves: make(map[string]bool), saves: make(map[string]bool),
markInd: 0, markInd: 0,
@ -231,6 +234,19 @@ func newNav(height int) *nav {
return 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) { func (nav *nav) getDirs(wd string) {
var dirs []*dir var dirs []*dir
@ -276,14 +292,19 @@ func (nav *nav) renew(height int) {
} }
func (nav *nav) load(path string) *dir { func (nav *nav) load(path string) *dir {
dir, ok := nav.dirCache[path] d, ok := nav.dirCache[path]
if !ok { if !ok {
dir = newDir(path) go func() {
dir.sort() d := newDir(path)
dir.ind, dir.pos = 0, 0 d.sort()
nav.dirCache[path] = dir 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() { func (nav *nav) sort() {

6
ui.go
View File

@ -246,6 +246,12 @@ func (win *win) printDir(dir *dir, marks map[string]int, saves map[string]bool)
fg, bg := termbox.ColorDefault, termbox.ColorDefault 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 { if len(dir.fi) == 0 {
fg = termbox.AttrBold fg = termbox.AttrBold
win.print(2, 0, fg, bg, "empty") win.print(2, 0, fg, bg, "empty")