1*d4e7c603Sniklas# $OpenBSD: input,v 1.2 2001/01/29 01:58:38 niklas Exp $ 2*d4e7c603Sniklas 3df930be7Sderaadt# @(#)input 5.5 (Berkeley) 7/2/94 4df930be7Sderaadt 5df930be7SderaadtMAPS, EXECUTABLE BUFFERS AND INPUT IN EX/VI: 6df930be7Sderaadt 7df930be7SderaadtThe basic rule is that input in ex/vi is a stack. Every time a key which 8df930be7Sderaadtgets expanded is encountered, it is expanded and the expansion is treated 9df930be7Sderaadtas if it were input from the user. So, maps and executable buffers are 10df930be7Sderaadtsimply pushed onto the stack from which keys are returned. The exception 11df930be7Sderaadtis that if the "remap" option is turned off, only a single map expansion 12df930be7Sderaadtis done. I intend to be fully backward compatible with this. 13df930be7Sderaadt 14df930be7SderaadtHistorically, if the mode of the editor changed (ex to vi or vice versa), 15df930be7Sderaadtany queued input was silently discarded. I don't see any reason to either 16df930be7Sderaadtsupport or not support this semantic. I intend to retain the queued input, 17df930be7Sderaadtmostly because it's simpler than throwing it away. 18df930be7Sderaadt 19df930be7SderaadtHistorically, neither the initial command on the command line (the + flag) 20df930be7Sderaadtor the +cmd associated with the ex and edit commands was subject to mapping. 21df930be7SderaadtAlso, while the +cmd appears to be subject to "@buffer" expansion, once 22df930be7Sderaadtexpanded it doesn't appear to work correctly. I don't see any reason to 23df930be7Sderaadteither support or not support these semantics, so, for consistency, I intend 24df930be7Sderaadtto pass both the initial command and the command associated with ex and edit 25df930be7Sderaadtcommands through the standard mapping and @ buffer expansion. 26df930be7Sderaadt 27df930be7SderaadtOne other difference between the historic ex/vi and nex/nvi is that nex 28df930be7Sderaadtdisplays the executed buffers as it executes them. This means that if 29df930be7Sderaadtthe file is: 30df930be7Sderaadt 31df930be7Sderaadt set term=xterm 32df930be7Sderaadt set term=yterm 33df930be7Sderaadt set term=yterm 34df930be7Sderaadt 35df930be7Sderaadtthe user will see the following during a typical edit session: 36df930be7Sderaadt 37df930be7Sderaadt nex testfile 38df930be7Sderaadt testfile: unmodified: line 3 39df930be7Sderaadt :1,$yank a 40df930be7Sderaadt :@a 41df930be7Sderaadt :set term=zterm 42df930be7Sderaadt :set term=yterm 43df930be7Sderaadt :set term=xterm 44df930be7Sderaadt :q! 45df930be7Sderaadt 46df930be7SderaadtThis seems like a feature and unlikely to break anything, so I don't 47df930be7Sderaadtintend to match historic practice in this area. 48df930be7Sderaadt 49df930be7SderaadtThe rest of this document is a set of conclusions as to how I believe 50df930be7Sderaadtthe historic maps and @ buffers work. The summary is as follows: 51df930be7Sderaadt 52df930be7Sderaadt1: For buffers that are cut in "line mode", or buffers that are not cut 53df930be7Sderaadt in line mode but which contain portions of more than a single line, a 54df930be7Sderaadt trailing <newline> character appears in the input for each line in the 55df930be7Sderaadt buffer when it is executed. For buffers not cut in line mode and which 56df930be7Sderaadt contain portions of only a single line, no additional characters 57df930be7Sderaadt appear in the input. 58df930be7Sderaadt2: Executable buffers that execute other buffers don't load their 59df930be7Sderaadt contents until they execute them. 60df930be7Sderaadt3: Maps and executable buffers are copied when they are executed -- 61df930be7Sderaadt they can be modified by the command but that does not change their 62df930be7Sderaadt actions. 63df930be7Sderaadt4: Historically, executable buffers are discarded if the editor 64df930be7Sderaadt switches between ex and vi modes. 65df930be7Sderaadt5: Executable buffers inside of map commands are expanded normally. 66df930be7Sderaadt Maps inside of executable buffers are expanded normally. 67df930be7Sderaadt6: If an error is encountered while executing a mapped command or buffer, 68df930be7Sderaadt the rest of the mapped command/buffer is discarded. No user input 69df930be7Sderaadt characters are discarded. 70df930be7Sderaadt7: Characters in executable buffers are remapped. 71df930be7Sderaadt8: Characters in executable buffers are not quoted. 72df930be7Sderaadt 73df930be7SderaadtIndividual test cases follow. Note, in the test cases, control characters 74df930be7Sderaadtare not literal and will have to be replaced to make the test cases work. 75df930be7Sderaadt 76df930be7Sderaadt=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 77df930be7Sderaadt1: For buffers that are cut in "line mode", or buffers that are not cut 78df930be7Sderaadt in line mode but which contain portions of more than a single line, a 79df930be7Sderaadt trailing <newline> character appears in the input for each line in the 80df930be7Sderaadt buffer when it is executed. For buffers not cut in line mode and which 81df930be7Sderaadt contain portions of only a single line, no additional characters 82df930be7Sderaadt appear in the input. 83df930be7Sderaadt 84df930be7Sderaadt=== test file === 85df930be7Sderaadt3Gw 86df930be7Sderaadtw 87df930be7Sderaadtline 1 foo bar baz 88df930be7Sderaadtline 2 foo bar baz 89df930be7Sderaadtline 3 foo bar baz 90df930be7Sderaadt=== end test file === 91df930be7Sderaadt 92df930be7Sderaadt If the first line is loaded into 'a' and executed: 93df930be7Sderaadt 94df930be7Sderaadt1G"ayy@a 95df930be7Sderaadt 96df930be7Sderaadt The cursor ends up on the '2', a result of pushing "3Gw^J" onto 97df930be7Sderaadt the stack. 98df930be7Sderaadt 99df930be7Sderaadt If the first two lines are loaded into 'a' and executed: 100df930be7Sderaadt 101df930be7Sderaadt1G2"ayy@a 102df930be7Sderaadt 103df930be7Sderaadt The cursor ends up on the 'f' in "foo" in the fifth line of the 104df930be7Sderaadt file, a result of pushing "3Gw^Jw^J" onto the stack. 105df930be7Sderaadt 106df930be7Sderaadt If the first line is loaded into 'a', but not using line mode, 107df930be7Sderaadt and executed: 108df930be7Sderaadt 109df930be7Sderaadt1G"ay$@a 110df930be7Sderaadt 111df930be7Sderaadt The cursor ends up on the '1', a result of pushing "3Gw" onto 112df930be7Sderaadt the stack 113df930be7Sderaadt 114df930be7Sderaadt If the first two lines are loaded into 'a', but not using line mode, 115df930be7Sderaadt and executed: 116df930be7Sderaadt 117df930be7Sderaadt1G2"ay$@a 118df930be7Sderaadt 119df930be7Sderaadt The cursor ends up on the 'f' in "foo" in the fifth line of the 120df930be7Sderaadt file, a result of pushing "3Gw^Jw^J" onto the stack. 121df930be7Sderaadt 122df930be7Sderaadt=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 123df930be7Sderaadt2: Executable buffers that execute other buffers don't load their 124df930be7Sderaadt contents until they execute them. 125df930be7Sderaadt 126df930be7Sderaadt=== test file === 127df930be7SderaadtcwLOAD B^[ 128df930be7Sderaadtline 1 foo bar baz 129df930be7Sderaadtline 2 foo bar baz 130df930be7Sderaadtline 3 foo bar baz 131df930be7Sderaadt@a@b 132df930be7Sderaadt"byy 133df930be7Sderaadt=== end test file === 134df930be7Sderaadt 135df930be7Sderaadt The command is loaded into 'e', and then executed. 'e' executes 136df930be7Sderaadt 'a', which loads 'b', then 'e' executes 'b'. 137df930be7Sderaadt 138df930be7Sderaadt5G"eyy6G"ayy1G@e 139df930be7Sderaadt 140df930be7Sderaadt The output should be: 141df930be7Sderaadt 142df930be7Sderaadt=== output file === 143df930be7SderaadtcwLOAD B^[ 144df930be7SderaadtLOAD B 1 foo bar baz 145df930be7Sderaadtline 2 foo bar baz 146df930be7Sderaadtline 3 foo bar baz 147df930be7Sderaadt@a@b 148df930be7Sderaadt"byy 149df930be7Sderaadt=== end output file === 150df930be7Sderaadt 151df930be7Sderaadt=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 152df930be7Sderaadt3: Maps and executable buffers are copied when they are executed -- 153df930be7Sderaadt they can be modified by the command but that does not change their 154df930be7Sderaadt actions. 155df930be7Sderaadt 156df930be7Sderaadt Executable buffers: 157df930be7Sderaadt 158df930be7Sderaadt=== test file === 159df930be7Sderaadtline 1 foo bar baz 160df930be7Sderaadtline 2 foo bar baz 161df930be7Sderaadtline 3 foo bar baz 162df930be7Sderaadt@a@b 163df930be7Sderaadt"eyy 164df930be7SderaadtcwEXECUTE B^[ 165df930be7Sderaadt=== end test file === 166df930be7Sderaadt 167df930be7Sderaadt4G"eyy5G"ayy6G"byy1G@eG"ep 168df930be7Sderaadt 169df930be7Sderaadt The command is loaded into 'e', and then executed. 'e' executes 170df930be7Sderaadt 'a', which loads 'e', then 'e' executes 'b' anyway. 171df930be7Sderaadt 172df930be7Sderaadt The output should be: 173df930be7Sderaadt 174df930be7Sderaadt=== output file === 175df930be7Sderaadtline 1 foo bar baz 176df930be7SderaadtEXECUTE B 2 foo bar baz 177df930be7Sderaadtline 3 foo bar baz 178df930be7Sderaadt@a@b 179df930be7Sderaadt"eyy 180df930be7SderaadtcwEXECUTE B^[ 181df930be7Sderaadtline 1 foo bar baz 182df930be7Sderaadt=== end output file === 183df930be7Sderaadt 184df930be7Sderaadt Maps: 185df930be7Sderaadt 186df930be7Sderaadt=== test file === 187df930be7SderaadtCine 1 foo bar baz 188df930be7Sderaadtline 2 foo bar baz 189df930be7Sderaadtline 3 foo bar baz 190df930be7Sderaadt=== end test file === 191df930be7Sderaadt 192df930be7Sderaadt Entering the command ':map = :map = rB^V^MrA^M1G==' shows that 193df930be7Sderaadt the first time the '=' is entered the '=' map is set and the 194df930be7Sderaadt character is changed to 'A', the second time the character is 195df930be7Sderaadt changed to 'B'. 196df930be7Sderaadt 197df930be7Sderaadt=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 198df930be7Sderaadt4: Historically, executable buffers are discarded if the editor 199df930be7Sderaadt switches between ex and vi modes. 200df930be7Sderaadt 201df930be7Sderaadt=== test file === 202df930be7Sderaadtline 1 foo bar baz 203df930be7Sderaadtline 2 foo bar baz 204df930be7Sderaadtline 3 foo bar baz 205df930be7SderaadtcwCHANGE^[Q:set 206df930be7Sderaadtset|visual|1Gwww 207df930be7Sderaadt=== end test file === 208df930be7Sderaadt 209df930be7Sderaadtvi testfile 210df930be7Sderaadt4G"ayy@a 211df930be7Sderaadt 212df930be7Sderaadtex testfile 213df930be7Sderaadt$p 214df930be7Sderaadtyank a 215df930be7Sderaadt@a 216df930be7Sderaadt 217df930be7Sderaadt In vi, the command is loaded into 'a' and then executed. The command 218df930be7Sderaadt subsequent to the 'Q' is (historically, silently) discarded. 219df930be7Sderaadt 220df930be7Sderaadt In ex, the command is loaded into 'a' and then executed. The command 221df930be7Sderaadt subsequent to the 'visual' is (historically, silently) discarded. The 222df930be7Sderaadt first set command is output by ex, although refreshing the screen usually 223df930be7Sderaadt causes it not to be seen. 224df930be7Sderaadt 225df930be7Sderaadt=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 226df930be7Sderaadt5: Executable buffers inside of map commands are expanded normally. 227df930be7Sderaadt Maps inside of executable buffers are expanded normally. 228df930be7Sderaadt 229df930be7Sderaadt Buffers inside of map commands: 230df930be7Sderaadt 231df930be7Sderaadt=== test file === 232df930be7Sderaadtline 1 foo bar baz 233df930be7Sderaadtline 2 foo bar baz 234df930be7Sderaadtline 3 foo bar baz 235df930be7SderaadtcwREPLACE BY A^[ 236df930be7Sderaadt=== end test file === 237df930be7Sderaadt 238df930be7Sderaadt4G"ay$:map x @a 239df930be7Sderaadt1Gx 240df930be7Sderaadt 241df930be7Sderaadt The output should be: 242df930be7Sderaadt 243df930be7Sderaadt=== output file === 244df930be7SderaadtREPLACE BY A 1 foo bar baz 245df930be7Sderaadtline 2 foo bar baz 246df930be7Sderaadtline 3 foo bar baz 247df930be7SderaadtcwREPLACE BY A^[ 248df930be7Sderaadt=== end output file === 249df930be7Sderaadt 250df930be7Sderaadt Maps commands inside of executable buffers: 251df930be7Sderaadt 252df930be7Sderaadt=== test file === 253df930be7Sderaadtline 1 foo bar baz 254df930be7Sderaadtline 2 foo bar baz 255df930be7Sderaadtline 3 foo bar baz 256df930be7SderaadtX 257df930be7Sderaadt=== end test file === 258df930be7Sderaadt 259df930be7Sderaadt:map X cwREPLACE BY XMAP^[ 260df930be7Sderaadt4G"ay$1G@a 261df930be7Sderaadt 262df930be7Sderaadt The output should be: 263df930be7Sderaadt 264df930be7Sderaadt=== output file === 265df930be7SderaadtREPLACE BY XMAP 1 foo bar baz 266df930be7Sderaadtline 2 foo bar baz 267df930be7Sderaadtline 3 foo bar baz 268df930be7SderaadtX 269df930be7Sderaadt=== end output file === 270df930be7Sderaadt 271df930be7Sderaadt Here's a test that does both, repeatedly. 272df930be7Sderaadt 273df930be7Sderaadt=== test file === 274df930be7Sderaadtline 1 foo bar baz 275df930be7Sderaadtline 2 foo bar baz 276df930be7Sderaadtline 3 foo bar baz 277df930be7SderaadtX 278df930be7SderaadtY 279df930be7SderaadtcwREPLACED BY C^[ 280df930be7Sderaadtblank line 281df930be7Sderaadt=== end test file === 282df930be7Sderaadt 283df930be7Sderaadt:map x @a 284df930be7Sderaadt4G"ay$ 285df930be7Sderaadt:map X @b 286df930be7Sderaadt5G"by$ 287df930be7Sderaadt:map Y @c 288df930be7Sderaadt6G"cy$ 289df930be7Sderaadt1Gx 290df930be7Sderaadt 291df930be7Sderaadt The output should be: 292df930be7Sderaadt 293df930be7Sderaadt=== output file === 294df930be7SderaadtREPLACED BY C 1 foo bar baz 295df930be7Sderaadtline 2 foo bar baz 296df930be7Sderaadtline 3 foo bar baz 297df930be7SderaadtX 298df930be7SderaadtY 299df930be7SderaadtcwREPLACED BY C^[ 300df930be7Sderaadtblank line 301df930be7Sderaadt=== end output file === 302df930be7Sderaadt 303df930be7Sderaadt=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 304df930be7Sderaadt6: If an error is encountered while executing a mapped command or 305df930be7Sderaadt a buffer, the rest of the mapped command/buffer is discarded. No 306df930be7Sderaadt user input characters are discarded. 307df930be7Sderaadt 308df930be7Sderaadt=== test file === 309df930be7Sderaadtline 1 foo bar baz 310df930be7Sderaadtline 2 foo bar baz 311df930be7Sderaadtline 3 foo bar baz 312df930be7Sderaadt:map = 10GcwREPLACMENT^V^[^[ 313df930be7Sderaadt=== end test file === 314df930be7Sderaadt 315df930be7Sderaadt The above mapping fails, however, if the 10G is changed to 1, 2, 316df930be7Sderaadt or 3G, it will succeed. 317df930be7Sderaadt 318df930be7Sderaadt=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 319df930be7Sderaadt7: Characters in executable buffers are remapped. 320df930be7Sderaadt 321df930be7Sderaadt=== test file === 322df930be7Sderaadtabcdefghijklmnnop 323df930be7Sderaadtggg 324df930be7Sderaadt=== end test file === 325df930be7Sderaadt 326df930be7Sderaadt:map g x 327df930be7Sderaadt2G"ay$1G@a 328df930be7Sderaadt 329df930be7Sderaadt The output should be: 330df930be7Sderaadt 331df930be7Sderaadt=== output file === 332df930be7Sderaadtdefghijklmnnop 333df930be7Sderaadtggg 334df930be7Sderaadt=== end output file === 335df930be7Sderaadt 336df930be7Sderaadt=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 337df930be7Sderaadt8: Characters in executable buffers are not quoted. 338df930be7Sderaadt 339df930be7Sderaadt=== test file === 340df930be7SderaadtiFOO^[ 341df930be7Sderaadt 342df930be7Sderaadt=== end test file === 343df930be7Sderaadt 344df930be7Sderaadt1G"ay$2G@a 345df930be7Sderaadt 346df930be7Sderaadt The output should be: 347df930be7Sderaadt 348df930be7Sderaadt=== output file === 349df930be7SderaadtiFOO^[ 350df930be7SderaadtFOO 351df930be7Sderaadt=== end output file === 352df930be7Sderaadt=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 353