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