wuzz/commands.go
2017-02-22 07:28:40 +01:00

153 lines
3.1 KiB
Go

package main
import (
"fmt"
"strings"
"unicode"
"github.com/jroimartin/gocui"
)
type CommandFunc func(*gocui.Gui, *gocui.View) error
var COMMANDS map[string]func(string, *App) CommandFunc = map[string]func(string, *App) CommandFunc{
"submit": func(_ string, a *App) CommandFunc {
return a.SubmitRequest
},
"save": func(_ string, a *App) CommandFunc {
return a.OpenSaveDialog
},
"history": func(_ string, a *App) CommandFunc {
return a.ToggleHistory
},
"quit": func(_ string, _ *App) CommandFunc {
return quit
},
"focus": func(args string, a *App) CommandFunc {
return func(g *gocui.Gui, _ *gocui.View) error {
return a.setViewByName(g, args)
}
},
"nextView": func(_ string, a *App) CommandFunc {
return a.NextView
},
"prevView": func(_ string, a *App) CommandFunc {
return a.PrevView
},
"scrollDown": func(_ string, _ *App) CommandFunc {
return scrollViewDown
},
"scrollUp": func(_ string, _ *App) CommandFunc {
return scrollViewUp
},
"pageDown": func(_ string, _ *App) CommandFunc {
return pageDown
},
"pageUp": func(_ string, _ *App) CommandFunc {
return pageUp
},
"deleteLine": func(_ string, _ *App) CommandFunc {
return deleteLine
},
"deleteWord": func(_ string, _ *App) CommandFunc {
return deleteWord
},
}
func scrollView(v *gocui.View, dy int) error {
v.Autoscroll = false
ox, oy := v.Origin()
if oy+dy < 0 {
dy = -oy
}
if _, err := v.Line(dy); dy > 0 && err != nil {
dy = 0
}
v.SetOrigin(ox, oy+dy)
return nil
}
func scrollViewUp(_ *gocui.Gui, v *gocui.View) error {
return scrollView(v, -1)
}
func scrollViewDown(_ *gocui.Gui, v *gocui.View) error {
return scrollView(v, 1)
}
func pageUp(_ *gocui.Gui, v *gocui.View) error {
_, height := v.Size()
scrollView(v, -height*2/3)
return nil
}
func pageDown(_ *gocui.Gui, v *gocui.View) error {
_, height := v.Size()
scrollView(v, height*2/3)
return nil
}
func deleteLine(_ *gocui.Gui, v *gocui.View) error {
if !v.Editable {
return nil
}
_, curY := v.Cursor()
_, oY := v.Origin()
currentLine := curY + oY
viewLines := strings.Split(strings.TrimSpace(v.Buffer()), "\n")
if currentLine >= len(viewLines) {
return nil
}
v.Clear()
if currentLine > 0 {
fmt.Fprintln(v, strings.Join(viewLines[:currentLine], "\n"))
}
fmt.Fprint(v, strings.Join(viewLines[currentLine+1:], "\n"))
v.SetCursor(0, currentLine)
v.SetOrigin(0, oY)
return nil
}
func deleteWord(_ *gocui.Gui, v *gocui.View) error {
cX, cY := v.Cursor()
oX, _ := v.Origin()
cX = cX - 1 + oX
line, err := v.Line(cY)
if err != nil || line == "" || cX < 0 {
return nil
}
if cX >= len(line) {
cX = len(line) - 1
}
origCharCateg := getCharCategory(rune(line[cX]))
v.EditDelete(true)
cX -= 1
for cX >= 0 {
c := rune(line[cX])
if origCharCateg != getCharCategory(c) {
break
}
v.EditDelete(true)
cX -= 1
}
return nil
}
func getCharCategory(chr rune) int {
switch {
case unicode.IsDigit(chr):
return 0
case unicode.IsLetter(chr):
return 1
case unicode.IsSpace(chr):
return 2
case unicode.IsPunct(chr):
return 3
}
return int(chr)
}
func quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}