119304Speter# @(#)input 5.5 (Berkeley) 7/2/94 219304Speter 319304SpeterMAPS, EXECUTABLE BUFFERS AND INPUT IN EX/VI: 419304Speter 519304SpeterThe basic rule is that input in ex/vi is a stack. Every time a key which 619304Spetergets expanded is encountered, it is expanded and the expansion is treated 719304Speteras if it were input from the user. So, maps and executable buffers are 819304Spetersimply pushed onto the stack from which keys are returned. The exception 919304Speteris that if the "remap" option is turned off, only a single map expansion 1019304Speteris done. I intend to be fully backward compatible with this. 1119304Speter 1219304SpeterHistorically, if the mode of the editor changed (ex to vi or vice versa), 1319304Speterany queued input was silently discarded. I don't see any reason to either 1419304Spetersupport or not support this semantic. I intend to retain the queued input, 1519304Spetermostly because it's simpler than throwing it away. 1619304Speter 1719304SpeterHistorically, neither the initial command on the command line (the + flag) 1819304Speteror the +cmd associated with the ex and edit commands was subject to mapping. 1919304SpeterAlso, while the +cmd appears to be subject to "@buffer" expansion, once 2019304Speterexpanded it doesn't appear to work correctly. I don't see any reason to 2119304Spetereither support or not support these semantics, so, for consistency, I intend 2219304Speterto pass both the initial command and the command associated with ex and edit 2319304Spetercommands through the standard mapping and @ buffer expansion. 2419304Speter 2519304SpeterOne other difference between the historic ex/vi and nex/nvi is that nex 2619304Speterdisplays the executed buffers as it executes them. This means that if 2719304Speterthe file is: 2819304Speter 2919304Speter set term=xterm 3019304Speter set term=yterm 3119304Speter set term=yterm 3219304Speter 3319304Speterthe user will see the following during a typical edit session: 3419304Speter 3519304Speter nex testfile 3619304Speter testfile: unmodified: line 3 3719304Speter :1,$yank a 3819304Speter :@a 3919304Speter :set term=zterm 4019304Speter :set term=yterm 4119304Speter :set term=xterm 4219304Speter :q! 4319304Speter 4419304SpeterThis seems like a feature and unlikely to break anything, so I don't 4519304Speterintend to match historic practice in this area. 4619304Speter 4719304SpeterThe rest of this document is a set of conclusions as to how I believe 4819304Speterthe historic maps and @ buffers work. The summary is as follows: 4919304Speter 5019304Speter1: For buffers that are cut in "line mode", or buffers that are not cut 5119304Speter in line mode but which contain portions of more than a single line, a 5219304Speter trailing <newline> character appears in the input for each line in the 5319304Speter buffer when it is executed. For buffers not cut in line mode and which 5419304Speter contain portions of only a single line, no additional characters 5519304Speter appear in the input. 5619304Speter2: Executable buffers that execute other buffers don't load their 5719304Speter contents until they execute them. 5819304Speter3: Maps and executable buffers are copied when they are executed -- 5919304Speter they can be modified by the command but that does not change their 6019304Speter actions. 6119304Speter4: Historically, executable buffers are discarded if the editor 6219304Speter switches between ex and vi modes. 6319304Speter5: Executable buffers inside of map commands are expanded normally. 6419304Speter Maps inside of executable buffers are expanded normally. 6519304Speter6: If an error is encountered while executing a mapped command or buffer, 6619304Speter the rest of the mapped command/buffer is discarded. No user input 6719304Speter characters are discarded. 6819304Speter7: Characters in executable buffers are remapped. 6919304Speter8: Characters in executable buffers are not quoted. 7019304Speter 7119304SpeterIndividual test cases follow. Note, in the test cases, control characters 7219304Speterare not literal and will have to be replaced to make the test cases work. 7319304Speter 7419304Speter=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 7519304Speter1: For buffers that are cut in "line mode", or buffers that are not cut 7619304Speter in line mode but which contain portions of more than a single line, a 7719304Speter trailing <newline> character appears in the input for each line in the 7819304Speter buffer when it is executed. For buffers not cut in line mode and which 7919304Speter contain portions of only a single line, no additional characters 8019304Speter appear in the input. 8119304Speter 8219304Speter=== test file === 8319304Speter3Gw 8419304Speterw 8519304Speterline 1 foo bar baz 8619304Speterline 2 foo bar baz 8719304Speterline 3 foo bar baz 8819304Speter=== end test file === 8919304Speter 9019304Speter If the first line is loaded into 'a' and executed: 9119304Speter 9219304Speter1G"ayy@a 9319304Speter 9419304Speter The cursor ends up on the '2', a result of pushing "3Gw^J" onto 9519304Speter the stack. 9619304Speter 9719304Speter If the first two lines are loaded into 'a' and executed: 9819304Speter 9919304Speter1G2"ayy@a 10019304Speter 10119304Speter The cursor ends up on the 'f' in "foo" in the fifth line of the 10219304Speter file, a result of pushing "3Gw^Jw^J" onto the stack. 10319304Speter 10419304Speter If the first line is loaded into 'a', but not using line mode, 10519304Speter and executed: 10619304Speter 10719304Speter1G"ay$@a 10819304Speter 10919304Speter The cursor ends up on the '1', a result of pushing "3Gw" onto 11019304Speter the stack 11119304Speter 11219304Speter If the first two lines are loaded into 'a', but not using line mode, 11319304Speter and executed: 11419304Speter 11519304Speter1G2"ay$@a 11619304Speter 11719304Speter The cursor ends up on the 'f' in "foo" in the fifth line of the 11819304Speter file, a result of pushing "3Gw^Jw^J" onto the stack. 11919304Speter 12019304Speter=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 12119304Speter2: Executable buffers that execute other buffers don't load their 12219304Speter contents until they execute them. 12319304Speter 12419304Speter=== test file === 12519304SpetercwLOAD B^[ 12619304Speterline 1 foo bar baz 12719304Speterline 2 foo bar baz 12819304Speterline 3 foo bar baz 12919304Speter@a@b 13019304Speter"byy 13119304Speter=== end test file === 13219304Speter 13319304Speter The command is loaded into 'e', and then executed. 'e' executes 13419304Speter 'a', which loads 'b', then 'e' executes 'b'. 13519304Speter 13619304Speter5G"eyy6G"ayy1G@e 13719304Speter 13819304Speter The output should be: 13919304Speter 14019304Speter=== output file === 14119304SpetercwLOAD B^[ 14219304SpeterLOAD B 1 foo bar baz 14319304Speterline 2 foo bar baz 14419304Speterline 3 foo bar baz 14519304Speter@a@b 14619304Speter"byy 14719304Speter=== end output file === 14819304Speter 14919304Speter=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 15019304Speter3: Maps and executable buffers are copied when they are executed -- 15119304Speter they can be modified by the command but that does not change their 15219304Speter actions. 15319304Speter 15419304Speter Executable buffers: 15519304Speter 15619304Speter=== test file === 15719304Speterline 1 foo bar baz 15819304Speterline 2 foo bar baz 15919304Speterline 3 foo bar baz 16019304Speter@a@b 16119304Speter"eyy 16219304SpetercwEXECUTE B^[ 16319304Speter=== end test file === 16419304Speter 16519304Speter4G"eyy5G"ayy6G"byy1G@eG"ep 16619304Speter 16719304Speter The command is loaded into 'e', and then executed. 'e' executes 16819304Speter 'a', which loads 'e', then 'e' executes 'b' anyway. 16919304Speter 17019304Speter The output should be: 17119304Speter 17219304Speter=== output file === 17319304Speterline 1 foo bar baz 17419304SpeterEXECUTE B 2 foo bar baz 17519304Speterline 3 foo bar baz 17619304Speter@a@b 17719304Speter"eyy 17819304SpetercwEXECUTE B^[ 17919304Speterline 1 foo bar baz 18019304Speter=== end output file === 18119304Speter 18219304Speter Maps: 18319304Speter 18419304Speter=== test file === 18519304SpeterCine 1 foo bar baz 18619304Speterline 2 foo bar baz 18719304Speterline 3 foo bar baz 18819304Speter=== end test file === 18919304Speter 19019304Speter Entering the command ':map = :map = rB^V^MrA^M1G==' shows that 19119304Speter the first time the '=' is entered the '=' map is set and the 19219304Speter character is changed to 'A', the second time the character is 19319304Speter changed to 'B'. 19419304Speter 19519304Speter=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 19619304Speter4: Historically, executable buffers are discarded if the editor 19719304Speter switches between ex and vi modes. 19819304Speter 19919304Speter=== test file === 20019304Speterline 1 foo bar baz 20119304Speterline 2 foo bar baz 20219304Speterline 3 foo bar baz 20319304SpetercwCHANGE^[Q:set 20419304Speterset|visual|1Gwww 20519304Speter=== end test file === 20619304Speter 20719304Spetervi testfile 20819304Speter4G"ayy@a 20919304Speter 21019304Speterex testfile 21119304Speter$p 21219304Speteryank a 21319304Speter@a 21419304Speter 21519304Speter In vi, the command is loaded into 'a' and then executed. The command 21619304Speter subsequent to the 'Q' is (historically, silently) discarded. 21719304Speter 21819304Speter In ex, the command is loaded into 'a' and then executed. The command 21919304Speter subsequent to the 'visual' is (historically, silently) discarded. The 22019304Speter first set command is output by ex, although refreshing the screen usually 22119304Speter causes it not to be seen. 22219304Speter 22319304Speter=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 22419304Speter5: Executable buffers inside of map commands are expanded normally. 22519304Speter Maps inside of executable buffers are expanded normally. 22619304Speter 22719304Speter Buffers inside of map commands: 22819304Speter 22919304Speter=== test file === 23019304Speterline 1 foo bar baz 23119304Speterline 2 foo bar baz 23219304Speterline 3 foo bar baz 23319304SpetercwREPLACE BY A^[ 23419304Speter=== end test file === 23519304Speter 23619304Speter4G"ay$:map x @a 23719304Speter1Gx 23819304Speter 23919304Speter The output should be: 24019304Speter 24119304Speter=== output file === 24219304SpeterREPLACE BY A 1 foo bar baz 24319304Speterline 2 foo bar baz 24419304Speterline 3 foo bar baz 24519304SpetercwREPLACE BY A^[ 24619304Speter=== end output file === 24719304Speter 24819304Speter Maps commands inside of executable buffers: 24919304Speter 25019304Speter=== test file === 25119304Speterline 1 foo bar baz 25219304Speterline 2 foo bar baz 25319304Speterline 3 foo bar baz 25419304SpeterX 25519304Speter=== end test file === 25619304Speter 25719304Speter:map X cwREPLACE BY XMAP^[ 25819304Speter4G"ay$1G@a 25919304Speter 26019304Speter The output should be: 26119304Speter 26219304Speter=== output file === 26319304SpeterREPLACE BY XMAP 1 foo bar baz 26419304Speterline 2 foo bar baz 26519304Speterline 3 foo bar baz 26619304SpeterX 26719304Speter=== end output file === 26819304Speter 26919304Speter Here's a test that does both, repeatedly. 27019304Speter 27119304Speter=== test file === 27219304Speterline 1 foo bar baz 27319304Speterline 2 foo bar baz 27419304Speterline 3 foo bar baz 27519304SpeterX 27619304SpeterY 27719304SpetercwREPLACED BY C^[ 27819304Speterblank line 27919304Speter=== end test file === 28019304Speter 28119304Speter:map x @a 28219304Speter4G"ay$ 28319304Speter:map X @b 28419304Speter5G"by$ 28519304Speter:map Y @c 28619304Speter6G"cy$ 28719304Speter1Gx 28819304Speter 28919304Speter The output should be: 29019304Speter 29119304Speter=== output file === 29219304SpeterREPLACED BY C 1 foo bar baz 29319304Speterline 2 foo bar baz 29419304Speterline 3 foo bar baz 29519304SpeterX 29619304SpeterY 29719304SpetercwREPLACED BY C^[ 29819304Speterblank line 29919304Speter=== end output file === 30019304Speter 30119304Speter=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 30219304Speter6: If an error is encountered while executing a mapped command or 30319304Speter a buffer, the rest of the mapped command/buffer is discarded. No 30419304Speter user input characters are discarded. 30519304Speter 30619304Speter=== test file === 30719304Speterline 1 foo bar baz 30819304Speterline 2 foo bar baz 30919304Speterline 3 foo bar baz 31019304Speter:map = 10GcwREPLACMENT^V^[^[ 31119304Speter=== end test file === 31219304Speter 31319304Speter The above mapping fails, however, if the 10G is changed to 1, 2, 31419304Speter or 3G, it will succeed. 31519304Speter 31619304Speter=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 31719304Speter7: Characters in executable buffers are remapped. 31819304Speter 31919304Speter=== test file === 32019304Speterabcdefghijklmnnop 32119304Speterggg 32219304Speter=== end test file === 32319304Speter 32419304Speter:map g x 32519304Speter2G"ay$1G@a 32619304Speter 32719304Speter The output should be: 32819304Speter 32919304Speter=== output file === 33019304Speterdefghijklmnnop 33119304Speterggg 33219304Speter=== end output file === 33319304Speter 33419304Speter=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 33519304Speter8: Characters in executable buffers are not quoted. 33619304Speter 33719304Speter=== test file === 33819304SpeteriFOO^[ 33919304Speter 34019304Speter=== end test file === 34119304Speter 34219304Speter1G"ay$2G@a 34319304Speter 34419304Speter The output should be: 34519304Speter 34619304Speter=== output file === 34719304SpeteriFOO^[ 34819304SpeterFOO 34919304Speter=== end output file === 35019304Speter=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 351