summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2017-01-23 12:47:55 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2017-01-23 12:55:11 +0900
commitdeccdb1ec5079d490bd390c14b3f9a25c8d574db (patch)
tree3cd56c23ab7629f42bc9d4a37947fd16c8f6e183 /src
parent12a43b5e62ca71eb25368b926d032c2666b43e4d (diff)
Cursor postition response can be preceded by user key strokes
Diffstat (limited to 'src')
-rw-r--r--src/tui/light.go30
1 files changed, 15 insertions, 15 deletions
diff --git a/src/tui/light.go b/src/tui/light.go
index 7bc2ec21..cfccc4b5 100644
--- a/src/tui/light.go
+++ b/src/tui/light.go
@@ -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))