Cursor postition response can be preceded by user key strokes

This commit is contained in:
Junegunn Choi 2017-01-23 12:47:55 +09:00
parent 12a43b5e62
commit deccdb1ec5
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627

View File

@ -4,6 +4,7 @@ import (
"fmt"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"syscall"
@ -20,10 +21,13 @@ const (
defaultHeight = 24
escPollInterval = 5
offsetPollTries = 10
)
const consoleDevice string = "/dev/tty"
var offsetRegexp *regexp.Regexp = regexp.MustCompile("\x1b\\[([0-9]+);([0-9]+)R")
func openTtyIn() *os.File {
in, err := os.OpenFile(consoleDevice, syscall.O_RDONLY, 0)
if err != nil {
@ -133,18 +137,14 @@ func (r *LightRenderer) defaultTheme() *ColorTheme {
func (r *LightRenderer) findOffset() (row int, col int) {
r.csi("6n")
r.flush()
bytes := r.getBytesInternal([]byte{})
// ^[[*;*R
if len(bytes) > 5 && bytes[0] == 27 && bytes[1] == 91 && bytes[len(bytes)-1] == 'R' {
nums := strings.Split(string(bytes[2:len(bytes)-1]), ";")
if len(nums) == 2 {
return atoi(nums[0], 0) - 1, atoi(nums[1], 0) - 1
bytes := []byte{}
for tries := 0; tries < offsetPollTries; tries++ {
bytes = r.getBytesInternal(bytes, tries > 0)
offsets := offsetRegexp.FindSubmatch(bytes)
if len(offsets) > 2 {
return atoi(string(offsets[1]), 0) - 1, atoi(string(offsets[2]), 0) - 1
}
return -1, -1
}
// No idea
return -1, -1
}
@ -274,18 +274,18 @@ func (r *LightRenderer) getch(nonblock bool) (int, bool) {
}
func (r *LightRenderer) getBytes() []byte {
return r.getBytesInternal(r.buffer)
return r.getBytesInternal(r.buffer, false)
}
func (r *LightRenderer) getBytesInternal(buffer []byte) []byte {
c, ok := r.getch(false)
if !ok {
func (r *LightRenderer) getBytesInternal(buffer []byte, nonblock bool) []byte {
c, ok := r.getch(nonblock)
if !nonblock && !ok {
r.Close()
errorExit("Failed to read " + consoleDevice)
}
retries := 0
if c == ESC {
if c == ESC || nonblock {
retries = r.escDelay / escPollInterval
}
buffer = append(buffer, byte(c))