buffer file and dir previews for drawing

Mentioned in #5.
This commit is contained in:
Gokcehan 2016-09-15 16:16:03 +03:00
parent ceb1f2d15a
commit 6094078185
3 changed files with 96 additions and 74 deletions

View File

@ -38,7 +38,7 @@ func client() {
app.ui.message = msg app.ui.message = msg
log.Printf(msg) log.Printf(msg)
} else { } else {
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
} }
defer rcFile.Close() defer rcFile.Close()

40
eval.go
View File

@ -125,29 +125,29 @@ func (e *CallExpr) eval(app *App, args []string) {
switch e.name { switch e.name {
case "up": case "up":
app.nav.up(1) app.nav.up(1)
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "half-up": case "half-up":
app.nav.up(app.nav.height / 2) app.nav.up(app.nav.height / 2)
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "page-up": case "page-up":
app.nav.up(app.nav.height) app.nav.up(app.nav.height)
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "down": case "down":
app.nav.down(1) app.nav.down(1)
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "half-down": case "half-down":
app.nav.down(app.nav.height / 2) app.nav.down(app.nav.height / 2)
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "page-down": case "page-down":
app.nav.down(app.nav.height) app.nav.down(app.nav.height)
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "updir": case "updir":
if err := app.nav.updir(); err != nil { if err := app.nav.updir(); err != nil {
app.ui.message = err.Error() app.ui.message = err.Error()
log.Print(err) log.Print(err)
return return
} }
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "open": case "open":
dir := app.nav.currDir() dir := app.nav.currDir()
@ -171,7 +171,7 @@ func (e *CallExpr) eval(app *App, args []string) {
log.Print(err) log.Print(err)
return return
} }
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
return return
} }
@ -203,14 +203,13 @@ func (e *CallExpr) eval(app *App, args []string) {
gExitFlag = true gExitFlag = true
case "bot": case "bot":
app.nav.bot() app.nav.bot()
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "top": case "top":
app.nav.top() app.nav.top()
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "read": case "read":
s := app.ui.prompt(app.nav, ":") s := app.ui.prompt(app.nav, ":")
if len(s) == 0 { if len(s) == 0 {
app.ui.echoFileInfo(app.nav)
return return
} }
log.Printf("command: %s", s) log.Printf("command: %s", s)
@ -224,23 +223,38 @@ func (e *CallExpr) eval(app *App, args []string) {
} }
case "read-shell": case "read-shell":
s := app.ui.prompt(app.nav, "$") s := app.ui.prompt(app.nav, "$")
if len(s) == 0 {
return
}
log.Printf("shell: %s", s) log.Printf("shell: %s", s)
app.runShell(s, nil, false, false) app.runShell(s, nil, false, false)
case "read-shell-wait": case "read-shell-wait":
s := app.ui.prompt(app.nav, "!") s := app.ui.prompt(app.nav, "!")
if len(s) == 0 {
return
}
log.Printf("shell-wait: %s", s) log.Printf("shell-wait: %s", s)
app.runShell(s, nil, true, false) app.runShell(s, nil, true, false)
case "read-shell-async": case "read-shell-async":
s := app.ui.prompt(app.nav, "&") s := app.ui.prompt(app.nav, "&")
if len(s) == 0 {
return
}
log.Printf("shell-async: %s", s) log.Printf("shell-async: %s", s)
app.runShell(s, nil, false, true) app.runShell(s, nil, false, true)
case "search": case "search":
s := app.ui.prompt(app.nav, "/") s := app.ui.prompt(app.nav, "/")
if len(s) == 0 {
return
}
log.Printf("search: %s", s) log.Printf("search: %s", s)
app.ui.message = "sorry, search is not implemented yet!" app.ui.message = "sorry, search is not implemented yet!"
// TODO: implement // TODO: implement
case "search-back": case "search-back":
s := app.ui.prompt(app.nav, "?") s := app.ui.prompt(app.nav, "?")
if len(s) == 0 {
return
}
log.Printf("search-back: %s", s) log.Printf("search-back: %s", s)
app.ui.message = "sorry, search-back is not implemented yet!" app.ui.message = "sorry, search-back is not implemented yet!"
// TODO: implement // TODO: implement
@ -288,7 +302,7 @@ func (e *CallExpr) eval(app *App, args []string) {
log.Print(err) log.Print(err)
return return
} }
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
default: default:
cmd, ok := gOpts.cmds[e.name] cmd, ok := gOpts.cmds[e.name]
if !ok { if !ok {
@ -307,7 +321,7 @@ func (e *ExecExpr) eval(app *App, args []string) {
log.Printf("shell: %s -- %s", e, args) log.Printf("shell: %s -- %s", e, args)
app.ui.clearMsg() app.ui.clearMsg()
app.runShell(e.expr, args, false, false) app.runShell(e.expr, args, false, false)
app.ui.echoFileInfo(app.nav) app.ui.loadFile(app.nav)
case "!": case "!":
log.Printf("shell-wait: %s -- %s", e, args) log.Printf("shell-wait: %s -- %s", e, args)
app.runShell(e.expr, args, true, false) app.runShell(e.expr, args, true, false)

128
ui.go
View File

@ -235,55 +235,14 @@ func (win *Win) printd(dir *Dir, marks map[string]bool) {
} }
} }
func (win *Win) printr(reg *os.File) error { func (win *Win) printr(reg []string) {
var reader io.ReadSeeker
if len(gOpts.previewer) != 0 {
cmd := exec.Command(gOpts.previewer, reg.Name(), strconv.Itoa(win.w), strconv.Itoa(win.h))
out, err := cmd.Output()
if err != nil {
log.Printf("previewing file: %s", err)
}
reader = bytes.NewReader(out)
} else {
reader = reg
}
fg, bg := termbox.ColorDefault, termbox.ColorDefault fg, bg := termbox.ColorDefault, termbox.ColorDefault
buf := bufio.NewScanner(reader) for i, l := range reg {
win.print(2, i, fg, bg, l)
for i := 0; i < win.h && buf.Scan(); i++ {
for _, r := range buf.Text() {
if unicode.IsSpace(r) {
continue
}
if !unicode.IsPrint(r) && r != EscapeCode {
fg = termbox.AttrBold
win.print(0, 0, fg, bg, "binary")
return nil
}
}
} }
if buf.Err() != nil { return
return fmt.Errorf("printing regular file: %s", buf.Err())
}
reader.Seek(0, 0)
buf = bufio.NewScanner(reader)
for i := 0; i < win.h && buf.Scan(); i++ {
win.print(2, i, fg, bg, buf.Text())
}
if buf.Err() != nil {
return fmt.Errorf("printing regular file: %s", buf.Err())
}
return nil
} }
type UI struct { type UI struct {
@ -292,6 +251,8 @@ type UI struct {
msgwin *Win msgwin *Win
menuwin *Win menuwin *Win
message string message string
regprev []string
dirprev *Dir
} }
func getWidths(wtot int) []int { func getWidths(wtot int) []int {
@ -352,7 +313,7 @@ func (ui *UI) renew() {
ui.msgwin.renew(wtot, 1, 0, htot-1) ui.msgwin.renew(wtot, 1, 0, htot-1)
} }
func (ui *UI) echoFileInfo(nav *Nav) { func (ui *UI) loadFile(nav *Nav) {
dir := nav.currDir() dir := nav.currDir()
if len(dir.fi) == 0 { if len(dir.fi) == 0 {
@ -362,6 +323,65 @@ func (ui *UI) echoFileInfo(nav *Nav) {
curr := nav.currFile() curr := nav.currFile()
ui.message = fmt.Sprintf("%v %v %v", curr.Mode(), humanize(curr.Size()), curr.ModTime().Format(time.ANSIC)) ui.message = fmt.Sprintf("%v %v %v", curr.Mode(), humanize(curr.Size()), curr.ModTime().Format(time.ANSIC))
if !gOpts.preview {
return
}
path := nav.currPath()
if curr.IsDir() {
dir := newDir(path)
dir.load(nav.inds[path], nav.poss[path], nav.height, nav.names[path])
ui.dirprev = dir
} else if curr.Mode().IsRegular() {
var reader io.Reader
if len(gOpts.previewer) != 0 {
cmd := exec.Command(gOpts.previewer, path, strconv.Itoa(nav.height))
out, err := cmd.Output()
if err != nil {
msg := fmt.Sprintf("previewing file: %s", err)
ui.message = msg
log.Print(msg)
}
reader = bytes.NewReader(out)
} else {
f, err := os.Open(path)
if err != nil {
msg := fmt.Sprintf("opening file: %s", err)
ui.message = msg
log.Print(msg)
}
reader = f
}
ui.regprev = nil
buf := bufio.NewScanner(reader)
for i := 0; i < nav.height && buf.Scan(); i++ {
for _, r := range buf.Text() {
if unicode.IsSpace(r) {
continue
}
if !unicode.IsPrint(r) && r != EscapeCode {
ui.regprev = []string{"binary"}
return
}
}
ui.regprev = append(ui.regprev, buf.Text())
}
if buf.Err() != nil {
msg := fmt.Sprintf("loading file: %s", buf.Err())
ui.message = msg
log.Print(msg)
}
}
} }
func (ui *UI) clearMsg() { func (ui *UI) clearMsg() {
@ -418,21 +438,9 @@ func (ui *UI) draw(nav *Nav) {
} }
if f.IsDir() { if f.IsDir() {
dir := newDir(path) preview.printd(ui.dirprev, nav.marks)
dir.load(nav.inds[path], nav.poss[path], nav.height, nav.names[path])
preview.printd(dir, nav.marks)
} else if f.Mode().IsRegular() { } else if f.Mode().IsRegular() {
file, err := os.Open(path) preview.printr(ui.regprev)
if err != nil {
msg := fmt.Sprintf("opening file: %s", err)
ui.message = msg
log.Print(msg)
}
if err := preview.printr(file); err != nil {
ui.message = err.Error()
log.Print(err)
}
} }
} }
} }