aboutsummaryrefslogtreecommitdiffstats
path: root/termui/termui.go
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2018-07-31 16:43:43 +0200
committerMichael Muré <batolettre@gmail.com>2018-07-31 16:44:23 +0200
commit87669e0f18f282854d340a676834b939e34e5ed3 (patch)
treec78eaa155d2939d6647ab814c6710d0d3ed69a6e /termui/termui.go
parenteb39c5c29bc0e9b5e15a940a1b71bdac688b6535 (diff)
downloadgit-bug-87669e0f18f282854d340a676834b939e34e5ed3.tar.gz
termui: use the editor to create a new bug
Diffstat (limited to 'termui/termui.go')
-rw-r--r--termui/termui.go153
1 files changed, 75 insertions, 78 deletions
diff --git a/termui/termui.go b/termui/termui.go
index e2e5ae24..9ac82fd3 100644
--- a/termui/termui.go
+++ b/termui/termui.go
@@ -2,104 +2,103 @@ package termui
import (
"github.com/MichaelMure/git-bug/cache"
+ "github.com/MichaelMure/git-bug/input"
"github.com/MichaelMure/git-bug/repository"
"github.com/jroimartin/gocui"
+ "github.com/pkg/errors"
)
+var errTerminateMainloop = errors.New("terminate gocui mainloop")
+
type termUI struct {
- cache cache.RepoCacher
+ g *gocui.Gui
+ gError chan error
+ cache cache.RepoCacher
+ activeWindow window
+
bugTable *bugTable
}
var ui *termUI
+type window interface {
+ keybindings(g *gocui.Gui) error
+ layout(g *gocui.Gui) error
+}
+
func Run(repo repository.Repo) error {
c := cache.NewRepoCache(repo)
ui = &termUI{
+ gError: make(chan error, 1),
cache: c,
bugTable: newBugTable(c),
}
+ ui.activeWindow = ui.bugTable
+
+ initGui()
+
+ err := <-ui.gError
+
+ if err != nil && err != gocui.ErrQuit {
+ return err
+ }
+
+ return nil
+}
+
+func initGui() {
g, err := gocui.NewGui(gocui.OutputNormal)
if err != nil {
- return err
+ ui.gError <- err
+ return
}
- defer g.Close()
+ ui.g = g
- g.SetManagerFunc(layout)
+ ui.g.SetManagerFunc(layout)
- err = keybindings(g)
+ err = keybindings(ui.g)
if err != nil {
- return err
+ ui.g.Close()
+ ui.gError <- err
+ return
}
err = g.MainLoop()
- if err != nil && err != gocui.ErrQuit {
- return err
+ if err != nil && err != errTerminateMainloop {
+ ui.g.Close()
+ ui.gError <- err
}
- return nil
+ return
}
func layout(g *gocui.Gui) error {
//maxX, maxY := g.Size()
- ui.bugTable.layout(g)
+ g.Cursor = false
- v, err := g.View("bugTable")
- if err != nil {
+ if err := ui.activeWindow.layout(g); err != nil {
return err
}
- cursorClamp(v)
-
return nil
}
func keybindings(g *gocui.Gui) error {
- if err := g.SetKeybinding("", 'q', gocui.ModNone, quit); err != nil {
- return err
- }
- if err := g.SetKeybinding("bugTable", 'j', gocui.ModNone, cursorDown); err != nil {
- return err
- }
- if err := g.SetKeybinding("bugTable", gocui.KeyArrowDown, gocui.ModNone, cursorDown); err != nil {
- return err
- }
- if err := g.SetKeybinding("bugTable", 'k', gocui.ModNone, cursorUp); err != nil {
- return err
- }
- if err := g.SetKeybinding("bugTable", gocui.KeyArrowUp, gocui.ModNone, cursorUp); err != nil {
+ // Quit
+ if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
return err
}
- if err := g.SetKeybinding("bugTable", 'h', gocui.ModNone, previousPage); err != nil {
+ if err := ui.bugTable.keybindings(g); err != nil {
return err
}
- if err := g.SetKeybinding("bugTable", gocui.KeyArrowLeft, gocui.ModNone, previousPage); err != nil {
- return err
- }
- if err := g.SetKeybinding("bugTable", gocui.KeyPgup, gocui.ModNone, previousPage); err != nil {
- return err
- }
- if err := g.SetKeybinding("bugTable", 'l', gocui.ModNone, nextPage); err != nil {
- return err
- }
- if err := g.SetKeybinding("bugTable", gocui.KeyArrowRight, gocui.ModNone, nextPage); err != nil {
- return err
- }
- if err := g.SetKeybinding("bugTable", gocui.KeyPgdn, gocui.ModNone, nextPage); err != nil {
- return err
- }
-
- //err = g.SetKeybinding("bugTable", 'p', gocui.ModNone, playSelected)
- //err = g.SetKeybinding("bugTable", gocui.KeyEnter, gocui.ModNone, playSelectedAndExit)
- //err = g.SetKeybinding("bugTable", 'm', gocui.ModNone, loadNextRecords)
return nil
}
@@ -108,50 +107,48 @@ func quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}
-func cursorDown(g *gocui.Gui, v *gocui.View) error {
- _, y := v.Cursor()
- y = minInt(y+1, ui.bugTable.getTableLength()-1)
-
- err := v.SetCursor(0, y)
- if err != nil {
- return err
- }
+func newBugWithEditor(g *gocui.Gui, v *gocui.View) error {
+ // This is somewhat hacky.
+ // As there is no way to pause gocui, run the editor, restart gocui,
+ // we have to stop it entirely and start a new one later.
+ //
+ // - an error channel is used to route the returned error of this new
+ // instance into the original launch function
+ // - a custom error (errTerminateMainloop) is used to terminate the original
+ // instance's mainLoop. This error is then filtered.
- return nil
-}
+ ui.g.Close()
-func cursorUp(g *gocui.Gui, v *gocui.View) error {
- _, y := v.Cursor()
- y = maxInt(y-1, 0)
+ title, message, err := input.BugCreateEditorInput(ui.cache.Repository(), "", "")
- err := v.SetCursor(0, y)
+ if err == input.ErrEmptyTitle {
+ // TODO: display proper error
+ return err
+ }
if err != nil {
return err
}
- return nil
-}
-
-func cursorClamp(v *gocui.View) error {
- _, y := v.Cursor()
-
- y = minInt(y, ui.bugTable.getTableLength()-1)
- y = maxInt(y, 0)
-
- err := v.SetCursor(0, y)
+ _, err = ui.cache.NewBug(title, message)
if err != nil {
return err
}
- return nil
+ initGui()
+
+ return errTerminateMainloop
}
-func nextPage(g *gocui.Gui, v *gocui.View) error {
- _, maxY := v.Size()
- return ui.bugTable.nextPage(maxY)
+func maxInt(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
}
-func previousPage(g *gocui.Gui, v *gocui.View) error {
- _, maxY := v.Size()
- return ui.bugTable.previousPage(maxY)
+func minInt(a, b int) int {
+ if a > b {
+ return b
+ }
+ return a
}