forked from aniani/vim
patch 8.0.0693: no terminal emulator support
Problem: No terminal emulator support. Cannot properly run commands in the
GUI. Cannot run a job interactively with an ssh connection.
Solution: Very early implementation of the :terminal command. Includes
libvterm converted to ANSI C. Many parts still missing.
This commit is contained in:
200
src/libvterm/t/02parser.test
Normal file
200
src/libvterm/t/02parser.test
Normal file
@@ -0,0 +1,200 @@
|
||||
INIT
|
||||
UTF8 0
|
||||
WANTPARSER
|
||||
|
||||
!Basic text
|
||||
PUSH "hello"
|
||||
text 0x68, 0x65, 0x6c, 0x6c, 0x6f
|
||||
|
||||
!C0
|
||||
PUSH "\x03"
|
||||
control 3
|
||||
|
||||
PUSH "\x1f"
|
||||
control 0x1f
|
||||
|
||||
!C1 8bit
|
||||
PUSH "\x83"
|
||||
control 0x83
|
||||
|
||||
PUSH "\x9f"
|
||||
control 0x9f
|
||||
|
||||
!C1 7bit
|
||||
PUSH "\e\x43"
|
||||
control 0x83
|
||||
|
||||
PUSH "\e\x5f"
|
||||
control 0x9f
|
||||
|
||||
!High bytes
|
||||
PUSH "\xa0\xcc\xfe"
|
||||
text 0xa0, 0xcc, 0xfe
|
||||
|
||||
!Mixed
|
||||
PUSH "1\n2"
|
||||
text 0x31
|
||||
control 10
|
||||
text 0x32
|
||||
|
||||
!Escape
|
||||
PUSH "\e="
|
||||
escape "="
|
||||
|
||||
!Escape 2-byte
|
||||
PUSH "\e(X"
|
||||
escape "(X"
|
||||
|
||||
!Split write Escape
|
||||
PUSH "\e("
|
||||
PUSH "Y"
|
||||
escape "(Y"
|
||||
|
||||
!Escape cancels Escape, starts another
|
||||
PUSH "\e(\e)Z"
|
||||
escape ")Z"
|
||||
|
||||
!CAN cancels Escape, returns to normal mode
|
||||
PUSH "\e(\x{18}AB"
|
||||
text 0x41, 0x42
|
||||
|
||||
!C0 in Escape interrupts and continues
|
||||
PUSH "\e(\nX"
|
||||
control 10
|
||||
escape "(X"
|
||||
|
||||
!CSI 0 args
|
||||
PUSH "\e[a"
|
||||
csi 0x61 *
|
||||
|
||||
!CSI 1 arg
|
||||
PUSH "\e[9b"
|
||||
csi 0x62 9
|
||||
|
||||
!CSI 2 args
|
||||
PUSH "\e[3;4c"
|
||||
csi 0x63 3,4
|
||||
|
||||
!CSI 1 arg 1 sub
|
||||
PUSH "\e[1:2c"
|
||||
csi 0x63 1+,2
|
||||
|
||||
!CSI many digits
|
||||
PUSH "\e[678d"
|
||||
csi 0x64 678
|
||||
|
||||
!CSI leading zero
|
||||
PUSH "\e[007e"
|
||||
csi 0x65 7
|
||||
|
||||
!CSI qmark
|
||||
PUSH "\e[?2;7f"
|
||||
csi 0x66 L=3f 2,7
|
||||
|
||||
!CSI greater
|
||||
PUSH "\e[>c"
|
||||
csi 0x63 L=3e *
|
||||
|
||||
!CSI SP
|
||||
PUSH "\e[12 q"
|
||||
csi 0x71 12 I=20
|
||||
|
||||
!Mixed CSI
|
||||
PUSH "A\e[8mB"
|
||||
text 0x41
|
||||
csi 0x6d 8
|
||||
text 0x42
|
||||
|
||||
!Split write
|
||||
PUSH "\e"
|
||||
PUSH "[a"
|
||||
csi 0x61 *
|
||||
PUSH "foo\e["
|
||||
text 0x66, 0x6f, 0x6f
|
||||
PUSH "4b"
|
||||
csi 0x62 4
|
||||
PUSH "\e[12;"
|
||||
PUSH "3c"
|
||||
csi 0x63 12,3
|
||||
|
||||
!Escape cancels CSI, starts Escape
|
||||
PUSH "\e[123\e9"
|
||||
escape "9"
|
||||
|
||||
!CAN cancels CSI, returns to normal mode
|
||||
PUSH "\e[12\x{18}AB"
|
||||
text 0x41, 0x42
|
||||
|
||||
!C0 in Escape interrupts and continues
|
||||
PUSH "\e[12\n;3X"
|
||||
control 10
|
||||
csi 0x58 12,3
|
||||
|
||||
!OSC BEL
|
||||
PUSH "\e]1;Hello\x07"
|
||||
osc "1;Hello"
|
||||
|
||||
!OSC ST (7bit)
|
||||
PUSH "\e]1;Hello\e\\"
|
||||
osc "1;Hello"
|
||||
|
||||
!OSC ST (8bit)
|
||||
PUSH "\x{9d}1;Hello\x9c"
|
||||
osc "1;Hello"
|
||||
|
||||
!Escape cancels OSC, starts Escape
|
||||
PUSH "\e]Something\e9"
|
||||
escape "9"
|
||||
|
||||
!CAN cancels OSC, returns to normal mode
|
||||
PUSH "\e]12\x{18}AB"
|
||||
text 0x41, 0x42
|
||||
|
||||
!C0 in OSC interrupts and continues
|
||||
PUSH "\e]2;\nBye\x07"
|
||||
control 10
|
||||
osc "2;Bye"
|
||||
|
||||
!DCS BEL
|
||||
PUSH "\ePHello\x07"
|
||||
dcs "Hello"
|
||||
|
||||
!DCS ST (7bit)
|
||||
PUSH "\ePHello\e\\"
|
||||
dcs "Hello"
|
||||
|
||||
!DCS ST (8bit)
|
||||
PUSH "\x{90}Hello\x9c"
|
||||
dcs "Hello"
|
||||
|
||||
!Escape cancels DCS, starts Escape
|
||||
PUSH "\ePSomething\e9"
|
||||
escape "9"
|
||||
|
||||
!CAN cancels DCS, returns to normal mode
|
||||
PUSH "\eP12\x{18}AB"
|
||||
text 0x41, 0x42
|
||||
|
||||
!C0 in OSC interrupts and continues
|
||||
PUSH "\ePBy\ne\x07"
|
||||
control 10
|
||||
dcs "Bye"
|
||||
|
||||
!NUL ignored
|
||||
PUSH "\x{00}"
|
||||
|
||||
!NUL ignored within CSI
|
||||
PUSH "\e[12\x{00}3m"
|
||||
csi 0x6d 123
|
||||
|
||||
!DEL ignored
|
||||
PUSH "\x{7f}"
|
||||
|
||||
!DEL ignored within CSI
|
||||
PUSH "\e[12\x{7f}3m"
|
||||
csi 0x6d 123
|
||||
|
||||
!DEL inside text"
|
||||
PUSH "AB\x{7f}C"
|
||||
text 0x41,0x42
|
||||
text 0x43
|
||||
122
src/libvterm/t/03encoding_utf8.test
Normal file
122
src/libvterm/t/03encoding_utf8.test
Normal file
@@ -0,0 +1,122 @@
|
||||
INIT
|
||||
WANTENCODING
|
||||
|
||||
!Low
|
||||
ENCIN "123"
|
||||
encout 0x31,0x32,0x33
|
||||
|
||||
# We want to prove the UTF-8 parser correctly handles all the sequences.
|
||||
# Easy way to do this is to check it does low/high boundary cases, as that
|
||||
# leaves only two for each sequence length
|
||||
#
|
||||
# These ranges are therefore:
|
||||
#
|
||||
# Two bytes:
|
||||
# U+0080 = 000 10000000 => 00010 000000
|
||||
# => 11000010 10000000 = C2 80
|
||||
# U+07FF = 111 11111111 => 11111 111111
|
||||
# => 11011111 10111111 = DF BF
|
||||
#
|
||||
# Three bytes:
|
||||
# U+0800 = 00001000 00000000 => 0000 100000 000000
|
||||
# => 11100000 10100000 10000000 = E0 A0 80
|
||||
# U+FFFD = 11111111 11111101 => 1111 111111 111101
|
||||
# => 11101111 10111111 10111101 = EF BF BD
|
||||
# (We avoid U+FFFE and U+FFFF as they're invalid codepoints)
|
||||
#
|
||||
# Four bytes:
|
||||
# U+10000 = 00001 00000000 00000000 => 000 010000 000000 000000
|
||||
# => 11110000 10010000 10000000 10000000 = F0 90 80 80
|
||||
# U+1FFFFF = 11111 11111111 11111111 => 111 111111 111111 111111
|
||||
# => 11110111 10111111 10111111 10111111 = F7 BF BF BF
|
||||
|
||||
!2 byte
|
||||
ENCIN "\xC2\x80\xDF\xBF"
|
||||
encout 0x0080, 0x07FF
|
||||
|
||||
!3 byte
|
||||
ENCIN "\xE0\xA0\x80\xEF\xBF\xBD"
|
||||
encout 0x0800,0xFFFD
|
||||
|
||||
!4 byte
|
||||
ENCIN "\xF0\x90\x80\x80\xF7\xBF\xBF\xBF"
|
||||
encout 0x10000,0x1fffff
|
||||
|
||||
# Next up, we check some invalid sequences
|
||||
# + Early termination (back to low bytes too soon)
|
||||
# + Early restart (another sequence introduction before the previous one was finished)
|
||||
|
||||
!Early termination
|
||||
ENCIN "\xC2!"
|
||||
encout 0xfffd,0x21
|
||||
|
||||
ENCIN "\xE0!\xE0\xA0!"
|
||||
encout 0xfffd,0x21,0xfffd,0x21
|
||||
|
||||
ENCIN "\xF0!\xF0\x90!\xF0\x90\x80!"
|
||||
encout 0xfffd,0x21,0xfffd,0x21,0xfffd,0x21
|
||||
|
||||
!Early restart
|
||||
ENCIN "\xC2\xC2\x90"
|
||||
encout 0xfffd,0x0090
|
||||
|
||||
ENCIN "\xE0\xC2\x90\xE0\xA0\xC2\x90"
|
||||
encout 0xfffd,0x0090,0xfffd,0x0090
|
||||
|
||||
ENCIN "\xF0\xC2\x90\xF0\x90\xC2\x90\xF0\x90\x80\xC2\x90"
|
||||
encout 0xfffd,0x0090,0xfffd,0x0090,0xfffd,0x0090
|
||||
|
||||
# Test the overlong sequences by giving an overlong encoding of U+0000 and
|
||||
# an encoding of the highest codepoint still too short
|
||||
#
|
||||
# Two bytes:
|
||||
# U+0000 = C0 80
|
||||
# U+007F = 000 01111111 => 00001 111111 =>
|
||||
# => 11000001 10111111 => C1 BF
|
||||
#
|
||||
# Three bytes:
|
||||
# U+0000 = E0 80 80
|
||||
# U+07FF = 00000111 11111111 => 0000 011111 111111
|
||||
# => 11100000 10011111 10111111 = E0 9F BF
|
||||
#
|
||||
# Four bytes:
|
||||
# U+0000 = F0 80 80 80
|
||||
# U+FFFF = 11111111 11111111 => 000 001111 111111 111111
|
||||
# => 11110000 10001111 10111111 10111111 = F0 8F BF BF
|
||||
|
||||
!Overlong
|
||||
ENCIN "\xC0\x80\xC1\xBF"
|
||||
encout 0xfffd,0xfffd
|
||||
|
||||
ENCIN "\xE0\x80\x80\xE0\x9F\xBF"
|
||||
encout 0xfffd,0xfffd
|
||||
|
||||
ENCIN "\xF0\x80\x80\x80\xF0\x8F\xBF\xBF"
|
||||
encout 0xfffd,0xfffd
|
||||
|
||||
# UTF-16 surrogates U+D800 and U+DFFF
|
||||
!UTF-16 Surrogates
|
||||
ENCIN "\xED\xA0\x80\xED\xBF\xBF"
|
||||
encout 0xfffd,0xfffd
|
||||
|
||||
!Split write
|
||||
ENCIN "\xC2"
|
||||
ENCIN "\xA0"
|
||||
encout 0x000A0
|
||||
|
||||
ENCIN "\xE0"
|
||||
ENCIN "\xA0\x80"
|
||||
encout 0x00800
|
||||
ENCIN "\xE0\xA0"
|
||||
ENCIN "\x80"
|
||||
encout 0x00800
|
||||
|
||||
ENCIN "\xF0"
|
||||
ENCIN "\x90\x80\x80"
|
||||
encout 0x10000
|
||||
ENCIN "\xF0\x90"
|
||||
ENCIN "\x80\x80"
|
||||
encout 0x10000
|
||||
ENCIN "\xF0\x90\x80"
|
||||
ENCIN "\x80"
|
||||
encout 0x10000
|
||||
55
src/libvterm/t/10state_putglyph.test
Normal file
55
src/libvterm/t/10state_putglyph.test
Normal file
@@ -0,0 +1,55 @@
|
||||
INIT
|
||||
UTF8 1
|
||||
WANTSTATE g
|
||||
|
||||
!Low
|
||||
RESET
|
||||
PUSH "ABC"
|
||||
putglyph 0x41 1 0,0
|
||||
putglyph 0x42 1 0,1
|
||||
putglyph 0x43 1 0,2
|
||||
|
||||
!UTF-8 1 char
|
||||
# U+00C1 = 0xC3 0x81 name: LATIN CAPITAL LETTER A WITH ACUTE
|
||||
# U+00E9 = 0xC3 0xA9 name: LATIN SMALL LETTER E WITH ACUTE
|
||||
RESET
|
||||
PUSH "\xC3\x81\xC3\xA9"
|
||||
putglyph 0xc1 1 0,0
|
||||
putglyph 0xe9 1 0,1
|
||||
|
||||
!UTF-8 wide char
|
||||
# U+FF10 = 0xEF 0xBC 0x90 name: FULLWIDTH DIGIT ZERO
|
||||
RESET
|
||||
PUSH "\xEF\xBC\x90 "
|
||||
putglyph 0xff10 2 0,0
|
||||
putglyph 0x20 1 0,2
|
||||
|
||||
!UTF-8 combining chars
|
||||
# U+0301 = 0xCC 0x81 name: COMBINING ACUTE
|
||||
RESET
|
||||
PUSH "e\xCC\x81Z"
|
||||
putglyph 0x65,0x301 1 0,0
|
||||
putglyph 0x5a 1 0,1
|
||||
|
||||
!Combining across buffers
|
||||
RESET
|
||||
PUSH "e"
|
||||
putglyph 0x65 1 0,0
|
||||
PUSH "\xCC\x81Z"
|
||||
putglyph 0x65,0x301 1 0,0
|
||||
putglyph 0x5a 1 0,1
|
||||
|
||||
RESET
|
||||
PUSH "e"
|
||||
putglyph 0x65 1 0,0
|
||||
PUSH "\xCC\x81"
|
||||
putglyph 0x65,0x301 1 0,0
|
||||
PUSH "\xCC\x82"
|
||||
putglyph 0x65,0x301,0x302 1 0,0
|
||||
|
||||
!DECSCA protected
|
||||
RESET
|
||||
PUSH "A\e[1\"qB\e[2\"qC"
|
||||
putglyph 0x41 1 0,0
|
||||
putglyph 0x42 1 0,1 prot
|
||||
putglyph 0x43 1 0,2
|
||||
224
src/libvterm/t/11state_movecursor.test
Normal file
224
src/libvterm/t/11state_movecursor.test
Normal file
@@ -0,0 +1,224 @@
|
||||
INIT
|
||||
UTF8 1
|
||||
WANTSTATE
|
||||
|
||||
!Implicit
|
||||
PUSH "ABC"
|
||||
?cursor = 0,3
|
||||
!Backspace
|
||||
PUSH "\b"
|
||||
?cursor = 0,2
|
||||
!Horizontal Tab
|
||||
PUSH "\t"
|
||||
?cursor = 0,8
|
||||
!Carriage Return
|
||||
PUSH "\r"
|
||||
?cursor = 0,0
|
||||
!Linefeed
|
||||
PUSH "\n"
|
||||
?cursor = 1,0
|
||||
|
||||
!Backspace bounded by lefthand edge
|
||||
PUSH "\e[4;2H"
|
||||
?cursor = 3,1
|
||||
PUSH "\b"
|
||||
?cursor = 3,0
|
||||
PUSH "\b"
|
||||
?cursor = 3,0
|
||||
|
||||
!Backspace cancels phantom
|
||||
PUSH "\e[4;80H"
|
||||
?cursor = 3,79
|
||||
PUSH "X"
|
||||
?cursor = 3,79
|
||||
PUSH "\b"
|
||||
?cursor = 3,78
|
||||
|
||||
!HT bounded by righthand edge
|
||||
PUSH "\e[1;78H"
|
||||
?cursor = 0,77
|
||||
PUSH "\t"
|
||||
?cursor = 0,79
|
||||
PUSH "\t"
|
||||
?cursor = 0,79
|
||||
|
||||
RESET
|
||||
|
||||
!Index
|
||||
PUSH "ABC\eD"
|
||||
?cursor = 1,3
|
||||
!Reverse Index
|
||||
PUSH "\eM"
|
||||
?cursor = 0,3
|
||||
!Newline
|
||||
PUSH "\eE"
|
||||
?cursor = 1,0
|
||||
|
||||
RESET
|
||||
|
||||
!Cursor Forward
|
||||
PUSH "\e[B"
|
||||
?cursor = 1,0
|
||||
PUSH "\e[3B"
|
||||
?cursor = 4,0
|
||||
PUSH "\e[0B"
|
||||
?cursor = 5,0
|
||||
|
||||
!Cursor Down
|
||||
PUSH "\e[C"
|
||||
?cursor = 5,1
|
||||
PUSH "\e[3C"
|
||||
?cursor = 5,4
|
||||
PUSH "\e[0C"
|
||||
?cursor = 5,5
|
||||
|
||||
!Cursor Up
|
||||
PUSH "\e[A"
|
||||
?cursor = 4,5
|
||||
PUSH "\e[3A"
|
||||
?cursor = 1,5
|
||||
PUSH "\e[0A"
|
||||
?cursor = 0,5
|
||||
|
||||
!Cursor Backward
|
||||
PUSH "\e[D"
|
||||
?cursor = 0,4
|
||||
PUSH "\e[3D"
|
||||
?cursor = 0,1
|
||||
PUSH "\e[0D"
|
||||
?cursor = 0,0
|
||||
|
||||
!Cursor Next Line
|
||||
PUSH " "
|
||||
?cursor = 0,3
|
||||
PUSH "\e[E"
|
||||
?cursor = 1,0
|
||||
PUSH " "
|
||||
?cursor = 1,3
|
||||
PUSH "\e[2E"
|
||||
?cursor = 3,0
|
||||
PUSH "\e[0E"
|
||||
?cursor = 4,0
|
||||
|
||||
!Cursor Previous Line
|
||||
PUSH " "
|
||||
?cursor = 4,3
|
||||
PUSH "\e[F"
|
||||
?cursor = 3,0
|
||||
PUSH " "
|
||||
?cursor = 3,3
|
||||
PUSH "\e[2F"
|
||||
?cursor = 1,0
|
||||
PUSH "\e[0F"
|
||||
?cursor = 0,0
|
||||
|
||||
!Cursor Horizonal Absolute
|
||||
PUSH "\n"
|
||||
?cursor = 1,0
|
||||
PUSH "\e[20G"
|
||||
?cursor = 1,19
|
||||
PUSH "\e[G"
|
||||
?cursor = 1,0
|
||||
|
||||
!Cursor Position
|
||||
PUSH "\e[10;5H"
|
||||
?cursor = 9,4
|
||||
PUSH "\e[8H"
|
||||
?cursor = 7,0
|
||||
PUSH "\e[H"
|
||||
?cursor = 0,0
|
||||
|
||||
!Cursor Position cancels phantom
|
||||
PUSH "\e[10;78H"
|
||||
?cursor = 9,77
|
||||
PUSH "ABC"
|
||||
?cursor = 9,79
|
||||
PUSH "\e[10;80H"
|
||||
PUSH "C"
|
||||
?cursor = 9,79
|
||||
PUSH "X"
|
||||
?cursor = 10,1
|
||||
|
||||
RESET
|
||||
|
||||
!Bounds Checking
|
||||
PUSH "\e[A"
|
||||
?cursor = 0,0
|
||||
PUSH "\e[D"
|
||||
?cursor = 0,0
|
||||
PUSH "\e[25;80H"
|
||||
?cursor = 24,79
|
||||
PUSH "\e[B"
|
||||
?cursor = 24,79
|
||||
PUSH "\e[C"
|
||||
?cursor = 24,79
|
||||
PUSH "\e[E"
|
||||
?cursor = 24,0
|
||||
PUSH "\e[H"
|
||||
?cursor = 0,0
|
||||
PUSH "\e[F"
|
||||
?cursor = 0,0
|
||||
PUSH "\e[999G"
|
||||
?cursor = 0,79
|
||||
PUSH "\e[99;99H"
|
||||
?cursor = 24,79
|
||||
|
||||
RESET
|
||||
|
||||
!Horizontal Position Absolute
|
||||
PUSH "\e[5`"
|
||||
?cursor = 0,4
|
||||
|
||||
!Horizontal Position Relative
|
||||
PUSH "\e[3a"
|
||||
?cursor = 0,7
|
||||
|
||||
!Horizontal Position Backward
|
||||
PUSH "\e[3j"
|
||||
?cursor = 0,4
|
||||
|
||||
!Horizontal and Vertical Position
|
||||
PUSH "\e[3;3f"
|
||||
?cursor = 2,2
|
||||
|
||||
!Vertical Position Absolute
|
||||
PUSH "\e[5d"
|
||||
?cursor = 4,2
|
||||
|
||||
!Vertical Position Relative
|
||||
PUSH "\e[2e"
|
||||
?cursor = 6,2
|
||||
|
||||
!Vertical Position Backward
|
||||
PUSH "\e[2k"
|
||||
?cursor = 4,2
|
||||
|
||||
RESET
|
||||
|
||||
!Horizontal Tab
|
||||
PUSH "\t"
|
||||
?cursor = 0,8
|
||||
PUSH " "
|
||||
?cursor = 0,11
|
||||
PUSH "\t"
|
||||
?cursor = 0,16
|
||||
PUSH " "
|
||||
?cursor = 0,23
|
||||
PUSH "\t"
|
||||
?cursor = 0,24
|
||||
PUSH " "
|
||||
?cursor = 0,32
|
||||
PUSH "\t"
|
||||
?cursor = 0,40
|
||||
|
||||
!Cursor Horizontal Tab
|
||||
PUSH "\e[I"
|
||||
?cursor = 0,48
|
||||
PUSH "\e[2I"
|
||||
?cursor = 0,64
|
||||
|
||||
!Cursor Backward Tab
|
||||
PUSH "\e[Z"
|
||||
?cursor = 0,56
|
||||
PUSH "\e[2Z"
|
||||
?cursor = 0,40
|
||||
150
src/libvterm/t/12state_scroll.test
Normal file
150
src/libvterm/t/12state_scroll.test
Normal file
@@ -0,0 +1,150 @@
|
||||
INIT
|
||||
UTF8 1
|
||||
WANTSTATE s
|
||||
|
||||
!Linefeed
|
||||
PUSH "\n"x24
|
||||
?cursor = 24,0
|
||||
PUSH "\n"
|
||||
scrollrect 0..25,0..80 => +1,+0
|
||||
?cursor = 24,0
|
||||
|
||||
RESET
|
||||
|
||||
!Index
|
||||
PUSH "\e[25H"
|
||||
PUSH "\eD"
|
||||
scrollrect 0..25,0..80 => +1,+0
|
||||
|
||||
RESET
|
||||
|
||||
!Reverse Index
|
||||
PUSH "\eM"
|
||||
scrollrect 0..25,0..80 => -1,+0
|
||||
|
||||
RESET
|
||||
|
||||
!Linefeed in DECSTBM
|
||||
PUSH "\e[1;10r"
|
||||
?cursor = 0,0
|
||||
PUSH "\n"x9
|
||||
?cursor = 9,0
|
||||
PUSH "\n"
|
||||
scrollrect 0..10,0..80 => +1,+0
|
||||
?cursor = 9,0
|
||||
|
||||
!Linefeed outside DECSTBM
|
||||
PUSH "\e[20H"
|
||||
?cursor = 19,0
|
||||
PUSH "\n"
|
||||
?cursor = 20,0
|
||||
|
||||
!Index in DECSTBM
|
||||
PUSH "\e[10H"
|
||||
PUSH "\e[9;10r"
|
||||
PUSH "\eM"
|
||||
?cursor = 8,0
|
||||
PUSH "\eM"
|
||||
scrollrect 8..10,0..80 => -1,+0
|
||||
|
||||
!Reverse Index in DECSTBM
|
||||
PUSH "\e[25H"
|
||||
?cursor = 24,0
|
||||
PUSH "\n"
|
||||
# no scrollrect
|
||||
?cursor = 24,0
|
||||
|
||||
!Linefeed in DECSTBM+DECSLRM
|
||||
PUSH "\e[?69h"
|
||||
PUSH "\e[3;10r\e[10;40s"
|
||||
PUSH "\e[10;10H\n"
|
||||
scrollrect 2..10,9..40 => +1,+0
|
||||
|
||||
!IND/RI in DECSTBM+DECSLRM
|
||||
PUSH "\eD"
|
||||
scrollrect 2..10,9..40 => +1,+0
|
||||
PUSH "\e[3;10H\eM"
|
||||
scrollrect 2..10,9..40 => -1,+0
|
||||
|
||||
!DECRQSS on DECSTBM
|
||||
PUSH "\eP\$qr\e\\"
|
||||
output "\eP1\$r3;10r\e\\"
|
||||
|
||||
!DECRQSS on DECSLRM
|
||||
PUSH "\eP\$qs\e\\"
|
||||
output "\eP1\$r10;40s\e\\"
|
||||
|
||||
!Setting invalid DECSLRM with !DECVSSM is still rejected
|
||||
PUSH "\e[?69l\e[;0s\e[?69h"
|
||||
|
||||
RESET
|
||||
|
||||
!Scroll Down
|
||||
PUSH "\e[S"
|
||||
scrollrect 0..25,0..80 => +1,+0
|
||||
?cursor = 0,0
|
||||
PUSH "\e[2S"
|
||||
scrollrect 0..25,0..80 => +2,+0
|
||||
?cursor = 0,0
|
||||
PUSH "\e[100S"
|
||||
scrollrect 0..25,0..80 => +25,+0
|
||||
|
||||
!Scroll Up
|
||||
PUSH "\e[T"
|
||||
scrollrect 0..25,0..80 => -1,+0
|
||||
?cursor = 0,0
|
||||
PUSH "\e[2T"
|
||||
scrollrect 0..25,0..80 => -2,+0
|
||||
?cursor = 0,0
|
||||
PUSH "\e[100T"
|
||||
scrollrect 0..25,0..80 => -25,+0
|
||||
|
||||
!SD/SU in DECSTBM
|
||||
PUSH "\e[5;20r"
|
||||
PUSH "\e[S"
|
||||
scrollrect 4..20,0..80 => +1,+0
|
||||
PUSH "\e[T"
|
||||
scrollrect 4..20,0..80 => -1,+0
|
||||
|
||||
RESET
|
||||
|
||||
!SD/SU in DECSTBM+DECSLRM
|
||||
PUSH "\e[?69h"
|
||||
PUSH "\e[3;10r\e[10;40s"
|
||||
?cursor = 0,0
|
||||
PUSH "\e[3;10H"
|
||||
?cursor = 2,9
|
||||
PUSH "\e[S"
|
||||
scrollrect 2..10,9..40 => +1,+0
|
||||
PUSH "\e[?69l"
|
||||
PUSH "\e[S"
|
||||
scrollrect 2..10,0..80 => +1,+0
|
||||
|
||||
!Invalid boundaries
|
||||
RESET
|
||||
|
||||
PUSH "\e[100;105r\eD"
|
||||
PUSH "\e[5;2r\eD"
|
||||
|
||||
RESET
|
||||
WANTSTATE -s+me
|
||||
|
||||
!Scroll Down move+erase emulation
|
||||
PUSH "\e[S"
|
||||
moverect 1..25,0..80 -> 0..24,0..80
|
||||
erase 24..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "\e[2S"
|
||||
moverect 2..25,0..80 -> 0..23,0..80
|
||||
erase 23..25,0..80
|
||||
?cursor = 0,0
|
||||
|
||||
!Scroll Up move+erase emulation
|
||||
PUSH "\e[T"
|
||||
moverect 0..24,0..80 -> 1..25,0..80
|
||||
erase 0..1,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "\e[2T"
|
||||
moverect 0..23,0..80 -> 2..25,0..80
|
||||
erase 0..2,0..80
|
||||
?cursor = 0,0
|
||||
300
src/libvterm/t/13state_edit.test
Normal file
300
src/libvterm/t/13state_edit.test
Normal file
@@ -0,0 +1,300 @@
|
||||
INIT
|
||||
UTF8 1
|
||||
WANTSTATE se
|
||||
|
||||
!ICH
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "ACD"
|
||||
PUSH "\e[2D"
|
||||
?cursor = 0,1
|
||||
PUSH "\e[@"
|
||||
scrollrect 0..1,1..80 => +0,-1
|
||||
?cursor = 0,1
|
||||
PUSH "B"
|
||||
?cursor = 0,2
|
||||
PUSH "\e[3@"
|
||||
scrollrect 0..1,2..80 => +0,-3
|
||||
|
||||
!ICH with DECSLRM
|
||||
PUSH "\e[?69h"
|
||||
PUSH "\e[;50s"
|
||||
PUSH "\e[20G\e[@"
|
||||
scrollrect 0..1,19..50 => +0,-1
|
||||
|
||||
!ICH outside DECSLRM
|
||||
PUSH "\e[70G\e[@"
|
||||
# nothing happens
|
||||
|
||||
!DCH
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "ABBC"
|
||||
PUSH "\e[3D"
|
||||
?cursor = 0,1
|
||||
PUSH "\e[P"
|
||||
scrollrect 0..1,1..80 => +0,+1
|
||||
?cursor = 0,1
|
||||
PUSH "\e[3P"
|
||||
scrollrect 0..1,1..80 => +0,+3
|
||||
?cursor = 0,1
|
||||
|
||||
!DCH with DECSLRM
|
||||
PUSH "\e[?69h"
|
||||
PUSH "\e[;50s"
|
||||
PUSH "\e[20G\e[P"
|
||||
scrollrect 0..1,19..50 => +0,+1
|
||||
|
||||
!DCH outside DECSLRM
|
||||
PUSH "\e[70G\e[P"
|
||||
# nothing happens
|
||||
|
||||
!ECH
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "ABC"
|
||||
PUSH "\e[2D"
|
||||
?cursor = 0,1
|
||||
PUSH "\e[X"
|
||||
erase 0..1,1..2
|
||||
?cursor = 0,1
|
||||
PUSH "\e[3X"
|
||||
erase 0..1,1..4
|
||||
?cursor = 0,1
|
||||
# ECH more columns than there are should be bounded
|
||||
PUSH "\e[100X"
|
||||
erase 0..1,1..80
|
||||
|
||||
!IL
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "A\r\nC"
|
||||
?cursor = 1,1
|
||||
PUSH "\e[L"
|
||||
scrollrect 1..25,0..80 => -1,+0
|
||||
# TODO: ECMA-48 says we should move to line home, but neither xterm nor
|
||||
# xfce4-terminal do this
|
||||
?cursor = 1,1
|
||||
PUSH "\rB"
|
||||
?cursor = 1,1
|
||||
PUSH "\e[3L"
|
||||
scrollrect 1..25,0..80 => -3,+0
|
||||
|
||||
!IL with DECSTBM
|
||||
PUSH "\e[5;15r"
|
||||
PUSH "\e[5H\e[L"
|
||||
scrollrect 4..15,0..80 => -1,+0
|
||||
|
||||
!IL outside DECSTBM
|
||||
PUSH "\e[20H\e[L"
|
||||
# nothing happens
|
||||
|
||||
!IL with DECSTBM+DECSLRM
|
||||
PUSH "\e[?69h"
|
||||
PUSH "\e[10;50s"
|
||||
PUSH "\e[5;10H\e[L"
|
||||
scrollrect 4..15,9..50 => -1,+0
|
||||
|
||||
!DL
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "A\r\nB\r\nB\r\nC"
|
||||
?cursor = 3,1
|
||||
PUSH "\e[2H"
|
||||
?cursor = 1,0
|
||||
PUSH "\e[M"
|
||||
scrollrect 1..25,0..80 => +1,+0
|
||||
?cursor = 1,0
|
||||
PUSH "\e[3M"
|
||||
scrollrect 1..25,0..80 => +3,+0
|
||||
?cursor = 1,0
|
||||
|
||||
!DL with DECSTBM
|
||||
PUSH "\e[5;15r"
|
||||
PUSH "\e[5H\e[M"
|
||||
scrollrect 4..15,0..80 => +1,+0
|
||||
|
||||
!DL outside DECSTBM
|
||||
PUSH "\e[20H\e[M"
|
||||
# nothing happens
|
||||
|
||||
!DL with DECSTBM+DECSLRM
|
||||
PUSH "\e[?69h"
|
||||
PUSH "\e[10;50s"
|
||||
PUSH "\e[5;10H\e[M"
|
||||
scrollrect 4..15,9..50 => +1,+0
|
||||
|
||||
!DECIC
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
PUSH "\e[20G\e[5'}"
|
||||
scrollrect 0..25,19..80 => +0,-5
|
||||
|
||||
!DECIC with DECSTBM+DECSLRM
|
||||
PUSH "\e[?69h"
|
||||
PUSH "\e[4;20r\e[20;60s"
|
||||
PUSH "\e[4;20H\e[3'}"
|
||||
scrollrect 3..20,19..60 => +0,-3
|
||||
|
||||
!DECIC outside DECSLRM
|
||||
PUSH "\e[70G\e['}"
|
||||
# nothing happens
|
||||
|
||||
!DECDC
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
PUSH "\e[20G\e[5'~"
|
||||
scrollrect 0..25,19..80 => +0,+5
|
||||
|
||||
!DECDC with DECSTBM+DECSLRM
|
||||
PUSH "\e[?69h"
|
||||
PUSH "\e[4;20r\e[20;60s"
|
||||
PUSH "\e[4;20H\e[3'~"
|
||||
scrollrect 3..20,19..60 => +0,+3
|
||||
|
||||
!DECDC outside DECSLRM
|
||||
PUSH "\e[70G\e['~"
|
||||
# nothing happens
|
||||
|
||||
!EL 0
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "ABCDE"
|
||||
PUSH "\e[3D"
|
||||
?cursor = 0,2
|
||||
PUSH "\e[0K"
|
||||
erase 0..1,2..80
|
||||
?cursor = 0,2
|
||||
|
||||
!EL 1
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "ABCDE"
|
||||
PUSH "\e[3D"
|
||||
?cursor = 0,2
|
||||
PUSH "\e[1K"
|
||||
erase 0..1,0..3
|
||||
?cursor = 0,2
|
||||
|
||||
!EL 2
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "ABCDE"
|
||||
PUSH "\e[3D"
|
||||
?cursor = 0,2
|
||||
PUSH "\e[2K"
|
||||
erase 0..1,0..80
|
||||
?cursor = 0,2
|
||||
|
||||
!SEL
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "\e[11G"
|
||||
?cursor = 0,10
|
||||
PUSH "\e[?0K"
|
||||
erase 0..1,10..80 selective
|
||||
?cursor = 0,10
|
||||
PUSH "\e[?1K"
|
||||
erase 0..1,0..11 selective
|
||||
?cursor = 0,10
|
||||
PUSH "\e[?2K"
|
||||
erase 0..1,0..80 selective
|
||||
?cursor = 0,10
|
||||
|
||||
!ED 0
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "\e[2;2H"
|
||||
?cursor = 1,1
|
||||
PUSH "\e[0J"
|
||||
erase 1..2,1..80
|
||||
erase 2..25,0..80
|
||||
?cursor = 1,1
|
||||
|
||||
!ED 1
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "\e[2;2H"
|
||||
?cursor = 1,1
|
||||
PUSH "\e[1J"
|
||||
erase 0..1,0..80
|
||||
erase 1..2,0..2
|
||||
?cursor = 1,1
|
||||
|
||||
!ED 2
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "\e[2;2H"
|
||||
?cursor = 1,1
|
||||
PUSH "\e[2J"
|
||||
erase 0..25,0..80
|
||||
?cursor = 1,1
|
||||
|
||||
!SED
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
PUSH "\e[5;5H"
|
||||
?cursor = 4,4
|
||||
PUSH "\e[?0J"
|
||||
erase 4..5,4..80 selective
|
||||
erase 5..25,0..80 selective
|
||||
?cursor = 4,4
|
||||
PUSH "\e[?1J"
|
||||
erase 0..4,0..80 selective
|
||||
erase 4..5,0..5 selective
|
||||
?cursor = 4,4
|
||||
PUSH "\e[?2J"
|
||||
erase 0..25,0..80 selective
|
||||
?cursor = 4,4
|
||||
|
||||
!DECRQSS on DECSCA
|
||||
PUSH "\e[2\"q"
|
||||
PUSH "\eP\$q\"q\e\\"
|
||||
output "\eP1\$r2\"q\e\\"
|
||||
|
||||
WANTSTATE -s+m
|
||||
|
||||
!ICH move+erase emuation
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "ACD"
|
||||
PUSH "\e[2D"
|
||||
?cursor = 0,1
|
||||
PUSH "\e[@"
|
||||
moverect 0..1,1..79 -> 0..1,2..80
|
||||
erase 0..1,1..2
|
||||
?cursor = 0,1
|
||||
PUSH "B"
|
||||
?cursor = 0,2
|
||||
PUSH "\e[3@"
|
||||
moverect 0..1,2..77 -> 0..1,5..80
|
||||
erase 0..1,2..5
|
||||
|
||||
!DCH move+erase emulation
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "ABBC"
|
||||
PUSH "\e[3D"
|
||||
?cursor = 0,1
|
||||
PUSH "\e[P"
|
||||
moverect 0..1,2..80 -> 0..1,1..79
|
||||
erase 0..1,79..80
|
||||
?cursor = 0,1
|
||||
PUSH "\e[3P"
|
||||
moverect 0..1,4..80 -> 0..1,1..77
|
||||
erase 0..1,77..80
|
||||
?cursor = 0,1
|
||||
105
src/libvterm/t/14state_encoding.test
Normal file
105
src/libvterm/t/14state_encoding.test
Normal file
@@ -0,0 +1,105 @@
|
||||
INIT
|
||||
WANTSTATE g
|
||||
|
||||
!Default
|
||||
RESET
|
||||
PUSH "#"
|
||||
putglyph 0x23 1 0,0
|
||||
|
||||
!Designate G0=UK
|
||||
RESET
|
||||
PUSH "\e(A"
|
||||
PUSH "#"
|
||||
putglyph 0x00a3 1 0,0
|
||||
|
||||
!Designate G0=DEC drawing
|
||||
RESET
|
||||
PUSH "\e(0"
|
||||
PUSH "a"
|
||||
putglyph 0x2592 1 0,0
|
||||
|
||||
!Designate G1 + LS1
|
||||
RESET
|
||||
PUSH "\e)0"
|
||||
PUSH "a"
|
||||
putglyph 0x61 1 0,0
|
||||
PUSH "\x0e"
|
||||
PUSH "a"
|
||||
putglyph 0x2592 1 0,1
|
||||
!LS0
|
||||
PUSH "\x0f"
|
||||
PUSH "a"
|
||||
putglyph 0x61 1 0,2
|
||||
|
||||
!Designate G2 + LS2
|
||||
PUSH "\e*0"
|
||||
PUSH "a"
|
||||
putglyph 0x61 1 0,3
|
||||
PUSH "\en"
|
||||
PUSH "a"
|
||||
putglyph 0x2592 1 0,4
|
||||
PUSH "\x0f"
|
||||
PUSH "a"
|
||||
putglyph 0x61 1 0,5
|
||||
|
||||
!Designate G3 + LS3
|
||||
PUSH "\e+0"
|
||||
PUSH "a"
|
||||
putglyph 0x61 1 0,6
|
||||
PUSH "\eo"
|
||||
PUSH "a"
|
||||
putglyph 0x2592 1 0,7
|
||||
PUSH "\x0f"
|
||||
PUSH "a"
|
||||
putglyph 0x61 1 0,8
|
||||
|
||||
!SS2
|
||||
PUSH "a\x{8e}aa"
|
||||
putglyph 0x61 1 0,9
|
||||
putglyph 0x2592 1 0,10
|
||||
putglyph 0x61 1 0,11
|
||||
|
||||
!SS3
|
||||
PUSH "a\x{8f}aa"
|
||||
putglyph 0x61 1 0,12
|
||||
putglyph 0x2592 1 0,13
|
||||
putglyph 0x61 1 0,14
|
||||
|
||||
!LS1R
|
||||
RESET
|
||||
PUSH "\e~"
|
||||
PUSH "\xe1"
|
||||
putglyph 0x61 1 0,0
|
||||
PUSH "\e)0"
|
||||
PUSH "\xe1"
|
||||
putglyph 0x2592 1 0,1
|
||||
|
||||
!LS2R
|
||||
RESET
|
||||
PUSH "\e}"
|
||||
PUSH "\xe1"
|
||||
putglyph 0x61 1 0,0
|
||||
PUSH "\e*0"
|
||||
PUSH "\xe1"
|
||||
putglyph 0x2592 1 0,1
|
||||
|
||||
!LS3R
|
||||
RESET
|
||||
PUSH "\e|"
|
||||
PUSH "\xe1"
|
||||
putglyph 0x61 1 0,0
|
||||
PUSH "\e+0"
|
||||
PUSH "\xe1"
|
||||
putglyph 0x2592 1 0,1
|
||||
|
||||
UTF8 1
|
||||
|
||||
!Mixed US-ASCII and UTF-8
|
||||
# U+0108 == 0xc4 0x88
|
||||
RESET
|
||||
PUSH "\e(B"
|
||||
PUSH "AB\xc4\x88D"
|
||||
putglyph 0x0041 1 0,0
|
||||
putglyph 0x0042 1 0,1
|
||||
putglyph 0x0108 1 0,2
|
||||
putglyph 0x0044 1 0,3
|
||||
86
src/libvterm/t/15state_mode.test
Normal file
86
src/libvterm/t/15state_mode.test
Normal file
@@ -0,0 +1,86 @@
|
||||
INIT
|
||||
UTF8 1
|
||||
WANTSTATE gme
|
||||
|
||||
!Insert/Replace Mode
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "AC\e[DB"
|
||||
putglyph 0x41 1 0,0
|
||||
putglyph 0x43 1 0,1
|
||||
putglyph 0x42 1 0,1
|
||||
PUSH "\e[4h"
|
||||
PUSH "\e[G"
|
||||
PUSH "AC\e[DB"
|
||||
moverect 0..1,0..79 -> 0..1,1..80
|
||||
erase 0..1,0..1
|
||||
putglyph 0x41 1 0,0
|
||||
moverect 0..1,1..79 -> 0..1,2..80
|
||||
erase 0..1,1..2
|
||||
putglyph 0x43 1 0,1
|
||||
moverect 0..1,1..79 -> 0..1,2..80
|
||||
erase 0..1,1..2
|
||||
putglyph 0x42 1 0,1
|
||||
|
||||
!Insert mode only happens once for UTF-8 combining
|
||||
PUSH "e"
|
||||
moverect 0..1,2..79 -> 0..1,3..80
|
||||
erase 0..1,2..3
|
||||
putglyph 0x65 1 0,2
|
||||
PUSH "\xCC\x81"
|
||||
putglyph 0x65,0x301 1 0,2
|
||||
|
||||
!Newline/Linefeed mode
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "\e[5G\n"
|
||||
?cursor = 1,4
|
||||
PUSH "\e[20h"
|
||||
PUSH "\e[5G\n"
|
||||
?cursor = 2,0
|
||||
|
||||
!DEC origin mode
|
||||
RESET
|
||||
erase 0..25,0..80
|
||||
?cursor = 0,0
|
||||
PUSH "\e[5;15r"
|
||||
PUSH "\e[H"
|
||||
?cursor = 0,0
|
||||
PUSH "\e[3;3H"
|
||||
?cursor = 2,2
|
||||
PUSH "\e[?6h"
|
||||
PUSH "\e[H"
|
||||
?cursor = 4,0
|
||||
PUSH "\e[3;3H"
|
||||
?cursor = 6,2
|
||||
|
||||
!DECRQM on DECOM
|
||||
PUSH "\e[?6h"
|
||||
PUSH "\e[?6\$p"
|
||||
output "\e[?6;1\$y"
|
||||
PUSH "\e[?6l"
|
||||
PUSH "\e[?6\$p"
|
||||
output "\e[?6;2\$y"
|
||||
|
||||
!Origin mode with DECSLRM
|
||||
PUSH "\e[?6h"
|
||||
PUSH "\e[?69h"
|
||||
PUSH "\e[20;60s"
|
||||
PUSH "\e[H"
|
||||
?cursor = 4,19
|
||||
|
||||
PUSH "\e[?69l"
|
||||
|
||||
!Origin mode bounds cursor to scrolling region
|
||||
PUSH "\e[H"
|
||||
PUSH "\e[10A"
|
||||
?cursor = 4,0
|
||||
PUSH "\e[20B"
|
||||
?cursor = 14,0
|
||||
|
||||
!Origin mode without scroll region
|
||||
PUSH "\e[?6l"
|
||||
PUSH "\e[r\e[?6h"
|
||||
?cursor = 0,0
|
||||
48
src/libvterm/t/16state_resize.test
Normal file
48
src/libvterm/t/16state_resize.test
Normal file
@@ -0,0 +1,48 @@
|
||||
INIT
|
||||
WANTSTATE g
|
||||
|
||||
!Placement
|
||||
RESET
|
||||
PUSH "AB\e[79GCDE"
|
||||
putglyph 0x41 1 0,0
|
||||
putglyph 0x42 1 0,1
|
||||
putglyph 0x43 1 0,78
|
||||
putglyph 0x44 1 0,79
|
||||
putglyph 0x45 1 1,0
|
||||
|
||||
!Resize
|
||||
RESET
|
||||
RESIZE 27,85
|
||||
PUSH "AB\e[79GCDE"
|
||||
putglyph 0x41 1 0,0
|
||||
putglyph 0x42 1 0,1
|
||||
putglyph 0x43 1 0,78
|
||||
putglyph 0x44 1 0,79
|
||||
putglyph 0x45 1 0,80
|
||||
?cursor = 0,81
|
||||
|
||||
!Resize without reset
|
||||
RESIZE 28,90
|
||||
?cursor = 0,81
|
||||
PUSH "FGHI"
|
||||
putglyph 0x46 1 0,81
|
||||
putglyph 0x47 1 0,82
|
||||
putglyph 0x48 1 0,83
|
||||
putglyph 0x49 1 0,84
|
||||
?cursor = 0,85
|
||||
|
||||
!Resize shrink moves cursor
|
||||
RESIZE 25,80
|
||||
?cursor = 0,79
|
||||
|
||||
!Resize grow doesn't cancel phantom
|
||||
RESET
|
||||
PUSH "\e[79GAB"
|
||||
putglyph 0x41 1 0,78
|
||||
putglyph 0x42 1 0,79
|
||||
?cursor = 0,79
|
||||
RESIZE 30,100
|
||||
?cursor = 0,80
|
||||
PUSH "C"
|
||||
putglyph 0x43 1 0,80
|
||||
?cursor = 0,81
|
||||
172
src/libvterm/t/17state_mouse.test
Normal file
172
src/libvterm/t/17state_mouse.test
Normal file
@@ -0,0 +1,172 @@
|
||||
INIT
|
||||
WANTSTATE p
|
||||
|
||||
!DECRQM on with mouse off
|
||||
PUSH "\e[?1000\$p"
|
||||
output "\e[?1000;2\$y"
|
||||
PUSH "\e[?1002\$p"
|
||||
output "\e[?1002;2\$y"
|
||||
PUSH "\e[?1003\$p"
|
||||
output "\e[?1003;2\$y"
|
||||
|
||||
!Mouse in simple button report mode
|
||||
RESET
|
||||
settermprop 1 true
|
||||
settermprop 2 true
|
||||
settermprop 7 1
|
||||
PUSH "\e[?1000h"
|
||||
settermprop 8 1
|
||||
|
||||
!Press 1
|
||||
MOUSEMOVE 0,0 0
|
||||
MOUSEBTN d 1 0
|
||||
output "\e[M\x20\x21\x21"
|
||||
|
||||
!Release 1
|
||||
MOUSEBTN u 1 0
|
||||
output "\e[M\x23\x21\x21"
|
||||
|
||||
!Ctrl-Press 1
|
||||
MOUSEBTN d 1 C
|
||||
output "\e[M\x30\x21\x21"
|
||||
MOUSEBTN u 1 C
|
||||
output "\e[M\x33\x21\x21"
|
||||
|
||||
!Button 2
|
||||
MOUSEBTN d 2 0
|
||||
output "\e[M\x21\x21\x21"
|
||||
MOUSEBTN u 2 0
|
||||
output "\e[M\x23\x21\x21"
|
||||
|
||||
!Position
|
||||
MOUSEMOVE 10,20 0
|
||||
MOUSEBTN d 1 0
|
||||
output "\e[M\x20\x35\x2b"
|
||||
|
||||
MOUSEBTN u 1 0
|
||||
output "\e[M\x23\x35\x2b"
|
||||
MOUSEMOVE 10,21 0
|
||||
# no output
|
||||
|
||||
!Wheel events
|
||||
MOUSEBTN d 4 0
|
||||
output "\e[M\x60\x36\x2b"
|
||||
MOUSEBTN d 4 0
|
||||
output "\e[M\x60\x36\x2b"
|
||||
MOUSEBTN d 5 0
|
||||
output "\e[M\x61\x36\x2b"
|
||||
|
||||
!DECRQM on mouse button mode
|
||||
PUSH "\e[?1000\$p"
|
||||
output "\e[?1000;1\$y"
|
||||
PUSH "\e[?1002\$p"
|
||||
output "\e[?1002;2\$y"
|
||||
PUSH "\e[?1003\$p"
|
||||
output "\e[?1003;2\$y"
|
||||
|
||||
!Drag events
|
||||
RESET
|
||||
settermprop 1 true
|
||||
settermprop 2 true
|
||||
settermprop 7 1
|
||||
PUSH "\e[?1002h"
|
||||
settermprop 8 2
|
||||
|
||||
MOUSEMOVE 5,5 0
|
||||
MOUSEBTN d 1 0
|
||||
output "\e[M\x20\x26\x26"
|
||||
MOUSEMOVE 5,6 0
|
||||
output "\e[M\x40\x27\x26"
|
||||
MOUSEMOVE 6,6 0
|
||||
output "\e[M\x40\x27\x27"
|
||||
MOUSEMOVE 6,6 0
|
||||
# no output
|
||||
MOUSEBTN u 1 0
|
||||
output "\e[M\x23\x27\x27"
|
||||
MOUSEMOVE 6,7
|
||||
# no output
|
||||
|
||||
!DECRQM on mouse drag mode
|
||||
PUSH "\e[?1000\$p"
|
||||
output "\e[?1000;2\$y"
|
||||
PUSH "\e[?1002\$p"
|
||||
output "\e[?1002;1\$y"
|
||||
PUSH "\e[?1003\$p"
|
||||
output "\e[?1003;2\$y"
|
||||
|
||||
!Non-drag motion events
|
||||
PUSH "\e[?1003h"
|
||||
settermprop 8 3
|
||||
|
||||
MOUSEMOVE 6,8 0
|
||||
output "\e[M\x43\x29\x27"
|
||||
|
||||
!DECRQM on mouse motion mode
|
||||
PUSH "\e[?1000\$p"
|
||||
output "\e[?1000;2\$y"
|
||||
PUSH "\e[?1002\$p"
|
||||
output "\e[?1002;2\$y"
|
||||
PUSH "\e[?1003\$p"
|
||||
output "\e[?1003;1\$y"
|
||||
|
||||
!Bounds checking
|
||||
MOUSEMOVE 300,300 0
|
||||
output "\e[M\x43\xff\xff"
|
||||
MOUSEBTN d 1 0
|
||||
output "\e[M\x20\xff\xff"
|
||||
MOUSEBTN u 1 0
|
||||
output "\e[M\x23\xff\xff"
|
||||
|
||||
!DECRQM on standard encoding mode
|
||||
PUSH "\e[?1005\$p"
|
||||
output "\e[?1005;2\$y"
|
||||
PUSH "\e[?1006\$p"
|
||||
output "\e[?1006;2\$y"
|
||||
PUSH "\e[?1015\$p"
|
||||
output "\e[?1015;2\$y"
|
||||
|
||||
!UTF-8 extended encoding mode
|
||||
# 300 + 32 + 1 = 333 = U+014d = \xc5\x8d
|
||||
PUSH "\e[?1005h"
|
||||
MOUSEBTN d 1 0
|
||||
output "\e[M\x20\xc5\x8d\xc5\x8d"
|
||||
MOUSEBTN u 1 0
|
||||
output "\e[M\x23\xc5\x8d\xc5\x8d"
|
||||
|
||||
!DECRQM on UTF-8 extended encoding mode
|
||||
PUSH "\e[?1005\$p"
|
||||
output "\e[?1005;1\$y"
|
||||
PUSH "\e[?1006\$p"
|
||||
output "\e[?1006;2\$y"
|
||||
PUSH "\e[?1015\$p"
|
||||
output "\e[?1015;2\$y"
|
||||
|
||||
!SGR extended encoding mode
|
||||
PUSH "\e[?1006h"
|
||||
MOUSEBTN d 1 0
|
||||
output "\e[<0;301;301M"
|
||||
MOUSEBTN u 1 0
|
||||
output "\e[<0;301;301m"
|
||||
|
||||
!DECRQM on SGR extended encoding mode
|
||||
PUSH "\e[?1005\$p"
|
||||
output "\e[?1005;2\$y"
|
||||
PUSH "\e[?1006\$p"
|
||||
output "\e[?1006;1\$y"
|
||||
PUSH "\e[?1015\$p"
|
||||
output "\e[?1015;2\$y"
|
||||
|
||||
!rxvt extended encoding mode
|
||||
PUSH "\e[?1015h"
|
||||
MOUSEBTN d 1 0
|
||||
output "\e[0;301;301M"
|
||||
MOUSEBTN u 1 0
|
||||
output "\e[3;301;301M"
|
||||
|
||||
!DECRQM on rxvt extended encoding mode
|
||||
PUSH "\e[?1005\$p"
|
||||
output "\e[?1005;2\$y"
|
||||
PUSH "\e[?1006\$p"
|
||||
output "\e[?1006;2\$y"
|
||||
PUSH "\e[?1015\$p"
|
||||
output "\e[?1015;1\$y"
|
||||
36
src/libvterm/t/18state_termprops.test
Normal file
36
src/libvterm/t/18state_termprops.test
Normal file
@@ -0,0 +1,36 @@
|
||||
INIT
|
||||
WANTSTATE p
|
||||
|
||||
RESET
|
||||
settermprop 1 true
|
||||
settermprop 2 true
|
||||
settermprop 7 1
|
||||
|
||||
!Cursor visibility
|
||||
PUSH "\e[?25h"
|
||||
settermprop 1 true
|
||||
PUSH "\e[?25\$p"
|
||||
output "\e[?25;1\$y"
|
||||
PUSH "\e[?25l"
|
||||
settermprop 1 false
|
||||
PUSH "\e[?25\$p"
|
||||
output "\e[?25;2\$y"
|
||||
|
||||
!Cursor blink
|
||||
PUSH "\e[?12h"
|
||||
settermprop 2 true
|
||||
PUSH "\e[?12\$p"
|
||||
output "\e[?12;1\$y"
|
||||
PUSH "\e[?12l"
|
||||
settermprop 2 false
|
||||
PUSH "\e[?12\$p"
|
||||
output "\e[?12;2\$y"
|
||||
|
||||
!Cursor shape
|
||||
PUSH "\e[3 q"
|
||||
settermprop 2 true
|
||||
settermprop 7 2
|
||||
|
||||
!Title
|
||||
PUSH "\e]2;Here is my title\a"
|
||||
settermprop 4 "Here is my title"
|
||||
69
src/libvterm/t/20state_wrapping.test
Normal file
69
src/libvterm/t/20state_wrapping.test
Normal file
@@ -0,0 +1,69 @@
|
||||
INIT
|
||||
UTF8 1
|
||||
WANTSTATE gm
|
||||
|
||||
!79th Column
|
||||
PUSH "\e[75G"
|
||||
PUSH "A"x5
|
||||
putglyph 0x41 1 0,74
|
||||
putglyph 0x41 1 0,75
|
||||
putglyph 0x41 1 0,76
|
||||
putglyph 0x41 1 0,77
|
||||
putglyph 0x41 1 0,78
|
||||
?cursor = 0,79
|
||||
|
||||
!80th Column Phantom
|
||||
PUSH "A"
|
||||
putglyph 0x41 1 0,79
|
||||
?cursor = 0,79
|
||||
|
||||
!Line Wraparound
|
||||
PUSH "B"
|
||||
putglyph 0x42 1 1,0
|
||||
?cursor = 1,1
|
||||
|
||||
!Line Wraparound during combined write
|
||||
PUSH "\e[78G"
|
||||
PUSH "BBBCC"
|
||||
putglyph 0x42 1 1,77
|
||||
putglyph 0x42 1 1,78
|
||||
putglyph 0x42 1 1,79
|
||||
putglyph 0x43 1 2,0
|
||||
putglyph 0x43 1 2,1
|
||||
?cursor = 2,2
|
||||
|
||||
!DEC Auto Wrap Mode
|
||||
RESET
|
||||
PUSH "\e[?7l"
|
||||
PUSH "\e[75G"
|
||||
PUSH "D"x6
|
||||
putglyph 0x44 1 0,74
|
||||
putglyph 0x44 1 0,75
|
||||
putglyph 0x44 1 0,76
|
||||
putglyph 0x44 1 0,77
|
||||
putglyph 0x44 1 0,78
|
||||
putglyph 0x44 1 0,79
|
||||
?cursor = 0,79
|
||||
PUSH "D"
|
||||
putglyph 0x44 1 0,79
|
||||
?cursor = 0,79
|
||||
PUSH "\e[?7h"
|
||||
|
||||
!80th column causes linefeed on wraparound
|
||||
PUSH "\e[25;78HABC"
|
||||
putglyph 0x41 1 24,77
|
||||
putglyph 0x42 1 24,78
|
||||
putglyph 0x43 1 24,79
|
||||
?cursor = 24,79
|
||||
PUSH "D"
|
||||
moverect 1..25,0..80 -> 0..24,0..80
|
||||
putglyph 0x44 1 24,0
|
||||
|
||||
!80th column phantom linefeed phantom cancelled by explicit cursor move
|
||||
PUSH "\e[25;78HABC"
|
||||
putglyph 0x41 1 24,77
|
||||
putglyph 0x42 1 24,78
|
||||
putglyph 0x43 1 24,79
|
||||
?cursor = 24,79
|
||||
PUSH "\e[25;1HD"
|
||||
putglyph 0x44 1 24,0
|
||||
60
src/libvterm/t/21state_tabstops.test
Normal file
60
src/libvterm/t/21state_tabstops.test
Normal file
@@ -0,0 +1,60 @@
|
||||
INIT
|
||||
WANTSTATE g
|
||||
|
||||
!Initial
|
||||
RESET
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,8
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,16
|
||||
?cursor = 0,17
|
||||
|
||||
!HTS
|
||||
PUSH "\e[5G\eH"
|
||||
PUSH "\e[G\tX"
|
||||
putglyph 0x58 1 0,4
|
||||
?cursor = 0,5
|
||||
|
||||
!TBC 0
|
||||
PUSH "\e[9G\e[g"
|
||||
PUSH "\e[G\tX\tX"
|
||||
putglyph 0x58 1 0,4
|
||||
putglyph 0x58 1 0,16
|
||||
?cursor = 0,17
|
||||
|
||||
!TBC 3
|
||||
PUSH "\e[3g\e[50G\eH\e[G"
|
||||
?cursor = 0,0
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,49
|
||||
?cursor = 0,50
|
||||
|
||||
!Tabstops after resize
|
||||
RESET
|
||||
RESIZE 30,100
|
||||
# Should be 100/8 = 12 tabstops
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,8
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,16
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,24
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,32
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,40
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,48
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,56
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,64
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,72
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,80
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,88
|
||||
PUSH "\tX"
|
||||
putglyph 0x58 1 0,96
|
||||
?cursor = 0,97
|
||||
64
src/libvterm/t/22state_save.test
Normal file
64
src/libvterm/t/22state_save.test
Normal file
@@ -0,0 +1,64 @@
|
||||
INIT
|
||||
WANTSTATE p
|
||||
|
||||
RESET
|
||||
settermprop 1 true
|
||||
settermprop 2 true
|
||||
settermprop 7 1
|
||||
|
||||
!Set up state
|
||||
PUSH "\e[2;2H"
|
||||
?cursor = 1,1
|
||||
PUSH "\e[1m"
|
||||
?pen bold = on
|
||||
|
||||
!Save
|
||||
PUSH "\e[?1048h"
|
||||
|
||||
!Change state
|
||||
PUSH "\e[5;5H"
|
||||
?cursor = 4,4
|
||||
PUSH "\e[4 q"
|
||||
settermprop 2 false
|
||||
settermprop 7 2
|
||||
PUSH "\e[22;4m"
|
||||
?pen bold = off
|
||||
?pen underline = 1
|
||||
|
||||
!Restore
|
||||
PUSH "\e[?1048l"
|
||||
settermprop 1 true
|
||||
settermprop 2 true
|
||||
settermprop 7 1
|
||||
?cursor = 1,1
|
||||
?pen bold = on
|
||||
?pen underline = 0
|
||||
|
||||
!Save/restore using DECSC/DECRC
|
||||
PUSH "\e[2;2H\e7"
|
||||
?cursor = 1,1
|
||||
|
||||
PUSH "\e[5;5H"
|
||||
?cursor = 4,4
|
||||
PUSH "\e8"
|
||||
settermprop 1 true
|
||||
settermprop 2 true
|
||||
settermprop 7 1
|
||||
?cursor = 1,1
|
||||
|
||||
!Save twice, restore twice happens on both edge transitions
|
||||
PUSH "\e[2;10H\e[?1048h\e[6;10H\e[?1048h"
|
||||
PUSH "\e[H"
|
||||
?cursor = 0,0
|
||||
PUSH "\e[?1048l"
|
||||
settermprop 1 true
|
||||
settermprop 2 true
|
||||
settermprop 7 1
|
||||
?cursor = 5,9
|
||||
PUSH "\e[H"
|
||||
?cursor = 0,0
|
||||
PUSH "\e[?1048l"
|
||||
settermprop 1 true
|
||||
settermprop 2 true
|
||||
settermprop 7 1
|
||||
?cursor = 5,9
|
||||
132
src/libvterm/t/25state_input.test
Normal file
132
src/libvterm/t/25state_input.test
Normal file
@@ -0,0 +1,132 @@
|
||||
INIT
|
||||
WANTSTATE
|
||||
|
||||
!Unmodified ASCII
|
||||
INCHAR 0 41
|
||||
output "A"
|
||||
INCHAR 0 61
|
||||
output "a"
|
||||
|
||||
!Ctrl modifier on ASCII letters
|
||||
INCHAR C 41
|
||||
output "\e[65;5u"
|
||||
INCHAR C 61
|
||||
output "\x01"
|
||||
|
||||
!Alt modifier on ASCII letters
|
||||
INCHAR A 41
|
||||
output "\eA"
|
||||
INCHAR A 61
|
||||
output "\ea"
|
||||
|
||||
!Ctrl-Alt modifier on ASCII letters
|
||||
INCHAR CA 41
|
||||
output "\e[65;7u"
|
||||
INCHAR CA 61
|
||||
output "\e\x01"
|
||||
|
||||
!Special handling of Ctrl-I
|
||||
INCHAR 0 49
|
||||
output "I"
|
||||
INCHAR 0 69
|
||||
output "i"
|
||||
INCHAR C 49
|
||||
output "\e[73;5u"
|
||||
INCHAR C 69
|
||||
output "\e[105;5u"
|
||||
INCHAR A 49
|
||||
output "\eI"
|
||||
INCHAR A 69
|
||||
output "\ei"
|
||||
INCHAR CA 49
|
||||
output "\e[73;7u"
|
||||
INCHAR CA 69
|
||||
output "\e[105;7u"
|
||||
|
||||
!Special handling of Space
|
||||
INCHAR 0 20
|
||||
output " "
|
||||
INCHAR S 20
|
||||
output "\e[32;2u"
|
||||
INCHAR C 20
|
||||
output "\0"
|
||||
INCHAR SC 20
|
||||
output "\e[32;6u"
|
||||
INCHAR A 20
|
||||
output "\e "
|
||||
INCHAR SA 20
|
||||
output "\e[32;4u"
|
||||
INCHAR CA 20
|
||||
output "\e\0"
|
||||
INCHAR SCA 20
|
||||
output "\e[32;8u"
|
||||
|
||||
!Cursor keys in reset (cursor) mode
|
||||
INKEY 0 Up
|
||||
output "\e[A"
|
||||
INKEY S Up
|
||||
output "\e[1;2A"
|
||||
INKEY C Up
|
||||
output "\e[1;5A"
|
||||
INKEY SC Up
|
||||
output "\e[1;6A"
|
||||
INKEY A Up
|
||||
output "\e[1;3A"
|
||||
INKEY SA Up
|
||||
output "\e[1;4A"
|
||||
INKEY CA Up
|
||||
output "\e[1;7A"
|
||||
INKEY SCA Up
|
||||
output "\e[1;8A"
|
||||
|
||||
!Cursor keys in application mode
|
||||
PUSH "\e[?1h"
|
||||
# Plain "Up" should be SS3 A now
|
||||
INKEY 0 Up
|
||||
output "\eOA"
|
||||
# Modified keys should still use CSI
|
||||
INKEY S Up
|
||||
output "\e[1;2A"
|
||||
INKEY C Up
|
||||
output "\e[1;5A"
|
||||
|
||||
!Shift-Tab should be different
|
||||
INKEY 0 Tab
|
||||
output "\x09"
|
||||
INKEY S Tab
|
||||
output "\e[Z"
|
||||
INKEY C Tab
|
||||
output "\e[9;5u"
|
||||
INKEY A Tab
|
||||
output "\e\x09"
|
||||
INKEY CA Tab
|
||||
output "\e[9;7u"
|
||||
|
||||
!Enter in linefeed mode
|
||||
INKEY 0 Enter
|
||||
output "\x0d"
|
||||
|
||||
!Enter in newline mode
|
||||
PUSH "\e[20h"
|
||||
INKEY 0 Enter
|
||||
output "\x0d\x0a"
|
||||
|
||||
!Keypad in DECKPNM
|
||||
INKEY 0 KP0
|
||||
output "0"
|
||||
|
||||
!Keypad in DECKPAM
|
||||
PUSH "\e="
|
||||
INKEY 0 KP0
|
||||
output "\eOp"
|
||||
|
||||
!Bracketed paste mode off
|
||||
PASTE START
|
||||
PASTE END
|
||||
|
||||
!Bracketed paste mode on
|
||||
PUSH "\e[?2004h"
|
||||
PASTE START
|
||||
output "\e[200~"
|
||||
PASTE END
|
||||
output "\e[201~"
|
||||
62
src/libvterm/t/26state_query.test
Normal file
62
src/libvterm/t/26state_query.test
Normal file
@@ -0,0 +1,62 @@
|
||||
INIT
|
||||
WANTSTATE
|
||||
|
||||
!DA
|
||||
RESET
|
||||
PUSH "\e[c"
|
||||
output "\e[?1;2c"
|
||||
|
||||
!DSR
|
||||
RESET
|
||||
PUSH "\e[5n"
|
||||
output "\e[0n"
|
||||
|
||||
!CPR
|
||||
PUSH "\e[6n"
|
||||
output "\e[1;1R"
|
||||
PUSH "\e[10;10H\e[6n"
|
||||
output "\e[10;10R"
|
||||
|
||||
!DECCPR
|
||||
PUSH "\e[?6n"
|
||||
output "\e[?10;10R"
|
||||
|
||||
!DECRQSS on DECSCUSR
|
||||
PUSH "\e[3 q"
|
||||
PUSH "\eP\$q q\e\\"
|
||||
output "\eP1\$r3 q\e\\"
|
||||
|
||||
!DECRQSS on SGR
|
||||
PUSH "\e[1;5;7m"
|
||||
PUSH "\eP\$qm\e\\"
|
||||
output "\eP1\$r1;5;7m\e\\"
|
||||
|
||||
!DECRQSS on SGR ANSI colours
|
||||
PUSH "\e[0;31;42m"
|
||||
PUSH "\eP\$qm\e\\"
|
||||
output "\eP1\$r31;42m\e\\"
|
||||
|
||||
!DECRQSS on SGR ANSI hi-bright colours
|
||||
PUSH "\e[0;93;104m"
|
||||
PUSH "\eP\$qm\e\\"
|
||||
output "\eP1\$r93;104m\e\\"
|
||||
|
||||
!DECRQSS on SGR 256-palette colours
|
||||
PUSH "\e[0;38:5:56;48:5:78m"
|
||||
PUSH "\eP\$qm\e\\"
|
||||
output "\eP1\$r38:5:56;48:5:78m\e\\"
|
||||
|
||||
!DECRQSS on SGR RGB8 colours
|
||||
PUSH "\e[0;38:2:24:68:112;48:2:13:57:101m"
|
||||
PUSH "\eP\$qm\e\\"
|
||||
output "\eP1\$r38:2:24:68:112;48:2:13:57:101m\e\\"
|
||||
|
||||
!S8C1T on DSR
|
||||
PUSH "\e G"
|
||||
PUSH "\e[5n"
|
||||
output "\x{9b}0n"
|
||||
PUSH "\e F"
|
||||
|
||||
!Truncation on attempted buffer overflow
|
||||
PUSH "\e[6n" x 20
|
||||
output "\e[10;10R" x 7
|
||||
32
src/libvterm/t/27state_reset.test
Normal file
32
src/libvterm/t/27state_reset.test
Normal file
@@ -0,0 +1,32 @@
|
||||
INIT
|
||||
WANTSTATE
|
||||
|
||||
RESET
|
||||
|
||||
!RIS homes cursor
|
||||
PUSH "\e[5;5H"
|
||||
?cursor = 4,4
|
||||
WANTSTATE +m
|
||||
PUSH "\ec"
|
||||
?cursor = 0,0
|
||||
WANTSTATE -m
|
||||
|
||||
!RIS cancels scrolling region
|
||||
PUSH "\e[5;10r"
|
||||
WANTSTATE +s
|
||||
PUSH "\ec\e[25H\n"
|
||||
scrollrect 0..25,0..80 => +1,+0
|
||||
WANTSTATE -s
|
||||
|
||||
!RIS erases screen
|
||||
PUSH "ABCDE"
|
||||
WANTSTATE +e
|
||||
PUSH "\ec"
|
||||
erase 0..25,0..80
|
||||
WANTSTATE -e
|
||||
|
||||
!RIS clears tabstops
|
||||
PUSH "\e[5G\eH\e[G\t"
|
||||
?cursor = 0,4
|
||||
PUSH "\ec\t"
|
||||
?cursor = 0,8
|
||||
61
src/libvterm/t/28state_dbl_wh.test
Normal file
61
src/libvterm/t/28state_dbl_wh.test
Normal file
@@ -0,0 +1,61 @@
|
||||
INIT
|
||||
WANTSTATE g
|
||||
|
||||
!Single Width, Single Height
|
||||
RESET
|
||||
PUSH "\e#5"
|
||||
PUSH "Hello"
|
||||
putglyph 0x48 1 0,0
|
||||
putglyph 0x65 1 0,1
|
||||
putglyph 0x6c 1 0,2
|
||||
putglyph 0x6c 1 0,3
|
||||
putglyph 0x6f 1 0,4
|
||||
|
||||
!Double Width, Single Height
|
||||
RESET
|
||||
PUSH "\e#6"
|
||||
PUSH "Hello"
|
||||
putglyph 0x48 1 0,0 dwl
|
||||
putglyph 0x65 1 0,1 dwl
|
||||
putglyph 0x6c 1 0,2 dwl
|
||||
putglyph 0x6c 1 0,3 dwl
|
||||
putglyph 0x6f 1 0,4 dwl
|
||||
?cursor = 0,5
|
||||
PUSH "\e[40GAB"
|
||||
putglyph 0x41 1 0,39 dwl
|
||||
putglyph 0x42 1 1,0
|
||||
?cursor = 1,1
|
||||
|
||||
!Double Height
|
||||
RESET
|
||||
PUSH "\e#3"
|
||||
PUSH "Hello"
|
||||
putglyph 0x48 1 0,0 dwl dhl-top
|
||||
putglyph 0x65 1 0,1 dwl dhl-top
|
||||
putglyph 0x6c 1 0,2 dwl dhl-top
|
||||
putglyph 0x6c 1 0,3 dwl dhl-top
|
||||
putglyph 0x6f 1 0,4 dwl dhl-top
|
||||
?cursor = 0,5
|
||||
PUSH "\r\n\e#4"
|
||||
PUSH "Hello"
|
||||
putglyph 0x48 1 1,0 dwl dhl-bottom
|
||||
putglyph 0x65 1 1,1 dwl dhl-bottom
|
||||
putglyph 0x6c 1 1,2 dwl dhl-bottom
|
||||
putglyph 0x6c 1 1,3 dwl dhl-bottom
|
||||
putglyph 0x6f 1 1,4 dwl dhl-bottom
|
||||
?cursor = 1,5
|
||||
|
||||
!Double Width scrolling
|
||||
RESET
|
||||
PUSH "\e[20H\e#6ABC"
|
||||
putglyph 0x41 1 19,0 dwl
|
||||
putglyph 0x42 1 19,1 dwl
|
||||
putglyph 0x43 1 19,2 dwl
|
||||
PUSH "\e[25H\n"
|
||||
PUSH "\e[19;4HDE"
|
||||
putglyph 0x44 1 18,3 dwl
|
||||
putglyph 0x45 1 18,4 dwl
|
||||
PUSH "\e[H\eM"
|
||||
PUSH "\e[20;6HFG"
|
||||
putglyph 0x46 1 19,5 dwl
|
||||
putglyph 0x47 1 19,6 dwl
|
||||
19
src/libvterm/t/29state_fallback.test
Normal file
19
src/libvterm/t/29state_fallback.test
Normal file
@@ -0,0 +1,19 @@
|
||||
INIT
|
||||
WANTSTATE f
|
||||
RESET
|
||||
|
||||
!Unrecognised control
|
||||
PUSH "\x03"
|
||||
control 03
|
||||
|
||||
!Unrecognised CSI
|
||||
PUSH "\e[?15;2z"
|
||||
csi 0x7a L=3f 15,2
|
||||
|
||||
!Unrecognised OSC
|
||||
PUSH "\e]27;Something\e\\"
|
||||
osc "27;Something"
|
||||
|
||||
!Unrecognised DCS
|
||||
PUSH "\ePz123\e\\"
|
||||
dcs "z123"
|
||||
106
src/libvterm/t/30pen.test
Normal file
106
src/libvterm/t/30pen.test
Normal file
@@ -0,0 +1,106 @@
|
||||
INIT
|
||||
UTF8 1
|
||||
WANTSTATE
|
||||
|
||||
!Reset
|
||||
PUSH "\e[m"
|
||||
?pen bold = off
|
||||
?pen underline = 0
|
||||
?pen italic = off
|
||||
?pen blink = off
|
||||
?pen reverse = off
|
||||
?pen font = 0
|
||||
?pen foreground = rgb(240,240,240)
|
||||
?pen background = rgb(0,0,0)
|
||||
|
||||
!Bold
|
||||
PUSH "\e[1m"
|
||||
?pen bold = on
|
||||
PUSH "\e[22m"
|
||||
?pen bold = off
|
||||
PUSH "\e[1m\e[m"
|
||||
?pen bold = off
|
||||
|
||||
!Underline
|
||||
PUSH "\e[4m"
|
||||
?pen underline = 1
|
||||
PUSH "\e[21m"
|
||||
?pen underline = 2
|
||||
PUSH "\e[24m"
|
||||
?pen underline = 0
|
||||
PUSH "\e[4m\e[m"
|
||||
?pen underline = 0
|
||||
|
||||
!Italic
|
||||
PUSH "\e[3m"
|
||||
?pen italic = on
|
||||
PUSH "\e[23m"
|
||||
?pen italic = off
|
||||
PUSH "\e[3m\e[m"
|
||||
?pen italic = off
|
||||
|
||||
!Blink
|
||||
PUSH "\e[5m"
|
||||
?pen blink = on
|
||||
PUSH "\e[25m"
|
||||
?pen blink = off
|
||||
PUSH "\e[5m\e[m"
|
||||
?pen blink = off
|
||||
|
||||
!Reverse
|
||||
PUSH "\e[7m"
|
||||
?pen reverse = on
|
||||
PUSH "\e[27m"
|
||||
?pen reverse = off
|
||||
PUSH "\e[7m\e[m"
|
||||
?pen reverse = off
|
||||
|
||||
!Font Selection
|
||||
PUSH "\e[11m"
|
||||
?pen font = 1
|
||||
PUSH "\e[19m"
|
||||
?pen font = 9
|
||||
PUSH "\e[10m"
|
||||
?pen font = 0
|
||||
PUSH "\e[11m\e[m"
|
||||
?pen font = 0
|
||||
|
||||
!Foreground
|
||||
PUSH "\e[31m"
|
||||
?pen foreground = rgb(224,0,0)
|
||||
PUSH "\e[32m"
|
||||
?pen foreground = rgb(0,224,0)
|
||||
PUSH "\e[34m"
|
||||
?pen foreground = rgb(0,0,224)
|
||||
PUSH "\e[91m"
|
||||
?pen foreground = rgb(255,64,64)
|
||||
PUSH "\e[38:2:10:20:30m"
|
||||
?pen foreground = rgb(10,20,30)
|
||||
PUSH "\e[38:5:1m"
|
||||
?pen foreground = rgb(224,0,0)
|
||||
PUSH "\e[39m"
|
||||
?pen foreground = rgb(240,240,240)
|
||||
|
||||
!Background
|
||||
PUSH "\e[41m"
|
||||
?pen background = rgb(224,0,0)
|
||||
PUSH "\e[42m"
|
||||
?pen background = rgb(0,224,0)
|
||||
PUSH "\e[44m"
|
||||
?pen background = rgb(0,0,224)
|
||||
PUSH "\e[101m"
|
||||
?pen background = rgb(255,64,64)
|
||||
PUSH "\e[48:2:10:20:30m"
|
||||
?pen background = rgb(10,20,30)
|
||||
PUSH "\e[48:5:1m"
|
||||
?pen background = rgb(224,0,0)
|
||||
PUSH "\e[49m"
|
||||
?pen background = rgb(0,0,0)
|
||||
|
||||
!Bold+ANSI colour == highbright
|
||||
PUSH "\e[m\e[1;37m"
|
||||
?pen bold = on
|
||||
?pen foreground = rgb(255,255,255)
|
||||
PUSH "\e[m\e[37;1m"
|
||||
?pen bold = on
|
||||
?pen foreground = rgb(255,255,255)
|
||||
69
src/libvterm/t/40screen_ascii.test
Normal file
69
src/libvterm/t/40screen_ascii.test
Normal file
@@ -0,0 +1,69 @@
|
||||
INIT
|
||||
WANTSCREEN c
|
||||
|
||||
!Get
|
||||
RESET
|
||||
PUSH "ABC"
|
||||
movecursor 0,3
|
||||
?screen_chars 0,0,1,3 = 0x41,0x42,0x43
|
||||
?screen_chars 0,0,1,80 = 0x41,0x42,0x43
|
||||
?screen_text 0,0,1,3 = 0x41,0x42,0x43
|
||||
?screen_text 0,0,1,80 = 0x41,0x42,0x43
|
||||
?screen_cell 0,0 = {0x41} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
?screen_cell 0,1 = {0x42} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
?screen_cell 0,2 = {0x43} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
?screen_row 0 = "ABC"
|
||||
?screen_eol 0,0 = 0
|
||||
?screen_eol 0,2 = 0
|
||||
?screen_eol 0,3 = 1
|
||||
PUSH "\e[H"
|
||||
movecursor 0,0
|
||||
?screen_chars 0,0,1,80 = 0x41,0x42,0x43
|
||||
?screen_text 0,0,1,80 = 0x41,0x42,0x43
|
||||
PUSH "E"
|
||||
movecursor 0,1
|
||||
?screen_chars 0,0,1,80 = 0x45,0x42,0x43
|
||||
?screen_text 0,0,1,80 = 0x45,0x42,0x43
|
||||
|
||||
WANTSCREEN -c
|
||||
|
||||
!Erase
|
||||
RESET
|
||||
PUSH "ABCDE\e[H\e[K"
|
||||
?screen_chars 0,0,1,80 =
|
||||
?screen_text 0,0,1,80 =
|
||||
|
||||
!Copycell
|
||||
RESET
|
||||
PUSH "ABC\e[H\e[@"
|
||||
PUSH "1"
|
||||
?screen_chars 0,0,1,80 = 0x31,0x41,0x42,0x43
|
||||
|
||||
RESET
|
||||
PUSH "ABC\e[H\e[P"
|
||||
?screen_chars 0,0,1,1 = 0x42
|
||||
?screen_chars 0,1,1,2 = 0x43
|
||||
?screen_chars 0,0,1,80 = 0x42,0x43
|
||||
|
||||
!Space padding
|
||||
RESET
|
||||
PUSH "Hello\e[CWorld"
|
||||
?screen_chars 0,0,1,80 = 0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64
|
||||
?screen_text 0,0,1,80 = 0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64
|
||||
|
||||
!Linefeed padding
|
||||
RESET
|
||||
PUSH "Hello\r\nWorld"
|
||||
?screen_chars 0,0,2,80 = 0x48,0x65,0x6c,0x6c,0x6f,0x0a,0x57,0x6f,0x72,0x6c,0x64
|
||||
?screen_text 0,0,2,80 = 0x48,0x65,0x6c,0x6c,0x6f,0x0a,0x57,0x6f,0x72,0x6c,0x64
|
||||
|
||||
!Altscreen
|
||||
RESET
|
||||
PUSH "P"
|
||||
?screen_chars 0,0,1,80 = 0x50
|
||||
PUSH "\e[?1049h"
|
||||
?screen_chars 0,0,1,80 =
|
||||
PUSH "\e[2K\e[HA"
|
||||
?screen_chars 0,0,1,80 = 0x41
|
||||
PUSH "\e[?1049l"
|
||||
?screen_chars 0,0,1,80 = 0x50
|
||||
47
src/libvterm/t/41screen_unicode.test
Normal file
47
src/libvterm/t/41screen_unicode.test
Normal file
@@ -0,0 +1,47 @@
|
||||
INIT
|
||||
UTF8 1
|
||||
WANTSCREEN
|
||||
|
||||
!Single width UTF-8
|
||||
# U+00C1 = 0xC3 0x81 name: LATIN CAPITAL LETTER A WITH ACUTE
|
||||
# U+00E9 = 0xC3 0xA9 name: LATIN SMALL LETTER E WITH ACUTE
|
||||
RESET
|
||||
PUSH "\xC3\x81\xC3\xA9"
|
||||
?screen_chars 0,0,1,80 = 0xc1,0xe9
|
||||
?screen_text 0,0,1,80 = 0xc3,0x81,0xc3,0xa9
|
||||
?screen_cell 0,0 = {0xc1} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Wide char
|
||||
# U+FF10 = 0xEF 0xBC 0x90 name: FULLWIDTH DIGIT ZERO
|
||||
RESET
|
||||
PUSH "0123\e[H"
|
||||
PUSH "\xEF\xBC\x90"
|
||||
?screen_chars 0,0,1,80 = 0xff10,0x32,0x33
|
||||
?screen_text 0,0,1,80 = 0xef,0xbc,0x90,0x32,0x33
|
||||
?screen_cell 0,0 = {0xff10} width=2 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Combining char
|
||||
# U+0301 = 0xCC 0x81 name: COMBINING ACUTE
|
||||
RESET
|
||||
PUSH "0123\e[H"
|
||||
PUSH "e\xCC\x81"
|
||||
?screen_chars 0,0,1,80 = 0x65,0x301,0x31,0x32,0x33
|
||||
?screen_text 0,0,1,80 = 0x65,0xcc,0x81,0x31,0x32,0x33
|
||||
?screen_cell 0,0 = {0x65,0x301} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!10 combining accents should not crash
|
||||
RESET
|
||||
PUSH "e\xCC\x81\xCC\x82\xCC\x83\xCC\x84\xCC\x85\xCC\x86\xCC\x87\xCC\x88\xCC\x89\xCC\x8A"
|
||||
?screen_cell 0,0 = {0x65,0x301,0x302,0x303,0x304,0x305} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!40 combining accents in two split writes of 20 should not crash
|
||||
RESET
|
||||
PUSH "e\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81"
|
||||
PUSH "\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81\xCC\x81"
|
||||
?screen_cell 0,0 = {0x65,0x301,0x301,0x301,0x301,0x301} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Outputing CJK doublewidth in 80th column should wraparound to next line and not crash"
|
||||
RESET
|
||||
PUSH "\e[80G\xEF\xBC\x90"
|
||||
?screen_cell 0,79 = {} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
?screen_cell 1,0 = {0xff10} width=2 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
155
src/libvterm/t/42screen_damage.test
Normal file
155
src/libvterm/t/42screen_damage.test
Normal file
@@ -0,0 +1,155 @@
|
||||
INIT
|
||||
WANTSCREEN Db
|
||||
|
||||
!Putglyph
|
||||
RESET
|
||||
damage 0..25,0..80
|
||||
PUSH "123"
|
||||
damage 0..1,0..1 = 0<31>
|
||||
damage 0..1,1..2 = 0<32>
|
||||
damage 0..1,2..3 = 0<33>
|
||||
|
||||
!Erase
|
||||
PUSH "\e[H"
|
||||
PUSH "\e[3X"
|
||||
damage 0..1,0..3
|
||||
|
||||
!Scroll damages entire line in two chunks
|
||||
PUSH "\e[H\e[5@"
|
||||
damage 0..1,5..80
|
||||
damage 0..1,0..5
|
||||
|
||||
!Scroll down damages entire screen in two chunks
|
||||
PUSH "\e[T"
|
||||
damage 1..25,0..80
|
||||
damage 0..1,0..80
|
||||
|
||||
!Altscreen damages entire area
|
||||
PUSH "\e[?1049h"
|
||||
damage 0..25,0..80
|
||||
PUSH "\e[?1049l"
|
||||
damage 0..25,0..80
|
||||
|
||||
WANTSCREEN m
|
||||
|
||||
!Scroll invokes moverect but not damage
|
||||
PUSH "\e[5@"
|
||||
moverect 0..1,0..75 -> 0..1,5..80
|
||||
damage 0..1,0..5
|
||||
|
||||
WANTSCREEN -m
|
||||
|
||||
!Merge to cells
|
||||
RESET
|
||||
damage 0..25,0..80
|
||||
DAMAGEMERGE CELL
|
||||
|
||||
PUSH "A"
|
||||
damage 0..1,0..1 = 0<41>
|
||||
PUSH "B"
|
||||
damage 0..1,1..2 = 0<42>
|
||||
PUSH "C"
|
||||
damage 0..1,2..3 = 0<43>
|
||||
|
||||
!Merge entire rows
|
||||
RESET
|
||||
damage 0..25,0..80
|
||||
DAMAGEMERGE ROW
|
||||
|
||||
PUSH "ABCDE\r\nEFGH"
|
||||
damage 0..1,0..5 = 0<41 42 43 44 45>
|
||||
DAMAGEFLUSH
|
||||
damage 1..2,0..4 = 1<45 46 47 48>
|
||||
PUSH "\e[3;6r\e[6H\eD"
|
||||
damage 2..5,0..80
|
||||
DAMAGEFLUSH
|
||||
damage 5..6,0..80
|
||||
|
||||
!Merge entire screen
|
||||
RESET
|
||||
damage 0..25,0..80
|
||||
DAMAGEMERGE SCREEN
|
||||
|
||||
PUSH "ABCDE\r\nEFGH"
|
||||
DAMAGEFLUSH
|
||||
damage 0..2,0..5 = 0<41 42 43 44 45> 1<45 46 47 48>
|
||||
PUSH "\e[3;6r\e[6H\eD"
|
||||
DAMAGEFLUSH
|
||||
damage 2..6,0..80
|
||||
|
||||
!Merge entire screen with moverect
|
||||
WANTSCREEN m
|
||||
|
||||
RESET
|
||||
damage 0..25,0..80
|
||||
DAMAGEMERGE SCREEN
|
||||
|
||||
PUSH "ABCDE\r\nEFGH"
|
||||
PUSH "\e[3;6r\e[6H\eD"
|
||||
damage 0..2,0..5 = 0<41 42 43 44 45> 1<45 46 47 48>
|
||||
moverect 3..6,0..80 -> 2..5,0..80
|
||||
DAMAGEFLUSH
|
||||
damage 5..6,0..80
|
||||
|
||||
!Merge scroll
|
||||
RESET
|
||||
damage 0..25,0..80
|
||||
DAMAGEMERGE SCROLL
|
||||
|
||||
PUSH "\e[H1\r\n2\r\n3"
|
||||
PUSH "\e[25H\n\n\n"
|
||||
sb_pushline 80 = 31
|
||||
sb_pushline 80 = 32
|
||||
sb_pushline 80 = 33
|
||||
DAMAGEFLUSH
|
||||
moverect 3..25,0..80 -> 0..22,0..80
|
||||
damage 0..25,0..80
|
||||
|
||||
!Merge scroll with damage
|
||||
PUSH "\e[25H"
|
||||
PUSH "ABCDE\r\nEFGH\r\n"
|
||||
sb_pushline 80 =
|
||||
sb_pushline 80 =
|
||||
DAMAGEFLUSH
|
||||
moverect 2..25,0..80 -> 0..23,0..80
|
||||
damage 22..25,0..80 = 22<41 42 43 44 45> 23<45 46 47 48>
|
||||
|
||||
!Merge scroll with damage past region
|
||||
PUSH "\e[3;6r\e[6H1\r\n2\r\n3\r\n4\r\n5"
|
||||
DAMAGEFLUSH
|
||||
damage 2..6,0..80 = 2<32> 3<33> 4<34> 5<35>
|
||||
|
||||
!Damage entirely outside scroll region
|
||||
PUSH "\e[HABC\e[3;6r\e[6H\r\n6"
|
||||
damage 0..1,0..3 = 0<41 42 43>
|
||||
DAMAGEFLUSH
|
||||
moverect 3..6,0..80 -> 2..5,0..80
|
||||
damage 5..6,0..80 = 5<36>
|
||||
|
||||
!Damage overlapping scroll region
|
||||
PUSH "\e[H\e[2J"
|
||||
DAMAGEFLUSH
|
||||
damage 0..25,0..80
|
||||
|
||||
PUSH "\e[HABCD\r\nEFGH\r\nIJKL\e[2;5r\e[5H\r\nMNOP"
|
||||
DAMAGEFLUSH
|
||||
moverect 2..5,0..80 -> 1..4,0..80
|
||||
damage 0..5,0..80 = 0<41 42 43 44> 1<49 4A 4B 4C>
|
||||
## TODO: is this right?
|
||||
|
||||
!Merge scroll*2 with damage
|
||||
RESET
|
||||
damage 0..25,0..80
|
||||
DAMAGEMERGE SCROLL
|
||||
|
||||
PUSH "\e[25H\r\nABCDE\b\b\b\e[2P\r\n"
|
||||
sb_pushline 80 =
|
||||
moverect 1..25,0..80 -> 0..24,0..80
|
||||
damage 24..25,0..80 = 24<41 42 43 44 45>
|
||||
moverect 24..25,4..80 -> 24..25,2..78
|
||||
damage 24..25,78..80
|
||||
sb_pushline 80 =
|
||||
DAMAGEFLUSH
|
||||
moverect 1..25,0..80 -> 0..24,0..80
|
||||
damage 24..25,0..80
|
||||
?screen_chars 23,0,24,5 = 0x41,0x42,0x45
|
||||
90
src/libvterm/t/43screen_resize.test
Normal file
90
src/libvterm/t/43screen_resize.test
Normal file
@@ -0,0 +1,90 @@
|
||||
INIT
|
||||
WANTSTATE
|
||||
WANTSCREEN
|
||||
|
||||
!Resize wider preserves cells
|
||||
RESET
|
||||
RESIZE 25,80
|
||||
PUSH "AB\r\nCD"
|
||||
?screen_chars 0,0,1,80 = 0x41,0x42
|
||||
?screen_chars 1,0,2,80 = 0x43,0x44
|
||||
RESIZE 25,100
|
||||
?screen_chars 0,0,1,100 = 0x41,0x42
|
||||
?screen_chars 1,0,2,100 = 0x43,0x44
|
||||
|
||||
!Resize wider allows print in new area
|
||||
RESET
|
||||
RESIZE 25,80
|
||||
PUSH "AB\e[79GCD"
|
||||
?screen_chars 0,0,1,2 = 0x41,0x42
|
||||
?screen_chars 0,78,1,80 = 0x43,0x44
|
||||
RESIZE 25,100
|
||||
?screen_chars 0,0,1,2 = 0x41,0x42
|
||||
?screen_chars 0,78,1,80 = 0x43,0x44
|
||||
PUSH "E"
|
||||
?screen_chars 0,78,1,81 = 0x43,0x44,0x45
|
||||
|
||||
!Resize shorter with blanks just truncates
|
||||
RESET
|
||||
RESIZE 25,80
|
||||
PUSH "Top\e[10HLine 10"
|
||||
?screen_chars 0,0,1,80 = 0x54,0x6f,0x70
|
||||
?screen_chars 9,0,10,80 = 0x4c,0x69,0x6e,0x65,0x20,0x31,0x30
|
||||
?cursor = 9,7
|
||||
RESIZE 20,80
|
||||
?screen_chars 0,0,1,80 = 0x54,0x6f,0x70
|
||||
?screen_chars 9,0,10,80 = 0x4c,0x69,0x6e,0x65,0x20,0x31,0x30
|
||||
?cursor = 9,7
|
||||
|
||||
!Resize shorter with content must scroll
|
||||
RESET
|
||||
RESIZE 25,80
|
||||
PUSH "Top\e[25HLine 25\e[15H"
|
||||
?screen_chars 0,0,1,80 = 0x54,0x6f,0x70
|
||||
?screen_chars 24,0,25,80 = 0x4c,0x69,0x6e,0x65,0x20,0x32,0x35
|
||||
?cursor = 14,0
|
||||
WANTSCREEN b
|
||||
RESIZE 20,80
|
||||
sb_pushline 80 = 54 6F 70
|
||||
sb_pushline 80 =
|
||||
sb_pushline 80 =
|
||||
sb_pushline 80 =
|
||||
sb_pushline 80 =
|
||||
?screen_chars 0,0,1,80 =
|
||||
?screen_chars 19,0,20,80 = 0x4c,0x69,0x6e,0x65,0x20,0x32,0x35
|
||||
?cursor = 9,0
|
||||
|
||||
!Resize shorter does not lose line with cursor
|
||||
# See also https://github.com/neovim/libvterm/commit/1b745d29d45623aa8d22a7b9288c7b0e331c7088
|
||||
RESET
|
||||
WANTSCREEN -b
|
||||
RESIZE 25,80
|
||||
WANTSCREEN b
|
||||
PUSH "\e[24HLine 24\r\nLine 25\r\n"
|
||||
sb_pushline 80 =
|
||||
?screen_chars 23,0,24,10 = 0x4c,0x69,0x6e,0x65,0x20,0x32,0x35
|
||||
?cursor = 24,0
|
||||
RESIZE 24,80
|
||||
sb_pushline 80 =
|
||||
?screen_chars 22,0,23,10 = 0x4c,0x69,0x6e,0x65,0x20,0x32,0x35
|
||||
?cursor = 23,0
|
||||
|
||||
!Resize taller attempts to pop scrollback
|
||||
RESET
|
||||
WANTSCREEN -b
|
||||
RESIZE 25,80
|
||||
PUSH "Line 1\e[25HBottom\e[15H"
|
||||
?screen_chars 0,0,1,80 = 0x4c,0x69,0x6e,0x65,0x20,0x31
|
||||
?screen_chars 24,0,25,80 = 0x42,0x6f,0x74,0x74,0x6f,0x6d
|
||||
?cursor = 14,0
|
||||
WANTSCREEN b
|
||||
RESIZE 30,80
|
||||
sb_popline 80
|
||||
sb_popline 80
|
||||
sb_popline 80
|
||||
sb_popline 80
|
||||
sb_popline 80
|
||||
?screen_chars 0,0,1,80 = 0x41,0x42,0x43,0x44,0x45
|
||||
?screen_chars 5,0,6,80 = 0x4c,0x69,0x6e,0x65,0x20,0x31
|
||||
?screen_chars 29,0,30,80 = 0x42,0x6f,0x74,0x74,0x6f,0x6d
|
||||
?cursor = 19,0
|
||||
55
src/libvterm/t/44screen_pen.test
Normal file
55
src/libvterm/t/44screen_pen.test
Normal file
@@ -0,0 +1,55 @@
|
||||
INIT
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
!Plain
|
||||
PUSH "A"
|
||||
?screen_cell 0,0 = {0x41} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Bold
|
||||
PUSH "\e[1mB"
|
||||
?screen_cell 0,1 = {0x42} width=1 attrs={B} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Italic
|
||||
PUSH "\e[3mC"
|
||||
?screen_cell 0,2 = {0x43} width=1 attrs={BI} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Underline
|
||||
PUSH "\e[4mD"
|
||||
?screen_cell 0,3 = {0x44} width=1 attrs={BU1I} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Reset
|
||||
PUSH "\e[mE"
|
||||
?screen_cell 0,4 = {0x45} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Font
|
||||
PUSH "\e[11mF\e[m"
|
||||
?screen_cell 0,5 = {0x46} width=1 attrs={F1} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Foreground
|
||||
PUSH "\e[31mG\e[m"
|
||||
?screen_cell 0,6 = {0x47} width=1 attrs={} fg=rgb(224,0,0) bg=rgb(0,0,0)
|
||||
|
||||
!Background
|
||||
PUSH "\e[42mH\e[m"
|
||||
?screen_cell 0,7 = {0x48} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,224,0)
|
||||
|
||||
!EL sets reverse and colours to end of line
|
||||
PUSH "\e[H\e[7;33;44m\e[K"
|
||||
?screen_cell 0,0 = {} width=1 attrs={R} fg=rgb(224,224,0) bg=rgb(0,0,224)
|
||||
?screen_cell 0,79 = {} width=1 attrs={R} fg=rgb(224,224,0) bg=rgb(0,0,224)
|
||||
|
||||
!DECSCNM xors reverse for entire screen
|
||||
PUSH "\e[?5h"
|
||||
?screen_cell 0,0 = {} width=1 attrs={} fg=rgb(224,224,0) bg=rgb(0,0,224)
|
||||
?screen_cell 0,79 = {} width=1 attrs={} fg=rgb(224,224,0) bg=rgb(0,0,224)
|
||||
?screen_cell 1,0 = {} width=1 attrs={R} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
PUSH "\e[?5\$p"
|
||||
output "\e[?5;1\$y"
|
||||
PUSH "\e[?5l"
|
||||
?screen_cell 0,0 = {} width=1 attrs={R} fg=rgb(224,224,0) bg=rgb(0,0,224)
|
||||
?screen_cell 0,79 = {} width=1 attrs={R} fg=rgb(224,224,0) bg=rgb(0,0,224)
|
||||
?screen_cell 1,0 = {} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
PUSH "\e[?5\$p"
|
||||
output "\e[?5;2\$y"
|
||||
16
src/libvterm/t/45screen_protect.test
Normal file
16
src/libvterm/t/45screen_protect.test
Normal file
@@ -0,0 +1,16 @@
|
||||
INIT
|
||||
WANTSCREEN
|
||||
|
||||
!Selective erase
|
||||
RESET
|
||||
PUSH "A\e[1\"qB\e[\"qC"
|
||||
?screen_chars 0,0,1,3 = 0x41,0x42,0x43
|
||||
PUSH "\e[G\e[?J"
|
||||
?screen_chars 0,0,1,3 = 0x20,0x42
|
||||
|
||||
!Non-selective erase
|
||||
RESET
|
||||
PUSH "A\e[1\"qB\e[\"qC"
|
||||
?screen_chars 0,0,1,3 = 0x41,0x42,0x43
|
||||
PUSH "\e[G\e[J"
|
||||
?screen_chars 0,0,1,3 =
|
||||
11
src/libvterm/t/46screen_extent.test
Normal file
11
src/libvterm/t/46screen_extent.test
Normal file
@@ -0,0 +1,11 @@
|
||||
INIT
|
||||
WANTSCREEN
|
||||
|
||||
!Bold extent
|
||||
RESET
|
||||
PUSH "AB\e[1mCD\e[mE"
|
||||
?screen_attrs_extent 0,0 = 0,0-1,1
|
||||
?screen_attrs_extent 0,1 = 0,0-1,1
|
||||
?screen_attrs_extent 0,2 = 0,2-1,3
|
||||
?screen_attrs_extent 0,3 = 0,2-1,3
|
||||
?screen_attrs_extent 0,4 = 0,4-1,79
|
||||
32
src/libvterm/t/47screen_dbl_wh.test
Normal file
32
src/libvterm/t/47screen_dbl_wh.test
Normal file
@@ -0,0 +1,32 @@
|
||||
INIT
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
!Single Width, Single Height
|
||||
RESET
|
||||
PUSH "\e#5"
|
||||
PUSH "abcde"
|
||||
?screen_cell 0,0 = {0x61} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Double Width, Single Height
|
||||
RESET
|
||||
PUSH "\e#6"
|
||||
PUSH "abcde"
|
||||
?screen_cell 0,0 = {0x61} width=1 attrs={} dwl fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Double Height
|
||||
RESET
|
||||
PUSH "\e#3"
|
||||
PUSH "abcde"
|
||||
PUSH "\r\n\e#4"
|
||||
PUSH "abcde"
|
||||
?screen_cell 0,0 = {0x61} width=1 attrs={} dwl dhl-top fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
?screen_cell 1,0 = {0x61} width=1 attrs={} dwl dhl-bottom fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
|
||||
!Late change
|
||||
RESET
|
||||
PUSH "abcde"
|
||||
?screen_cell 0,0 = {0x61} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
PUSH "\e#6"
|
||||
?screen_cell 0,0 = {0x61} width=1 attrs={} dwl fg=rgb(240,240,240) bg=rgb(0,0,0)
|
||||
17
src/libvterm/t/48screen_termprops.test
Normal file
17
src/libvterm/t/48screen_termprops.test
Normal file
@@ -0,0 +1,17 @@
|
||||
INIT
|
||||
WANTSCREEN p
|
||||
|
||||
RESET
|
||||
settermprop 1 true
|
||||
settermprop 2 true
|
||||
settermprop 7 1
|
||||
|
||||
!Cursor visibility
|
||||
PUSH "\e[?25h"
|
||||
settermprop 1 true
|
||||
PUSH "\e[?25l"
|
||||
settermprop 1 false
|
||||
|
||||
!Title
|
||||
PUSH "\e]2;Here is my title\a"
|
||||
settermprop 4 "Here is my title"
|
||||
87
src/libvterm/t/90vttest_01-movement-1.test
Normal file
87
src/libvterm/t/90vttest_01-movement-1.test
Normal file
@@ -0,0 +1,87 @@
|
||||
INIT
|
||||
WANTSTATE
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
PUSH "\e#8"
|
||||
|
||||
PUSH "\e[9;10H\e[1J"
|
||||
PUSH "\e[18;60H\e[0J\e[1K"
|
||||
PUSH "\e[9;71H\e[0K"
|
||||
|
||||
$SEQ 10 16: PUSH "\e[\#;10H\e[1K\e[\#;71H\e[0K"
|
||||
|
||||
PUSH "\e[17;30H\e[2K"
|
||||
|
||||
$SEQ 1 80: PUSH "\e[24;\#f*\e[1;\#f*"
|
||||
|
||||
PUSH "\e[2;2H"
|
||||
|
||||
$REP 22: PUSH "+\e[1D\eD"
|
||||
|
||||
PUSH "\e[23;79H"
|
||||
$REP 22: PUSH "+\e[1D\eM"
|
||||
|
||||
PUSH "\e[2;1H"
|
||||
$SEQ 2 23: PUSH "*\e[\#;80H*\e[10D\eE"
|
||||
|
||||
PUSH "\e[2;10H\e[42D\e[2C"
|
||||
$REP 76: PUSH "+\e[0C\e[2D\e[1C"
|
||||
|
||||
PUSH "\e[23;70H\e[42C\e[2D"
|
||||
|
||||
$REP 76: PUSH "+\e[1D\e[1C\e[0D\b"
|
||||
|
||||
PUSH "\e[1;1H"
|
||||
PUSH "\e[10A"
|
||||
PUSH "\e[1A"
|
||||
PUSH "\e[0A"
|
||||
PUSH "\e[24;80H"
|
||||
PUSH "\e[10B"
|
||||
PUSH "\e[1B"
|
||||
PUSH "\e[0B"
|
||||
PUSH "\e[10;12H"
|
||||
|
||||
$REP 58: PUSH " "
|
||||
PUSH "\e[1B\e[58D"
|
||||
|
||||
$REP 58: PUSH " "
|
||||
PUSH "\e[1B\e[58D"
|
||||
|
||||
$REP 58: PUSH " "
|
||||
PUSH "\e[1B\e[58D"
|
||||
|
||||
$REP 58: PUSH " "
|
||||
PUSH "\e[1B\e[58D"
|
||||
|
||||
$REP 58: PUSH " "
|
||||
PUSH "\e[1B\e[58D"
|
||||
|
||||
$REP 58: PUSH " "
|
||||
PUSH "\e[1B\e[58D"
|
||||
|
||||
PUSH "\e[5A\e[1CThe screen should be cleared, and have an unbroken bor-"
|
||||
PUSH "\e[12;13Hder of *'s and +'s around the edge, and exactly in the"
|
||||
PUSH "\e[13;13Hmiddle there should be a frame of E's around this text"
|
||||
PUSH "\e[14;13Hwith one (1) free position around it. Push <RETURN>"
|
||||
|
||||
# And the result is...
|
||||
|
||||
!Output
|
||||
?screen_row 0 = "********************************************************************************"
|
||||
?screen_row 1 = "*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*"
|
||||
$SEQ 2 7: ?screen_row \# = "*+ +*"
|
||||
?screen_row 8 = "*+ EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +*"
|
||||
?screen_row 9 = "*+ E E +*"
|
||||
?screen_row 10 = "*+ E The screen should be cleared, and have an unbroken bor- E +*"
|
||||
?screen_row 11 = "*+ E der of *'s and +'s around the edge, and exactly in the E +*"
|
||||
?screen_row 12 = "*+ E middle there should be a frame of E's around this text E +*"
|
||||
?screen_row 13 = "*+ E with one (1) free position around it. Push <RETURN> E +*"
|
||||
?screen_row 14 = "*+ E E +*"
|
||||
?screen_row 15 = "*+ EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +*"
|
||||
$SEQ 16 21: ?screen_row \# = "*+ +*"
|
||||
?screen_row 22 = "*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*"
|
||||
?screen_row 23 = "********************************************************************************"
|
||||
|
||||
?cursor = 13,67
|
||||
40
src/libvterm/t/90vttest_01-movement-2.test
Normal file
40
src/libvterm/t/90vttest_01-movement-2.test
Normal file
@@ -0,0 +1,40 @@
|
||||
INIT
|
||||
WANTSTATE
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
PUSH "\e[3;21r"
|
||||
PUSH "\e[?6h"
|
||||
|
||||
PUSH "\e[19;1HA\e[19;80Ha\x0a\e[18;80HaB\e[19;80HB\b b\x0a\e[19;80HC\b\b\t\tc\e[19;2H\bC\x0a\e[19;80H\x0a\e[18;1HD\e[18;80Hd"
|
||||
PUSH "\e[19;1HE\e[19;80He\x0a\e[18;80HeF\e[19;80HF\b f\x0a\e[19;80HG\b\b\t\tg\e[19;2H\bG\x0a\e[19;80H\x0a\e[18;1HH\e[18;80Hh"
|
||||
PUSH "\e[19;1HI\e[19;80Hi\x0a\e[18;80HiJ\e[19;80HJ\b j\x0a\e[19;80HK\b\b\t\tk\e[19;2H\bK\x0a\e[19;80H\x0a\e[18;1HL\e[18;80Hl"
|
||||
PUSH "\e[19;1HM\e[19;80Hm\x0a\e[18;80HmN\e[19;80HN\b n\x0a\e[19;80HO\b\b\t\to\e[19;2H\bO\x0a\e[19;80H\x0a\e[18;1HP\e[18;80Hp"
|
||||
PUSH "\e[19;1HQ\e[19;80Hq\x0a\e[18;80HqR\e[19;80HR\b r\x0a\e[19;80HS\b\b\t\ts\e[19;2H\bS\x0a\e[19;80H\x0a\e[18;1HT\e[18;80Ht"
|
||||
PUSH "\e[19;1HU\e[19;80Hu\x0a\e[18;80HuV\e[19;80HV\b v\x0a\e[19;80HW\b\b\t\tw\e[19;2H\bW\x0a\e[19;80H\x0a\e[18;1HX\e[18;80Hx"
|
||||
PUSH "\e[19;1HY\e[19;80Hy\x0a\e[18;80HyZ\e[19;80HZ\b z\x0a"
|
||||
|
||||
!Output
|
||||
|
||||
?screen_row 2 = "I i"
|
||||
?screen_row 3 = "J j"
|
||||
?screen_row 4 = "K k"
|
||||
?screen_row 5 = "L l"
|
||||
?screen_row 6 = "M m"
|
||||
?screen_row 7 = "N n"
|
||||
?screen_row 8 = "O o"
|
||||
?screen_row 9 = "P p"
|
||||
?screen_row 10 = "Q q"
|
||||
?screen_row 11 = "R r"
|
||||
?screen_row 12 = "S s"
|
||||
?screen_row 13 = "T t"
|
||||
?screen_row 14 = "U u"
|
||||
?screen_row 15 = "V v"
|
||||
?screen_row 16 = "W w"
|
||||
?screen_row 17 = "X x"
|
||||
?screen_row 18 = "Y y"
|
||||
?screen_row 19 = "Z z"
|
||||
?screen_row 20 = ""
|
||||
|
||||
?cursor = 20,79
|
||||
21
src/libvterm/t/90vttest_01-movement-3.test
Normal file
21
src/libvterm/t/90vttest_01-movement-3.test
Normal file
@@ -0,0 +1,21 @@
|
||||
# Test of cursor-control characters inside ESC sequences
|
||||
INIT
|
||||
WANTSTATE
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
PUSH "A B C D E F G H I"
|
||||
PUSH "\x0d\x0a"
|
||||
PUSH "A\e[2\bCB\e[2\bCC\e[2\bCD\e[2\bCE\e[2\bCF\e[2\bCG\e[2\bCH\e[2\bCI"
|
||||
PUSH "\x0d\x0a"
|
||||
PUSH "A \e[\x0d2CB\e[\x0d4CC\e[\x0d6CD\e[\x0d8CE\e[\x0d10CF\e[\x0d12CG\e[\x0d14CH\e[\x0d16CI"
|
||||
PUSH "\x0d\x0a"
|
||||
PUSH "A \e[1\x0bAB \e[1\x0bAC \e[1\x0bAD \e[1\x0bAE \e[1\x0bAF \e[1\x0bAG \e[1\x0bAH \e[1\x0bAI \e[1\x0bA"
|
||||
|
||||
!Output
|
||||
|
||||
$SEQ 0 2: ?screen_row \# = "A B C D E F G H I"
|
||||
?screen_row 3 = "A B C D E F G H I "
|
||||
|
||||
?cursor = 3,18
|
||||
36
src/libvterm/t/90vttest_01-movement-4.test
Normal file
36
src/libvterm/t/90vttest_01-movement-4.test
Normal file
@@ -0,0 +1,36 @@
|
||||
# Test of leading zeroes in ESC sequences
|
||||
INIT
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
PUSH "\e[00000000004;000000001HT"
|
||||
PUSH "\e[00000000004;000000002Hh"
|
||||
PUSH "\e[00000000004;000000003Hi"
|
||||
PUSH "\e[00000000004;000000004Hs"
|
||||
PUSH "\e[00000000004;000000005H "
|
||||
PUSH "\e[00000000004;000000006Hi"
|
||||
PUSH "\e[00000000004;000000007Hs"
|
||||
PUSH "\e[00000000004;000000008H "
|
||||
PUSH "\e[00000000004;000000009Ha"
|
||||
PUSH "\e[00000000004;0000000010H "
|
||||
PUSH "\e[00000000004;0000000011Hc"
|
||||
PUSH "\e[00000000004;0000000012Ho"
|
||||
PUSH "\e[00000000004;0000000013Hr"
|
||||
PUSH "\e[00000000004;0000000014Hr"
|
||||
PUSH "\e[00000000004;0000000015He"
|
||||
PUSH "\e[00000000004;0000000016Hc"
|
||||
PUSH "\e[00000000004;0000000017Ht"
|
||||
PUSH "\e[00000000004;0000000018H "
|
||||
PUSH "\e[00000000004;0000000019Hs"
|
||||
PUSH "\e[00000000004;0000000020He"
|
||||
PUSH "\e[00000000004;0000000021Hn"
|
||||
PUSH "\e[00000000004;0000000022Ht"
|
||||
PUSH "\e[00000000004;0000000023He"
|
||||
PUSH "\e[00000000004;0000000024Hn"
|
||||
PUSH "\e[00000000004;0000000025Hc"
|
||||
PUSH "\e[00000000004;0000000026He"
|
||||
|
||||
!Output
|
||||
|
||||
?screen_row 3 = "This is a correct sentence"
|
||||
18
src/libvterm/t/90vttest_02-screen-1.test
Normal file
18
src/libvterm/t/90vttest_02-screen-1.test
Normal file
@@ -0,0 +1,18 @@
|
||||
# Test of WRAP AROUND mode setting.
|
||||
INIT
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
PUSH "\e[?7h"
|
||||
$REP 170: PUSH "*"
|
||||
|
||||
PUSH "\e[?7l\e[3;1H"
|
||||
$REP 177: PUSH "*"
|
||||
|
||||
PUSH "\e[?7h\e[5;1HOK"
|
||||
|
||||
!Output
|
||||
$SEQ 0 2: ?screen_row \# = "********************************************************************************"
|
||||
?screen_row 3 = ""
|
||||
?screen_row 4 = "OK"
|
||||
29
src/libvterm/t/90vttest_02-screen-2.test
Normal file
29
src/libvterm/t/90vttest_02-screen-2.test
Normal file
@@ -0,0 +1,29 @@
|
||||
# TAB setting/resetting
|
||||
INIT
|
||||
WANTSTATE
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
PUSH "\e[2J\e[3g"
|
||||
|
||||
PUSH "\e[1;1H"
|
||||
$REP 26: PUSH "\e[3C\eH"
|
||||
|
||||
PUSH "\e[1;4H"
|
||||
$REP 13: PUSH "\e[0g\e[6C"
|
||||
|
||||
PUSH "\e[1;7H"
|
||||
PUSH "\e[1g\e[2g"
|
||||
|
||||
PUSH "\e[1;1H"
|
||||
$REP 13: PUSH "\t*"
|
||||
|
||||
PUSH "\e[2;2H"
|
||||
$REP 13: PUSH " *"
|
||||
|
||||
!Output
|
||||
?screen_row 0 = " * * * * * * * * * * * * *"
|
||||
?screen_row 1 = " * * * * * * * * * * * * *"
|
||||
|
||||
?cursor = 1,79
|
||||
16
src/libvterm/t/90vttest_02-screen-3.test
Normal file
16
src/libvterm/t/90vttest_02-screen-3.test
Normal file
@@ -0,0 +1,16 @@
|
||||
# Origin mode
|
||||
INIT
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
PUSH "\e[?6h"
|
||||
PUSH "\e[23;24r"
|
||||
PUSH "\n"
|
||||
PUSH "Bottom"
|
||||
PUSH "\e[1;1H"
|
||||
PUSH "Above"
|
||||
|
||||
!Output
|
||||
?screen_row 22 = "Above"
|
||||
?screen_row 23 = "Bottom"
|
||||
17
src/libvterm/t/90vttest_02-screen-4.test
Normal file
17
src/libvterm/t/90vttest_02-screen-4.test
Normal file
@@ -0,0 +1,17 @@
|
||||
# Origin mode (2)
|
||||
INIT
|
||||
WANTSCREEN
|
||||
|
||||
RESET
|
||||
|
||||
PUSH "\e[?6l"
|
||||
PUSH "\e[23;24r"
|
||||
PUSH "\e[24;1H"
|
||||
PUSH "Bottom"
|
||||
PUSH "\e[1;1H"
|
||||
PUSH "Top"
|
||||
|
||||
!Output
|
||||
?screen_row 23 = "Bottom"
|
||||
?screen_row 0 = "Top"
|
||||
|
||||
13
src/libvterm/t/92lp1640917.test
Normal file
13
src/libvterm/t/92lp1640917.test
Normal file
@@ -0,0 +1,13 @@
|
||||
INIT
|
||||
WANTSTATE
|
||||
|
||||
!Mouse reporting should not break by idempotent DECSM 1002
|
||||
PUSH "\e[?1002h"
|
||||
MOUSEMOVE 0,0 0
|
||||
MOUSEBTN d 1 0
|
||||
output "\e[M\x20\x21\x21"
|
||||
MOUSEMOVE 1,0 0
|
||||
output "\e[M\x40\x21\x22"
|
||||
PUSH "\e[?1002h"
|
||||
MOUSEMOVE 2,0 0
|
||||
output "\e[M\x40\x21\x23"
|
||||
929
src/libvterm/t/harness.c
Normal file
929
src/libvterm/t/harness.c
Normal file
@@ -0,0 +1,929 @@
|
||||
#include "vterm.h"
|
||||
#include "../src/vterm_internal.h" /* We pull in some internal bits too */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define streq(a,b) (!strcmp(a,b))
|
||||
#define strstartswith(a,b) (!strncmp(a,b,strlen(b)))
|
||||
|
||||
static size_t inplace_hex2bytes(char *s)
|
||||
{
|
||||
char *inpos = s, *outpos = s;
|
||||
|
||||
while(*inpos) {
|
||||
unsigned int ch;
|
||||
sscanf(inpos, "%2x", &ch);
|
||||
*outpos = ch;
|
||||
outpos += 1; inpos += 2;
|
||||
}
|
||||
|
||||
return outpos - s;
|
||||
}
|
||||
|
||||
static VTermModifier strpe_modifiers(char **strp)
|
||||
{
|
||||
VTermModifier state = 0;
|
||||
|
||||
while((*strp)[0]) {
|
||||
switch(((*strp)++)[0]) {
|
||||
case 'S': state |= VTERM_MOD_SHIFT; break;
|
||||
case 'C': state |= VTERM_MOD_CTRL; break;
|
||||
case 'A': state |= VTERM_MOD_ALT; break;
|
||||
default: return state;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static VTermKey strp_key(char *str)
|
||||
{
|
||||
static struct {
|
||||
char *name;
|
||||
VTermKey key;
|
||||
} keys[] = {
|
||||
{ "Up", VTERM_KEY_UP },
|
||||
{ "Tab", VTERM_KEY_TAB },
|
||||
{ "Enter", VTERM_KEY_ENTER },
|
||||
{ "KP0", VTERM_KEY_KP_0 },
|
||||
{ NULL, VTERM_KEY_NONE },
|
||||
};
|
||||
int i;
|
||||
|
||||
for(i = 0; keys[i].name; i++) {
|
||||
if(streq(str, keys[i].name))
|
||||
return keys[i].key;
|
||||
}
|
||||
|
||||
return VTERM_KEY_NONE;
|
||||
}
|
||||
|
||||
static VTerm *vt;
|
||||
static VTermState *state;
|
||||
static VTermScreen *screen;
|
||||
|
||||
static VTermEncodingInstance encoding;
|
||||
|
||||
static int parser_text(const char bytes[], size_t len, void *user)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("text ");
|
||||
for(i = 0; i < len; i++) {
|
||||
unsigned char b = bytes[i];
|
||||
if(b < 0x20 || b == 0x7f || (b >= 0x80 && b < 0xa0))
|
||||
break;
|
||||
printf(i ? ",%x" : "%x", b);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int parser_control(unsigned char control, void *user)
|
||||
{
|
||||
printf("control %02x\n", control);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parser_escape(const char bytes[], size_t len, void *user)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(bytes[0] >= 0x20 && bytes[0] < 0x30) {
|
||||
if(len < 2)
|
||||
return -1;
|
||||
len = 2;
|
||||
}
|
||||
else {
|
||||
len = 1;
|
||||
}
|
||||
|
||||
printf("escape ");
|
||||
for(i = 0; i < len; i++)
|
||||
printf("%02x", bytes[i]);
|
||||
printf("\n");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int parser_csi(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user)
|
||||
{
|
||||
int i;
|
||||
printf("csi %02x", command);
|
||||
|
||||
if(leader && leader[0]) {
|
||||
printf(" L=");
|
||||
for(i = 0; leader[i]; i++)
|
||||
printf("%02x", leader[i]);
|
||||
}
|
||||
|
||||
for(i = 0; i < argcount; i++) {
|
||||
char sep = i ? ',' : ' ';
|
||||
|
||||
if(args[i] == CSI_ARG_MISSING)
|
||||
printf("%c*", sep);
|
||||
else
|
||||
printf("%c%ld%s", sep, CSI_ARG(args[i]), CSI_ARG_HAS_MORE(args[i]) ? "+" : "");
|
||||
}
|
||||
|
||||
if(intermed && intermed[0]) {
|
||||
printf(" I=");
|
||||
for(i = 0; intermed[i]; i++)
|
||||
printf("%02x", intermed[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parser_osc(const char *command, size_t cmdlen, void *user)
|
||||
{
|
||||
int i;
|
||||
printf("osc ");
|
||||
for(i = 0; i < cmdlen; i++)
|
||||
printf("%02x", command[i]);
|
||||
printf("\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parser_dcs(const char *command, size_t cmdlen, void *user)
|
||||
{
|
||||
int i;
|
||||
printf("dcs ");
|
||||
for(i = 0; i < cmdlen; i++)
|
||||
printf("%02x", command[i]);
|
||||
printf("\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static VTermParserCallbacks parser_cbs = {
|
||||
parser_text, /* text */
|
||||
parser_control, /* control */
|
||||
parser_escape, /* escape */
|
||||
parser_csi, /* csi */
|
||||
parser_osc, /* osc */
|
||||
parser_dcs, /* dcs */
|
||||
NULL /* resize */
|
||||
};
|
||||
|
||||
/* These callbacks are shared by State and Screen */
|
||||
|
||||
static int want_movecursor = 0;
|
||||
static VTermPos state_pos;
|
||||
static int movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user)
|
||||
{
|
||||
state_pos = pos;
|
||||
|
||||
if(want_movecursor)
|
||||
printf("movecursor %d,%d\n", pos.row, pos.col);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int want_scrollrect = 0;
|
||||
static int scrollrect(VTermRect rect, int downward, int rightward, void *user)
|
||||
{
|
||||
if(!want_scrollrect)
|
||||
return 0;
|
||||
|
||||
printf("scrollrect %d..%d,%d..%d => %+d,%+d\n",
|
||||
rect.start_row, rect.end_row, rect.start_col, rect.end_col,
|
||||
downward, rightward);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int want_moverect = 0;
|
||||
static int moverect(VTermRect dest, VTermRect src, void *user)
|
||||
{
|
||||
if(!want_moverect)
|
||||
return 0;
|
||||
|
||||
printf("moverect %d..%d,%d..%d -> %d..%d,%d..%d\n",
|
||||
src.start_row, src.end_row, src.start_col, src.end_col,
|
||||
dest.start_row, dest.end_row, dest.start_col, dest.end_col);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int want_settermprop = 0;
|
||||
static int settermprop(VTermProp prop, VTermValue *val, void *user)
|
||||
{
|
||||
VTermValueType type;
|
||||
if(!want_settermprop)
|
||||
return 1;
|
||||
|
||||
type = vterm_get_prop_type(prop);
|
||||
switch(type) {
|
||||
case VTERM_VALUETYPE_BOOL:
|
||||
printf("settermprop %d %s\n", prop, val->boolean ? "true" : "false");
|
||||
return 1;
|
||||
case VTERM_VALUETYPE_INT:
|
||||
printf("settermprop %d %d\n", prop, val->number);
|
||||
return 1;
|
||||
case VTERM_VALUETYPE_STRING:
|
||||
printf("settermprop %d \"%s\"\n", prop, val->string);
|
||||
return 1;
|
||||
case VTERM_VALUETYPE_COLOR:
|
||||
printf("settermprop %d rgb(%d,%d,%d)\n", prop, val->color.red, val->color.green, val->color.blue);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* These callbacks are for State */
|
||||
|
||||
static int want_state_putglyph = 0;
|
||||
static int state_putglyph(VTermGlyphInfo *info, VTermPos pos, void *user)
|
||||
{
|
||||
int i;
|
||||
if(!want_state_putglyph)
|
||||
return 1;
|
||||
|
||||
printf("putglyph ");
|
||||
for(i = 0; info->chars[i]; i++)
|
||||
printf(i ? ",%x" : "%x", info->chars[i]);
|
||||
printf(" %d %d,%d", info->width, pos.row, pos.col);
|
||||
if(info->protected_cell)
|
||||
printf(" prot");
|
||||
if(info->dwl)
|
||||
printf(" dwl");
|
||||
if(info->dhl)
|
||||
printf(" dhl-%s", info->dhl == 1 ? "top" : info->dhl == 2 ? "bottom" : "?" );
|
||||
printf("\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int want_state_erase = 0;
|
||||
static int state_erase(VTermRect rect, int selective, void *user)
|
||||
{
|
||||
if(!want_state_erase)
|
||||
return 1;
|
||||
|
||||
printf("erase %d..%d,%d..%d%s\n",
|
||||
rect.start_row, rect.end_row, rect.start_col, rect.end_col,
|
||||
selective ? " selective" : "");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct {
|
||||
int bold;
|
||||
int underline;
|
||||
int italic;
|
||||
int blink;
|
||||
int reverse;
|
||||
int strike;
|
||||
int font;
|
||||
VTermColor foreground;
|
||||
VTermColor background;
|
||||
} state_pen;
|
||||
static int state_setpenattr(VTermAttr attr, VTermValue *val, void *user)
|
||||
{
|
||||
switch(attr) {
|
||||
case VTERM_ATTR_BOLD:
|
||||
state_pen.bold = val->boolean;
|
||||
break;
|
||||
case VTERM_ATTR_UNDERLINE:
|
||||
state_pen.underline = val->number;
|
||||
break;
|
||||
case VTERM_ATTR_ITALIC:
|
||||
state_pen.italic = val->boolean;
|
||||
break;
|
||||
case VTERM_ATTR_BLINK:
|
||||
state_pen.blink = val->boolean;
|
||||
break;
|
||||
case VTERM_ATTR_REVERSE:
|
||||
state_pen.reverse = val->boolean;
|
||||
break;
|
||||
case VTERM_ATTR_STRIKE:
|
||||
state_pen.strike = val->boolean;
|
||||
break;
|
||||
case VTERM_ATTR_FONT:
|
||||
state_pen.font = val->number;
|
||||
break;
|
||||
case VTERM_ATTR_FOREGROUND:
|
||||
state_pen.foreground = val->color;
|
||||
break;
|
||||
case VTERM_ATTR_BACKGROUND:
|
||||
state_pen.background = val->color;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int state_setlineinfo(int row, const VTermLineInfo *newinfo, const VTermLineInfo *oldinfo, void *user)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
VTermStateCallbacks state_cbs = {
|
||||
state_putglyph, /* putglyph */
|
||||
movecursor, /* movecursor */
|
||||
scrollrect, /* scrollrect */
|
||||
moverect, /* moverect */
|
||||
state_erase, /* erase */
|
||||
NULL, /* initpen */
|
||||
state_setpenattr, /* setpenattr */
|
||||
settermprop, /* settermprop */
|
||||
NULL, /* bell */
|
||||
NULL, /* resize */
|
||||
state_setlineinfo, /* setlineinfo */
|
||||
};
|
||||
|
||||
static int want_screen_damage = 0;
|
||||
static int want_screen_damage_cells = 0;
|
||||
static int screen_damage(VTermRect rect, void *user)
|
||||
{
|
||||
if(!want_screen_damage)
|
||||
return 1;
|
||||
|
||||
printf("damage %d..%d,%d..%d",
|
||||
rect.start_row, rect.end_row, rect.start_col, rect.end_col);
|
||||
|
||||
if(want_screen_damage_cells) {
|
||||
bool equals = false;
|
||||
int row;
|
||||
int col;
|
||||
|
||||
for(row = rect.start_row; row < rect.end_row; row++) {
|
||||
int eol = rect.end_col;
|
||||
while(eol > rect.start_col) {
|
||||
VTermScreenCell cell;
|
||||
VTermPos pos;
|
||||
pos.row = row;
|
||||
pos.col = eol-1;
|
||||
vterm_screen_get_cell(screen, pos, &cell);
|
||||
if(cell.chars[0])
|
||||
break;
|
||||
|
||||
eol--;
|
||||
}
|
||||
|
||||
if(eol == rect.start_col)
|
||||
break;
|
||||
|
||||
if(!equals)
|
||||
printf(" ="), equals = true;
|
||||
|
||||
printf(" %d<", row);
|
||||
for(col = rect.start_col; col < eol; col++) {
|
||||
VTermScreenCell cell;
|
||||
VTermPos pos;
|
||||
pos.row = row;
|
||||
pos.col = col;
|
||||
vterm_screen_get_cell(screen, pos, &cell);
|
||||
printf(col == rect.start_col ? "%02X" : " %02X", cell.chars[0]);
|
||||
}
|
||||
printf(">");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int want_screen_scrollback = 0;
|
||||
static int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user)
|
||||
{
|
||||
int eol;
|
||||
int c;
|
||||
|
||||
if(!want_screen_scrollback)
|
||||
return 1;
|
||||
|
||||
eol = cols;
|
||||
while(eol && !cells[eol-1].chars[0])
|
||||
eol--;
|
||||
|
||||
printf("sb_pushline %d =", cols);
|
||||
for(c = 0; c < eol; c++)
|
||||
printf(" %02X", cells[c].chars[0]);
|
||||
printf("\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int screen_sb_popline(int cols, VTermScreenCell *cells, void *user)
|
||||
{
|
||||
int col;
|
||||
|
||||
if(!want_screen_scrollback)
|
||||
return 0;
|
||||
|
||||
/* All lines of scrollback contain "ABCDE" */
|
||||
for(col = 0; col < cols; col++) {
|
||||
if(col < 5)
|
||||
cells[col].chars[0] = 'A' + col;
|
||||
else
|
||||
cells[col].chars[0] = 0;
|
||||
|
||||
cells[col].width = 1;
|
||||
}
|
||||
|
||||
printf("sb_popline %d\n", cols);
|
||||
return 1;
|
||||
}
|
||||
|
||||
VTermScreenCallbacks screen_cbs = {
|
||||
screen_damage, /* damage */
|
||||
moverect, /* moverect */
|
||||
movecursor, /* movecursor */
|
||||
settermprop, /* settermprop */
|
||||
NULL, /* bell */
|
||||
NULL, /* resize */
|
||||
screen_sb_pushline, /* sb_pushline */
|
||||
screen_sb_popline /* sb_popline */
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char line[1024] = {0};
|
||||
int flag;
|
||||
|
||||
int err;
|
||||
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
while(fgets(line, sizeof line, stdin)) {
|
||||
char *nl;
|
||||
size_t outlen;
|
||||
err = 0;
|
||||
|
||||
if((nl = strchr(line, '\n')))
|
||||
*nl = '\0';
|
||||
|
||||
if(streq(line, "INIT")) {
|
||||
if(!vt)
|
||||
vt = vterm_new(25, 80);
|
||||
}
|
||||
|
||||
else if(streq(line, "WANTPARSER")) {
|
||||
vterm_parser_set_callbacks(vt, &parser_cbs, NULL);
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "WANTSTATE") && (line[9] == '\0' || line[9] == ' ')) {
|
||||
int i = 9;
|
||||
int sense = 1;
|
||||
if(!state) {
|
||||
state = vterm_obtain_state(vt);
|
||||
vterm_state_set_callbacks(state, &state_cbs, NULL);
|
||||
vterm_state_set_bold_highbright(state, 1);
|
||||
vterm_state_reset(state, 1);
|
||||
}
|
||||
|
||||
while(line[i] == ' ')
|
||||
i++;
|
||||
for( ; line[i]; i++)
|
||||
switch(line[i]) {
|
||||
case '+':
|
||||
sense = 1;
|
||||
break;
|
||||
case '-':
|
||||
sense = 0;
|
||||
break;
|
||||
case 'g':
|
||||
want_state_putglyph = sense;
|
||||
break;
|
||||
case 's':
|
||||
want_scrollrect = sense;
|
||||
break;
|
||||
case 'm':
|
||||
want_moverect = sense;
|
||||
break;
|
||||
case 'e':
|
||||
want_state_erase = sense;
|
||||
break;
|
||||
case 'p':
|
||||
want_settermprop = sense;
|
||||
break;
|
||||
case 'f':
|
||||
vterm_state_set_unrecognised_fallbacks(state, sense ? &parser_cbs : NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unrecognised WANTSTATE flag '%c'\n", line[i]);
|
||||
}
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "WANTSCREEN") && (line[10] == '\0' || line[10] == ' ')) {
|
||||
int i = 10;
|
||||
int sense = 1;
|
||||
if(!screen)
|
||||
screen = vterm_obtain_screen(vt);
|
||||
vterm_screen_enable_altscreen(screen, 1);
|
||||
vterm_screen_set_callbacks(screen, &screen_cbs, NULL);
|
||||
|
||||
while(line[i] == ' ')
|
||||
i++;
|
||||
for( ; line[i]; i++)
|
||||
switch(line[i]) {
|
||||
case '-':
|
||||
sense = 0;
|
||||
break;
|
||||
case 'd':
|
||||
want_screen_damage = sense;
|
||||
break;
|
||||
case 'D':
|
||||
want_screen_damage = sense;
|
||||
want_screen_damage_cells = sense;
|
||||
break;
|
||||
case 'm':
|
||||
want_moverect = sense;
|
||||
break;
|
||||
case 'c':
|
||||
want_movecursor = sense;
|
||||
break;
|
||||
case 'p':
|
||||
want_settermprop = 1;
|
||||
break;
|
||||
case 'b':
|
||||
want_screen_scrollback = sense;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unrecognised WANTSCREEN flag '%c'\n", line[i]);
|
||||
}
|
||||
}
|
||||
|
||||
else if(sscanf(line, "UTF8 %d", &flag)) {
|
||||
vterm_set_utf8(vt, flag);
|
||||
}
|
||||
|
||||
else if(streq(line, "RESET")) {
|
||||
if(state) {
|
||||
vterm_state_reset(state, 1);
|
||||
vterm_state_get_cursorpos(state, &state_pos);
|
||||
}
|
||||
if(screen) {
|
||||
vterm_screen_reset(screen, 1);
|
||||
}
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "RESIZE ")) {
|
||||
int rows, cols;
|
||||
char *linep = line + 7;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
sscanf(linep, "%d, %d", &rows, &cols);
|
||||
vterm_set_size(vt, rows, cols);
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "PUSH ")) {
|
||||
char *bytes = line + 5;
|
||||
size_t len = inplace_hex2bytes(bytes);
|
||||
size_t written = vterm_input_write(vt, bytes, len);
|
||||
if(written < len)
|
||||
fprintf(stderr, "! short write\n");
|
||||
}
|
||||
|
||||
else if(streq(line, "WANTENCODING")) {
|
||||
/* This isn't really external API but it's hard to get this out any
|
||||
* other way
|
||||
*/
|
||||
encoding.enc = vterm_lookup_encoding(ENC_UTF8, 'u');
|
||||
if(encoding.enc->init)
|
||||
(*encoding.enc->init)(encoding.enc, encoding.data);
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "ENCIN ")) {
|
||||
char *bytes = line + 6;
|
||||
size_t len = inplace_hex2bytes(bytes);
|
||||
|
||||
uint32_t cp[1024];
|
||||
int cpi = 0;
|
||||
size_t pos = 0;
|
||||
|
||||
(*encoding.enc->decode)(encoding.enc, encoding.data,
|
||||
cp, &cpi, len, bytes, &pos, len);
|
||||
|
||||
if(cpi > 0) {
|
||||
int i;
|
||||
printf("encout ");
|
||||
for(i = 0; i < cpi; i++) {
|
||||
printf(i ? ",%x" : "%x", cp[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "INCHAR ")) {
|
||||
char *linep = line + 7;
|
||||
unsigned int c = 0;
|
||||
VTermModifier mod;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
mod = strpe_modifiers(&linep);
|
||||
sscanf(linep, " %x", &c);
|
||||
|
||||
vterm_keyboard_unichar(vt, c, mod);
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "INKEY ")) {
|
||||
VTermModifier mod;
|
||||
VTermKey key;
|
||||
char *linep = line + 6;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
mod = strpe_modifiers(&linep);
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
key = strp_key(linep);
|
||||
|
||||
vterm_keyboard_key(vt, key, mod);
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "PASTE ")) {
|
||||
char *linep = line + 6;
|
||||
if(streq(linep, "START"))
|
||||
vterm_keyboard_start_paste(vt);
|
||||
else if(streq(linep, "END"))
|
||||
vterm_keyboard_end_paste(vt);
|
||||
else
|
||||
goto abort_line;
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "MOUSEMOVE ")) {
|
||||
char *linep = line + 10;
|
||||
int row, col, len;
|
||||
VTermModifier mod;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
sscanf(linep, "%d,%d%n", &row, &col, &len);
|
||||
linep += len;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
mod = strpe_modifiers(&linep);
|
||||
vterm_mouse_move(vt, row, col, mod);
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "MOUSEBTN ")) {
|
||||
char *linep = line + 9;
|
||||
char press;
|
||||
int button, len;
|
||||
VTermModifier mod;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
sscanf(linep, "%c %d%n", &press, &button, &len);
|
||||
linep += len;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
mod = strpe_modifiers(&linep);
|
||||
vterm_mouse_button(vt, button, (press == 'd' || press == 'D'), mod);
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "DAMAGEMERGE ")) {
|
||||
char *linep = line + 12;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
if(streq(linep, "CELL"))
|
||||
vterm_screen_set_damage_merge(screen, VTERM_DAMAGE_CELL);
|
||||
else if(streq(linep, "ROW"))
|
||||
vterm_screen_set_damage_merge(screen, VTERM_DAMAGE_ROW);
|
||||
else if(streq(linep, "SCREEN"))
|
||||
vterm_screen_set_damage_merge(screen, VTERM_DAMAGE_SCREEN);
|
||||
else if(streq(linep, "SCROLL"))
|
||||
vterm_screen_set_damage_merge(screen, VTERM_DAMAGE_SCROLL);
|
||||
}
|
||||
|
||||
else if(strstartswith(line, "DAMAGEFLUSH")) {
|
||||
vterm_screen_flush_damage(screen);
|
||||
}
|
||||
|
||||
else if(line[0] == '?') {
|
||||
if(streq(line, "?cursor")) {
|
||||
VTermPos pos;
|
||||
vterm_state_get_cursorpos(state, &pos);
|
||||
if(pos.row != state_pos.row)
|
||||
printf("! row mismatch: state=%d,%d event=%d,%d\n",
|
||||
pos.row, pos.col, state_pos.row, state_pos.col);
|
||||
else if(pos.col != state_pos.col)
|
||||
printf("! col mismatch: state=%d,%d event=%d,%d\n",
|
||||
pos.row, pos.col, state_pos.row, state_pos.col);
|
||||
else
|
||||
printf("%d,%d\n", state_pos.row, state_pos.col);
|
||||
}
|
||||
else if(strstartswith(line, "?pen ")) {
|
||||
VTermValue val;
|
||||
char *linep = line + 5;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
|
||||
#define BOOLSTR(v) ((v) ? "on" : "off")
|
||||
|
||||
if(streq(linep, "bold")) {
|
||||
vterm_state_get_penattr(state, VTERM_ATTR_BOLD, &val);
|
||||
if(val.boolean != state_pen.bold)
|
||||
printf("! pen bold mismatch; state=%s, event=%s\n",
|
||||
BOOLSTR(val.boolean), BOOLSTR(state_pen.bold));
|
||||
else
|
||||
printf("%s\n", BOOLSTR(state_pen.bold));
|
||||
}
|
||||
else if(streq(linep, "underline")) {
|
||||
vterm_state_get_penattr(state, VTERM_ATTR_UNDERLINE, &val);
|
||||
if(val.boolean != state_pen.underline)
|
||||
printf("! pen underline mismatch; state=%d, event=%d\n",
|
||||
val.boolean, state_pen.underline);
|
||||
else
|
||||
printf("%d\n", state_pen.underline);
|
||||
}
|
||||
else if(streq(linep, "italic")) {
|
||||
vterm_state_get_penattr(state, VTERM_ATTR_ITALIC, &val);
|
||||
if(val.boolean != state_pen.italic)
|
||||
printf("! pen italic mismatch; state=%s, event=%s\n",
|
||||
BOOLSTR(val.boolean), BOOLSTR(state_pen.italic));
|
||||
else
|
||||
printf("%s\n", BOOLSTR(state_pen.italic));
|
||||
}
|
||||
else if(streq(linep, "blink")) {
|
||||
vterm_state_get_penattr(state, VTERM_ATTR_BLINK, &val);
|
||||
if(val.boolean != state_pen.blink)
|
||||
printf("! pen blink mismatch; state=%s, event=%s\n",
|
||||
BOOLSTR(val.boolean), BOOLSTR(state_pen.blink));
|
||||
else
|
||||
printf("%s\n", BOOLSTR(state_pen.blink));
|
||||
}
|
||||
else if(streq(linep, "reverse")) {
|
||||
vterm_state_get_penattr(state, VTERM_ATTR_REVERSE, &val);
|
||||
if(val.boolean != state_pen.reverse)
|
||||
printf("! pen reverse mismatch; state=%s, event=%s\n",
|
||||
BOOLSTR(val.boolean), BOOLSTR(state_pen.reverse));
|
||||
else
|
||||
printf("%s\n", BOOLSTR(state_pen.reverse));
|
||||
}
|
||||
else if(streq(linep, "font")) {
|
||||
vterm_state_get_penattr(state, VTERM_ATTR_FONT, &val);
|
||||
if(val.boolean != state_pen.font)
|
||||
printf("! pen font mismatch; state=%d, event=%d\n",
|
||||
val.boolean, state_pen.font);
|
||||
else
|
||||
printf("%d\n", state_pen.font);
|
||||
}
|
||||
else if(streq(linep, "foreground")) {
|
||||
printf("rgb(%d,%d,%d)\n", state_pen.foreground.red, state_pen.foreground.green, state_pen.foreground.blue);
|
||||
}
|
||||
else if(streq(linep, "background")) {
|
||||
printf("rgb(%d,%d,%d)\n", state_pen.background.red, state_pen.background.green, state_pen.background.blue);
|
||||
}
|
||||
else
|
||||
printf("?\n");
|
||||
}
|
||||
else if(strstartswith(line, "?screen_chars ")) {
|
||||
char *linep = line + 13;
|
||||
VTermRect rect;
|
||||
size_t len;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
if(sscanf(linep, "%d,%d,%d,%d", &rect.start_row, &rect.start_col, &rect.end_row, &rect.end_col) < 4) {
|
||||
printf("! screen_chars unrecognised input\n");
|
||||
goto abort_line;
|
||||
}
|
||||
len = vterm_screen_get_chars(screen, NULL, 0, rect);
|
||||
if(len == (size_t)-1)
|
||||
printf("! screen_chars error\n");
|
||||
else if(len == 0)
|
||||
printf("\n");
|
||||
else {
|
||||
uint32_t *chars = malloc(sizeof(uint32_t) * len);
|
||||
size_t i;
|
||||
vterm_screen_get_chars(screen, chars, len, rect);
|
||||
for(i = 0; i < len; i++) {
|
||||
printf("0x%02x%s", chars[i], i < len-1 ? "," : "\n");
|
||||
}
|
||||
free(chars);
|
||||
}
|
||||
}
|
||||
else if(strstartswith(line, "?screen_text ")) {
|
||||
char *linep = line + 12;
|
||||
VTermRect rect;
|
||||
size_t len;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
if(sscanf(linep, "%d,%d,%d,%d", &rect.start_row, &rect.start_col, &rect.end_row, &rect.end_col) < 4) {
|
||||
printf("! screen_text unrecognised input\n");
|
||||
goto abort_line;
|
||||
}
|
||||
len = vterm_screen_get_text(screen, NULL, 0, rect);
|
||||
if(len == (size_t)-1)
|
||||
printf("! screen_text error\n");
|
||||
else if(len == 0)
|
||||
printf("\n");
|
||||
else {
|
||||
/* Put an overwrite guard at both ends of the buffer */
|
||||
unsigned char *buffer = malloc(len + 4);
|
||||
unsigned char *text = buffer + 2;
|
||||
text[-2] = 0x55; text[-1] = 0xAA;
|
||||
text[len] = 0x55; text[len+1] = 0xAA;
|
||||
|
||||
vterm_screen_get_text(screen, (char *)text, len, rect);
|
||||
|
||||
if(text[-2] != 0x55 || text[-1] != 0xAA)
|
||||
printf("! screen_get_text buffer overrun left [%02x,%02x]\n", text[-2], text[-1]);
|
||||
else if(text[len] != 0x55 || text[len+1] != 0xAA)
|
||||
printf("! screen_get_text buffer overrun right [%02x,%02x]\n", text[len], text[len+1]);
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < len; i++) {
|
||||
printf("0x%02x%s", text[i], i < len-1 ? "," : "\n");
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
else if(strstartswith(line, "?screen_cell ")) {
|
||||
char *linep = line + 12;
|
||||
int i;
|
||||
VTermPos pos;
|
||||
VTermScreenCell cell;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
if(sscanf(linep, "%d,%d\n", &pos.row, &pos.col) < 2) {
|
||||
printf("! screen_cell unrecognised input\n");
|
||||
goto abort_line;
|
||||
}
|
||||
if(!vterm_screen_get_cell(screen, pos, &cell))
|
||||
goto abort_line;
|
||||
printf("{");
|
||||
for(i = 0; i < VTERM_MAX_CHARS_PER_CELL && cell.chars[i]; i++) {
|
||||
printf("%s0x%x", i ? "," : "", cell.chars[i]);
|
||||
}
|
||||
printf("} width=%d attrs={", cell.width);
|
||||
if(cell.attrs.bold) printf("B");
|
||||
if(cell.attrs.underline) printf("U%d", cell.attrs.underline);
|
||||
if(cell.attrs.italic) printf("I");
|
||||
if(cell.attrs.blink) printf("K");
|
||||
if(cell.attrs.reverse) printf("R");
|
||||
if(cell.attrs.font) printf("F%d", cell.attrs.font);
|
||||
printf("} ");
|
||||
if(cell.attrs.dwl) printf("dwl ");
|
||||
if(cell.attrs.dhl) printf("dhl-%s ", cell.attrs.dhl == 2 ? "bottom" : "top");
|
||||
printf("fg=rgb(%d,%d,%d) ", cell.fg.red, cell.fg.green, cell.fg.blue);
|
||||
printf("bg=rgb(%d,%d,%d)\n", cell.bg.red, cell.bg.green, cell.bg.blue);
|
||||
}
|
||||
else if(strstartswith(line, "?screen_eol ")) {
|
||||
VTermPos pos;
|
||||
char *linep = line + 12;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
if(sscanf(linep, "%d,%d\n", &pos.row, &pos.col) < 2) {
|
||||
printf("! screen_eol unrecognised input\n");
|
||||
goto abort_line;
|
||||
}
|
||||
printf("%d\n", vterm_screen_is_eol(screen, pos));
|
||||
}
|
||||
else if(strstartswith(line, "?screen_attrs_extent ")) {
|
||||
VTermPos pos;
|
||||
VTermRect rect;
|
||||
char *linep = line + 21;
|
||||
while(linep[0] == ' ')
|
||||
linep++;
|
||||
if(sscanf(linep, "%d,%d\n", &pos.row, &pos.col) < 2) {
|
||||
printf("! screen_attrs_extent unrecognised input\n");
|
||||
goto abort_line;
|
||||
}
|
||||
rect.start_col = 0;
|
||||
rect.end_col = -1;
|
||||
if(!vterm_screen_get_attrs_extent(screen, &rect, pos, ~0)) {
|
||||
printf("! screen_attrs_extent failed\n");
|
||||
goto abort_line;
|
||||
}
|
||||
printf("%d,%d-%d,%d\n", rect.start_row, rect.start_col, rect.end_row, rect.end_col);
|
||||
}
|
||||
else
|
||||
printf("?\n");
|
||||
|
||||
memset(line, 0, sizeof line);
|
||||
continue;
|
||||
}
|
||||
|
||||
else
|
||||
abort_line: err = 1;
|
||||
|
||||
outlen = vterm_output_get_buffer_current(vt);
|
||||
if(outlen > 0) {
|
||||
int i;
|
||||
char outbuff[1024];
|
||||
vterm_output_read(vt, outbuff, outlen);
|
||||
|
||||
printf("output ");
|
||||
for(i = 0; i < outlen; i++)
|
||||
printf("%x%s", (unsigned char)outbuff[i], i < outlen-1 ? "," : "\n");
|
||||
}
|
||||
|
||||
printf(err ? "?\n" : "DONE\n");
|
||||
}
|
||||
|
||||
vterm_free(vt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
196
src/libvterm/t/run-test.pl
Normal file
196
src/libvterm/t/run-test.pl
Normal file
@@ -0,0 +1,196 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use IO::Handle;
|
||||
use IPC::Open2 qw( open2 );
|
||||
use POSIX qw( WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG );
|
||||
|
||||
my $VALGRIND = 0;
|
||||
GetOptions(
|
||||
'valgrind|v+' => \$VALGRIND,
|
||||
) or exit 1;
|
||||
|
||||
my ( $hin, $hout, $hpid );
|
||||
{
|
||||
local $ENV{LD_LIBRARY_PATH} = ".libs";
|
||||
my @command = "t/.libs/harness";
|
||||
unshift @command, "valgrind", "--quiet", "--error-exitcode=126" if $VALGRIND;
|
||||
|
||||
$hpid = open2 $hout, $hin, @command or die "Cannot open2 harness - $!";
|
||||
}
|
||||
|
||||
my $exitcode = 0;
|
||||
|
||||
my $command;
|
||||
my @expect;
|
||||
|
||||
sub do_onetest
|
||||
{
|
||||
$hin->print( "$command\n" );
|
||||
undef $command;
|
||||
|
||||
my $fail_printed = 0;
|
||||
|
||||
while( my $outline = <$hout> ) {
|
||||
last if $outline eq "DONE\n" or $outline eq "?\n";
|
||||
|
||||
chomp $outline;
|
||||
|
||||
if( !@expect ) {
|
||||
print "# Test failed\n" unless $fail_printed++;
|
||||
print "# expected nothing more\n" .
|
||||
"# Actual: $outline\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my $expectation = shift @expect;
|
||||
|
||||
next if $expectation eq $outline;
|
||||
|
||||
print "# Test failed\n" unless $fail_printed++;
|
||||
print "# Expected: $expectation\n" .
|
||||
"# Actual: $outline\n";
|
||||
}
|
||||
|
||||
if( @expect ) {
|
||||
print "# Test failed\n" unless $fail_printed++;
|
||||
print "# Expected: $_\n" .
|
||||
"# didn't happen\n" for @expect;
|
||||
}
|
||||
|
||||
$exitcode = 1 if $fail_printed;
|
||||
}
|
||||
|
||||
sub do_line
|
||||
{
|
||||
my ( $line ) = @_;
|
||||
|
||||
if( $line =~ m/^!(.*)/ ) {
|
||||
do_onetest if defined $command;
|
||||
print "> $1\n";
|
||||
}
|
||||
|
||||
# Commands have capitals
|
||||
elsif( $line =~ m/^([A-Z]+)/ ) {
|
||||
# Some convenience formatting
|
||||
if( $line =~ m/^(PUSH|ENCIN) (.*)$/ ) {
|
||||
# we're evil
|
||||
my $string = eval($2);
|
||||
$line = "$1 " . unpack "H*", $string;
|
||||
}
|
||||
|
||||
do_onetest if defined $command;
|
||||
|
||||
$command = $line;
|
||||
undef @expect;
|
||||
}
|
||||
# Expectations have lowercase
|
||||
elsif( $line =~ m/^([a-z]+)/ ) {
|
||||
# Convenience formatting
|
||||
if( $line =~ m/^(text|encout) (.*)$/ ) {
|
||||
$line = "$1 " . join ",", map sprintf("%x", $_), eval($2);
|
||||
}
|
||||
elsif( $line =~ m/^(output) (.*)$/ ) {
|
||||
$line = "$1 " . join ",", map sprintf("%x", $_), unpack "C*", eval($2);
|
||||
}
|
||||
elsif( $line =~ m/^control (.*)$/ ) {
|
||||
$line = sprintf "control %02x", eval($1);
|
||||
}
|
||||
elsif( $line =~ m/^csi (\S+) (.*)$/ ) {
|
||||
$line = sprintf "csi %02x %s", eval($1), $2; # TODO
|
||||
}
|
||||
elsif( $line =~ m/^(escape|osc|dcs) (.*)$/ ) {
|
||||
$line = "$1 " . join "", map sprintf("%02x", $_), unpack "C*", eval($2);
|
||||
}
|
||||
elsif( $line =~ m/^putglyph (\S+) (.*)$/ ) {
|
||||
$line = "putglyph " . join( ",", map sprintf("%x", $_), eval($1) ) . " $2";
|
||||
}
|
||||
elsif( $line =~ m/^(?:movecursor|scrollrect|moverect|erase|damage|sb_pushline|sb_popline|settermprop|setmousefunc) / ) {
|
||||
# no conversion
|
||||
}
|
||||
else {
|
||||
warn "Unrecognised test expectation '$line'\n";
|
||||
}
|
||||
|
||||
push @expect, $line;
|
||||
}
|
||||
# ?screen_row assertion is emulated here
|
||||
elsif( $line =~ s/^\?screen_row\s+(\d+)\s*=\s*// ) {
|
||||
my $row = $1;
|
||||
my $row1 = $row + 1;
|
||||
my $want = eval($line);
|
||||
|
||||
do_onetest if defined $command;
|
||||
|
||||
# TODO: may not be 80
|
||||
$hin->print( "\?screen_chars $row,0,$row1,80\n" );
|
||||
my $response = <$hout>;
|
||||
chomp $response;
|
||||
|
||||
$response = pack "C*", map hex, split m/,/, $response;
|
||||
if( $response ne $want ) {
|
||||
print "# Assert ?screen_row $row failed:\n" .
|
||||
"# Expected: $want\n" .
|
||||
"# Actual: $response\n";
|
||||
$exitcode = 1;
|
||||
}
|
||||
}
|
||||
# Assertions start with '?'
|
||||
elsif( $line =~ s/^\?([a-z]+.*?=)\s+// ) {
|
||||
do_onetest if defined $command;
|
||||
|
||||
my ( $assertion ) = $1 =~ m/^(.*)\s+=/;
|
||||
|
||||
$hin->print( "\?$assertion\n" );
|
||||
my $response = <$hout>; defined $response or wait, die "Test harness failed - $?\n";
|
||||
chomp $response;
|
||||
|
||||
if( $response ne $line ) {
|
||||
print "# Assert $assertion failed:\n" .
|
||||
"# Expected: $line\n" .
|
||||
"# Actual: $response\n";
|
||||
$exitcode = 1;
|
||||
}
|
||||
}
|
||||
# Test controls start with '$'
|
||||
elsif( $line =~ s/\$SEQ\s+(\d+)\s+(\d+):\s*// ) {
|
||||
my ( $low, $high ) = ( $1, $2 );
|
||||
foreach my $val ( $low .. $high ) {
|
||||
( my $inner = $line ) =~ s/\\#/$val/g;
|
||||
do_line( $inner );
|
||||
}
|
||||
}
|
||||
elsif( $line =~ s/\$REP\s+(\d+):\s*// ) {
|
||||
my $count = $1;
|
||||
do_line( $line ) for 1 .. $count;
|
||||
}
|
||||
else {
|
||||
die "Unrecognised TEST line $line\n";
|
||||
}
|
||||
}
|
||||
|
||||
open my $test, "<", $ARGV[0] or die "Cannot open test script $ARGV[0] - $!";
|
||||
|
||||
while( my $line = <$test> ) {
|
||||
$line =~ s/^\s+//;
|
||||
next if $line =~ m/^(?:#|$)/;
|
||||
|
||||
chomp $line;
|
||||
do_line( $line );
|
||||
}
|
||||
|
||||
do_onetest if defined $command;
|
||||
|
||||
close $hin;
|
||||
close $hout;
|
||||
|
||||
waitpid $hpid, 0;
|
||||
if( $? ) {
|
||||
printf STDERR "Harness exited %d\n", WEXITSTATUS($?) if WIFEXITED($?);
|
||||
printf STDERR "Harness exit signal %d\n", WTERMSIG($?) if WIFSIGNALED($?);
|
||||
$exitcode = WIFEXITED($?) ? WEXITSTATUS($?) : 125;
|
||||
}
|
||||
|
||||
exit $exitcode;
|
||||
Reference in New Issue
Block a user