1 # @(#)input 5.5 (Berkeley) 7/2/94 2 3 MAPS, EXECUTABLE BUFFERS AND INPUT IN EX/VI: 4 5 The basic rule is that input in ex/vi is a stack. Every time a key which 6 gets expanded is encountered, it is expanded and the expansion is treated 7 as if it were input from the user. So, maps and executable buffers are 8 simply pushed onto the stack from which keys are returned. The exception 9 is that if the "remap" option is turned off, only a single map expansion 10 is done. I intend to be fully backward compatible with this. 11 12 Historically, if the mode of the editor changed (ex to vi or vice versa), 13 any queued input was silently discarded. I don't see any reason to either 14 support or not support this semantic. I intend to retain the queued input, 15 mostly because it's simpler than throwing it away. 16 17 Historically, neither the initial command on the command line (the + flag) 18 or the +cmd associated with the ex and edit commands was subject to mapping. 19 Also, while the +cmd appears to be subject to "@buffer" expansion, once 20 expanded it doesn't appear to work correctly. I don't see any reason to 21 either support or not support these semantics, so, for consistency, I intend 22 to pass both the initial command and the command associated with ex and edit 23 commands through the standard mapping and @ buffer expansion. 24 25 One other difference between the historic ex/vi and nex/nvi is that nex 26 displays the executed buffers as it executes them. This means that if 27 the file is: 28 29 set term=xterm 30 set term=yterm 31 set term=yterm 32 33 the 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 44 This seems like a feature and unlikely to break anything, so I don't 45 intend to match historic practice in this area. 46 47 The rest of this document is a set of conclusions as to how I believe 48 the historic maps and @ buffers work. The summary is as follows: 49 50 1: 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. 56 2: Executable buffers that execute other buffers don't load their 57 contents until they execute them. 58 3: 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. 61 4: Historically, executable buffers are discarded if the editor 62 switches between ex and vi modes. 63 5: Executable buffers inside of map commands are expanded normally. 64 Maps inside of executable buffers are expanded normally. 65 6: 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. 68 7: Characters in executable buffers are remapped. 69 8: Characters in executable buffers are not quoted. 70 71 Individual test cases follow. Note, in the test cases, control characters 72 are not literal and will have to be replaced to make the test cases work. 73 74 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 75 1: 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 === 83 3Gw 84 w 85 line 1 foo bar baz 86 line 2 foo bar baz 87 line 3 foo bar baz 88 === end test file === 89 90 If the first line is loaded into 'a' and executed: 91 92 1G"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 99 1G2"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 107 1G"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 115 1G2"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 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 121 2: Executable buffers that execute other buffers don't load their 122 contents until they execute them. 123 124 === test file === 125 cwLOAD B^[ 126 line 1 foo bar baz 127 line 2 foo bar baz 128 line 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 136 5G"eyy6G"ayy1G@e 137 138 The output should be: 139 140 === output file === 141 cwLOAD B^[ 142 LOAD B 1 foo bar baz 143 line 2 foo bar baz 144 line 3 foo bar baz 145 @a@b 146 "byy 147 === end output file === 148 149 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 150 3: 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 === 157 line 1 foo bar baz 158 line 2 foo bar baz 159 line 3 foo bar baz 160 @a@b 161 "eyy 162 cwEXECUTE B^[ 163 === end test file === 164 165 4G"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 === 173 line 1 foo bar baz 174 EXECUTE B 2 foo bar baz 175 line 3 foo bar baz 176 @a@b 177 "eyy 178 cwEXECUTE B^[ 179 line 1 foo bar baz 180 === end output file === 181 182 Maps: 183 184 === test file === 185 Cine 1 foo bar baz 186 line 2 foo bar baz 187 line 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 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 196 4: Historically, executable buffers are discarded if the editor 197 switches between ex and vi modes. 198 199 === test file === 200 line 1 foo bar baz 201 line 2 foo bar baz 202 line 3 foo bar baz 203 cwCHANGE^[Q:set 204 set|visual|1Gwww 205 === end test file === 206 207 vi testfile 208 4G"ayy@a 209 210 ex testfile 211 $p 212 yank 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 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 224 5: 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 === 230 line 1 foo bar baz 231 line 2 foo bar baz 232 line 3 foo bar baz 233 cwREPLACE BY A^[ 234 === end test file === 235 236 4G"ay$:map x @a 237 1Gx 238 239 The output should be: 240 241 === output file === 242 REPLACE BY A 1 foo bar baz 243 line 2 foo bar baz 244 line 3 foo bar baz 245 cwREPLACE BY A^[ 246 === end output file === 247 248 Maps commands inside of executable buffers: 249 250 === test file === 251 line 1 foo bar baz 252 line 2 foo bar baz 253 line 3 foo bar baz 254 X 255 === end test file === 256 257 :map X cwREPLACE BY XMAP^[ 258 4G"ay$1G@a 259 260 The output should be: 261 262 === output file === 263 REPLACE BY XMAP 1 foo bar baz 264 line 2 foo bar baz 265 line 3 foo bar baz 266 X 267 === end output file === 268 269 Here's a test that does both, repeatedly. 270 271 === test file === 272 line 1 foo bar baz 273 line 2 foo bar baz 274 line 3 foo bar baz 275 X 276 Y 277 cwREPLACED BY C^[ 278 blank line 279 === end test file === 280 281 :map x @a 282 4G"ay$ 283 :map X @b 284 5G"by$ 285 :map Y @c 286 6G"cy$ 287 1Gx 288 289 The output should be: 290 291 === output file === 292 REPLACED BY C 1 foo bar baz 293 line 2 foo bar baz 294 line 3 foo bar baz 295 X 296 Y 297 cwREPLACED BY C^[ 298 blank line 299 === end output file === 300 301 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 302 6: 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 === 307 line 1 foo bar baz 308 line 2 foo bar baz 309 line 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 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 317 7: Characters in executable buffers are remapped. 318 319 === test file === 320 abcdefghijklmnnop 321 ggg 322 === end test file === 323 324 :map g x 325 2G"ay$1G@a 326 327 The output should be: 328 329 === output file === 330 defghijklmnnop 331 ggg 332 === end output file === 333 334 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 335 8: Characters in executable buffers are not quoted. 336 337 === test file === 338 iFOO^[ 339 340 === end test file === 341 342 1G"ay$2G@a 343 344 The output should be: 345 346 === output file === 347 iFOO^[ 348 FOO 349 === end output file === 350 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 351