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