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