package main import ( "fmt" "log" "strings" "github.com/jroimartin/gocui" ) var messages []string var users = []string{"Alice", "Bob", "Charlie"} func layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("users", 0, 0, 20, maxY-1); err != nil { if err != gocui.ErrUnknownView { return err } v.Title = "Users" v.Clear() for _, u := range users { fmt.Fprintln(v, u) } } if v, err := g.SetView("chat", 21, 0, maxX-1, maxY-5); err != nil { if err != gocui.ErrUnknownView { return err } v.Title = "Chat" v.Wrap = true updateChatView(v) } if v, err := g.SetView("input", 21, maxY-4, maxX-1, maxY-1); err != nil { if err != gocui.ErrUnknownView { return err } v.Title = "Type your message" v.Editable = true v.Wrap = true if _, err := g.SetCurrentView("input"); err != nil { return err } } return nil } func updateChatView(v *gocui.View) { v.Clear() for _, msg := range messages { fmt.Fprintln(v, msg) } } func sendMessage(g *gocui.Gui, v *gocui.View) error { input := strings.TrimSpace(v.Buffer()) v.Clear() v.SetCursor(0, 0) v.SetOrigin(0, 0) if input != "" { messages = append(messages, "You: "+input) if chatView, err := g.View("chat"); err == nil { updateChatView(chatView) } } v.Clear() v.SetCursor(0, 0) return nil } func keybindings(g *gocui.Gui) error { // Ctrl+C to quit if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { return err } // Enter to send message // Enter adds a new line (multiline input) if err := g.SetKeybinding("input", gocui.KeyArrowDown, gocui.ModNone, insertNewline); err != nil { return err } // Ctrl+Enter sends the message if err := g.SetKeybinding("input", gocui.KeyEnter, gocui.ModNone, sendMessage); err != nil { return err } return nil } func insertNewline(g *gocui.Gui, v *gocui.View) error { v.EditNewLine() return nil } func quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit } func main() { g, err := gocui.NewGui(gocui.OutputNormal) if err != nil { log.Panicln(err) } defer g.Close() g.SetManagerFunc(layout) if err := keybindings(g); err != nil { log.Panicln(err) } if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { log.Panicln(err) } }