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