summaryrefslogtreecommitdiffstats
path: root/contrib/nvi/docs/internals/quoting
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/nvi/docs/internals/quoting')
-rw-r--r--contrib/nvi/docs/internals/quoting208
1 files changed, 208 insertions, 0 deletions
diff --git a/contrib/nvi/docs/internals/quoting b/contrib/nvi/docs/internals/quoting
new file mode 100644
index 0000000..a5fb892
--- /dev/null
+++ b/contrib/nvi/docs/internals/quoting
@@ -0,0 +1,208 @@
+# @(#)quoting 5.5 (Berkeley) 11/12/94
+
+QUOTING IN EX/VI:
+
+There are four escape characters in historic ex/vi:
+
+ \ (backslashes)
+ ^V
+ ^Q (assuming it wasn't used for IXON/IXOFF)
+ The terminal literal next character.
+
+Vi did not use the lnext character, it always used ^V (or ^Q).
+^V and ^Q were equivalent in all cases for vi.
+
+There are four different areas in ex/vi where escaping characters
+is interesting:
+
+ 1: In vi text input mode.
+ 2: In vi command mode.
+ 3: In ex command and text input modes.
+ 4: In the ex commands themselves.
+
+1: Vi text input mode (a, i, o, :colon commands, etc.):
+
+ The set of characters that users might want to escape are as follows.
+ As ^L and ^Z were not special in input mode, they are not listed.
+
+ carriage return (^M)
+ escape (^[)
+ autoindents (^D, 0, ^, ^T)
+ erase (^H)
+ word erase (^W)
+ line erase (^U)
+ newline (^J) (not historic practice)
+
+ Historic practice was that ^V was the only way to escape any
+ of these characters, and that whatever character followed
+ the ^V was taken literally, e.g. ^V^V is a single ^V. I
+ don't see any strong reason to make it possible to escape
+ ^J, so I'm going to leave that alone.
+
+ One comment regarding the autoindent characters. In historic
+ vi, if you entered "^V0^D" autoindent erasure was still
+ triggered, although it wasn't if you entered "0^V^D". In
+ nvi, if you escape either character, autoindent erasure is
+ not triggered.
+
+ Abbreviations were not performed if the non-word character
+ that triggered the abbreviation was escaped by a ^V. Input
+ maps were not triggered if any part of the map was escaped
+ by a ^V.
+
+ The historic vi implementation for the 'r' command requires
+ two leading ^V's to replace a character with a literal
+ character. This is obviously a bug, and should be fixed.
+
+2: Vi command mode
+
+ Command maps were not triggered if the second or later
+ character of a map was escaped by a ^V.
+
+ The obvious extension is that ^V should keep the next command
+ character from being mapped, so you can do ":map x xxx" and
+ then enter ^Vx to delete a single character.
+
+3: Ex command and text input modes.
+
+ As ex ran in canonical mode, there was little work that it
+ needed to do for quoting. The notable differences between
+ ex and vi are that it was possible to escape a <newline> in
+ the ex command and text input modes, and ex used the "literal
+ next" character, not control-V/control-Q.
+
+4: The ex commands:
+
+ Ex commands are delimited by '|' or newline characters.
+ Within the commands, whitespace characters delimit the
+ arguments. Backslash will generally escape any following
+ character. In the abbreviate, unabbreviate, map and unmap
+ commands, control-V escapes the next character, instead.
+
+ This is historic behavior in vi, although there are special
+ cases where it's impossible to escape a character, generally
+ a whitespace character.
+
+ Escaping characters in file names in ex commands:
+
+ :cd [directory] (directory)
+ :chdir [directory] (directory)
+ :edit [+cmd] [file] (file)
+ :ex [+cmd] [file] (file)
+ :file [file] (file)
+ :next [file ...] (file ...)
+ :read [!cmd | file] (file)
+ :source [file] (file)
+ :write [!cmd | file] (file)
+ :wq [file] (file)
+ :xit [file] (file)
+
+ Since file names are also subject to word expansion, the
+ underlying shell had better be doing the correct backslash
+ escaping. This is NOT historic behavior in vi, making it
+ impossible to insert a whitespace, newline or carriage return
+ character into a file name.
+
+4: Escaping characters in non-file arguments in ex commands:
+
+ :abbreviate word string (word, string)
+* :edit [+cmd] [file] (+cmd)
+* :ex [+cmd] [file] (+cmd)
+ :map word string (word, string)
+* :set [option ...] (option)
+* :tag string (string)
+ :unabbreviate word (word)
+ :unmap word (word)
+
+ These commands use whitespace to delimit their arguments, and use
+ ^V to escape those characters. The exceptions are starred in the
+ above list, and are discussed below.
+
+ In general, I intend to treat a ^V in any argument, followed by
+ any character, as that literal character. This will permit
+ editing of files name "foo|", for example, by using the string
+ "foo\^V|", where the literal next character protects the pipe
+ from the ex command parser and the backslash protects it from the
+ shell expansion.
+
+ This is backward compatible with historical vi, although there
+ were a number of special cases where vi wasn't consistent.
+
+4.1: The edit/ex commands:
+
+ The edit/ex commands are a special case because | symbols may
+ occur in the "+cmd" field, for example:
+
+ :edit +10|s/abc/ABC/ file.c
+
+ In addition, the edit and ex commands have historically
+ ignored literal next characters in the +cmd string, so that
+ the following command won't work.
+
+ :edit +10|s/X/^V / file.c
+
+ I intend to handle the literal next character in edit/ex consistently
+ with how it is handled in other commands.
+
+ More fun facts to know and tell:
+ The acid test for the ex/edit commands:
+
+ date > file1; date > file2
+ vi
+ :edit +1|s/./XXX/|w file1| e file2|1 | s/./XXX/|wq
+
+ No version of vi, of which I'm aware, handles it.
+
+4.2: The set command:
+
+ The set command treats ^V's as literal characters, so the
+ following command won't work. Backslashes do work in this
+ case, though, so the second version of the command does work.
+
+ set tags=tags_file1^V tags_file2
+ set tags=tags_file1\ tags_file2
+
+ I intend to continue permitting backslashes in set commands,
+ but to also permit literal next characters to work as well.
+ This is backward compatible, but will also make set
+ consistent with the other commands. I think it's unlikely
+ to break any historic .exrc's, given that there are probably
+ very few files with ^V's in their name.
+
+4.3: The tag command:
+
+ The tag command ignores ^V's and backslashes; there's no way to
+ get a space into a tag name.
+
+ I think this is a don't care, and I don't intend to fix it.
+
+5: Regular expressions:
+
+ :global /pattern/ command
+ :substitute /pattern/replace/
+ :vglobal /pattern/ command
+
+ I intend to treat a backslash in the pattern, followed by the
+ delimiter character or a backslash, as that literal character.
+
+ This is historic behavior in vi. It would get rid of a fairly
+ hard-to-explain special case if we could just use the character
+ immediately following the backslash in all cases, or, if we
+ changed nvi to permit using the literal next character as a
+ pattern escape character, but that would probably break historic
+ scripts.
+
+ There is an additional escaping issue for regular expressions.
+ Within the pattern and replacement, the '|' character did not
+ delimit ex commands. For example, the following is legal.
+
+ :substitute /|/PIPE/|s/P/XXX/
+
+ This is a special case that I will support.
+
+6: Ending anything with an escape character:
+
+ In all of the above rules, an escape character (either ^V or a
+ backslash) at the end of an argument or file name is not handled
+ specially, but used as a literal character.
+
OpenPOWER on IntegriCloud