feat: tx: implemented more stuff and reorganized way to handle signals and keys.
This commit is contained in:
parent
1e2d60b0d5
commit
2a13fa4ee3
3 changed files with 69 additions and 28 deletions
|
@ -67,7 +67,7 @@ const (
|
||||||
RequestCursorPosition = CSI+"6n"
|
RequestCursorPosition = CSI+"6n"
|
||||||
|
|
||||||
SaveCursorPositionDEC = ESC+" 7"
|
SaveCursorPositionDEC = ESC+" 7"
|
||||||
UnodCursorPositionDEC = ESC+" 8"
|
UndoCursorPositionDEC = ESC+" 8"
|
||||||
|
|
||||||
SaveCursorPositionSCO = CSI+"s"
|
SaveCursorPositionSCO = CSI+"s"
|
||||||
UndoCursorPositionSCO = CSI+"u"
|
UndoCursorPositionSCO = CSI+"u"
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import "surdeus.su/core/cli/tx"
|
import "surdeus.su/core/cli/tx"
|
||||||
import "log"
|
import "log"
|
||||||
import "os"
|
import "os"
|
||||||
import "io"
|
//import "io"
|
||||||
import "surdeus.su/core/cli/aes"
|
import "surdeus.su/core/cli/aes"
|
||||||
//import "fmt"
|
//import "fmt"
|
||||||
|
|
||||||
|
@ -12,27 +12,34 @@ func main() {
|
||||||
term, err := tx.NewTerminal(os.Stdin)
|
term, err := tx.NewTerminal(os.Stdin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Some not terminal handling.
|
// 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()
|
term.EnableAltBuffer()
|
||||||
defer term.Restore()
|
defer term.Restore()
|
||||||
|
|
||||||
w, h, err := term.GetSize()
|
MAIN:
|
||||||
if err != nil {
|
for { select {
|
||||||
log.Fatalf("term.GetSize(...): %s\n", err)
|
// 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()
|
||||||
}
|
}
|
||||||
term.Printf("TermSize: %dx%d\r\n", w, h)
|
// Handling keys.
|
||||||
|
case key := <-keys :
|
||||||
for {
|
|
||||||
key, _, err := term.ReadKey()
|
|
||||||
|
|
||||||
if key == tx.KeyControlC {
|
if key == tx.KeyControlC {
|
||||||
break
|
break MAIN
|
||||||
}
|
}
|
||||||
if !normalMode && key == tx.KeyESC {
|
if !normalMode && key == tx.KeyESC {
|
||||||
normalMode = true
|
normalMode = true
|
||||||
continue
|
break
|
||||||
}
|
}
|
||||||
if normalMode { switch key {
|
if normalMode { switch key {
|
||||||
case 'j':
|
case 'j':
|
||||||
|
@ -47,25 +54,19 @@ func main() {
|
||||||
case 'i' :
|
case 'i' :
|
||||||
normalMode = false
|
normalMode = false
|
||||||
}
|
}
|
||||||
continue }
|
break }
|
||||||
|
|
||||||
if key == tx.KeyEnter {
|
if key == tx.KeyEnter {
|
||||||
term.NextLine(1)
|
term.NextLine(1)
|
||||||
//term.Print("enter")
|
//term.Print("enter")
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
log.Fatalf("term.ReadLine(...): %s\n", err)
|
|
||||||
}
|
|
||||||
term.Print(
|
term.Print(
|
||||||
aes.ETF("%s", string(key)).
|
aes.ETF("%s", string(key)).
|
||||||
Bold().
|
Bold().
|
||||||
With(aes.EffectRedFG),
|
With(aes.EffectRedFG),
|
||||||
)
|
)
|
||||||
}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
48
tx/term.go
48
tx/term.go
|
@ -5,6 +5,13 @@ import "surdeus.su/core/cli/aes"
|
||||||
import "bufio"
|
import "bufio"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "os"
|
import "os"
|
||||||
|
import "os/signal"
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
type Signal = os.Signal
|
||||||
|
const (
|
||||||
|
SignalWinChange = syscall.SIGWINCH
|
||||||
|
)
|
||||||
|
|
||||||
type Terminal struct {
|
type Terminal struct {
|
||||||
x *term.Terminal
|
x *term.Terminal
|
||||||
|
@ -12,6 +19,9 @@ type Terminal struct {
|
||||||
input *bufio.Reader
|
input *bufio.Reader
|
||||||
fd int
|
fd int
|
||||||
prevState *term.State
|
prevState *term.State
|
||||||
|
|
||||||
|
signals chan Signal
|
||||||
|
keys chan Key
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTerminal(input *os.File) (*Terminal, error) {
|
func NewTerminal(input *os.File) (*Terminal, error) {
|
||||||
|
@ -33,14 +43,27 @@ func NewTerminal(input *os.File) (*Terminal, error) {
|
||||||
return &ret, nil
|
return &ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) MakeRaw() error {
|
func (t *Terminal) MakeRaw() (chan Key, chan Signal, error) {
|
||||||
state, err := term.MakeRaw(t.fd)
|
state, err := term.MakeRaw(t.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
t.prevState = state
|
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 {
|
func (t *Terminal) Restore() error {
|
||||||
|
@ -57,7 +80,7 @@ func (t *Terminal) Restore() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) GetSize() (int, int, error) {
|
func (t *Terminal) Size() (int, int, error) {
|
||||||
return term.GetSize(t.fd)
|
return term.GetSize(t.fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,10 +88,12 @@ func (t *Terminal) ReadLine() (string, error) {
|
||||||
return t.x.ReadLine()
|
return t.x.ReadLine()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func (t *Terminal) ReadKey() (Key, int, error) {
|
func (t *Terminal) ReadKey() (Key, int, error) {
|
||||||
r, size, err := t.input.ReadRune()
|
r, size, err := t.input.ReadRune()
|
||||||
return Key(r), size, err
|
return Key(r), size, err
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func (t *Terminal) Write(bts []byte) (int, error) {
|
func (t *Terminal) Write(bts []byte) (int, error) {
|
||||||
return t.x.Write(bts)
|
return t.x.Write(bts)
|
||||||
|
@ -102,6 +127,18 @@ func (t *Terminal) MoveCursorDown(n int) {
|
||||||
t.Printf(aes.MoveCursorDownFormat, n)
|
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) {
|
func (t *Terminal) NextLine(n int) {
|
||||||
t.Printf(
|
t.Printf(
|
||||||
aes.MoveCursorToBeginOfNextLineDownFormat,
|
aes.MoveCursorToBeginOfNextLineDownFormat,
|
||||||
|
@ -117,3 +154,6 @@ func (t *Terminal) DisableAltBuffer() {
|
||||||
t.Printf("%s", aes.DisableAltBuffer)
|
t.Printf("%s", aes.DisableAltBuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Terminal) ClearScreen() {
|
||||||
|
t.Write([]byte(aes.EraseEntireScreen))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue