From 80f43fe39c59b0b8f2feda1610a0b58c21f04981 Mon Sep 17 00:00:00 2001 From: Gokcehan Date: Sun, 28 Jan 2018 20:13:28 +0300 Subject: [PATCH] preview files asynchronously Mentioned in #5 and #92. --- app.go | 9 +++++ ui.go | 125 +++++++++++++++++++++++++++++++++------------------------ 2 files changed, 82 insertions(+), 52 deletions(-) diff --git a/app.go b/app.go index 13bd1f6..1762470 100644 --- a/app.go +++ b/app.go @@ -106,6 +106,15 @@ func (app *app) loop() { } } + app.ui.draw(app.nav) + case p := <-app.ui.prevChan: + curr, err := app.nav.currFile() + if err == nil { + if p.path == curr.path { + app.ui.regPrev = p.lines + } + } + app.ui.draw(app.nav) case e := <-clientChan: for i := 0; i < e.count; i++ { diff --git a/ui.go b/ui.go index 9600e0c..fd7f3ce 100644 --- a/ui.go +++ b/ui.go @@ -381,6 +381,7 @@ type ui struct { msg string regPrev []string dirPrev *dir + prevChan chan preview keyChan chan string evChan chan termbox.Event menuBuf *bytes.Buffer @@ -440,12 +441,13 @@ func newUI() *ui { }() return &ui{ - wins: getWins(), - pwdWin: newWin(wtot, 1, 0, 0), - msgWin: newWin(wtot, 1, 0, htot-1), - menuWin: newWin(wtot, 1, 0, htot-2), - keyChan: make(chan string, 1000), - evChan: evChan, + wins: getWins(), + pwdWin: newWin(wtot, 1, 0, 0), + msgWin: newWin(wtot, 1, 0, htot-1), + menuWin: newWin(wtot, 1, 0, htot-2), + prevChan: make(chan preview), + keyChan: make(chan string, 1000), + evChan: evChan, } } @@ -473,6 +475,68 @@ func (ui *ui) printf(format string, a ...interface{}) { ui.print(fmt.Sprintf(format, a...)) } +type preview struct { + path string + lines []string +} + +func (ui *ui) preview(nav *nav) { + curr, err := nav.currFile() + if err != nil { + return + } + + var reader io.Reader + + if len(gOpts.previewer) != 0 { + cmd := exec.Command(gOpts.previewer, curr.path, strconv.Itoa(nav.height)) + + out, err := cmd.StdoutPipe() + if err != nil { + ui.printf("previewing file: %s", err) + } + + if err := cmd.Start(); err != nil { + ui.printf("previewing file: %s", err) + } + + defer cmd.Wait() + defer out.Close() + reader = out + } else { + f, err := os.Open(curr.path) + if err != nil { + ui.printf("opening file: %s", err) + } + + defer f.Close() + reader = f + } + + var prev preview + + prev.path = curr.path + + buf := bufio.NewScanner(reader) + + for i := 0; i < nav.height && buf.Scan(); i++ { + for _, r := range buf.Text() { + if r == 0 { + prev.lines = []string{"\033[1mbinary\033[0m"} + ui.prevChan <- prev + return + } + } + prev.lines = append(prev.lines, buf.Text()) + } + + if buf.Err() != nil { + ui.printf("loading file: %s", buf.Err()) + } + + ui.prevChan <- prev +} + func (ui *ui) loadFile(nav *nav) { curr, err := nav.currFile() if err != nil { @@ -484,53 +548,10 @@ func (ui *ui) loadFile(nav *nav) { } if curr.IsDir() { - dir := nav.load(curr.path) - ui.dirPrev = dir + ui.dirPrev = nav.load(curr.path) } else if curr.Mode().IsRegular() { - var reader io.Reader - - if len(gOpts.previewer) != 0 { - cmd := exec.Command(gOpts.previewer, curr.path, strconv.Itoa(nav.height)) - - out, err := cmd.StdoutPipe() - if err != nil { - ui.printf("previewing file: %s", err) - } - - if err := cmd.Start(); err != nil { - ui.printf("previewing file: %s", err) - } - - defer cmd.Wait() - defer out.Close() - reader = out - } else { - f, err := os.Open(curr.path) - if err != nil { - ui.printf("opening file: %s", err) - } - - defer f.Close() - reader = f - } - - ui.regPrev = nil - - buf := bufio.NewScanner(reader) - - for i := 0; i < nav.height && buf.Scan(); i++ { - for _, r := range buf.Text() { - if r == 0 { - ui.regPrev = []string{"\033[1mbinary\033[0m"} - return - } - } - ui.regPrev = append(ui.regPrev, buf.Text()) - } - - if buf.Err() != nil { - ui.printf("loading file: %s", buf.Err()) - } + ui.regPrev = []string{"\033[1mloading...\033[0m"} + go ui.preview(nav) } }