lf/eval.go
2016-08-28 15:04:57 +03:00

314 lines
6.7 KiB
Go

package main
import (
"fmt"
"log"
"os"
"strconv"
"strings"
)
func (e *SetExpr) eval(app *App, args []string) {
switch e.opt {
case "hidden":
gOpts.hidden = true
app.nav.renew(app.nav.height)
case "nohidden":
gOpts.hidden = false
app.nav.renew(app.nav.height)
case "hidden!":
gOpts.hidden = !gOpts.hidden
app.nav.renew(app.nav.height)
case "preview":
gOpts.preview = true
case "nopreview":
gOpts.preview = false
case "preview!":
gOpts.preview = !gOpts.preview
case "scrolloff":
n, err := strconv.Atoi(e.val)
if err != nil {
msg := fmt.Sprintf("scrolloff: %s", err)
app.ui.message = msg
log.Print(msg)
return
}
if n < 0 {
msg := "scrolloff: value should be a non-negative number"
app.ui.message = msg
log.Print(msg)
return
}
max := app.ui.wins[0].h/2 - 1
if n > max {
// TODO: stay at the same row while up/down in the middle
n = max
}
gOpts.scrolloff = n
case "tabstop":
n, err := strconv.Atoi(e.val)
if err != nil {
msg := fmt.Sprintf("tabstop: %s", err)
app.ui.message = msg
log.Print(msg)
return
}
if n <= 0 {
msg := "tabstop: value should be a positive number"
app.ui.message = msg
log.Print(msg)
return
}
gOpts.tabstop = n
case "ifs":
gOpts.ifs = e.val
case "previewer":
gOpts.previewer = e.val
case "shell":
gOpts.shell = e.val
case "showinfo":
if e.val != "none" && e.val != "size" && e.val != "time" {
msg := "showinfo should either be 'none', 'size' or 'time'"
app.ui.message = msg
log.Print(msg)
return
}
gOpts.showinfo = e.val
case "sortby":
if e.val != "name" && e.val != "size" && e.val != "time" {
msg := "sortby should either be 'name', 'size' or 'time'"
app.ui.message = msg
log.Print(msg)
return
}
gOpts.sortby = e.val
app.nav.renew(app.nav.height)
case "ratios":
toks := strings.Split(e.val, ":")
var rats []int
for _, s := range toks {
i, err := strconv.Atoi(s)
if err != nil {
msg := fmt.Sprintf("ratios: %s", err)
app.ui.message = msg
log.Print(msg)
return
}
rats = append(rats, i)
}
gOpts.ratios = rats
app.ui = newUI()
default:
msg := fmt.Sprintf("unknown option: %s", e.opt)
app.ui.message = msg
log.Print(msg)
}
}
func (e *MapExpr) eval(app *App, args []string) {
gOpts.keys[e.keys] = e.expr
}
func (e *CmdExpr) eval(app *App, args []string) {
gOpts.cmds[e.name] = e.expr
}
func (e *CallExpr) eval(app *App, args []string) {
// TODO: check for extra toks in each case
switch e.name {
case "quit":
gExitFlag = true
case "echo":
app.ui.message = strings.Join(e.args, " ")
case "down":
app.nav.down()
app.ui.echoFileInfo(app.nav)
case "up":
app.nav.up()
app.ui.echoFileInfo(app.nav)
case "updir":
if err := app.nav.updir(); err != nil {
app.ui.message = err.Error()
log.Print(err)
return
}
app.ui.echoFileInfo(app.nav)
case "open":
dir := app.nav.currDir()
if len(dir.fi) == 0 {
return
}
path := app.nav.currPath()
f, err := os.Stat(path)
if err != nil {
msg := fmt.Sprintf("open: %s", err)
app.ui.message = msg
log.Print(msg)
return
}
if f.IsDir() {
if err := app.nav.open(); err != nil {
app.ui.message = err.Error()
log.Print(err)
return
}
app.ui.echoFileInfo(app.nav)
return
}
if gSelectionPath != "" {
out, err := os.Create(gSelectionPath)
if err != nil {
log.Printf("opening selection file: %s", err)
}
defer out.Close()
if len(app.nav.marks) != 0 {
marks := app.nav.currMarks()
path = strings.Join(marks, "\n")
}
_, err = out.WriteString(path)
if err != nil {
log.Printf("writing selection file: %s", err)
}
gExitFlag = true
return
}
if cmd, ok := gOpts.cmds["open-file"]; ok {
cmd.eval(app, e.args)
}
case "bot":
app.nav.bot()
app.ui.echoFileInfo(app.nav)
case "top":
app.nav.top()
app.ui.echoFileInfo(app.nav)
case "cd":
path := "~"
if len(e.args) > 0 {
path = e.args[0]
}
if err := app.nav.cd(path); err != nil {
app.ui.message = err.Error()
log.Print(err)
return
}
app.ui.echoFileInfo(app.nav)
case "read":
s := app.ui.prompt(app.nav, ":")
if len(s) == 0 {
app.ui.echoFileInfo(app.nav)
return
}
log.Printf("command: %s", s)
p := newParser(strings.NewReader(s))
for p.parse() {
p.expr.eval(app, nil)
}
if p.err != nil {
app.ui.message = p.err.Error()
log.Print(p.err)
}
case "read-shell":
s := app.ui.prompt(app.nav, "$")
log.Printf("shell: %s", s)
app.runShell(s, nil, false, false)
case "read-shell-wait":
s := app.ui.prompt(app.nav, "!")
log.Printf("shell-wait: %s", s)
app.runShell(s, nil, true, false)
case "read-shell-async":
s := app.ui.prompt(app.nav, "&")
log.Printf("shell-async: %s", s)
app.runShell(s, nil, false, true)
case "search":
s := app.ui.prompt(app.nav, "/")
log.Printf("search: %s", s)
app.ui.message = "sorry, search is not implemented yet!"
// TODO: implement
case "search-back":
s := app.ui.prompt(app.nav, "?")
log.Printf("search-back: %s", s)
app.ui.message = "sorry, search-back is not implemented yet!"
// TODO: implement
case "toggle":
app.nav.toggle()
case "yank":
if err := app.nav.save(true); err != nil {
msg := fmt.Sprintf("yank: %s", err)
app.ui.message = msg
log.Printf(msg)
return
}
app.nav.marks = make(map[string]bool)
case "delete":
if err := app.nav.save(false); err != nil {
msg := fmt.Sprintf("delete: %s", err)
app.ui.message = msg
log.Printf(msg)
return
}
app.nav.marks = make(map[string]bool)
case "paste":
if err := app.nav.paste(); err != nil {
msg := fmt.Sprintf("paste: %s", err)
app.ui.message = msg
log.Printf(msg)
return
}
app.nav.renew(app.nav.height)
app.nav.save(false)
saveFiles(nil, false)
case "renew":
app.ui.sync()
app.ui.renew()
app.nav.renew(app.ui.wins[0].h)
default:
cmd, ok := gOpts.cmds[e.name]
if !ok {
msg := fmt.Sprintf("command not found: %s", e.name)
app.ui.message = msg
log.Print(msg)
return
}
cmd.eval(app, e.args)
}
}
func (e *ExecExpr) eval(app *App, args []string) {
switch e.pref {
case "$":
log.Printf("shell: %s -- %s", e, args)
app.ui.clearMsg()
app.runShell(e.expr, args, false, false)
app.ui.echoFileInfo(app.nav)
case "!":
log.Printf("shell-wait: %s -- %s", e, args)
app.runShell(e.expr, args, true, false)
case "&":
log.Printf("shell-async: %s -- %s", e, args)
app.runShell(e.expr, args, false, true)
case "/":
log.Printf("search: %s -- %s", e, args)
// TODO: implement
case "?":
log.Printf("search-back: %s -- %s", e, args)
// TODO: implement
default:
log.Printf("unknown execution prefix: %q", e.pref)
}
}
func (e *ListExpr) eval(app *App, args []string) {
for _, expr := range e.exprs {
expr.eval(app, nil)
}
}