Skip to content

Instantly share code, notes, and snippets.

@jroimartin
Last active April 7, 2017 07:22
Show Gist options
  • Save jroimartin/1ac98d3da7278fa18866c9cae0af6007 to your computer and use it in GitHub Desktop.
Save jroimartin/1ac98d3da7278fa18866c9cae0af6007 to your computer and use it in GitHub Desktop.
gocui: using the Editor interface to implement a custom edition mode
package main
import (
"log"
"github.com/jroimartin/gocui"
)
type VimEditor struct {
Insert bool
}
func (ve *VimEditor) Edit(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) {
if ve.Insert {
ve.InsertMode(v, key, ch, mod)
} else {
ve.NormalMode(v, key, ch, mod)
}
}
func (ve *VimEditor) InsertMode(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) {
switch {
case key == gocui.KeyEsc:
ve.Insert = false
case ch != 0 && mod == 0:
v.EditWrite(ch)
case key == gocui.KeySpace:
v.EditWrite(' ')
case key == gocui.KeyBackspace || key == gocui.KeyBackspace2:
v.EditDelete(true)
case key == gocui.KeyDelete:
v.EditDelete(false)
case key == gocui.KeyInsert:
v.Overwrite = !v.Overwrite
case key == gocui.KeyEnter:
v.EditNewLine()
case key == gocui.KeyArrowDown:
v.MoveCursor(0, 1, false)
case key == gocui.KeyArrowUp:
v.MoveCursor(0, -1, false)
case key == gocui.KeyArrowLeft:
v.MoveCursor(-1, 0, false)
case key == gocui.KeyArrowRight:
v.MoveCursor(1, 0, false)
}
// TODO: handle other keybindings...
}
func (ve *VimEditor) NormalMode(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) {
switch {
case ch == 'i':
ve.Insert = true
case ch == 'j':
v.MoveCursor(0, 1, false)
case ch == 'k':
v.MoveCursor(0, -1, false)
case ch == 'h':
v.MoveCursor(-1, 0, false)
case ch == 'l':
v.MoveCursor(1, 0, false)
}
// TODO: handle other keybindings...
}
func quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}
func layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
if v, err := g.SetView("main", 0, 0, maxX-1, maxY-1); err != nil {
if err != gocui.ErrUnknownView {
return err
}
v.Editable = true
v.Wrap = true
v.Editor = &VimEditor{}
if _, err := g.SetCurrentView("main"); err != nil {
return err
}
}
return nil
}
func main() {
g, err := gocui.NewGui(gocui.OutputNormal)
if err != nil {
log.Fatalln(err)
}
defer g.Close()
g.SetManagerFunc(layout)
g.InputEsc = true
g.Cursor = true
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
log.Fatalln(err)
}
if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
log.Fatalln(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment