Home | History | Annotate | Line # | Download | only in internals
      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