Skip to content

Instantly share code, notes, and snippets.

@mplewis
Created September 23, 2022 21:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mplewis/d645c38058df21634c9f984fd88a5a04 to your computer and use it in GitHub Desktop.
Save mplewis/d645c38058df21634c9f984fd88a5a04 to your computer and use it in GitHub Desktop.
Demo "chat" app which shows how to use Go and carraige returns to show live messages alongside an editable chat input line
package main
import (
"fmt"
"math/rand"
"time"
"github.com/eiannone/keyboard"
)
const clearLine = "\033[2K\r"
func main() {
msgs := make(chan string)
// fake chatters
go func() {
t := time.NewTicker(1 * time.Second)
for range t.C {
msgs <- fmt.Sprintf("%08d", rand.Intn(100000000))
}
}()
newInput := make(chan struct{})
done := make(chan struct{})
var buf string
// key listener
go func() {
for {
char, key, err := keyboard.GetSingleKey()
if err != nil {
panic(err)
}
// handle quitting the app with Ctrl-C
if key == keyboard.KeyCtrlC {
done <- struct{}{}
break
}
if key == keyboard.KeyBackspace || key == keyboard.KeyBackspace2 {
if len(buf) > 0 {
buf = buf[:len(buf)-1]
}
} else if key == keyboard.KeyEnter { // enter sends a message
msgs <- buf
buf = ""
} else if char != 0 {
buf += string(char)
}
newInput <- struct{}{}
}
}()
go func() {
for {
select {
case msg := <-msgs:
fmt.Print(clearLine)
fmt.Println(msg)
fmt.Print(buf)
case <-newInput:
fmt.Print(clearLine)
fmt.Print(buf)
}
}
}()
// wait for Ctrl-C
<-done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment