feat: tx: implemented more stuff and reorganized way to handle signals and keys.

This commit is contained in:
Andrey Parhomenko 2024-07-27 00:27:34 +05:00
parent 1e2d60b0d5
commit 2a13fa4ee3
3 changed files with 69 additions and 28 deletions

View file

@ -67,7 +67,7 @@ const (
RequestCursorPosition = CSI+"6n"
SaveCursorPositionDEC = ESC+" 7"
UnodCursorPositionDEC = ESC+" 8"
UndoCursorPositionDEC = ESC+" 8"
SaveCursorPositionSCO = CSI+"s"
UndoCursorPositionSCO = CSI+"u"

View file

@ -3,7 +3,7 @@ package main
import "surdeus.su/core/cli/tx"
import "log"
import "os"
import "io"
//import "io"
import "surdeus.su/core/cli/aes"
//import "fmt"
@ -12,27 +12,34 @@ func main() {
term, err := tx.NewTerminal(os.Stdin)
if err != nil {
// Some not terminal handling.
log.Fatal("tx.NewTerminal(...): %s\n", err)
log.Fatalf("tx.NewTerminal(...): %s\n", err)
}
keys, signals, err := term.MakeRaw()
if err != nil {
log.Fatalf("term.MakeRaw(...) %s\n", err)
}
term.MakeRaw()
term.EnableAltBuffer()
defer term.Restore()
w, h, err := term.GetSize()
if err != nil {
log.Fatalf("term.GetSize(...): %s\n", err)
}
term.Printf("TermSize: %dx%d\r\n", w, h)
for {
key, _, err := term.ReadKey()
MAIN:
for { select {
// Handling signals.
case sig := <-signals :
if sig == tx.SignalWinChange {
term.SaveCursor()
term.MoveCursorHome()
w, h, _ := term.Size()
term.Printf("%dx%d", w, h)
term.UndoCursor()
}
// Handling keys.
case key := <-keys :
if key == tx.KeyControlC {
break
break MAIN
}
if !normalMode && key == tx.KeyESC {
normalMode = true
continue
break
}
if normalMode { switch key {
case 'j':
@ -47,25 +54,19 @@ func main() {
case 'i' :
normalMode = false
}
continue }
break }
if key == tx.KeyEnter {
term.NextLine(1)
//term.Print("enter")
continue
break
}
if err != nil {
if err == io.EOF {
break
}
log.Fatalf("term.ReadLine(...): %s\n", err)
}
term.Print(
aes.ETF("%s", string(key)).
Bold().
With(aes.EffectRedFG),
)
}
}}
}

View file

@ -5,6 +5,13 @@ import "surdeus.su/core/cli/aes"
import "bufio"
import "fmt"
import "os"
import "os/signal"
import "syscall"
type Signal = os.Signal
const (
SignalWinChange = syscall.SIGWINCH
)
type Terminal struct {
x *term.Terminal
@ -12,6 +19,9 @@ type Terminal struct {
input *bufio.Reader
fd int
prevState *term.State
signals chan Signal
keys chan Key
}
func NewTerminal(input *os.File) (*Terminal, error) {
@ -33,14 +43,27 @@ func NewTerminal(input *os.File) (*Terminal, error) {
return &ret, nil
}
func (t *Terminal) MakeRaw() error {
func (t *Terminal) MakeRaw() (chan Key, chan Signal, error) {
state, err := term.MakeRaw(t.fd)
if err != nil {
return err
return nil, nil, err
}
t.prevState = state
return nil
t.signals = make(chan Signal, 1)
signal.Notify(
t.signals,
syscall.SIGWINCH,
)
t.keys = make(chan Key, 1)
go func() {
for {
r, _, _ := t.input.ReadRune()
t.keys <- Key(r)
}
} ()
return t.keys, t.signals, nil
}
func (t *Terminal) Restore() error {
@ -57,7 +80,7 @@ func (t *Terminal) Restore() error {
return nil
}
func (t *Terminal) GetSize() (int, int, error) {
func (t *Terminal) Size() (int, int, error) {
return term.GetSize(t.fd)
}
@ -65,10 +88,12 @@ func (t *Terminal) ReadLine() (string, error) {
return t.x.ReadLine()
}
/*
func (t *Terminal) ReadKey() (Key, int, error) {
r, size, err := t.input.ReadRune()
return Key(r), size, err
}
*/
func (t *Terminal) Write(bts []byte) (int, error) {
return t.x.Write(bts)
@ -102,6 +127,18 @@ func (t *Terminal) MoveCursorDown(n int) {
t.Printf(aes.MoveCursorDownFormat, n)
}
func (t *Terminal) MoveCursorHome() {
t.Printf("%s", aes.MoveCursorHome)
}
func (t *Terminal) SaveCursor() {
t.Printf("%s", aes.SaveCursorPositionDEC)
}
func (t *Terminal) UndoCursor() {
t.Printf("%s", aes.UndoCursorPositionDEC)
}
func (t *Terminal) NextLine(n int) {
t.Printf(
aes.MoveCursorToBeginOfNextLineDownFormat,
@ -117,3 +154,6 @@ func (t *Terminal) DisableAltBuffer() {
t.Printf("%s", aes.DisableAltBuffer)
}
func (t *Terminal) ClearScreen() {
t.Write([]byte(aes.EraseEntireScreen))
}