forked from sloum/bombadillo
Replace calls to `stty` with <termios.h> cgo
This removes the dependency on `stty` and is the standard POSIX way of modifying terminal state. It requires cgo, so cross-compiling might not be trivial. Otherwise there are no additional dependencies brought in, and this already supports all POSIXish platforms. Fixes #154.
This commit is contained in:
parent
36ae4a228f
commit
60c1c6cff4
20
client.go
20
client.go
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -19,6 +18,7 @@ import (
|
||||||
"tildegit.org/sloum/bombadillo/http"
|
"tildegit.org/sloum/bombadillo/http"
|
||||||
"tildegit.org/sloum/bombadillo/local"
|
"tildegit.org/sloum/bombadillo/local"
|
||||||
"tildegit.org/sloum/bombadillo/telnet"
|
"tildegit.org/sloum/bombadillo/telnet"
|
||||||
|
"tildegit.org/sloum/bombadillo/termios"
|
||||||
)
|
)
|
||||||
|
|
||||||
//------------------------------------------------\\
|
//------------------------------------------------\\
|
||||||
|
@ -43,14 +43,7 @@ type client struct {
|
||||||
//--------------------------------------------------\\
|
//--------------------------------------------------\\
|
||||||
|
|
||||||
func (c *client) GetSizeOnce() {
|
func (c *client) GetSizeOnce() {
|
||||||
cmd := exec.Command("stty", "size")
|
var w, h = termios.GetWindowSize()
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
out, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
cui.Exit(5, "Fatal error: Unable to retrieve terminal size")
|
|
||||||
}
|
|
||||||
var h, w int
|
|
||||||
_, _ = fmt.Sscan(string(out), &h, &w)
|
|
||||||
c.Height = h
|
c.Height = h
|
||||||
c.Width = w
|
c.Width = w
|
||||||
}
|
}
|
||||||
|
@ -61,14 +54,7 @@ func (c *client) GetSize() {
|
||||||
c.Draw()
|
c.Draw()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
cmd := exec.Command("stty", "size")
|
var w, h = termios.GetWindowSize()
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
out, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
cui.Exit(5, "Fatal error: Unable to retrieve terminal size")
|
|
||||||
}
|
|
||||||
var h, w int
|
|
||||||
_, _ = fmt.Sscan(string(out), &h, &w)
|
|
||||||
if h != c.Height || w != c.Width {
|
if h != c.Height || w != c.Width {
|
||||||
c.Height = h
|
c.Height = h
|
||||||
c.Width = w
|
c.Width = w
|
||||||
|
|
32
cui/cui.go
32
cui/cui.go
|
@ -5,6 +5,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
|
"tildegit.org/sloum/bombadillo/termios"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Shapes = map[string]string{
|
var Shapes = map[string]string{
|
||||||
|
@ -55,7 +57,7 @@ func Exit(exitCode int, msg string) {
|
||||||
|
|
||||||
// InitTerm sets the terminal modes appropriate for Bombadillo
|
// InitTerm sets the terminal modes appropriate for Bombadillo
|
||||||
func InitTerm() {
|
func InitTerm() {
|
||||||
SetCharMode()
|
termios.SetCharMode()
|
||||||
Tput("smcup") // use alternate screen
|
Tput("smcup") // use alternate screen
|
||||||
Tput("rmam") // turn off line wrapping
|
Tput("rmam") // turn off line wrapping
|
||||||
}
|
}
|
||||||
|
@ -64,7 +66,7 @@ func InitTerm() {
|
||||||
func CleanupTerm() {
|
func CleanupTerm() {
|
||||||
moveCursorToward("down", 500)
|
moveCursorToward("down", 500)
|
||||||
moveCursorToward("right", 500)
|
moveCursorToward("right", 500)
|
||||||
SetLineMode()
|
termios.SetLineMode()
|
||||||
|
|
||||||
fmt.Print("\n")
|
fmt.Print("\n")
|
||||||
fmt.Print("\033[?25h") // reenables cursor blinking
|
fmt.Print("\033[?25h") // reenables cursor blinking
|
||||||
|
@ -98,7 +100,7 @@ func Getch() rune {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLine(prefix string) (string, error) {
|
func GetLine(prefix string) (string, error) {
|
||||||
SetLineMode()
|
termios.SetLineMode()
|
||||||
|
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
fmt.Print(prefix)
|
fmt.Print(prefix)
|
||||||
|
@ -107,32 +109,10 @@ func GetLine(prefix string) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCharMode()
|
termios.SetCharMode()
|
||||||
return text[:len(text)-1], nil
|
return text[:len(text)-1], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetCharMode() {
|
|
||||||
cmd := exec.Command("stty", "cbreak", "-echo")
|
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Print("\033[?25l")
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetLineMode() {
|
|
||||||
cmd := exec.Command("stty", "-cbreak", "echo")
|
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Tput(opt string) {
|
func Tput(opt string) {
|
||||||
cmd := exec.Command("tput", opt)
|
cmd := exec.Command("tput", opt)
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
// +build cgo
|
||||||
|
|
||||||
|
package termios
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
// NOTE: ioctl() is variadic so cgo requires a wrapper
|
||||||
|
int getWinsize(struct winsize* ws) {
|
||||||
|
return ioctl(STDOUT_FILENO, TIOCGWINSZ, ws);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func GetWindowSize() (int, int) {
|
||||||
|
var value C.struct_winsize
|
||||||
|
C.getWinsize(&value)
|
||||||
|
return int(value.ws_col), int(value.ws_row)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTermios() C.struct_termios {
|
||||||
|
var termios C.struct_termios
|
||||||
|
C.tcgetattr(C.STDIN_FILENO, &termios)
|
||||||
|
return termios
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTermios(termios C.struct_termios) {
|
||||||
|
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &termios)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetCharMode() {
|
||||||
|
var t = getTermios()
|
||||||
|
t.c_lflag = t.c_lflag &^ (C.ICANON | C.ECHO)
|
||||||
|
setTermios(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLineMode() {
|
||||||
|
var t = getTermios()
|
||||||
|
t.c_lflag = t.c_lflag | (C.ICANON | C.ECHO)
|
||||||
|
setTermios(t)
|
||||||
|
}
|
Loading…
Reference in New Issue