package main import ( "bufio" "fmt" "io" "log" "time" "os/exec" "github.com/awesome-gocui/gocui" "github.com/pelletier/go-toml" ) var ( settings *toml.Tree srv_stdin io.WriteCloser ) // reload settings (and maybe other things too) func reload() { settings, _ = toml.LoadFile("serverwrapper.toml") } //builds the cmd which is called to run the server func build_cmd() (string, []string) { return "ping", []string{"-t", "8.8.8.8"} } //run the server-thread func server_run(g *gocui.Gui) { //create the command cmd_str, cmd_args := build_cmd() cmd := exec.Command(cmd_str, cmd_args...) //connect pipes stdout, err := cmd.StdoutPipe() cmd.Stderr = cmd.Stdout srv_stdin, err = cmd.StdinPipe() //this one is global, because we write to it elsewhere // run the process err = cmd.Start() if err != nil { log.Panicln("Failed to call server command \"" + cmd.String() + "\"") } //read pipes and write them to the ring buffer buf := bufio.NewScanner(stdout) for { if buf.Scan() { g.Update(func(g *gocui.Gui) error { v, err := g.View("srv_log") if err != nil { return err } fmt.Fprintln(v, buf.Text()) return nil }) } else { time.Sleep(300 * time.Millisecond) } } } func main() { //initialize settings by "re"loading them from disk reload() //init the CUI g, err := gocui.NewGui(gocui.OutputNormal, false) 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) } go server_run(g) //run the CUI main loop if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { log.Panicln(err) } } //create or update the CUI layout func layout(g *gocui.Gui) error { maxX, maxY := g.Size() v, err := g.SetView("srv_log", 0, 0, maxX-1, int(float32(maxY) * 0.8), 0) if err != nil { if err != gocui.ErrUnknownView { return err } //*only* put initialization code for the view here v.Autoscroll = true } return nil } func quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit }