Golang 製の CUI ツールを作成する! gocui を試してみた。
こんにちは k-jun です。今回は Golang にて TUI を構築するツール gocui を試してみます。
https://github.com/jroimartin/gocui
go"cui" と銘打っていますが、TUI じゃないんですかね、これ。Console User Interface と Terminal User Interface だったら後者のほうが正しそうな。
Setup
$ go get github.com/jroimartin/gocui
Run
一旦 README に記載もある以下のコードを実行してみます。
package main import ( "fmt" "log" "github.com/jroimartin/gocui" ) func main() { g, err := gocui.NewGui(gocui.OutputNormal) if err != nil { log.Panicln(err) } defer g.Close() g.SetManagerFunc(layout) if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { log.Panicln(err) } if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { log.Panicln(err) } } func layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("hello", maxX/2-7, maxY/2, maxX/2+7, maxY/2+2); err != nil { if err != gocui.ErrUnknownView { return err } fmt.Fprintln(v, "Hello world!") } return nil } func quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit }
何やら window らしきものが生成されていそうですね。
よさそうなので、他に何ができるのかを Document を参考に見てみます。
https://pkg.go.dev/github.com/jroimartin/gocui#section-readme
更新する例も作ってみました。
package main import ( "fmt" "log" "math/rand" "strconv" "time" "github.com/jroimartin/gocui" ) func main() { ... g.Update(func(g *gocui.Gui) error { time.Sleep(1000 * 3 * time.Millisecond) v, err := g.View("hello") if err != nil { // handle error } v.Clear() fmt.Fprintln(v, "Writing from different goroutines") return nil }) ... }
Update 関数により View をリセットすることで新しい View が render され、見えるようになるようです。layout 関数にて、for で rendering を繰り返す形にもしてみましたが、どうやら layout 関数が return して初めて rendering が開始されるようです。
layout 関数はあくまでも position を決定するのみで、更新の際には別途 Update 関数が必要ということですね。他にも mouse イベントが取得できるようなのでこれも試してみます。
package main import ( "fmt" "log" "math/rand" "time" "github.com/jroimartin/gocui" ) func main() { g, err := gocui.NewGui(gocui.OutputNormal) if err != nil { log.Panicln(err) } defer g.Close() g.SetManagerFunc(layout) g.Mouse = true if err = g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, quit); err != nil { log.Panicln(err) } ... }
左クリックで 終了する機能をつけてみました。筆者は iTerm2 から基本的にコーディングをしていますが、iTerm2 からは クリックイベントを受け取れず.... しかし、Mac デフォルトの Terminal アプリからは クリックイベントが取得できることが確認できました!!!
これを使用することでなかなかおもしろいことができそうです。それでは今回はこのへんで。