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