bombadillo/cui/cui.go
Hannu Hartikainen e3e2afc4fc Replace calls to stty with syscalls
- Move termios-related functionality to its own package
- Reimplement stty calls using ioctl calls
- Add per-platform constants for linux and non-linux because the ioctl
  enums are different. The enums in Darwin seem to come from BSD and so
  I'm assuming they might also work for other operating systems. If not,
  we'll need to add other build-constrained const files.

This code has been tested on Darwin and will be tested on Linux before
merging.
2020-05-24 09:25:38 +03:00

127 lines
2.5 KiB
Go

package cui
import (
"bufio"
"fmt"
"os"
"os/exec"
"tildegit.org/sloum/bombadillo/termios"
)
var Shapes = map[string]string{
"walll": "╎",
"wallr": " ",
"ceiling": " ",
"floor": " ",
"tl": "╎",
"tr": " ",
"bl": "╎",
"br": " ",
"awalll": "▌",
"awallr": "▐",
"aceiling": "▀",
"afloor": "▄",
"atl": "▞",
"atr": "▜",
"abl": "▚",
"abr": "▟",
}
func MoveCursorTo(row, col int) {
fmt.Printf("\033[%d;%dH", row, col)
}
func moveCursorToward(dir string, amount int) {
directions := map[string]string{
"up": "A",
"down": "B",
"left": "D",
"right": "C",
}
if val, ok := directions[dir]; ok {
fmt.Printf("\033[%d%s", amount, val)
}
}
// Exit performs cleanup operations before exiting the application
func Exit(exitCode int, msg string) {
CleanupTerm()
if msg != "" {
fmt.Print(msg, "\n")
}
fmt.Print("\033[23;0t") // Restore window title from terminal stack
os.Exit(exitCode)
}
// InitTerm sets the terminal modes appropriate for Bombadillo
func InitTerm() {
termios.SetCharMode()
Tput("smcup") // use alternate screen
Tput("rmam") // turn off line wrapping
fmt.Print("\033[?25l") // hide cursor
}
// CleanupTerm reverts changs to terminal mode made by InitTerm
func CleanupTerm() {
moveCursorToward("down", 500)
moveCursorToward("right", 500)
termios.SetLineMode()
fmt.Print("\n")
fmt.Print("\033[?25h") // reenables cursor blinking
Tput("smam") // turn on line wrap
Tput("rmcup") // stop using alternate screen
}
func Clear(dir string) {
directions := map[string]string{
"up": "\033[1J",
"down": "\033[0J",
"left": "\033[1K",
"right": "\033[0K",
"line": "\033[2K",
"screen": "\033[2J",
}
if val, ok := directions[dir]; ok {
fmt.Print(val)
}
}
func Getch() rune {
reader := bufio.NewReader(os.Stdin)
char, _, err := reader.ReadRune()
if err != nil {
return '@'
}
return char
}
func GetLine(prefix string) (string, error) {
termios.SetLineMode()
reader := bufio.NewReader(os.Stdin)
fmt.Print(prefix)
text, err := reader.ReadString('\n')
if err != nil {
return "", err
}
termios.SetCharMode()
return text[:len(text)-1], nil
}
func Tput(opt string) {
cmd := exec.Command("tput", opt)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
// explicitly ignoring the error here as
// the alternate screen is an optional feature
// that may not be available everywhere we expect
// to run
_ = cmd.Run()
}