1# @(#)input 5.5 (Berkeley) 7/2/94 2 3MAPS, EXECUTABLE BUFFERS AND INPUT IN EX/VI: 4 5The basic rule is that input in ex/vi is a stack. Every time a key which 6gets expanded is encountered, it is expanded and the expansion is treated 7as if it were input from the user. So, maps and executable buffers are 8simply pushed onto the stack from which keys are returned. The exception 9is that if the "remap" option is turned off, only a single map expansion 10is done. I intend to be fully backward compatible with this. 11 12Historically, if the mode of the editor changed (ex to vi or vice versa), 13any queued input was silently discarded. I don't see any reason to either 14support or not support this semantic. I intend to retain the queued input, 15mostly because it's simpler than throwing it away. 16 17Historically, neither the initial command on the command line (the + flag) 18or the +cmd associated with the ex and edit commands was subject to mapping. 19Also, while the +cmd appears to be subject to "@buffer" expansion, once 20expanded it doesn't appear to work correctly. I don't see any reason to 21either support or not support these semantics, so, for consistency, I intend 22to pass both the initial command and the command associated with ex and edit 23commands through the standard mapping and @ buffer expansion. 24 25One other difference between the historic ex/vi and nex/nvi is that nex 26displays the executed buffers as it executes them. This means that if 27the file is: 28 29 set term=xterm 30 set term=yterm 31 set term=yterm 32 33the user will see the following during a typical edit session: 34 35 nex testfile 36 testfile: unmodified: line 3 37 :1,$yank a 38 :@a 39 :set term=zterm 40 :set term=yterm 41 :set term=xterm 42 :q! 43 44This seems like a feature and unlikely to break anything, so I don't 45intend to match historic practice in this area. 46 47The rest of this document is a set of conclusions as to how I believe 48the historic maps and @ buffers work. The summary is as follows: 49 501: For buffers that are cut in "line mode", or buffers that are not cut 51 in line mode but which contain portions of more than a single line, a 52 trailing <newline> character appears in the input for each line in the 53 buffer when it is executed. For buffers not cut in line mode and which 54 contain portions of only a single line, no additional characters 55 appear in the input. 562: Executable buffers that execute other buffers don't load their 57 contents until they execute them. 583: Maps and executable buffers are copied when they are executed -- 59 they can be modified by the command but that does not change their 60 actions. 614: Historically, executable buffers are discarded if the editor 62 switches between ex and vi modes. 635: Executable buffers inside of map commands are expanded normally. 64 Maps inside of executable buffers are expanded normally. 656: If an error is encountered while executing a mapped command or buffer, 66 the rest of the mapped command/buffer is discarded. No user input 67 characters are discarded. 687: Characters in executable buffers are remapped. 698: Characters in executable buffers are not quoted. 70 71Individual test cases follow. Note, in the test cases, control characters 72are not literal and will have to be replaced to make the test cases work. 73 74=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 751: For buffers that are cut in "line mode", or buffers that are not cut 76 in line mode but which contain portions of more than a single line, a 77 trailing <newline> character appears in the input for each line in the 78 buffer when it is executed. For buffers not cut in line mode and which 79 contain portions of only a single line, no additional characters 80 appear in the input. 81 82=== test file === 833Gw 84w 85line 1 foo bar baz 86line 2 foo bar baz 87line 3 foo bar baz 88=== end test file === 89 90 If the first line is loaded into 'a' and executed: 91 921G"ayy@a 93 94 The cursor ends up on the '2', a result of pushing "3Gw^J" onto 95 the stack. 96 97 If the first two lines are loaded into 'a' and executed: 98 991G2"ayy@a 100 101 The cursor ends up on the 'f' in "foo" in the fifth line of the 102 file, a result of pushing "3Gw^Jw^J" onto the stack. 103 104 If the first line is loaded into 'a', but not using line mode, 105 and executed: 106 1071G"ay$@a 108 109 The cursor ends up on the '1', a result of pushing "3Gw" onto 110 the stack 111 112 If the first two lines are loaded into 'a', but not using line mode, 113 and executed: 114 1151G2"ay$@a 116 117 The cursor ends up on the 'f' in "foo" in the fifth line of the 118 file, a result of pushing "3Gw^Jw^J" onto the stack. 119 120=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1212: Executable buffers that execute other buffers don't load their 122 contents until they execute them. 123 124=== test file === 125cwLOAD B^[ 126line 1 foo bar baz 127line 2 foo bar baz 128line 3 foo bar baz 129@a@b 130"byy 131=== end test file === 132 133 The command is loaded into 'e', and then executed. 'e' executes 134 'a', which loads 'b', then 'e' executes 'b'. 135 1365G"eyy6G"ayy1G@e 137 138 The output should be: 139 140=== output file === 141cwLOAD B^[ 142LOAD B 1 foo bar baz 143line 2 foo bar baz 144line 3 foo bar baz 145@a@b 146"byy 147=== end output file === 148 149=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1503: Maps and executable buffers are copied when they are executed -- 151 they can be modified by the command but that does not change their 152 actions. 153 154 Executable buffers: 155 156=== test file === 157line 1 foo bar baz 158line 2 foo bar baz 159line 3 foo bar baz 160@a@b 161"eyy 162cwEXECUTE B^[ 163=== end test file === 164 1654G"eyy5G"ayy6G"byy1G@eG"ep 166 167 The command is loaded into 'e', and then executed. 'e' executes 168 'a', which loads 'e', then 'e' executes 'b' anyway. 169 170 The output should be: 171 172=== output file === 173line 1 foo bar baz 174EXECUTE B 2 foo bar baz 175line 3 foo bar baz 176@a@b 177"eyy 178cwEXECUTE B^[ 179line 1 foo bar baz 180=== end output file === 181 182 Maps: 183 184=== test file === 185Cine 1 foo bar baz 186line 2 foo bar baz 187line 3 foo bar baz 188=== end test file === 189 190 Entering the command ':map = :map = rB^V^MrA^M1G==' shows that 191 the first time the '=' is entered the '=' map is set and the 192 character is changed to 'A', the second time the character is 193 changed to 'B'. 194 195=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1964: Historically, executable buffers are discarded if the editor 197 switches between ex and vi modes. 198 199=== test file === 200line 1 foo bar baz 201line 2 foo bar baz 202line 3 foo bar baz 203cwCHANGE^[Q:set 204set|visual|1Gwww 205=== end test file === 206 207vi testfile 2084G"ayy@a 209 210ex testfile 211$p 212yank a 213@a 214 215 In vi, the command is loaded into 'a' and then executed. The command 216 subsequent to the 'Q' is (historically, silently) discarded. 217 218 In ex, the command is loaded into 'a' and then executed. The command 219 subsequent to the 'visual' is (historically, silently) discarded. The 220 first set command is output by ex, although refreshing the screen usually 221 causes it not to be seen. 222 223=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2245: Executable buffers inside of map commands are expanded normally. 225 Maps inside of executable buffers are expanded normally. 226 227 Buffers inside of map commands: 228 229=== test file === 230line 1 foo bar baz 231line 2 foo bar baz 232line 3 foo bar baz 233cwREPLACE BY A^[ 234=== end test file === 235 2364G"ay$:map x @a 2371Gx 238 239 The output should be: 240 241=== output file === 242REPLACE BY A 1 foo bar baz 243line 2 foo bar baz 244line 3 foo bar baz 245cwREPLACE BY A^[ 246=== end output file === 247 248 Maps commands inside of executable buffers: 249 250=== test file === 251line 1 foo bar baz 252line 2 foo bar baz 253line 3 foo bar baz 254X 255=== end test file === 256 257:map X cwREPLACE BY XMAP^[ 2584G"ay$1G@a 259 260 The output should be: 261 262=== output file === 263REPLACE BY XMAP 1 foo bar baz 264line 2 foo bar baz 265line 3 foo bar baz 266X 267=== end output file === 268 269 Here's a test that does both, repeatedly. 270 271=== test file === 272line 1 foo bar baz 273line 2 foo bar baz 274line 3 foo bar baz 275X 276Y 277cwREPLACED BY C^[ 278blank line 279=== end test file === 280 281:map x @a 2824G"ay$ 283:map X @b 2845G"by$ 285:map Y @c 2866G"cy$ 2871Gx 288 289 The output should be: 290 291=== output file === 292REPLACED BY C 1 foo bar baz 293line 2 foo bar baz 294line 3 foo bar baz 295X 296Y 297cwREPLACED BY C^[ 298blank line 299=== end output file === 300 301=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3026: If an error is encountered while executing a mapped command or 303 a buffer, the rest of the mapped command/buffer is discarded. No 304 user input characters are discarded. 305 306=== test file === 307line 1 foo bar baz 308line 2 foo bar baz 309line 3 foo bar baz 310:map = 10GcwREPLACMENT^V^[^[ 311=== end test file === 312 313 The above mapping fails, however, if the 10G is changed to 1, 2, 314 or 3G, it will succeed. 315 316=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3177: Characters in executable buffers are remapped. 318 319=== test file === 320abcdefghijklmnnop 321ggg 322=== end test file === 323 324:map g x 3252G"ay$1G@a 326 327 The output should be: 328 329=== output file === 330defghijklmnnop 331ggg 332=== end output file === 333 334=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 3358: Characters in executable buffers are not quoted. 336 337=== test file === 338iFOO^[ 339 340=== end test file === 341 3421G"ay$2G@a 343 344 The output should be: 345 346=== output file === 347iFOO^[ 348FOO 349=== end output file === 350=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 351