terminal_wrapper/terminal.go

92 lines
1.6 KiB
Go

package terminal_wrapper
import (
"errors"
"fmt"
"golang.org/x/term"
"os"
)
type Terminal struct {
oldState *term.State
file *os.File
fd int
internal *term.Terminal
}
type Cursor struct {
terminal *Terminal
}
const (
escFmt = "\x1b["
)
var (
ErrNotTerminal = errors.New("not a terminal")
)
func MakeTerminal(f *os.File) (t *Terminal, err error) {
t = &Terminal{
file: f,
}
t.fd = int(t.file.Fd())
if !term.IsTerminal(t.fd) {
return nil, ErrNotTerminal
}
t.oldState, err = term.MakeRaw(t.fd)
t.internal = term.NewTerminal(t.file, "")
return t, nil
}
func (t *Terminal) Restore() error {
return term.Restore(t.fd, t.oldState)
}
func (t *Terminal) Write(b []byte) (int, error) {
return t.internal.Write(b)
}
func (t *Terminal) EscapePrintln(a ...any) {
_, _ = t.Println(escFmt + fmt.Sprint(a...))
}
func (t *Terminal) EscapePrint(a ...any) {
_, _ = t.Print(escFmt + fmt.Sprint(a...))
}
func (t *Terminal) EscapePrintf(format string, a ...any) {
_, _ = t.Printf(escFmt+format, a...)
}
func (t *Terminal) Printf(format string, a ...any) (int, error) {
return fmt.Fprintf(t, format, a...)
}
func (t *Terminal) Print(a ...any) (int, error) {
return fmt.Fprint(t, a...)
}
func (t *Terminal) Println(a ...any) (int, error) {
return fmt.Fprintln(t, a...)
}
func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
return t.internal.ReadPassword(prompt)
}
func (t *Terminal) ClearScreen() {
t.EscapePrintf("2J")
}
func (t *Terminal) Cursor() Cursor {
return Cursor{
terminal: t,
}
}
func (t *Terminal) ClearLine() {
t.EscapePrintf("2K")
}