1#!/bin/sh 2# 3# $OpenBSD: vi.sh,v 1.9 2021/09/02 07:14:15 jasper Exp $ 4# 5# Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org> 6# Copyright (c) 2017 Anton Lindqvist <anton@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=vi 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# ^H, ^?: Erase. 37testseq "ab\bc" " # ab\b \bc" 38testseq "ab\0177c" " # ab\b \bc" 39 40# ^J, ^M: End of line. 41testseq "echo a\nb" " # echo a\r\r\na\r\n # b" 42testseq "echo a\rb" " # echo a\r\r\na\r\n # b" 43testseq "echo a\0033\nb" " # echo a\b\r\r\na\r\n # b" 44testseq "echo a\0033\rb" " # echo a\b\r\r\na\r\n # b" 45 46# ^U: Kill. 47testseq "ab\0033ic\0025d" " # ab\bcb\b\b\bb \b\b\bdb\b" 48 49# ^V: Literal next. 50testseq "a\0026\0033b" " # a^\b^[b" 51 52# ^W: Word erase. 53testseq "one two\0027rep" " # one two\b\b\b \b\b\brep" 54 55# A: Append at end of line. 56# 0: Move to column 0. 57testseq "one\00330A two" " # one\b\b\bone two" 58testseq "one\003302A two\0033" " # one\b\b\bone two two\b" 59 60# a: Append. 61# .: Redo. 62testseq "ab\00330axy" " # ab\b\baxb\byb\b" 63testseq "ab\003302axy\0033" " # ab\b\baxb\byb\bxyb\b\b" 64testseq "ab\00330axy\0033." " # ab\b\baxb\byb\b\byxyb\b\b" 65 66# B: Move back big word. 67testseq "one 2.0\0033BD" " # one 2.0\b\b\b \b\b\b\b" 68 69# b: Move back word. 70# C: Change to end of line. 71# D: Delete to end of line. 72testseq "one ab.cd\0033bDa.\00332bD" \ 73 " # one ab.cd\b\b \b\b\b..\b\b\b\b \b\b\b\b\b" 74testseq "one two\0033bCrep" " # one two\b\b\b \b\b\brep" 75 76# c: Change region. 77testseq "one two\0033cbrep" " # one two\b\b\bo \b\b\bro\beo\bpo\b" 78testseq "one two\00332chx" " # one two\b\b\bo \b\b\bxo\b" 79 80# d: Delete region. 81testseq "one two\0033db" " # one two\b\b\bo \b\b\b" 82testseq "one two xy\00332db" " # one two xy\b\b\b\b\b\by \b\b\b\b\b\b" 83 84# E: Move to end of big word. 85testseq "1.00 two\00330ED" " # 1.00 two\b\r # 1.0 \b\b\b\b\b\b" 86 87# e: Move to end of word. 88testseq "onex two\00330eD" " # onex two\b\r # one \b\b\b\b\b\b" 89 90# F: Find character backward. 91# ;: Repeat last search. 92# ,: Repeat last search in opposite direction. 93testseq "hello\00332FlD" " # hello\b\b\b \b\b\b\b" 94testseq "hello\0033Flix\0033;ix" " # hello\b\bxlo\b\b\b\bxlxlo\b\b\b\b" 95testseq "hello\00332Flix\00332,ix" " # hello\b\b\bxllo\b\b\b\bxlxlo\b\b" 96 97# f: Find character forward. 98testseq "hello\003302flD" " # hello\b\b\b\b\bhel \b\b\b" 99 100# h, ^H: Move left. 101# i: Insert. 102testseq "hello\00332hix" " # hello\b\b\bxllo\b\b\b" 103testseq "hello\00332\b2ix\0033" " # hello\b\b\bxllo\b\b\bxllo\b\b\b\b" 104 105# I: Insert before first non-blank. 106# ^: Move to the first non-whitespace character. 107testseq " ab\0033Ixy" " # ab\b\bxab\b\byab\b\b" 108testseq " ab\00332Ixy\0033" " # ab\b\bxab\b\byab\b\bxyab\b\b\b" 109testseq " ab\0033^ixy" " # ab\b\bxab\b\byab\b\b" 110 111# L: Undefined command (beep). 112testseq "ab\0033Lx" " # ab\b\a \b\b" 113 114# l, space: Move right. 115# ~: Change case. 116testseq "abc\003302l~" " # abc\b\b\babC\b" 117testseq "abc\00330 rx" " # abc\b\b\bax\b" 118 119# P: Paste at current position. 120testseq "abcde\0033hDhP" " # abcde\b\b \b\b\b\bdebc\b\b" 121testseq "abcde\0033hDh2P" " # abcde\b\b \b\b\b\bdedebc\b\b\b" 122 123# p: Paste after current position. 124testseq "abcd\0033hDhp" " # abcd\b\b \b\b\b\bacdb\b\b" 125testseq "abcd\0033hDh2p" " # abcd\b\b \b\b\b\bacdcdb\b\b" 126 127# R: Replace. 128testseq "abcd\00332h2Rx\0033" " # abcd\b\b\bxx\b" 129testseq "abcdef\00334h2Rxy\0033" " # abcdef\b\b\b\b\bxyxy\b" 130 131# r: Replace character. 132testseq "abcd\00332h2rxiy" " # abcd\b\b\bxx\byxd\b\b" 133testseq "\0303\0266\0033ro" " # \0303\0266\bo \b\b" 134testseq "\0342\0202\0254\0033ro" " # \0342\0202\0254\bo \b\b\b" 135testseq "\0303\0266\00332ro" " # \0303\0266\b\a" 136 137# S: Substitute whole line. 138testseq "oldst\0033Snew" " # oldst\b\b\b\b\b \r # new" 139testseq "oldstr\033Snew" " # oldstr\b\r # \r # new" 140 141# s: Substitute. 142testseq "abcd\00332h2sx" " # abcd\b\b\bd \b\b\bxd\b" 143testseq "\0303\0266\0033s" " # \0303\0266\b \b\b" 144 145# T: Move backward after character. 146testseq "helloo\0033TlD" " # helloo\b\b \b\b\b" 147testseq "hello\00332TlD" " # hello\b\b \b\b\b" 148 149# t: Move forward before character. 150testseq "abc\00330tcD" " # abc\b\b\ba \b\b\b" 151testseq "hello\003302tlD" " # hello\b\b\b\b\bhe \b\b\b\b" 152 153# U: Undo all changes. 154testseq "test\0033U" " # test\b\b\b\b \b\b\b\b" 155 156# u: Undo. 157testseq "test\0033hxu" " # test\b\bt \b\bst\b\b" 158 159# W: Move forward big word. 160testseq "1.0 two\00330WD" " # 1.0 two\b\r # 1.0 \b\b\b\b" 161 162# w: Move forward word. 163testseq "ab cd ef\003302wD" " # ab cd ef\b\r # ab cd \b\b\b" 164 165# X: Delete previous character. 166testseq "abcd\00332X" " # abcd\b\b\bd \b\b\b" 167 168# x: Delete character. 169# |: Move to column. 170testseq "abcd\00332|2x" " # abcd\b\b\bd \b\b\b" 171testseq "\0303\0266a\0033xx" " # \0303\0266a\b \b\b \b\b" 172 173# Y: Yank to end of line. 174testseq "abcd\0033hYp" " # abcd\b\bccdd\b\b" 175 176# y: Yank region. 177# $: Move to the last character. 178testseq "abcd\00332h2ylp" " # abcd\b\b\bbbccd\b\b\b" 179testseq "abcd\00332h2yl\$p" " # abcd\b\b\bbcdbc\b" 180 181# %: Find match. 182testseq "(x)\0033%lrc" " # (x)\b\b\b(c\b" 183testseq "(x)\00330%hrc" " # (x)\b\b\b(x\bc\b" 184 185# ^R: Redraw. 186testseq "test\0033h\0022" " # test\b\b\r\r\n # test\b\b" 187