2022-03-13 17:48:49 +00:00
|
|
|
package readline
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"regexp"
|
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Lmorg code
|
|
|
|
// -------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
func leftMost() []byte {
|
|
|
|
fd := int(os.Stdout.Fd())
|
|
|
|
w, _, err := GetSize(fd)
|
|
|
|
if err != nil {
|
|
|
|
return []byte{'\r', '\n'}
|
|
|
|
}
|
|
|
|
|
|
|
|
b := make([]byte, w+1)
|
|
|
|
for i := 0; i < w; i++ {
|
|
|
|
b[i] = ' '
|
|
|
|
}
|
|
|
|
b[w] = '\r'
|
|
|
|
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
var rxRcvCursorPos = regexp.MustCompile("^\x1b([0-9]+);([0-9]+)R$")
|
|
|
|
|
|
|
|
func (rl *Instance) getCursorPos() (x int, y int) {
|
|
|
|
if !rl.EnableGetCursorPos {
|
|
|
|
return -1, -1
|
|
|
|
}
|
|
|
|
|
|
|
|
disable := func() (int, int) {
|
|
|
|
os.Stderr.WriteString("\r\ngetCursorPos() not supported by terminal emulator, disabling....\r\n")
|
|
|
|
rl.EnableGetCursorPos = false
|
|
|
|
return -1, -1
|
|
|
|
}
|
|
|
|
|
|
|
|
print(seqGetCursorPos)
|
|
|
|
b := make([]byte, 64)
|
|
|
|
i, err := os.Stdin.Read(b)
|
|
|
|
if err != nil {
|
|
|
|
return disable()
|
|
|
|
}
|
|
|
|
|
|
|
|
if !rxRcvCursorPos.Match(b[:i]) {
|
|
|
|
return disable()
|
|
|
|
}
|
|
|
|
|
|
|
|
match := rxRcvCursorPos.FindAllStringSubmatch(string(b[:i]), 1)
|
|
|
|
y, err = strconv.Atoi(match[0][1])
|
|
|
|
if err != nil {
|
|
|
|
return disable()
|
|
|
|
}
|
|
|
|
|
|
|
|
x, err = strconv.Atoi(match[0][2])
|
|
|
|
if err != nil {
|
|
|
|
return disable()
|
|
|
|
}
|
|
|
|
|
|
|
|
return x, y
|
|
|
|
}
|
|
|
|
|
|
|
|
// DISPLAY ------------------------------------------------------------
|
|
|
|
// All cursorMoveFunctions move the cursor as it is seen by the user.
|
|
|
|
// This means that they are not used to keep any reference point when
|
|
|
|
// when we internally move around clearning and printing things
|
|
|
|
|
|
|
|
func moveCursorUp(i int) {
|
|
|
|
if i < 1 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("\x1b[%dA", i)
|
|
|
|
}
|
|
|
|
|
|
|
|
func moveCursorDown(i int) {
|
|
|
|
if i < 1 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("\x1b[%dB", i)
|
|
|
|
}
|
|
|
|
|
|
|
|
func moveCursorForwards(i int) {
|
|
|
|
if i < 1 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("\x1b[%dC", i)
|
|
|
|
}
|
|
|
|
|
|
|
|
func moveCursorBackwards(i int) {
|
|
|
|
if i < 1 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("\x1b[%dD", i)
|
|
|
|
}
|
|
|
|
|
2022-03-24 01:11:24 +00:00
|
|
|
func (rl *Instance) backspace(forward bool) {
|
2022-03-13 17:48:49 +00:00
|
|
|
if len(rl.line) == 0 || rl.pos == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-03-24 01:11:24 +00:00
|
|
|
rl.deleteBackspace(forward)
|
2022-03-13 17:48:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (rl *Instance) moveCursorByAdjust(adjust int) {
|
|
|
|
switch {
|
|
|
|
case adjust > 0:
|
|
|
|
rl.pos += adjust
|
|
|
|
case adjust < 0:
|
|
|
|
rl.pos += adjust
|
|
|
|
}
|
|
|
|
|
|
|
|
// The position can never be negative
|
|
|
|
if rl.pos < 0 {
|
|
|
|
rl.pos = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// The cursor can never be longer than the line
|
|
|
|
if rl.pos > len(rl.line) {
|
|
|
|
rl.pos = len(rl.line)
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we are at the end of line, and not in Insert mode, move back one.
|
|
|
|
if rl.modeViMode != VimInsert && (rl.pos == len(rl.line)) && len(rl.line) > 0 {
|
|
|
|
if rl.modeViMode != VimInsert {
|
|
|
|
rl.pos--
|
|
|
|
} else if rl.modeViMode == VimInsert && rl.searchMode == HistoryFind && rl.modeAutoFind {
|
|
|
|
rl.pos--
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|