xref: /openbsd/regress/bin/ksh/edit/emacs.sh (revision f45a9042)
1#!/bin/sh
2#
3# $OpenBSD: emacs.sh,v 1.15 2021/09/02 07:14:15 jasper Exp $
4#
5# Copyright (c) 2017 Anton Lindqvist <anton@openbsd.org>
6# Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
7#
8# Permission to use, copy, modify, and distribute this software for any
9# purpose with or without fee is hereby granted, provided that the above
10# copyright notice and this permission notice appear in all copies.
11#
12# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20. "${1:-.}/subr.sh"
21
22KSH=$2
23
24EDITOR=
25ENV=
26HISTFILE=
27MAIL=
28PS1=' # '
29VISUAL=emacs
30export EDITOR ENV HISTFILE MAIL PS1 VISUAL
31
32# The function testseq() sets up a pseudo terminal and feeds its first
33# argument to a shell on standard input.  It then checks that output
34# from the shell to the pseudo terminal agrees with the second argument.
35
36# auto-insert
37testseq "abc" " # abc"
38
39# insertion of valid UTF-8
40testseq "z\0002\0302\0200" " # z\b\0302\0200z\b"
41testseq "z\0002\0337\0277" " # z\b\0337\0277z\b"
42testseq "z\0002\0340\0240\0200" " # z\b\0340\0240\0200z\b"
43testseq "z\0002\0354\0277\0277" " # z\b\0354\0277\0277z\b"
44testseq "z\0002\0355\0200\0200" " # z\b\0355\0200\0200z\b"
45testseq "z\0002\0355\0237\0277" " # z\b\0355\0237\0277z\b"
46testseq "z\0002\0356\0200\0200" " # z\b\0356\0200\0200z\b"
47testseq "z\0002\0357\0277\0277" " # z\b\0357\0277\0277z\b"
48testseq "z\0002\0360\0220\0200\0200" " # z\b\0360\0220\0200\0200z\b"
49testseq "z\0002\0360\0277\0277\0277" " # z\b\0360\0277\0277\0277z\b"
50testseq "z\0002\0361\0200\0200\0200" " # z\b\0361\0200\0200\0200z\b"
51testseq "z\0002\0363\0277\0277\0277" " # z\b\0363\0277\0277\0277z\b"
52testseq "z\0002\0364\0200\0200\0200" " # z\b\0364\0200\0200\0200z\b"
53testseq "z\0002\0364\0217\0277\0277" " # z\b\0364\0217\0277\0277z\b"
54
55# insertion of incomplete UTF-8
56testseq "z\0002\0302\0006" " # z\b\0302z\bz"
57testseq "z\0002\0377\0006" " # z\b\0377z\bz"
58testseq "z\0002\0337\0006" " # z\b\0337z\bz"
59testseq "z\0002\0340\0006" " # z\b\0340z\bz"
60testseq "z\0002\0357\0006" " # z\b\0357z\bz"
61testseq "z\0002\0364\0006" " # z\b\0364z\bz"
62testseq "z\0002\0340\0240\0006" " # z\b\0340\0240z\bz"
63testseq "z\0002\0354\0277\0006" " # z\b\0354\0277z\bz"
64testseq "z\0002\0355\0200\0006" " # z\b\0355\0200z\bz"
65testseq "z\0002\0355\0237\0006" " # z\b\0355\0237z\bz"
66testseq "z\0002\0356\0200\0006" " # z\b\0356\0200z\bz"
67testseq "z\0002\0357\0277\0006" " # z\b\0357\0277z\bz"
68testseq "z\0002\0360\0220\0200\0006" " # z\b\0360\0220\0200z\bz"
69testseq "z\0002\0360\0277\0277\0006" " # z\b\0360\0277\0277z\bz"
70testseq "z\0002\0361\0200\0200\0006" " # z\b\0361\0200\0200z\bz"
71testseq "z\0002\0363\0200\0200\0006" " # z\b\0363\0200\0200z\bz"
72testseq "z\0002\0363\0277\0277\0006" " # z\b\0363\0277\0277z\bz"
73testseq "z\0002\0364\0200\0200\0006" " # z\b\0364\0200\0200z\bz"
74testseq "z\0002\0364\0217\0277\0006" " # z\b\0364\0217\0277z\bz"
75
76# insertion of invalid bytes
77testseq "z\0002\0300\0277" " # z\b\0300z\b\b\0300\0277z\b"
78testseq "z\0002\0301\0277" " # z\b\0301z\b\b\0301\0277z\b"
79testseq "z\0002\0360\0217" " # z\b\0360z\b\b\0360\0217z\b"
80testseq "z\0002\0365\0217" " # z\b\0365z\b\b\0365\0217z\b"
81testseq "z\0002\0367\0217" " # z\b\0367z\b\b\0367\0217z\b"
82testseq "z\0002\0370\0217" " # z\b\0370z\b\b\0370\0217z\b"
83testseq "z\0002\0377\0217" " # z\b\0377z\b\b\0377\0217z\b"
84
85# insertion of excessively long encodings
86testseq "z\0002\0340\0200\0200" \
87	" # z\b\0340z\b\b\0340\0200z\b\b\0340\0200\0200z\b"
88testseq "z\0002\0340\0201\0277" \
89	" # z\b\0340z\b\b\0340\0201z\b\b\0340\0201\0277z\b"
90testseq "z\0002\0340\0202\0200" \
91	" # z\b\0340z\b\b\0340\0202z\b\b\0340\0202\0200z\b"
92testseq "z\0002\0340\0237\0277" \
93	" # z\b\0340z\b\b\0340\0237z\b\b\0340\0237\0277z\b"
94testseq "z\0002\0360\0200\0200\0200" \
95  " # z\b\0360z\b\b\0360\0200z\b\b\0360\0200\0200z\b\b\0360\0200\0200\0200z\b"
96testseq "z\0002\0360\0217\0277\0277" \
97  " # z\b\0360z\b\b\0360\0217z\b\b\0360\0217\0277z\b\b\0360\0217\0277\0277z\b"
98
99# insertion of surrogates and execessive code points
100testseq "z\0002\0355\0240\0200" \
101	" # z\b\0355z\b\b\0355\0240z\b\b\0355\0240\0200z\b"
102testseq "z\0002\0355\0277\0277" \
103	" # z\b\0355z\b\b\0355\0277z\b\b\0355\0277\0277z\b"
104testseq "z\0002\0364\0220\0200\0200" \
105  " # z\b\0364z\b\b\0364\0220z\b\b\0364\0220\0200z\b\b\0364\0220\0200\0200z\b"
106testseq "z\0002\0364\0277\0277\0277" \
107  " # z\b\0364z\b\b\0364\0277z\b\b\0364\0277\0277z\b\b\0364\0277\0277\0277z\b"
108
109# insertion of unmatched meta sequence
110testseq "z\0002\0033[3z" " # z\b\0007"
111
112# ^C, ^G: abort
113testseq "echo 1\0003" " # echo 1\r\n # "
114testseq "echo 1\0007" " # echo 1\r\n # "
115
116# ^B, Left: backward-char
117testseq "\0002" " # \0007"
118testseq "a\0002" " # a\0010"
119testseq "\0303\0266\0002" " # \0303\0266\0010"
120testseq "a\0033[D" " # a\0010"
121testseq "a\0033OD" " # a\0010"
122
123# ^[b, Ctrl-Left: backward-word
124testseq "\0033b" " # \0007"
125testseq "a1_$\0033b" " # a1_$\0010\0010\0010\0010"
126testseq "a1 \0303\0266\0033b\0033b" " # a1 \0303\0266\0010\0010\0010\0010"
127testseq "a1_$\0033[1;5D" " # a1_$\0010\0010\0010\0010"
128
129# ^[<: beginning-of-history
130testseq "\0033<" " # \0007"
131testseq ": 1\n: 2\n\0033<" " # : 1\r\r\n # : 2\r\r\n # \r # : 1 \0010"
132
133# ^A, Home, Ctrl-Down: beginning-of-line
134testseq "\0001" " # "
135testseq "aa\0001" " # aa\0010\0010"
136testseq "\0303\0266\0001" " # \0303\0266\0010"
137testseq "aa\0033[H" " # aa\0010\0010"
138testseq "aa\0033OH" " # aa\0010\0010"
139testseq "aa\0033[1~" " # aa\0010\0010"
140testseq "aa\0033[1;5B" " # aa\0010\0010"
141
142# [n] ^[C, ^[c: capitalize-word
143testseq "\0033C\0033c" " # \0007\0007"
144testseq "ab cd\0001\0033C" " # ab cd\0010\0010\0010\0010\0010Ab"
145testseq "ab\0001\00332\0033C" " # ab\0010\0010Ab"
146testseq "ab cd\0001\00332\0033C" " # ab cd\0010\0010\0010\0010\0010Ab Cd"
147testseq "1a\0001\0033C" " # 1a\0010\00101a"
148testseq "\0026\0002\0001\0033C" " # ^B\0010\0010^B"
149testseq "\0303\0266b\0001\0033C" " # \0303\0266b\0010\0010\0303\0266b"
150
151# ^[#: comment
152testseq "\0033#" " # \r #  \0010\r\r\n # "
153testseq "a\0033#" " # a\r # #a \0010\0010\0010\r\r\n # "
154
155# XXX ^[^[: complete
156# XXX ^X^[: complete-command
157# XXX ^[^X: complete-file
158# XXX ^I, ^[=: complete-list
159
160# [n] ERASE, ^?, ^H: delete-char-backward
161testseq "\0177\0010" " # \0007\0007"
162testseq "ab\00332\0177" " # ab\0010\0010  \0010\0010"
163testseq "a\00332\0177" " # a\0010 \0010"
164testseq "\0303\0266\0177" " # \0303\0266\0010 \0010"
165
166# [n] Delete: delete-char-forward
167testseq "\0033[3~" " # \0007"
168testseq "a\0033[3~" " # a\0007"
169testseq "a\0001\0033[3~" " # a\0010 \0010"
170testseq "ab\0001\00332\0033[3~" " # ab\0010\0010  \0010\0010"
171testseq "a\0001\00332\0033[3~" " # a\0010 \0010"
172testseq "\0303\0266\0001\0033[3~" " # \0303\0266\0010 \0010"
173
174# [n] ^[ERASE, ^[^?, ^[^H, ^[h: delete-word-backward
175testseq "\0033\0177\033\0010\0033h" " # \0007\0007\0007"
176testseq "ab\0033\0177" " # ab\0010\0010  \0010\0010"
177testseq "ab cd\00332\0033\0177" \
178	" # ab cd\0010\0010\0010\0010\0010     \0010\0010\0010\0010\0010"
179testseq "ab\00332\0033\0177" " # ab\0010\0010  \0010\0010"
180testseq "ab \0303\0266\0033\0177" " # ab \0303\0266\0010 \0010"
181
182# [n] ^[d: delete-word-forward
183testseq "\0033d" " # \0007"
184testseq "ab\0001\0033d" " # ab\0010\0010  \0010\0010"
185testseq "ab cd\0001\00332\0033d" \
186	" # ab cd\0010\0010\0010\0010\0010     \0010\0010\0010\0010\0010"
187testseq "ab\0001\00332\0033d" " # ab\0010\0010  \0010\0010"
188
189# [n] ^N, ^XB, Down: down-history
190# [n] ^P, ^XA, Up: up-history
191testseq "\0016\0030B\0020\0030A" " # \0007\0007\0007\0007"
192testseq ": 1\n\0020\0016" " # : 1\r\r\n # \r # : 1 \0010\0007"
193testseq ": 1\n: 2\n\0020\0020\0016" \
194	" # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010\r # : 1 \0010\r # : 2 \0010"
195testseq ": 1\n: 2\n\0033[A\0033[A\0033[B" \
196	" # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010\r # : 1 \0010\r # : 2 \0010"
197testseq ": 1\n: 2\n\0033OA\0033OA\0033OB" \
198	" # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010\r # : 1 \0010\r # : 2 \0010"
199
200# [n] ^[L, ^[l: downcase-word
201testseq "\0033L\0033l" " # \0007\0007"
202testseq "AB\0001\0033L" " # AB\0010\0010ab"
203testseq "AB CD\0001\00332\0033L" " # AB CD\0010\0010\0010\0010\0010ab cd"
204testseq "AB\0001\00332\0033L" " # AB\0010\0010ab"
205testseq "1A\0001\0033L" " # 1A\0010\00101a"
206testseq "\0026\0002A\0001\0033L" " # ^BA\0010\0010\0010^Ba"
207testseq "\0303\0266A\0001\0033L" " # \0303\0266A\0010\0010\0303\0266a"
208
209# ^[>: end-of-history
210testseq "\0033>" " # \0007"
211testseq ": 1\n\0033>" " # : 1\r\r\n # \r # : 1 \0010"
212
213# ^E, End, Ctrl-Up: end-of-line
214testseq "\0005" " # "
215testseq "abc\0001\0005" " # abc\0010\0010\0010abc"
216testseq "\0303\0266\0001\0005" " # \0303\0266\0010\0303\0266"
217testseq "abc\0001\0033[F" " # abc\0010\0010\0010abc"
218testseq "abc\0001\0033OF" " # abc\0010\0010\0010abc"
219testseq "abc\0001\0033[4~" " # abc\0010\0010\0010abc"
220testseq "abc\0001\0033[1;5A" " # abc\0010\0010\0010abc"
221
222# ^_: eot
223testseq "\0037" " # ^D\r\r"
224
225# [n] ^D: eot-or-delete
226testseq "\0004" " # ^D\r\r"
227
228# ^X^X: exchange-point-and-mark
229# ^[space: set-mark-command
230testseq "\0030\0030" " # \0007"
231testseq "abc\0033 \0001\0030\0030" " # abc\0010\0010\0010abc"
232testseq "\0303\0266\0033 \0001\0030\0030" " # \0303\0266\0010\0303\0266"
233
234# XXX ^[*: expand-file
235
236# [n] ^F, ^XC, Right: forward-char
237testseq "\0006\0030C" " # \0007\0007"
238testseq "abc\0001\0006" " # abc\0010\0010\0010a"
239testseq "abc\0001\00332\0006" " # abc\0010\0010\0010ab"
240testseq "a\0001\00332\0006" " # a\0010a"
241testseq "\0303\0266\0001\0006" " # \0303\0266\0010\0303\0266"
242testseq "abc\0001\0033[C" " # abc\0010\0010\0010a"
243testseq "abc\0001\0033OC" " # abc\0010\0010\0010a"
244
245# [n] ^[f, Ctrl-Right: forward-word
246testseq "\0033f" " # \0007"
247testseq "ab\0001\0033f" " # ab\0010\0010ab"
248testseq "ab cd\0001\00332\0033f" " # ab cd\0010\0010\0010\0010\0010ab cd"
249testseq "ab\0001\00332\0033f" " # ab\0010\0010ab"
250testseq "\0303\0266\0001\0033f" " # \0303\0266\0010\0303\0266"
251testseq "ab\0001\0033[1;5C" " # ab\0010\0010ab"
252
253# [n] ^[g: goto-history
254testseq "\0033g" " # \0007"
255testseq ": 1\n\0033g" " # : 1\r\r\n # \r # : 1 \0010"
256testseq ": 1\n: 2\n\00332\0033g" " # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010"
257testseq ": 1\n\00332\0033g" " # : 1\r\r\n # \0007"
258
259# KILL: kill-line
260testseq "\0025" " # \r #  \0010"
261testseq "ab\0025" " # ab\r #    \0010\0010\0010"
262
263# [n] ^K: kill-to-eol
264testseq "\0013" " # "
265testseq "abc\0002\0002\0013" " # abc\0010\0010  \0010\0010"
266
267# XXX ^[?: list
268# XXX ^X?: list-command
269# XXX ^X^Y: list-file
270
271# ^J, ^M: newline
272testseq "\0012\0015" " # \r\r\n # \r\r\n # "
273testseq ": 1\0012" " # : 1\r\r\n # "
274testseq ": 1\0001\0012" " # : 1\0010\0010\0010\r\r\n # "
275
276# ^O: newline-and-next
277testseq "\0017" " # \r\r\n # \0007"
278testseq ": 1\n: 2\n\0020\0020\0017" \
279	" # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010\r # : 1 \0010\r\r\n # \r # : 2 \0010"
280
281# QUIT: no-op
282testseq "\0034" " # "
283
284# [n] ^[., ^[_: prev-hist-word
285testseq "\0033.\0033_" " # \0007\0007"
286testseq ": 1\n\0033." " # : 1\r\r\n # 1"
287testseq ": 1\n\00331\0033." " # : 1\r\r\n # :"
288testseq ": 1\n\00333\0033." " # : 1\r\r\n # "
289
290# ^V, ^^: quote
291testseq "\0026\0001" " # ^A"
292testseq "\0036\0001" " # ^A"
293
294# [n] ^[^]: search-character-backward
295testseq "\0033\0035a" " # \0007"
296testseq "echo\0033\0035e" " # echo\0010\0010\0010\0010"
297testseq "echo\0033\0035a" " # echo\0007"
298testseq "eecho\00332\0033\0035e" " # eecho\0010\0010\0010\0010\0010"
299testseq "echo\00332\0033\0035e" " # echo\0007"
300
301# [n] ^]: search-character-forward
302testseq "\0035a" " # \0007"
303testseq "echo\0001\0035o" " # echo\0010\0010\0010\0010ech"
304testseq "echo\0001\0035a" " # echo\0010\0010\0010\0010\0007"
305testseq "echoo\0001\00332\0035o" " # echoo\0010\0010\0010\0010\0010echo"
306# XXX differs from search-character-backward, should ring bell
307testseq "echo\0001\00332\0035o" " # echo\0010\0010\0010\0010ech"
308
309# ^R: search-history
310testseq "\0022" " # \r\nI-search: "
311testseq "echo\n\0022e" \
312	" # echo\r\r\n\r\n # \r\nI-search: \r\n\r # echo \0010\0010\0010\0010"
313testseq "echo\n\0022a" " # echo\r\r\n\r\n # \r\nI-search: \0007\r\nI-search: a"
314
315# ^T: transpose-chars
316testseq "\0024" " # \0007"
317testseq "a\0024" " # a\0007"
318testseq "ab\0024" " # ab\0010\0010ba"
319testseq "ab\0001\0024" " # ab\0010\0010\0007"
320# XXX UTF-8 testseq "\0303\0266a\0024" " # \0303\0266a\0010\0010a\303\0266"
321
322# [n] ^[U, ^[u: upcase-word
323testseq "\0033U\0033u" " # \0007\0007"
324testseq "ab\0001\0033U" " # ab\0010\0010AB"
325testseq "ab cd\0001\00332\0033U" " # ab cd\0010\0010\0010\0010\0010AB CD"
326testseq "ab\0001\00332\0033U" " # ab\0010\0010AB"
327testseq "1a\0001\0033U" " # 1a\0010\00101A"
328testseq "\0026\0002a\0001\0033U" " # ^Ba\0010\0010\0010^BA"
329testseq "\0303\0266a\0001\0033U" " # \0303\0266a\0010\0010\0303\0266A"
330
331# ^Y: yank
332testseq "\0031" " # \r\nnothing to yank\r\n # "
333testseq "abc\0027\0031" " # abc\0010\0010\0010   \0010\0010\0010abc"
334testseq "ab/cd\0027\0001\0031" \
335	" # ab/cd\0010\0010  \0010\0010\0010\0010\0010cdab/\0010\0010\0010"
336
337# ^[y: yank-pop
338testseq "\0033y" " # \r\nyank something first\r\n # "
339testseq "ab/cd\0027\0027\0031\0033y" \
340	" # ab/cd\0010\0010  \0010\0010\0010\0010\0010   \0010\0010\0010ab/\0010\0010\0010   \0010\0010\0010cd"
341