feat: improve rendering performance on windows (#47)
* feat: to ignore the codepoint 0 * feat: hide cursor whole rendering phase * feat: change EraseDown timing * feat: add sleep * feat: to async Read on windows * style: goimports * refactor: use defer * feat: remove ignore flush * chore: remove ignore output
This commit is contained in:
parent
4dbd0dc8ff
commit
c6186541a9
|
@ -237,16 +237,16 @@ 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 {
|
||||
if b, err := p.in.Read(); err == nil && !(len(b) == 1 && b[0] == 0) {
|
||||
bufCh <- b
|
||||
}
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
render.go
18
render.go
|
@ -1,6 +1,8 @@
|
|||
package prompt
|
||||
|
||||
import "runtime"
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Render to render prompt information from state of Buffer.
|
||||
type Render struct {
|
||||
|
@ -172,9 +174,7 @@ func (r *Render) Render(buffer *Buffer, completion *CompletionManager) {
|
|||
if r.col == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Erasing
|
||||
r.clear(r.previousCursor)
|
||||
r.backward(r.previousCursor, r.previousCursor)
|
||||
|
||||
line := buffer.Text()
|
||||
prefix := r.getCurrentPrefix()
|
||||
|
@ -189,13 +189,20 @@ func (r *Render) Render(buffer *Buffer, completion *CompletionManager) {
|
|||
return
|
||||
}
|
||||
|
||||
defer r.out.Flush()
|
||||
|
||||
// Rendering
|
||||
r.out.HideCursor()
|
||||
defer r.out.ShowCursor()
|
||||
|
||||
r.renderPrefix()
|
||||
r.out.SetColor(r.inputTextColor, r.inputBGColor, false)
|
||||
r.out.WriteStr(line)
|
||||
r.out.SetColor(DefaultColor, DefaultColor, false)
|
||||
r.lineWrap(cursor)
|
||||
|
||||
r.out.EraseDown()
|
||||
|
||||
cursor = r.backward(cursor, len(line)-buffer.CursorPosition)
|
||||
|
||||
r.renderCompletion(buffer, completion)
|
||||
|
@ -209,9 +216,6 @@ func (r *Render) Render(buffer *Buffer, completion *CompletionManager) {
|
|||
cursor += len(suggest.Text)
|
||||
r.lineWrap(cursor)
|
||||
}
|
||||
|
||||
r.out.Flush()
|
||||
|
||||
r.previousCursor = cursor
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,20 @@ package prompt
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"syscall"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mattn/go-tty"
|
||||
)
|
||||
|
||||
const maxReadBytes = 1024
|
||||
|
||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
|
||||
var procGetNumberOfConsoleInputEvents = kernel32.NewProc("GetNumberOfConsoleInputEvents")
|
||||
|
||||
// WindowsParser is a ConsoleParser implementation for Win32 console.
|
||||
type WindowsParser struct {
|
||||
tty *tty.TTY
|
||||
|
@ -43,11 +50,21 @@ func (p *WindowsParser) GetKey(b []byte) Key {
|
|||
|
||||
// Read returns byte array.
|
||||
func (p *WindowsParser) Read() ([]byte, error) {
|
||||
buf := make([]byte, maxReadBytes)
|
||||
var ev uint32
|
||||
r0, _, err := procGetNumberOfConsoleInputEvents.Call(p.tty.Input().Fd(), uintptr(unsafe.Pointer(&ev)))
|
||||
if r0 == 0 {
|
||||
return nil, err
|
||||
}
|
||||
if ev == 0 {
|
||||
return nil, errors.New("EAGAIN")
|
||||
}
|
||||
|
||||
r, err := p.tty.ReadRune()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := make([]byte, maxReadBytes)
|
||||
n := utf8.EncodeRune(buf[:], r)
|
||||
for p.tty.Buffered() && n < maxReadBytes {
|
||||
r, err := p.tty.ReadRune()
|
||||
|
|
|
@ -20,8 +20,6 @@ type WindowsWriter struct {
|
|||
// WriteRaw to write raw byte array
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -257,7 +255,6 @@ func (w *WindowsWriter) SetColor(fg, bg Color, bold bool) {
|
|||
if !ok {
|
||||
b, _ = backgroundANSIColors[DefaultColor]
|
||||
}
|
||||
w.out.Write([]byte{0x1b, 0x5b, 0x33, 0x39, 0x3b, 0x34, 0x39, 0x6d})
|
||||
w.WriteRaw([]byte{0x1b, 0x5b})
|
||||
if !bold {
|
||||
w.WriteRaw([]byte{0x30, 0x3b})
|
||||
|
|
Loading…
Reference in New Issue