feat: tx: started implementing cursor stuff.
This commit is contained in:
parent
141d2a53be
commit
1e2d60b0d5
7 changed files with 145 additions and 4 deletions
|
@ -14,6 +14,7 @@ func (effects Effects) Format() string {
|
|||
return strings.Join(intStrs, ";")
|
||||
}
|
||||
|
||||
// Effect codes.
|
||||
const (
|
||||
EffectReset Effect = iota
|
||||
EffectBold
|
||||
|
@ -23,6 +24,7 @@ const (
|
|||
EffectBlinking
|
||||
)
|
||||
|
||||
// Keep effect codes.
|
||||
const (
|
||||
EffectInverse Effect = 7 + iota
|
||||
EffectHidden
|
||||
|
@ -30,6 +32,7 @@ const (
|
|||
EffectStirke
|
||||
)
|
||||
|
||||
// Foreground effect codes.
|
||||
const (
|
||||
EffectBlackFG = 30 + iota
|
||||
EffectRedFG
|
||||
|
@ -42,6 +45,7 @@ const (
|
|||
EffectDefaultFG
|
||||
)
|
||||
|
||||
// Background effect codes.
|
||||
const (
|
||||
EffectBlackBG Effect = 40 + iota
|
||||
EffectRedBG
|
||||
|
|
60
aes/es.go
60
aes/es.go
|
@ -1,5 +1,9 @@
|
|||
package aes
|
||||
|
||||
const (
|
||||
KeyESC = '\x1B'
|
||||
)
|
||||
|
||||
const (
|
||||
// Start.
|
||||
ESC = "\x1B"
|
||||
|
@ -14,6 +18,7 @@ const (
|
|||
OSC = ESC+"]"
|
||||
)
|
||||
|
||||
// Special control sequences.
|
||||
const (
|
||||
BEL = "\a"
|
||||
BS = "\b"
|
||||
|
@ -25,3 +30,58 @@ const (
|
|||
DEL = "\x7F"
|
||||
)
|
||||
|
||||
// Erasing control sequences.
|
||||
// Names are self describing.
|
||||
const (
|
||||
EraseInDisplay = CSI+"J"
|
||||
EraseFromCursorToEndOfScreen = CSI+"0J"
|
||||
EraseFromCursorToBeginOfScreen = CSI+"1J"
|
||||
EraseEntireScreen = CSI+"2J"
|
||||
EraseSavedLines = CSI+"3J"
|
||||
EraseInLine = CSI+"K"
|
||||
EraseFromCursorToEndOfLine = CSI+"0K"
|
||||
EraseFromStartOfLineToCursor = CSI+"1K"
|
||||
EraseEntireLine = CSI+"2K"
|
||||
)
|
||||
|
||||
// Cursor control sequences.
|
||||
// Any that ends with the "Format" means that
|
||||
// the format is meant to be used via fmt.Sprintf
|
||||
// or any fitting function to provide arguments
|
||||
// into the escape code.
|
||||
const (
|
||||
MoveCursorHome = CSI+"H"
|
||||
|
||||
// Line, column (both int).
|
||||
MoveCursorToFormat = CSI+"%d;%dH"
|
||||
SecondaryMoveCursorToFormat = CSI+"%d;%df"
|
||||
MoveCursorUpFormat = CSI+"%dA"
|
||||
MoveCursorDownFormat = CSI+"%dB"
|
||||
MoveCursorRightFormat = CSI+"%dC"
|
||||
MoveCursorLeftFormat = CSI+"%dD"
|
||||
MoveCursorToBeginOfNextLineDownFormat = CSI+"%dE"
|
||||
MoveCursorToBeginOfPrevLineUpFormat = CSI+"%dF"
|
||||
MoveCursorToColumnFormat = CSI+"%dG"
|
||||
|
||||
RequestCursorPositionReportFormat =CSI+"%d;%dR"
|
||||
RequestCursorPosition = CSI+"6n"
|
||||
|
||||
SaveCursorPositionDEC = ESC+" 7"
|
||||
UnodCursorPositionDEC = ESC+" 8"
|
||||
|
||||
SaveCursorPositionSCO = CSI+"s"
|
||||
UndoCursorPositionSCO = CSI+"u"
|
||||
)
|
||||
|
||||
// Common private modes.
|
||||
const (
|
||||
MakeCursorInvisible = CSI+"?25l"
|
||||
MakeCursorVisible = CSI+"?25h"
|
||||
|
||||
UndoScreen = CSI+"?47l"
|
||||
SaveScreen = CSI+"?47h"
|
||||
|
||||
EnableAltBuffer = CSI+"?1049h"
|
||||
DisableAltBuffer = CSI+"?1049l"
|
||||
)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package aes
|
|||
|
||||
import "fmt"
|
||||
|
||||
// The type implements more or less
|
||||
type EffectText struct {
|
||||
Effects Effects
|
||||
Text string
|
||||
|
@ -13,17 +14,24 @@ func (et EffectText) String() string {
|
|||
et.Effects.Format(), et.Text,
|
||||
)
|
||||
}
|
||||
|
||||
// Create new EffectText with formatted
|
||||
// by the fmt.Sprintf string as text data.
|
||||
func ETF(format string, v ...any) EffectText {
|
||||
ret := EffectText{}
|
||||
ret.Text = fmt.Sprintf(format, v...)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Returns the new EffectText with specified
|
||||
// effects appended.
|
||||
func (et EffectText) With(effects ...Effect) EffectText {
|
||||
et.Effects = append(et.Effects, effects...)
|
||||
return et
|
||||
}
|
||||
|
||||
// Add the bold effect and return
|
||||
// the resulting EffectText.
|
||||
func (et EffectText) Bold() EffectText {
|
||||
return et.With(EffectBold)
|
||||
}
|
||||
|
|
|
@ -8,12 +8,14 @@ import "surdeus.su/core/cli/aes"
|
|||
//import "fmt"
|
||||
|
||||
func main() {
|
||||
normalMode := true
|
||||
term, err := tx.NewTerminal(os.Stdin)
|
||||
if err != nil {
|
||||
// Some not terminal handling.
|
||||
log.Fatal("tx.NewTerminal(...): %s\n", err)
|
||||
}
|
||||
term.MakeRaw()
|
||||
term.EnableAltBuffer()
|
||||
defer term.Restore()
|
||||
|
||||
w, h, err := term.GetSize()
|
||||
|
@ -24,17 +26,45 @@ func main() {
|
|||
|
||||
for {
|
||||
key, _, err := term.ReadKey()
|
||||
|
||||
if key == tx.KeyControlC {
|
||||
break
|
||||
}
|
||||
if !normalMode && key == tx.KeyESC {
|
||||
normalMode = true
|
||||
continue
|
||||
}
|
||||
if normalMode { switch key {
|
||||
case 'j':
|
||||
term.MoveCursorDown(1)
|
||||
case 'k':
|
||||
term.MoveCursorUp(1)
|
||||
case 'h':
|
||||
term.MoveCursorLeft(1)
|
||||
case 'l' :
|
||||
term.MoveCursorRight(1)
|
||||
case tx.KeyESC :
|
||||
case 'i' :
|
||||
normalMode = false
|
||||
}
|
||||
continue }
|
||||
|
||||
if key == tx.KeyEnter {
|
||||
term.NextLine(1)
|
||||
//term.Print("enter")
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
log.Fatalf("term.ReadLine(...): %s\n", err)
|
||||
}
|
||||
if key == tx.KeyControlC {
|
||||
break
|
||||
}
|
||||
term.Print(
|
||||
"shit:", aes.ETF("%q", key).Bold().With(aes.EffectRedFG), "\r\n",
|
||||
aes.ETF("%s", string(key)).
|
||||
Bold().
|
||||
With(aes.EffectRedFG),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package tx
|
||||
|
||||
import "surdeus.su/core/cli/aes"
|
||||
|
||||
type Key rune
|
||||
|
||||
const (
|
||||
KeyControlC Key = '\x03'
|
||||
KeyESC = aes.KeyESC
|
||||
KeyReturn = '\r'
|
||||
KeyEnter = KeyReturn
|
||||
)
|
||||
|
||||
|
|
34
tx/term.go
34
tx/term.go
|
@ -1,6 +1,7 @@
|
|||
package tx
|
||||
|
||||
import "golang.org/x/term"
|
||||
import "surdeus.su/core/cli/aes"
|
||||
import "bufio"
|
||||
import "fmt"
|
||||
import "os"
|
||||
|
@ -43,6 +44,7 @@ func (t *Terminal) MakeRaw() error {
|
|||
}
|
||||
|
||||
func (t *Terminal) Restore() error {
|
||||
t.DisableAltBuffer()
|
||||
if t == nil || t.prevState == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -83,3 +85,35 @@ func (t *Terminal) Print(v ...any) (int, error) {
|
|||
str := fmt.Sprint(v...)
|
||||
return t.Write([]byte(str))
|
||||
}
|
||||
|
||||
func (t *Terminal) MoveCursorRight(n int) {
|
||||
t.Printf(aes.MoveCursorRightFormat, n)
|
||||
}
|
||||
|
||||
func (t *Terminal) MoveCursorLeft(n int) {
|
||||
t.Printf(aes.MoveCursorLeftFormat, n)
|
||||
}
|
||||
|
||||
func (t *Terminal) MoveCursorUp(n int) {
|
||||
t.Printf(aes.MoveCursorUpFormat, n)
|
||||
}
|
||||
|
||||
func (t *Terminal) MoveCursorDown(n int) {
|
||||
t.Printf(aes.MoveCursorDownFormat, n)
|
||||
}
|
||||
|
||||
func (t *Terminal) NextLine(n int) {
|
||||
t.Printf(
|
||||
aes.MoveCursorToBeginOfNextLineDownFormat,
|
||||
n,
|
||||
)
|
||||
}
|
||||
|
||||
func (t *Terminal) EnableAltBuffer() {
|
||||
t.Printf("%s", aes.EnableAltBuffer)
|
||||
}
|
||||
|
||||
func (t *Terminal) DisableAltBuffer() {
|
||||
t.Printf("%s", aes.DisableAltBuffer)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue