Skip to content

Instantly share code, notes, and snippets.

@devries
Created April 30, 2020 16:35
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 devries/ffe09749c3fbcc6553ea7d240c5a4b03 to your computer and use it in GitHub Desktop.
Save devries/ffe09749c3fbcc6553ea7d240c5a4b03 to your computer and use it in GitHub Desktop.
Some terminal UI example
package main
import (
"bytes"
"fmt"
"os"
"os/exec"
"strings"
)
func main() {
r, c := initialize()
clear()
move(0, 0)
fmt.Printf("Rows: %d, Columns: %d", r, c)
move(1, 0)
fmt.Print(strings.Repeat("#", c))
for i := 2; i < r-2; i++ {
move(i, 0)
fmt.Print("#")
move(i, c-1)
fmt.Print("#")
}
move(r-2, 0)
fmt.Print(strings.Repeat("#", c))
x := 2
y := 1
for {
move(x, y)
input, err := readInput()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
break
}
if input == "ESC" {
break
} else if input == "SPACE" {
fmt.Printf("#")
} else if input == "UP" {
x -= 1
} else if input == "DOWN" {
x += 1
} else if input == "LEFT" {
y -= 1
} else if input == "RIGHT" {
y += 1
} else if input == "C" {
fmt.Printf(" ")
}
}
move(r-1, 0)
cleanup()
}
func initialize() (rows int, columns int) {
var output bytes.Buffer
cmd := exec.Command("stty", "cbreak", "-echo", "size")
cmd.Stdout = &output
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
panic(err)
}
_, err = fmt.Sscanf(output.String(), "%d %d", &rows, &columns)
if err != nil {
panic(fmt.Errorf("Unable to read screen size: %s", err))
}
return
}
func cleanup() {
cmd := exec.Command("stty", "-cbreak", "echo")
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
panic(err)
}
}
func clear() {
fmt.Print("\x1b[2J")
}
func move(x, y int) {
fmt.Printf("\x1b[%d;%df", x+1, y+1)
}
func resize() (rows int, columns int) {
var output bytes.Buffer
cmd := exec.Command("stty", "size")
cmd.Stdout = &output
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
panic(err)
}
_, err = fmt.Sscanf(output.String(), "%d %d", &rows, &columns)
if err != nil {
panic(fmt.Errorf("Unable to read screen size: %s", err))
}
return
}
func readInput() (string, error) {
buffer := make([]byte, 100)
cnt, err := os.Stdin.Read(buffer)
if err != nil {
return "", nil
}
if cnt == 1 && buffer[0] == 0x1b {
return "ESC", nil
} else if cnt == 1 && buffer[0] == ' ' {
return "SPACE", nil
} else if cnt == 1 && buffer[0] == 'c' {
return "C", nil
} else if cnt >= 3 {
if buffer[0] == 0x1b && buffer[1] == '[' {
switch buffer[2] {
case 'A':
return "UP", nil
case 'B':
return "DOWN", nil
case 'C':
return "RIGHT", nil
case 'D':
return "LEFT", nil
}
}
}
return "", nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment