Add some refactor changes
This commit is contained in:
parent
04883edce4
commit
661e5e0c0b
|
@ -4,7 +4,7 @@ import "github.com/c-bata/go-prompt"
|
|||
|
||||
func main() {
|
||||
l := 20
|
||||
out := prompt.NewVT100StandardOutputWriter()
|
||||
out := prompt.NewStandardOutputWriter()
|
||||
out.EraseScreen()
|
||||
for i := 0; i < l; i++ {
|
||||
out.CursorGoTo(i, 0)
|
||||
|
|
|
@ -38,7 +38,7 @@ func main() {
|
|||
bufCh := make(chan []byte, 128)
|
||||
go readBuffer(bufCh)
|
||||
fmt.Print("> ")
|
||||
parser := prompt.NewVT100StandardInputParser()
|
||||
parser := prompt.NewStandardInputParser()
|
||||
|
||||
for {
|
||||
b := <-bufCh
|
||||
|
|
|
@ -40,6 +40,8 @@ type ConsoleParser interface {
|
|||
GetKey(b []byte) Key
|
||||
// GetWinSize returns winsize struct which is the response of ioctl(2).
|
||||
GetWinSize() *WinSize
|
||||
// Read returns byte array.
|
||||
Read() ([]byte, error)
|
||||
}
|
||||
|
||||
type ConsoleWriter interface {
|
||||
|
|
2
emacs.go
2
emacs.go
|
@ -110,7 +110,7 @@ var emacsKeyBindings = []KeyBind{
|
|||
{
|
||||
Key: ControlL,
|
||||
Fn: func(buf *Buffer) {
|
||||
out := NewVT100StandardOutputWriter()
|
||||
out := NewStandardOutputWriter()
|
||||
out.EraseScreen()
|
||||
out.CursorGoTo(0, 0)
|
||||
},
|
||||
|
|
|
@ -174,10 +174,10 @@ func OptionAddKeyBind(b ...KeyBind) Option {
|
|||
// New returns a Prompt with powerful auto-completion.
|
||||
func New(executor Executor, completer Completer, opts ...Option) *Prompt {
|
||||
pt := &Prompt{
|
||||
in: NewVT100StandardInputParser(),
|
||||
in: NewStandardInputParser(),
|
||||
renderer: &Render{
|
||||
prefix: "> ",
|
||||
out: NewVT100StandardOutputWriter(),
|
||||
out: NewStandardOutputWriter(),
|
||||
prefixTextColor: Blue,
|
||||
prefixBGColor: DefaultColor,
|
||||
inputTextColor: DefaultColor,
|
||||
|
|
|
@ -11,12 +11,14 @@ import (
|
|||
"github.com/pkg/term/termios"
|
||||
)
|
||||
|
||||
type VT100Parser struct {
|
||||
const maxReadBytes = 1024
|
||||
|
||||
type PosixParser struct {
|
||||
fd int
|
||||
origTermios syscall.Termios
|
||||
}
|
||||
|
||||
func (t *VT100Parser) Setup() error {
|
||||
func (t *PosixParser) Setup() error {
|
||||
// Set NonBlocking mode because if syscall.Read block this goroutine, it cannot receive data from stopCh.
|
||||
if err := syscall.SetNonblock(t.fd, true); err != nil {
|
||||
log.Println("[ERROR] Cannot set non blocking mode.")
|
||||
|
@ -29,7 +31,7 @@ func (t *VT100Parser) Setup() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *VT100Parser) TearDown() error {
|
||||
func (t *PosixParser) TearDown() error {
|
||||
if err := syscall.SetNonblock(t.fd, false); err != nil {
|
||||
log.Println("[ERROR] Cannot set blocking mode.")
|
||||
return err
|
||||
|
@ -41,7 +43,16 @@ func (t *VT100Parser) TearDown() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *VT100Parser) setRawMode() error {
|
||||
func (t *PosixParser) Read() ([]byte, error) {
|
||||
buf := make([]byte, maxReadBytes)
|
||||
n, err := syscall.Read(syscall.Stdin, buf)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return buf[:n], nil
|
||||
}
|
||||
|
||||
func (t *PosixParser) setRawMode() error {
|
||||
x := t.origTermios.Lflag
|
||||
if x &^= syscall.ICANON; x != 0 && x == t.origTermios.Lflag {
|
||||
// fd is already raw mode
|
||||
|
@ -60,14 +71,14 @@ func (t *VT100Parser) setRawMode() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *VT100Parser) resetRawMode() error {
|
||||
func (t *PosixParser) resetRawMode() error {
|
||||
if t.origTermios.Lflag == 0 {
|
||||
return nil
|
||||
}
|
||||
return termios.Tcsetattr(uintptr(t.fd), termios.TCSANOW, &t.origTermios)
|
||||
}
|
||||
|
||||
func (t *VT100Parser) GetKey(b []byte) Key {
|
||||
func (t *PosixParser) GetKey(b []byte) Key {
|
||||
for _, k := range asciiSequences {
|
||||
if bytes.Equal(k.ASCIICode, b) {
|
||||
return k.Key
|
||||
|
@ -85,7 +96,7 @@ type ioctlWinsize struct {
|
|||
}
|
||||
|
||||
// GetWinSize returns winsize struct which is the response of ioctl(2).
|
||||
func (t *VT100Parser) GetWinSize() *WinSize {
|
||||
func (t *PosixParser) GetWinSize() *WinSize {
|
||||
ws := &ioctlWinsize{}
|
||||
retCode, _, errno := syscall.Syscall(
|
||||
syscall.SYS_IOCTL,
|
||||
|
@ -239,10 +250,10 @@ var asciiSequences []*ASCIICode = []*ASCIICode{
|
|||
{Key: Ignore, ASCIICode: []byte{0x1b, 0x5b, 0x46}}, // Linux console
|
||||
}
|
||||
|
||||
var _ ConsoleParser = &VT100Parser{}
|
||||
var _ ConsoleParser = &PosixParser{}
|
||||
|
||||
func NewVT100StandardInputParser() *VT100Parser {
|
||||
return &VT100Parser{
|
||||
func NewStandardInputParser() *PosixParser {
|
||||
return &PosixParser{
|
||||
fd: syscall.Stdin,
|
||||
}
|
||||
}
|
|
@ -7,34 +7,34 @@ import (
|
|||
"syscall"
|
||||
)
|
||||
|
||||
type VT100Writer struct {
|
||||
type PosixWriter struct {
|
||||
fd int
|
||||
buffer []byte
|
||||
}
|
||||
|
||||
func (w *VT100Writer) WriteRaw(data []byte) {
|
||||
func (w *PosixWriter) WriteRaw(data []byte) {
|
||||
w.buffer = append(w.buffer, data...)
|
||||
// Flush because sometimes the render is broken when a large amount data in buffer.
|
||||
w.Flush()
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) Write(data []byte) {
|
||||
func (w *PosixWriter) Write(data []byte) {
|
||||
w.WriteRaw(byteFilter(data, writeFilter))
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) WriteRawStr(data string) {
|
||||
func (w *PosixWriter) WriteRawStr(data string) {
|
||||
w.WriteRaw([]byte(data))
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) WriteStr(data string) {
|
||||
func (w *PosixWriter) WriteStr(data string) {
|
||||
w.Write([]byte(data))
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) Flush() error {
|
||||
func (w *PosixWriter) Flush() error {
|
||||
_, err := syscall.Write(w.fd, w.buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -45,48 +45,48 @@ func (w *VT100Writer) Flush() error {
|
|||
|
||||
/* Erase */
|
||||
|
||||
func (w *VT100Writer) EraseScreen() {
|
||||
func (w *PosixWriter) EraseScreen() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x32, 0x4a})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseUp() {
|
||||
func (w *PosixWriter) EraseUp() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x31, 0x4a})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseDown() {
|
||||
func (w *PosixWriter) EraseDown() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x4a})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseStartOfLine() {
|
||||
func (w *PosixWriter) EraseStartOfLine() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x31, 0x4b})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseEndOfLine() {
|
||||
func (w *PosixWriter) EraseEndOfLine() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x4b})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseLine() {
|
||||
func (w *PosixWriter) EraseLine() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x32, 0x4b})
|
||||
return
|
||||
}
|
||||
|
||||
/* Cursor */
|
||||
|
||||
func (w *VT100Writer) ShowCursor() {
|
||||
func (w *PosixWriter) ShowCursor() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x3f, 0x31, 0x32, 0x6c, 0x1b, 0x5b, 0x3f, 0x32, 0x35, 0x68})
|
||||
}
|
||||
|
||||
func (w *VT100Writer) HideCursor() {
|
||||
func (w *PosixWriter) HideCursor() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x3f, 0x32, 0x35, 0x6c})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorGoTo(row, col int) {
|
||||
func (w *PosixWriter) CursorGoTo(row, col int) {
|
||||
r := strconv.Itoa(row)
|
||||
c := strconv.Itoa(col)
|
||||
w.WriteRaw([]byte{0x1b, 0x5b})
|
||||
|
@ -97,7 +97,7 @@ func (w *VT100Writer) CursorGoTo(row, col int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorUp(n int) {
|
||||
func (w *PosixWriter) CursorUp(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
|
@ -111,7 +111,7 @@ func (w *VT100Writer) CursorUp(n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorDown(n int) {
|
||||
func (w *PosixWriter) CursorDown(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
|
@ -125,7 +125,7 @@ func (w *VT100Writer) CursorDown(n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorForward(n int) {
|
||||
func (w *PosixWriter) CursorForward(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
|
@ -139,7 +139,7 @@ func (w *VT100Writer) CursorForward(n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorBackward(n int) {
|
||||
func (w *PosixWriter) CursorBackward(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
|
@ -153,52 +153,52 @@ func (w *VT100Writer) CursorBackward(n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) AskForCPR() {
|
||||
func (w *PosixWriter) AskForCPR() {
|
||||
// CPR: Cursor Position Request.
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x36, 0x6e})
|
||||
w.Flush()
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) SaveCursor() {
|
||||
func (w *PosixWriter) SaveCursor() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x73})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) UnSaveCursor() {
|
||||
func (w *PosixWriter) UnSaveCursor() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x75})
|
||||
return
|
||||
}
|
||||
|
||||
/* Scrolling */
|
||||
|
||||
func (w *VT100Writer) ScrollDown() {
|
||||
func (w *PosixWriter) ScrollDown() {
|
||||
w.WriteRaw([]byte{0x1b, 0x44})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) ScrollUp() {
|
||||
func (w *PosixWriter) ScrollUp() {
|
||||
w.WriteRaw([]byte{0x1b, 0x4d})
|
||||
return
|
||||
}
|
||||
|
||||
/* Title */
|
||||
|
||||
func (w *VT100Writer) SetTitle(title string) {
|
||||
func (w *PosixWriter) SetTitle(title string) {
|
||||
w.WriteRaw([]byte{0x1b, 0x5d, 0x32, 0x3b})
|
||||
w.WriteRaw(byteFilter([]byte(title), setTextFilter))
|
||||
w.WriteRaw([]byte{0x07})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) ClearTitle() {
|
||||
func (w *PosixWriter) ClearTitle() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5d, 0x32, 0x3b, 0x07})
|
||||
return
|
||||
}
|
||||
|
||||
/* Font */
|
||||
|
||||
func (w *VT100Writer) SetColor(fg, bg Color, bold bool) {
|
||||
func (w *PosixWriter) SetColor(fg, bg Color, bold bool) {
|
||||
f, ok := foregroundANSIColors[fg]
|
||||
if !ok {
|
||||
f = foregroundANSIColors[DefaultColor]
|
||||
|
@ -292,10 +292,10 @@ func byteFilter(buf []byte, fn ...func(b byte) bool) []byte {
|
|||
return byteFilter(ret, fn[1:]...)
|
||||
}
|
||||
|
||||
var _ ConsoleWriter = &VT100Writer{}
|
||||
var _ ConsoleWriter = &PosixWriter{}
|
||||
|
||||
func NewVT100StandardOutputWriter() *VT100Writer {
|
||||
return &VT100Writer{
|
||||
func NewStandardOutputWriter() *PosixWriter {
|
||||
return &PosixWriter{
|
||||
fd: syscall.Stdout,
|
||||
}
|
||||
}
|
20
prompt.go
20
prompt.go
|
@ -10,8 +10,6 @@ import (
|
|||
const (
|
||||
logfile = "/tmp/go-prompt-debug.log"
|
||||
envEnableLog = "GO_PROMPT_ENABLE_LOG"
|
||||
|
||||
maxReadBytes = 1024
|
||||
)
|
||||
|
||||
// Executor is called when user input something text.
|
||||
|
@ -122,6 +120,8 @@ func (p *Prompt) feed(b []byte) (shouldExit bool, exec *Exec) {
|
|||
}
|
||||
case BackTab:
|
||||
p.completion.Previous()
|
||||
case ControlSpace:
|
||||
return
|
||||
default:
|
||||
if s, ok := p.completion.GetSelectedSuggestion(); ok {
|
||||
w := p.buf.Document().GetWordBeforeCursor()
|
||||
|
@ -237,6 +237,22 @@ func (p *Prompt) Input() string {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Prompt) readBuffer(bufCh chan []byte, stopCh chan struct{}) {
|
||||
log.Printf("[INFO] readBuffer start")
|
||||
for {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
select {
|
||||
case <-stopCh:
|
||||
log.Print("[INFO] stop readBuffer")
|
||||
return
|
||||
default:
|
||||
if b, err := p.in.Read(); err == nil {
|
||||
bufCh <- b
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompt) setUp() {
|
||||
p.in.Setup()
|
||||
p.renderer.Setup()
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
// +build !windows
|
||||
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"log"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (p *Prompt) readBuffer(bufCh chan []byte, stopCh chan struct{}) {
|
||||
buf := make([]byte, maxReadBytes)
|
||||
|
||||
log.Printf("[INFO] readBuffer start")
|
||||
for {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
select {
|
||||
case <-stopCh:
|
||||
log.Print("[INFO] stop readBuffer")
|
||||
return
|
||||
default:
|
||||
if n, err := syscall.Read(syscall.Stdin, buf); err == nil {
|
||||
cbuf := make([]byte, n)
|
||||
copy(cbuf, buf[:n])
|
||||
bufCh <- cbuf
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
// +build windows
|
||||
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func (p *Prompt) readBuffer(bufCh chan []byte, stopCh chan struct{}) {
|
||||
buf := make([]byte, maxReadBytes)
|
||||
|
||||
log.Printf("[INFO] readBuffer start")
|
||||
for {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
select {
|
||||
case <-stopCh:
|
||||
log.Print("[INFO] stop readBuffer")
|
||||
return
|
||||
default:
|
||||
if r, err := p.in.(*VT100Parser).tty.ReadRune(); err == nil {
|
||||
n := utf8.EncodeRune(buf[:], r)
|
||||
cbuf := make([]byte, n)
|
||||
copy(cbuf, buf[:n])
|
||||
bufCh <- cbuf
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,30 +4,31 @@ package prompt
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"syscall"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/mattn/go-tty"
|
||||
)
|
||||
|
||||
type VT100Parser struct {
|
||||
fd syscall.Handle
|
||||
const maxReadBytes = 1024
|
||||
|
||||
type WindowsParser struct {
|
||||
tty *tty.TTY
|
||||
}
|
||||
|
||||
func (t *VT100Parser) Setup() error {
|
||||
tty, err := tty.Open()
|
||||
func (p *WindowsParser) Setup() error {
|
||||
t, err := tty.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.tty = tty
|
||||
p.tty = t
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *VT100Parser) TearDown() error {
|
||||
return t.tty.Close()
|
||||
func (p *WindowsParser) TearDown() error {
|
||||
return p.tty.Close()
|
||||
}
|
||||
|
||||
func (t *VT100Parser) GetKey(b []byte) Key {
|
||||
func (p *WindowsParser) GetKey(b []byte) Key {
|
||||
for _, k := range asciiSequences {
|
||||
if bytes.Compare(k.ASCIICode, b) == 0 {
|
||||
return k.Key
|
||||
|
@ -36,9 +37,19 @@ func (t *VT100Parser) GetKey(b []byte) Key {
|
|||
return NotDefined
|
||||
}
|
||||
|
||||
func (p *WindowsParser) Read() ([]byte, error) {
|
||||
buf := make([]byte, maxReadBytes)
|
||||
r, err := p.tty.ReadRune()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
n := utf8.EncodeRune(buf[:], r)
|
||||
return buf[:n], nil
|
||||
}
|
||||
|
||||
// GetWinSize returns winsize struct which is the response of ioctl(2).
|
||||
func (t *VT100Parser) GetWinSize() *WinSize {
|
||||
w, h, err := t.tty.Size()
|
||||
func (p *WindowsParser) GetWinSize() *WinSize {
|
||||
w, h, err := p.tty.Size()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -185,8 +196,6 @@ var asciiSequences []*ASCIICode = []*ASCIICode{
|
|||
{Key: Ignore, ASCIICode: []byte{0x1b, 0x5b, 0x46}}, // Linux console
|
||||
}
|
||||
|
||||
func NewVT100StandardInputParser() *VT100Parser {
|
||||
return &VT100Parser{
|
||||
fd: syscall.Stdin,
|
||||
}
|
||||
func NewStandardInputParser() *WindowsParser {
|
||||
return &WindowsParser{}
|
||||
}
|
|
@ -9,34 +9,34 @@ import (
|
|||
"github.com/mattn/go-colorable"
|
||||
)
|
||||
|
||||
type VT100Writer struct {
|
||||
type WindowsWriter struct {
|
||||
out io.Writer
|
||||
buffer []byte
|
||||
}
|
||||
|
||||
func (w *VT100Writer) WriteRaw(data []byte) {
|
||||
func (w *WindowsWriter) WriteRaw(data []byte) {
|
||||
w.buffer = append(w.buffer, data...)
|
||||
// Flush because sometimes the render is broken when a large amount data in buffer.
|
||||
w.Flush()
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) Write(data []byte) {
|
||||
func (w *WindowsWriter) Write(data []byte) {
|
||||
w.WriteRaw(byteFilter(data, writeFilter))
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) WriteRawStr(data string) {
|
||||
func (w *WindowsWriter) WriteRawStr(data string) {
|
||||
w.WriteRaw([]byte(data))
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) WriteStr(data string) {
|
||||
func (w *WindowsWriter) WriteStr(data string) {
|
||||
w.Write([]byte(data))
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) Flush() error {
|
||||
func (w *WindowsWriter) Flush() error {
|
||||
_, err := w.out.Write(w.buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -47,48 +47,48 @@ func (w *VT100Writer) Flush() error {
|
|||
|
||||
/* Erase */
|
||||
|
||||
func (w *VT100Writer) EraseScreen() {
|
||||
func (w *WindowsWriter) EraseScreen() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x32, 0x4a})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseUp() {
|
||||
func (w *WindowsWriter) EraseUp() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x31, 0x4a})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseDown() {
|
||||
func (w *WindowsWriter) EraseDown() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x4a})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseStartOfLine() {
|
||||
func (w *WindowsWriter) EraseStartOfLine() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x31, 0x4b})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseEndOfLine() {
|
||||
func (w *WindowsWriter) EraseEndOfLine() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x4b})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) EraseLine() {
|
||||
func (w *WindowsWriter) EraseLine() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x32, 0x4b})
|
||||
return
|
||||
}
|
||||
|
||||
/* Cursor */
|
||||
|
||||
func (w *VT100Writer) ShowCursor() {
|
||||
func (w *WindowsWriter) ShowCursor() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x3f, 0x31, 0x32, 0x6c, 0x1b, 0x5b, 0x3f, 0x32, 0x35, 0x68})
|
||||
}
|
||||
|
||||
func (w *VT100Writer) HideCursor() {
|
||||
func (w *WindowsWriter) HideCursor() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x3f, 0x32, 0x35, 0x6c})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorGoTo(row, col int) {
|
||||
func (w *WindowsWriter) CursorGoTo(row, col int) {
|
||||
r := strconv.Itoa(row)
|
||||
c := strconv.Itoa(col)
|
||||
w.WriteRaw([]byte{0x1b, 0x5b})
|
||||
|
@ -99,7 +99,7 @@ func (w *VT100Writer) CursorGoTo(row, col int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorUp(n int) {
|
||||
func (w *WindowsWriter) CursorUp(n int) {
|
||||
if n < 0 {
|
||||
w.CursorDown(n)
|
||||
return
|
||||
|
@ -111,7 +111,7 @@ func (w *VT100Writer) CursorUp(n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorDown(n int) {
|
||||
func (w *WindowsWriter) CursorDown(n int) {
|
||||
if n < 0 {
|
||||
w.CursorUp(n)
|
||||
return
|
||||
|
@ -123,7 +123,7 @@ func (w *VT100Writer) CursorDown(n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorForward(n int) {
|
||||
func (w *WindowsWriter) CursorForward(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
|
@ -137,7 +137,7 @@ func (w *VT100Writer) CursorForward(n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) CursorBackward(n int) {
|
||||
func (w *WindowsWriter) CursorBackward(n int) {
|
||||
if n == 0 {
|
||||
return
|
||||
} else if n < 0 {
|
||||
|
@ -151,52 +151,52 @@ func (w *VT100Writer) CursorBackward(n int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) AskForCPR() {
|
||||
func (w *WindowsWriter) AskForCPR() {
|
||||
// CPR: Cursor Position Request.
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x36, 0x6e})
|
||||
w.Flush()
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) SaveCursor() {
|
||||
func (w *WindowsWriter) SaveCursor() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x73})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) UnSaveCursor() {
|
||||
func (w *WindowsWriter) UnSaveCursor() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5b, 0x75})
|
||||
return
|
||||
}
|
||||
|
||||
/* Scrolling */
|
||||
|
||||
func (w *VT100Writer) ScrollDown() {
|
||||
func (w *WindowsWriter) ScrollDown() {
|
||||
w.WriteRaw([]byte{0x1b, 0x44})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) ScrollUp() {
|
||||
func (w *WindowsWriter) ScrollUp() {
|
||||
w.WriteRaw([]byte{0x1b, 0x4d})
|
||||
return
|
||||
}
|
||||
|
||||
/* Title */
|
||||
|
||||
func (w *VT100Writer) SetTitle(title string) {
|
||||
func (w *WindowsWriter) SetTitle(title string) {
|
||||
w.WriteRaw([]byte{0x1b, 0x5d, 0x32, 0x3b})
|
||||
w.WriteRaw(byteFilter([]byte(title), setTextFilter))
|
||||
w.WriteRaw([]byte{0x07})
|
||||
return
|
||||
}
|
||||
|
||||
func (w *VT100Writer) ClearTitle() {
|
||||
func (w *WindowsWriter) ClearTitle() {
|
||||
w.WriteRaw([]byte{0x1b, 0x5d, 0x32, 0x3b, 0x07})
|
||||
return
|
||||
}
|
||||
|
||||
/* Font */
|
||||
|
||||
func (w *VT100Writer) SetColor(fg, bg Color, bold bool) {
|
||||
func (w *WindowsWriter) SetColor(fg, bg Color, bold bool) {
|
||||
f, ok := foregroundANSIColors[fg]
|
||||
if !ok {
|
||||
f, _ = foregroundANSIColors[DefaultColor]
|
||||
|
@ -290,10 +290,10 @@ func byteFilter(buf []byte, fn ...func(b byte) bool) []byte {
|
|||
return byteFilter(ret, fn[1:]...)
|
||||
}
|
||||
|
||||
var _ ConsoleWriter = &VT100Writer{}
|
||||
var _ ConsoleWriter = &WindowsWriter{}
|
||||
|
||||
func NewVT100StandardOutputWriter() *VT100Writer {
|
||||
return &VT100Writer{
|
||||
func NewStandardOutputWriter() *WindowsWriter {
|
||||
return &WindowsWriter{
|
||||
out: colorable.NewColorableStdout(),
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue