1#!/bin/sh 2# 3# $OpenBSD: emacs.sh,v 1.11 2019/04/03 14:59:34 jca 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= 28MALLOC_OPTIONS=S 29PS1=' # ' 30VISUAL=emacs 31export EDITOR ENV HISTFILE MAIL MALLOC_OPTIONS PS1 VISUAL 32 33# auto-insert 34testseq "abc" " # abc" 35 36# insertion of valid UTF-8 37testseq "z\0002\0302\0200" " # z\b\0302\0200z\b" 38testseq "z\0002\0337\0277" " # z\b\0337\0277z\b" 39testseq "z\0002\0340\0240\0200" " # z\b\0340\0240\0200z\b" 40testseq "z\0002\0354\0277\0277" " # z\b\0354\0277\0277z\b" 41testseq "z\0002\0355\0200\0200" " # z\b\0355\0200\0200z\b" 42testseq "z\0002\0355\0237\0277" " # z\b\0355\0237\0277z\b" 43testseq "z\0002\0356\0200\0200" " # z\b\0356\0200\0200z\b" 44testseq "z\0002\0357\0277\0277" " # z\b\0357\0277\0277z\b" 45testseq "z\0002\0364\0200\0200\0200" " # z\b\0364\0200\0200\0200z\b" 46testseq "z\0002\0364\0217\0277\0277" " # z\b\0364\0217\0277\0277z\b" 47 48# insertion of incomplete UTF-8 49testseq "z\0002\0302\0006" " # z\b\0302z\bz" 50testseq "z\0002\0377\0006" " # z\b\0377z\bz" 51testseq "z\0002\0337\0006" " # z\b\0337z\bz" 52testseq "z\0002\0340\0006" " # z\b\0340z\bz" 53testseq "z\0002\0357\0006" " # z\b\0357z\bz" 54testseq "z\0002\0364\0006" " # z\b\0364z\bz" 55testseq "z\0002\0340\0240\0006" " # z\b\0340\0240z\bz" 56testseq "z\0002\0354\0277\0006" " # z\b\0354\0277z\bz" 57testseq "z\0002\0355\0200\0006" " # z\b\0355\0200z\bz" 58testseq "z\0002\0355\0237\0006" " # z\b\0355\0237z\bz" 59testseq "z\0002\0356\0200\0006" " # z\b\0356\0200z\bz" 60testseq "z\0002\0357\0277\0006" " # z\b\0357\0277z\bz" 61testseq "z\0002\0364\0200\0200\0006" " # z\b\0364\0200\0200z\bz" 62testseq "z\0002\0364\0217\0277\0006" " # z\b\0364\0217\0277z\bz" 63 64# insertion of invalid bytes 65testseq "z\0002\0300\0277" " # z\b\0300z\b\b\0300\0277z\b" 66testseq "z\0002\0301\0277" " # z\b\0301z\b\b\0301\0277z\b" 67testseq "z\0002\0360\0217" " # z\b\0360z\b\b\0360\0217z\b" 68testseq "z\0002\0363\0217" " # z\b\0363z\b\b\0363\0217z\b" 69testseq "z\0002\0365\0217" " # z\b\0365z\b\b\0365\0217z\b" 70testseq "z\0002\0367\0217" " # z\b\0367z\b\b\0367\0217z\b" 71testseq "z\0002\0370\0217" " # z\b\0370z\b\b\0370\0217z\b" 72testseq "z\0002\0377\0217" " # z\b\0377z\b\b\0377\0217z\b" 73 74# insertion of excessively long encodings 75testseq "z\0002\0340\0200\0200" \ 76 " # z\b\0340z\b\b\0340\0200z\b\b\0340\0200\0200z\b" 77testseq "z\0002\0340\0201\0277" \ 78 " # z\b\0340z\b\b\0340\0201z\b\b\0340\0201\0277z\b" 79testseq "z\0002\0340\0202\0200" \ 80 " # z\b\0340z\b\b\0340\0202z\b\b\0340\0202\0200z\b" 81testseq "z\0002\0340\0237\0277" \ 82 " # z\b\0340z\b\b\0340\0237z\b\b\0340\0237\0277z\b" 83 84# insertion of surrogates and execessive code points 85testseq "z\0002\0355\0240\0200" \ 86 " # z\b\0355z\b\b\0355\0240z\b\b\0355\0240\0200z\b" 87testseq "z\0002\0355\0277\0277" \ 88 " # z\b\0355z\b\b\0355\0277z\b\b\0355\0277\0277z\b" 89testseq "z\0002\0364\0220\0200\0200" \ 90 " # z\b\0364z\b\b\0364\0220z\b\b\0364\0220\0200z\b\b\0364\0220\0200\0200z\b" 91testseq "z\0002\0364\0277\0277\0277" \ 92 " # z\b\0364z\b\b\0364\0277z\b\b\0364\0277\0277z\b\b\0364\0277\0277\0277z\b" 93 94# insertion of unmatched meta sequence 95testseq "z\0002\0033[3z" " # z\b\0007" 96 97# ^C, ^G: abort 98testseq "echo 1\0003" " # echo 1\r\n # " 99testseq "echo 1\0007" " # echo 1\r\n # " 100 101# ^B, Left: backward-char 102testseq "\0002" " # \0007" 103testseq "a\0002" " # a\0010" 104testseq "\0303\0266\0002" " # \0303\0266\0010" 105testseq "a\0033[D" " # a\0010" 106testseq "a\0033OD" " # a\0010" 107 108# ^[b, Ctrl-Left: backward-word 109testseq "\0033b" " # \0007" 110testseq "a1_$\0033b" " # a1_$\0010\0010\0010\0010" 111testseq "a1 \0303\0266\0033b\0033b" " # a1 \0303\0266\0010\0010\0010\0010" 112testseq "a1_$\0033[1;5D" " # a1_$\0010\0010\0010\0010" 113 114# ^[<: beginning-of-history 115testseq "\0033<" " # \0007" 116testseq ": 1\n: 2\n\0033<" " # : 1\r\r\n # : 2\r\r\n # \r # : 1 \0010" 117 118# ^A, Home, Ctrl-Down: beginning-of-line 119testseq "\0001" " # " 120testseq "aa\0001" " # aa\0010\0010" 121testseq "\0303\0266\0001" " # \0303\0266\0010" 122testseq "aa\0033[H" " # aa\0010\0010" 123testseq "aa\0033OH" " # aa\0010\0010" 124testseq "aa\0033[1~" " # aa\0010\0010" 125testseq "aa\0033[1;5B" " # aa\0010\0010" 126 127# [n] ^[C, ^[c: capitalize-word 128testseq "\0033C\0033c" " # \0007\0007" 129testseq "ab cd\0001\0033C" " # ab cd\0010\0010\0010\0010\0010Ab" 130testseq "ab\0001\00332\0033C" " # ab\0010\0010Ab" 131testseq "ab cd\0001\00332\0033C" " # ab cd\0010\0010\0010\0010\0010Ab Cd" 132testseq "1a\0001\0033C" " # 1a\0010\00101a" 133testseq "\0026\0002\0001\0033C" " # ^B\0010\0010^B" 134testseq "\0303\0266b\0001\0033C" " # \0303\0266b\0010\0010\0303\0266b" 135 136# ^[#: comment 137testseq "\0033#" " # \r # \0010\r\r\n # " 138testseq "a\0033#" " # a\r # #a \0010\0010\0010\r\r\n # " 139 140# XXX ^[^[: complete 141# XXX ^X^[: complete-command 142# XXX ^[^X: complete-file 143# XXX ^I, ^[=: complete-list 144 145# [n] ERASE, ^?, ^H: delete-char-backward 146testseq "\0177\0010" " # \0007\0007" 147testseq "ab\00332\0177" " # ab\0010\0010 \0010\0010" 148testseq "a\00332\0177" " # a\0010 \0010" 149testseq "\0303\0266\0177" " # \0303\0266\0010 \0010" 150 151# [n] Delete: delete-char-forward 152testseq "\0033[3~" " # \0007" 153testseq "a\0033[3~" " # a\0007" 154testseq "a\0001\0033[3~" " # a\0010 \0010" 155testseq "ab\0001\00332\0033[3~" " # ab\0010\0010 \0010\0010" 156testseq "a\0001\00332\0033[3~" " # a\0010 \0010" 157testseq "\0303\0266\0001\0033[3~" " # \0303\0266\0010 \0010" 158 159# [n] ^[ERASE, ^[^?, ^[^H, ^[h: delete-word-backward 160testseq "\0033\0177\033\0010\0033h" " # \0007\0007\0007" 161testseq "ab\0033\0177" " # ab\0010\0010 \0010\0010" 162testseq "ab cd\00332\0033\0177" \ 163 " # ab cd\0010\0010\0010\0010\0010 \0010\0010\0010\0010\0010" 164testseq "ab\00332\0033\0177" " # ab\0010\0010 \0010\0010" 165testseq "ab \0303\0266\0033\0177" " # ab \0303\0266\0010 \0010" 166 167# [n] ^[d: delete-word-forward 168testseq "\0033d" " # \0007" 169testseq "ab\0001\0033d" " # ab\0010\0010 \0010\0010" 170testseq "ab cd\0001\00332\0033d" \ 171 " # ab cd\0010\0010\0010\0010\0010 \0010\0010\0010\0010\0010" 172testseq "ab\0001\00332\0033d" " # ab\0010\0010 \0010\0010" 173 174# [n] ^N, ^XB, Down: down-history 175# [n] ^P, ^XA, Up: up-history 176testseq "\0016\0030B\0020\0030A" " # \0007\0007\0007\0007" 177testseq ": 1\n\0020\0016" " # : 1\r\r\n # \r # : 1 \0010\0007" 178testseq ": 1\n: 2\n\0020\0020\0016" \ 179 " # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010\r # : 1 \0010\r # : 2 \0010" 180testseq ": 1\n: 2\n\0033[A\0033[A\0033[B" \ 181 " # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010\r # : 1 \0010\r # : 2 \0010" 182testseq ": 1\n: 2\n\0033OA\0033OA\0033OB" \ 183 " # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010\r # : 1 \0010\r # : 2 \0010" 184 185# [n] ^[L, ^[l: downcase-word 186testseq "\0033L\0033l" " # \0007\0007" 187testseq "AB\0001\0033L" " # AB\0010\0010ab" 188testseq "AB CD\0001\00332\0033L" " # AB CD\0010\0010\0010\0010\0010ab cd" 189testseq "AB\0001\00332\0033L" " # AB\0010\0010ab" 190testseq "1A\0001\0033L" " # 1A\0010\00101a" 191testseq "\0026\0002A\0001\0033L" " # ^BA\0010\0010\0010^Ba" 192testseq "\0303\0266A\0001\0033L" " # \0303\0266A\0010\0010\0303\0266a" 193 194# ^[>: end-of-history 195testseq "\0033>" " # \0007" 196testseq ": 1\n\0033>" " # : 1\r\r\n # \r # : 1 \0010" 197 198# ^E, End, Ctrl-Up: end-of-line 199testseq "\0005" " # " 200testseq "abc\0001\0005" " # abc\0010\0010\0010abc" 201testseq "\0303\0266\0001\0005" " # \0303\0266\0010\0303\0266" 202testseq "abc\0001\0033[F" " # abc\0010\0010\0010abc" 203testseq "abc\0001\0033OF" " # abc\0010\0010\0010abc" 204testseq "abc\0001\0033[4~" " # abc\0010\0010\0010abc" 205testseq "abc\0001\0033[1;5A" " # abc\0010\0010\0010abc" 206 207# ^_: eot 208testseq "\0037" " # ^D\r\r" 209 210# [n] ^D: eot-or-delete 211testseq "\0004" " # ^D\r\r" 212 213# ^X^X: exchange-point-and-mark 214# ^[space: set-mark-command 215testseq "\0030\0030" " # \0007" 216testseq "abc\0033 \0001\0030\0030" " # abc\0010\0010\0010abc" 217testseq "\0303\0266\0033 \0001\0030\0030" " # \0303\0266\0010\0303\0266" 218 219# XXX ^[*: expand-file 220 221# [n] ^F, ^XC, Right: forward-char 222testseq "\0006\0030C" " # \0007\0007" 223testseq "abc\0001\0006" " # abc\0010\0010\0010a" 224testseq "abc\0001\00332\0006" " # abc\0010\0010\0010ab" 225testseq "a\0001\00332\0006" " # a\0010a" 226testseq "\0303\0266\0001\0006" " # \0303\0266\0010\0303\0266" 227testseq "abc\0001\0033[C" " # abc\0010\0010\0010a" 228testseq "abc\0001\0033OC" " # abc\0010\0010\0010a" 229 230# [n] ^[f, Ctrl-Right: forward-word 231testseq "\0033f" " # \0007" 232testseq "ab\0001\0033f" " # ab\0010\0010ab" 233testseq "ab cd\0001\00332\0033f" " # ab cd\0010\0010\0010\0010\0010ab cd" 234testseq "ab\0001\00332\0033f" " # ab\0010\0010ab" 235testseq "\0303\0266\0001\0033f" " # \0303\0266\0010\0303\0266" 236testseq "ab\0001\0033[1;5C" " # ab\0010\0010ab" 237 238# [n] ^[g: goto-history 239testseq "\0033g" " # \0007" 240testseq ": 1\n\0033g" " # : 1\r\r\n # \r # : 1 \0010" 241testseq ": 1\n: 2\n\00332\0033g" " # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010" 242testseq ": 1\n\00332\0033g" " # : 1\r\r\n # \0007" 243 244# KILL: kill-line 245testseq "\0025" " # \r # \0010" 246testseq "ab\0025" " # ab\r # \0010\0010\0010" 247 248# [n] ^K: kill-to-eol 249testseq "\0013" " # " 250testseq "abc\0002\0002\0013" " # abc\0010\0010 \0010\0010" 251 252# XXX ^[?: list 253# XXX ^X?: list-command 254# XXX ^X^Y: list-file 255 256# ^J, ^M: newline 257testseq "\0012\0015" " # \r\r\n # \r\r\n # " 258testseq ": 1\0012" " # : 1\r\r\n # " 259testseq ": 1\0001\0012" " # : 1\0010\0010\0010\r\r\n # " 260 261# ^O: newline-and-next 262testseq "\0017" " # \r\r\n # \0007" 263testseq ": 1\n: 2\n\0020\0020\0017" \ 264 " # : 1\r\r\n # : 2\r\r\n # \r # : 2 \0010\r # : 1 \0010\r\r\n # \r # : 2 \0010" 265 266# QUIT: no-op 267testseq "\0034" " # " 268 269# [n] ^[., ^[_: prev-hist-word 270testseq "\0033.\0033_" " # \0007\0007" 271testseq ": 1\n\0033." " # : 1\r\r\n # 1" 272testseq ": 1\n\00331\0033." " # : 1\r\r\n # :" 273testseq ": 1\n\00333\0033." " # : 1\r\r\n # " 274 275# ^V, ^^: quote 276testseq "\0026\0001" " # ^A" 277testseq "\0036\0001" " # ^A" 278 279# [n] ^[^]: search-character-backward 280testseq "\0033\0035a" " # \0007" 281testseq "echo\0033\0035e" " # echo\0010\0010\0010\0010" 282testseq "echo\0033\0035a" " # echo\0007" 283testseq "eecho\00332\0033\0035e" " # eecho\0010\0010\0010\0010\0010" 284testseq "echo\00332\0033\0035e" " # echo\0007" 285 286# [n] ^]: search-character-forward 287testseq "\0035a" " # \0007" 288testseq "echo\0001\0035o" " # echo\0010\0010\0010\0010ech" 289testseq "echo\0001\0035a" " # echo\0010\0010\0010\0010\0007" 290testseq "echoo\0001\00332\0035o" " # echoo\0010\0010\0010\0010\0010echo" 291# XXX differs from search-character-backward, should ring bell 292testseq "echo\0001\00332\0035o" " # echo\0010\0010\0010\0010ech" 293 294# ^R: search-history 295testseq "\0022" " # \r\nI-search: " 296testseq "echo\n\0022e" \ 297 " # echo\r\r\n\r\n # \r\nI-search: \r\n\r # echo \0010\0010\0010\0010" 298testseq "echo\n\0022a" " # echo\r\r\n\r\n # \r\nI-search: \0007\r\nI-search: a" 299 300# ^T: transpose-chars 301testseq "\0024" " # \0007" 302testseq "a\0024" " # a\0007" 303testseq "ab\0024" " # ab\0010\0010ba" 304testseq "ab\0001\0024" " # ab\0010\0010\0007" 305# XXX UTF-8 testseq "\0303\0266a\0024" " # \0303\0266a\0010\0010a\303\0266" 306 307# [n] ^[U, ^[u: upcase-word 308testseq "\0033U\0033u" " # \0007\0007" 309testseq "ab\0001\0033U" " # ab\0010\0010AB" 310testseq "ab cd\0001\00332\0033U" " # ab cd\0010\0010\0010\0010\0010AB CD" 311testseq "ab\0001\00332\0033U" " # ab\0010\0010AB" 312testseq "1a\0001\0033U" " # 1a\0010\00101A" 313testseq "\0026\0002a\0001\0033U" " # ^Ba\0010\0010\0010^BA" 314testseq "\0303\0266a\0001\0033U" " # \0303\0266a\0010\0010\0303\0266A" 315 316# ^Y: yank 317testseq "\0031" " # \r\nnothing to yank\r\n # " 318testseq "abc\0027\0031" " # abc\0010\0010\0010 \0010\0010\0010abc" 319testseq "ab/cd\0027\0001\0031" \ 320 " # ab/cd\0010\0010 \0010\0010\0010\0010\0010cdab/\0010\0010\0010" 321 322# ^[y: yank-pop 323testseq "\0033y" " # \r\nyank something first\r\n # " 324testseq "ab/cd\0027\0027\0031\0033y" \ 325 " # ab/cd\0010\0010 \0010\0010\0010\0010\0010 \0010\0010\0010ab/\0010\0010\0010 \0010\0010\0010cd" 326