mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
* POC for odo interactive testing
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* add interactive tests to make target test-integration
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* [WIP] use func to pass test instructions
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* cleanup comments/test
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* cleanup minor changes
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* fix unit test failure
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* skip for windows
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* skip for windows by not compiling, cleanup
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* cleanup, and add the make target to test files
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* incorporate review, adding comments, cleanup
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* fix failing make validate
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* update test dependency, and possible fix for windows
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
* Revert "update test dependency, and possible fix for windows"
This reverts commit 55580b7dc5.
* Final cleanup
Signed-off-by: anandrkskd <anandrkskd@gmail.com>
190 lines
4.4 KiB
Go
190 lines
4.4 KiB
Go
package vt10x
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// CSI (Control Sequence Introducer)
|
|
// ESC+[
|
|
type csiEscape struct {
|
|
buf []byte
|
|
args []int
|
|
mode byte
|
|
priv bool
|
|
}
|
|
|
|
func (c *csiEscape) reset() {
|
|
c.buf = c.buf[:0]
|
|
c.args = c.args[:0]
|
|
c.mode = 0
|
|
c.priv = false
|
|
}
|
|
|
|
func (c *csiEscape) put(b byte) bool {
|
|
c.buf = append(c.buf, b)
|
|
if b >= 0x40 && b <= 0x7E || len(c.buf) >= 256 {
|
|
c.parse()
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (c *csiEscape) parse() {
|
|
c.mode = c.buf[len(c.buf)-1]
|
|
if len(c.buf) == 1 {
|
|
return
|
|
}
|
|
s := string(c.buf)
|
|
c.args = c.args[:0]
|
|
if s[0] == '?' {
|
|
c.priv = true
|
|
s = s[1:]
|
|
}
|
|
s = s[:len(s)-1]
|
|
ss := strings.Split(s, ";")
|
|
for _, p := range ss {
|
|
i, err := strconv.Atoi(p)
|
|
if err != nil {
|
|
//t.logf("invalid CSI arg '%s'\n", p)
|
|
break
|
|
}
|
|
c.args = append(c.args, i)
|
|
}
|
|
}
|
|
|
|
func (c *csiEscape) arg(i, def int) int {
|
|
if i >= len(c.args) || i < 0 {
|
|
return def
|
|
}
|
|
return c.args[i]
|
|
}
|
|
|
|
// maxarg takes the maximum of arg(i, def) and def
|
|
func (c *csiEscape) maxarg(i, def int) int {
|
|
return max(c.arg(i, def), def)
|
|
}
|
|
|
|
func (t *State) handleCSI() {
|
|
c := &t.csi
|
|
switch c.mode {
|
|
default:
|
|
goto unknown
|
|
case '@': // ICH - insert <n> blank char
|
|
t.insertBlanks(c.arg(0, 1))
|
|
case 'A': // CUU - cursor <n> up
|
|
t.moveTo(t.cur.X, t.cur.Y-c.maxarg(0, 1))
|
|
case 'B', 'e': // CUD, VPR - cursor <n> down
|
|
t.moveTo(t.cur.X, t.cur.Y+c.maxarg(0, 1))
|
|
case 'c': // DA - device attributes
|
|
if c.arg(0, 0) == 0 {
|
|
// TODO: write vt102 id
|
|
}
|
|
case 'C', 'a': // CUF, HPR - cursor <n> forward
|
|
t.moveTo(t.cur.X+c.maxarg(0, 1), t.cur.Y)
|
|
case 'D': // CUB - cursor <n> backward
|
|
t.moveTo(t.cur.X-c.maxarg(0, 1), t.cur.Y)
|
|
case 'E': // CNL - cursor <n> down and first col
|
|
t.moveTo(0, t.cur.Y+c.arg(0, 1))
|
|
case 'F': // CPL - cursor <n> up and first col
|
|
t.moveTo(0, t.cur.Y-c.arg(0, 1))
|
|
case 'g': // TBC - tabulation clear
|
|
switch c.arg(0, 0) {
|
|
// clear current tab stop
|
|
case 0:
|
|
t.tabs[t.cur.X] = false
|
|
// clear all tabs
|
|
case 3:
|
|
for i := range t.tabs {
|
|
t.tabs[i] = false
|
|
}
|
|
default:
|
|
goto unknown
|
|
}
|
|
case 'G', '`': // CHA, HPA - Move to <col>
|
|
t.moveTo(c.arg(0, 1)-1, t.cur.Y)
|
|
case 'H', 'f': // CUP, HVP - move to <row> <col>
|
|
t.moveAbsTo(c.arg(1, 1)-1, c.arg(0, 1)-1)
|
|
case 'I': // CHT - cursor forward tabulation <n> tab stops
|
|
n := c.arg(0, 1)
|
|
for i := 0; i < n; i++ {
|
|
t.putTab(true)
|
|
}
|
|
case 'J': // ED - clear screen
|
|
// TODO: sel.ob.x = -1
|
|
switch c.arg(0, 0) {
|
|
case 0: // below
|
|
t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y)
|
|
if t.cur.Y < t.rows-1 {
|
|
t.clear(0, t.cur.Y+1, t.cols-1, t.rows-1)
|
|
}
|
|
case 1: // above
|
|
if t.cur.Y > 1 {
|
|
t.clear(0, 0, t.cols-1, t.cur.Y-1)
|
|
}
|
|
t.clear(0, t.cur.Y, t.cur.X, t.cur.Y)
|
|
case 2: // all
|
|
t.clear(0, 0, t.cols-1, t.rows-1)
|
|
default:
|
|
goto unknown
|
|
}
|
|
case 'K': // EL - clear line
|
|
switch c.arg(0, 0) {
|
|
case 0: // right
|
|
t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y)
|
|
case 1: // left
|
|
t.clear(0, t.cur.Y, t.cur.X, t.cur.Y)
|
|
case 2: // all
|
|
t.clear(0, t.cur.Y, t.cols-1, t.cur.Y)
|
|
}
|
|
case 'S': // SU - scroll <n> lines up
|
|
t.scrollUp(t.top, c.arg(0, 1))
|
|
case 'T': // SD - scroll <n> lines down
|
|
t.scrollDown(t.top, c.arg(0, 1))
|
|
case 'L': // IL - insert <n> blank lines
|
|
t.insertBlankLines(c.arg(0, 1))
|
|
case 'l': // RM - reset mode
|
|
t.setMode(c.priv, false, c.args)
|
|
case 'M': // DL - delete <n> lines
|
|
t.deleteLines(c.arg(0, 1))
|
|
case 'X': // ECH - erase <n> chars
|
|
t.clear(t.cur.X, t.cur.Y, t.cur.X+c.arg(0, 1)-1, t.cur.Y)
|
|
case 'P': // DCH - delete <n> chars
|
|
t.deleteChars(c.arg(0, 1))
|
|
case 'Z': // CBT - cursor backward tabulation <n> tab stops
|
|
n := c.arg(0, 1)
|
|
for i := 0; i < n; i++ {
|
|
t.putTab(false)
|
|
}
|
|
case 'd': // VPA - move to <row>
|
|
t.moveAbsTo(t.cur.X, c.arg(0, 1)-1)
|
|
case 'h': // SM - set terminal mode
|
|
t.setMode(c.priv, true, c.args)
|
|
case 'm': // SGR - terminal attribute (color)
|
|
t.setAttr(c.args)
|
|
case 'n':
|
|
switch c.arg(0, 0) {
|
|
case 5: // DSR - device status report
|
|
t.w.Write([]byte("\033[0n"))
|
|
case 6: // CPR - cursor position report
|
|
t.w.Write([]byte(fmt.Sprintf("\033[%d;%dR", t.cur.Y+1, t.cur.X+1)))
|
|
}
|
|
case 'r': // DECSTBM - set scrolling region
|
|
if c.priv {
|
|
goto unknown
|
|
} else {
|
|
t.setScroll(c.arg(0, 1)-1, c.arg(1, t.rows)-1)
|
|
t.moveAbsTo(0, 0)
|
|
}
|
|
case 's': // DECSC - save cursor position (ANSI.SYS)
|
|
t.saveCursor()
|
|
case 'u': // DECRC - restore cursor position (ANSI.SYS)
|
|
t.restoreCursor()
|
|
}
|
|
return
|
|
unknown: // TODO: get rid of this goto
|
|
t.logf("unknown CSI sequence '%c'\n", c.mode)
|
|
// TODO: c.dump()
|
|
}
|