package main import ( "bufio" // "fmt" "io" "log" "time" // "math" "container/ring" "os/exec" "github.com/jroimartin/gocui" "github.com/pelletier/go-toml" ) var settings *toml.Tree var stdout_ring *ring.Ring var srv_stdin io.WriteCloser var new_stdout bool = false // 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() { //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() { stdout_ring.Value = buf.Text() stdout_ring = stdout_ring.Next() new_stdout = true } else { time.Sleep(300 * time.Millisecond) } } } func main() { //initialize settings by "re"loading them from disk reload() //initialize the stdout/err ringbuffer stdout_ring = ring.New(255) //init the CUI 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) } go server_run() go func(g *gocui.Gui) { for { time.Sleep(50 * time.Millisecond) if new_stdout { new_stdout = false g.Update(layout) } } }(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)) if err != nil { if err != gocui.ErrUnknownView { return err } //dont put code in here you idiot } v.Clear() vW, vH := v.Size() r := stdout_ring.Prev() for i := 0; i < vH; i++ { v.SetCursor(0, vH - i - 1) if r.Value != nil { s := r.Value.(string) for i := 0; i < len(s) && i < vW; i++ { v.EditWrite([]rune(s)[i]) } } r = r.Prev() } return nil } func quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit }