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