Home | History | Annotate | Line # | Download | only in internals
      1  1.1  christos #	@(#)quoting	5.5 (Berkeley) 11/12/94
      2  1.1  christos 
      3  1.1  christos QUOTING IN EX/VI:
      4  1.1  christos 
      5  1.1  christos There are four escape characters in historic ex/vi:
      6  1.1  christos 
      7  1.1  christos 	\ (backslashes)
      8  1.1  christos 	^V
      9  1.1  christos 	^Q (assuming it wasn't used for IXON/IXOFF)
     10  1.1  christos 	The terminal literal next character.
     11  1.1  christos 
     12  1.1  christos Vi did not use the lnext character, it always used ^V (or ^Q).
     13  1.1  christos ^V and ^Q were equivalent in all cases for vi.
     14  1.1  christos 
     15  1.1  christos There are four different areas in ex/vi where escaping characters
     16  1.1  christos is interesting:
     17  1.1  christos 
     18  1.1  christos 	1: In vi text input mode.
     19  1.1  christos 	2: In vi command mode.
     20  1.1  christos 	3: In ex command and text input modes.
     21  1.1  christos 	4: In the ex commands themselves.
     22  1.1  christos 
     23  1.1  christos 1: Vi text input mode (a, i, o, :colon commands, etc.):
     24  1.1  christos 
     25  1.1  christos    The set of characters that users might want to escape are as follows.
     26  1.1  christos    As ^L and ^Z were not special in input mode, they are not listed.
     27  1.1  christos 
     28  1.1  christos 	carriage return (^M)
     29  1.1  christos 	escape		(^[)
     30  1.1  christos 	autoindents	(^D, 0, ^, ^T)
     31  1.1  christos 	erase		(^H)
     32  1.1  christos 	word erase	(^W)
     33  1.1  christos 	line erase	(^U)
     34  1.1  christos 	newline		(^J)		(not historic practice)
     35  1.1  christos 
     36  1.1  christos    Historic practice was that ^V was the only way to escape any
     37  1.1  christos    of these characters, and that whatever character followed
     38  1.1  christos    the ^V was taken literally, e.g. ^V^V is a single ^V.  I
     39  1.1  christos    don't see any strong reason to make it possible to escape
     40  1.1  christos    ^J, so I'm going to leave that alone.
     41  1.1  christos 
     42  1.1  christos    One comment regarding the autoindent characters.  In historic
     43  1.1  christos    vi, if you entered "^V0^D" autoindent erasure was still
     44  1.1  christos    triggered, although it wasn't if you entered "0^V^D".  In
     45  1.1  christos    nvi, if you escape either character, autoindent erasure is
     46  1.1  christos    not triggered.
     47  1.1  christos 
     48  1.1  christos    Abbreviations were not performed if the non-word character
     49  1.1  christos    that triggered the abbreviation was escaped by a ^V.  Input
     50  1.1  christos    maps were not triggered if any part of the map was escaped
     51  1.1  christos    by a ^V.
     52  1.1  christos 
     53  1.1  christos    The historic vi implementation for the 'r' command requires
     54  1.1  christos    two leading ^V's to replace a character with a literal
     55  1.1  christos    character.  This is obviously a bug, and should be fixed.
     56  1.1  christos 
     57  1.1  christos 2: Vi command mode
     58  1.1  christos 
     59  1.1  christos    Command maps were not triggered if the second or later
     60  1.1  christos    character of a map was escaped by a ^V.
     61  1.1  christos 
     62  1.1  christos    The obvious extension is that ^V should keep the next command
     63  1.1  christos    character from being mapped, so you can do ":map x xxx" and
     64  1.1  christos    then enter ^Vx to delete a single character.
     65  1.1  christos 
     66  1.1  christos 3: Ex command and text input modes.
     67  1.1  christos 
     68  1.1  christos    As ex ran in canonical mode, there was little work that it
     69  1.1  christos    needed to do for quoting.  The notable differences between
     70  1.1  christos    ex and vi are that it was possible to escape a <newline> in
     71  1.1  christos    the ex command and text input modes, and ex used the "literal
     72  1.1  christos    next" character, not control-V/control-Q.
     73  1.1  christos 
     74  1.1  christos 4: The ex commands:
     75  1.1  christos 
     76  1.1  christos    Ex commands are delimited by '|' or newline characters.
     77  1.1  christos    Within the commands, whitespace characters delimit the
     78  1.1  christos    arguments.  Backslash will generally escape any following
     79  1.1  christos    character.  In the abbreviate, unabbreviate, map and unmap
     80  1.1  christos    commands, control-V escapes the next character, instead.
     81  1.1  christos 
     82  1.1  christos    This is historic behavior in vi, although there are special
     83  1.1  christos    cases where it's impossible to escape a character, generally
     84  1.1  christos    a whitespace character.
     85  1.1  christos 
     86  1.1  christos    Escaping characters in file names in ex commands:
     87  1.1  christos 
     88  1.1  christos 	:cd [directory]				(directory)
     89  1.1  christos 	:chdir [directory]			(directory)
     90  1.1  christos 	:edit [+cmd] [file]			(file)
     91  1.1  christos 	:ex [+cmd] [file]			(file)
     92  1.1  christos 	:file [file]				(file)
     93  1.1  christos 	:next [file ...]			(file ...)
     94  1.1  christos 	:read [!cmd | file]			(file)
     95  1.1  christos 	:source [file]				(file)
     96  1.1  christos 	:write [!cmd | file]			(file)
     97  1.1  christos 	:wq [file]				(file)
     98  1.1  christos 	:xit [file]				(file)
     99  1.1  christos 
    100  1.1  christos    Since file names are also subject to word expansion, the
    101  1.1  christos    underlying shell had better be doing the correct backslash
    102  1.1  christos    escaping.  This is NOT historic behavior in vi, making it
    103  1.1  christos    impossible to insert a whitespace, newline or carriage return
    104  1.1  christos    character into a file name.
    105  1.1  christos 
    106  1.1  christos 4: Escaping characters in non-file arguments in ex commands:
    107  1.1  christos 
    108  1.1  christos 	:abbreviate word string			(word, string)
    109  1.1  christos *	:edit [+cmd] [file]			(+cmd)
    110  1.1  christos *	:ex [+cmd] [file]			(+cmd)
    111  1.1  christos 	:map word string			(word, string)
    112  1.1  christos *	:set [option ...]			(option)
    113  1.1  christos *	:tag string				(string)
    114  1.1  christos 	:unabbreviate word			(word)
    115  1.1  christos 	:unmap word				(word)
    116  1.1  christos 
    117  1.1  christos    These commands use whitespace to delimit their arguments, and use
    118  1.1  christos    ^V to escape those characters.  The exceptions are starred in the
    119  1.1  christos    above list, and are discussed below.
    120  1.1  christos 
    121  1.1  christos    In general, I intend to treat a ^V in any argument, followed by
    122  1.1  christos    any character, as that literal character.  This will permit
    123  1.1  christos    editing of files name "foo|", for example, by using the string
    124  1.1  christos    "foo\^V|", where the literal next character protects the pipe
    125  1.1  christos    from the ex command parser and the backslash protects it from the
    126  1.1  christos    shell expansion.
    127  1.1  christos 
    128  1.1  christos    This is backward compatible with historical vi, although there
    129  1.1  christos    were a number of special cases where vi wasn't consistent.
    130  1.1  christos 
    131  1.1  christos 4.1: The edit/ex commands:
    132  1.1  christos 
    133  1.1  christos    The edit/ex commands are a special case because | symbols may
    134  1.1  christos    occur in the "+cmd" field, for example:
    135  1.1  christos 
    136  1.1  christos 	:edit +10|s/abc/ABC/ file.c
    137  1.1  christos 
    138  1.1  christos    In addition, the edit and ex commands have historically
    139  1.1  christos    ignored literal next characters in the +cmd string, so that
    140  1.1  christos    the following command won't work.
    141  1.1  christos 
    142  1.1  christos 	:edit +10|s/X/^V / file.c
    143  1.1  christos 
    144  1.1  christos    I intend to handle the literal next character in edit/ex consistently
    145  1.1  christos    with how it is handled in other commands.
    146  1.1  christos 
    147  1.1  christos    More fun facts to know and tell:
    148  1.1  christos 	The acid test for the ex/edit commands:
    149  1.1  christos 
    150  1.1  christos 		date > file1; date > file2
    151  1.1  christos 		vi
    152  1.1  christos 		:edit +1|s/./XXX/|w file1| e file2|1 | s/./XXX/|wq
    153  1.1  christos 
    154  1.1  christos 	No version of vi, of which I'm aware, handles it.
    155  1.1  christos 
    156  1.1  christos 4.2: The set command:
    157  1.1  christos 
    158  1.1  christos    The set command treats ^V's as literal characters, so the
    159  1.1  christos    following command won't work.  Backslashes do work in this
    160  1.1  christos    case, though, so the second version of the command does work.
    161  1.1  christos 
    162  1.1  christos 	set tags=tags_file1^V tags_file2
    163  1.1  christos 	set tags=tags_file1\ tags_file2
    164  1.1  christos 
    165  1.1  christos    I intend to continue permitting backslashes in set commands,
    166  1.1  christos    but to also permit literal next characters to work as well.
    167  1.1  christos    This is backward compatible, but will also make set
    168  1.1  christos    consistent with the other commands.  I think it's unlikely
    169  1.1  christos    to break any historic .exrc's, given that there are probably
    170  1.1  christos    very few files with ^V's in their name.
    171  1.1  christos 
    172  1.1  christos 4.3: The tag command:
    173  1.1  christos 
    174  1.1  christos    The tag command ignores ^V's and backslashes; there's no way to
    175  1.1  christos    get a space into a tag name.
    176  1.1  christos 
    177  1.1  christos    I think this is a don't care, and I don't intend to fix it.
    178  1.1  christos 
    179  1.1  christos 5: Regular expressions:
    180  1.1  christos 
    181  1.1  christos 	:global /pattern/ command
    182  1.1  christos 	:substitute /pattern/replace/
    183  1.1  christos 	:vglobal /pattern/ command
    184  1.1  christos 
    185  1.1  christos    I intend to treat a backslash in the pattern, followed by the
    186  1.1  christos    delimiter character or a backslash, as that literal character.
    187  1.1  christos 
    188  1.1  christos    This is historic behavior in vi.  It would get rid of a fairly
    189  1.1  christos    hard-to-explain special case if we could just use the character
    190  1.1  christos    immediately following the backslash in all cases, or, if we
    191  1.1  christos    changed nvi to permit using the literal next character as a
    192  1.1  christos    pattern escape character, but that would probably break historic
    193  1.1  christos    scripts.
    194  1.1  christos 
    195  1.1  christos    There is an additional escaping issue for regular expressions.
    196  1.1  christos    Within the pattern and replacement, the '|' character did not
    197  1.1  christos    delimit ex commands.  For example, the following is legal.
    198  1.1  christos 
    199  1.1  christos 	:substitute /|/PIPE/|s/P/XXX/
    200  1.1  christos 
    201  1.1  christos    This is a special case that I will support.
    202  1.1  christos 
    203  1.1  christos 6: Ending anything with an escape character:
    204  1.1  christos 
    205  1.1  christos    In all of the above rules, an escape character (either ^V or a
    206  1.1  christos    backslash) at the end of an argument or file name is not handled
    207  1.1  christos    specially, but used as a literal character.
    208  1.1  christos 
    209