input revision 1.1.4.2 1 1.1.4.2 yamt # @(#)input 5.5 (Berkeley) 7/2/94
2 1.1.4.2 yamt
3 1.1.4.2 yamt MAPS, EXECUTABLE BUFFERS AND INPUT IN EX/VI:
4 1.1.4.2 yamt
5 1.1.4.2 yamt The basic rule is that input in ex/vi is a stack. Every time a key which
6 1.1.4.2 yamt gets expanded is encountered, it is expanded and the expansion is treated
7 1.1.4.2 yamt as if it were input from the user. So, maps and executable buffers are
8 1.1.4.2 yamt simply pushed onto the stack from which keys are returned. The exception
9 1.1.4.2 yamt is that if the "remap" option is turned off, only a single map expansion
10 1.1.4.2 yamt is done. I intend to be fully backward compatible with this.
11 1.1.4.2 yamt
12 1.1.4.2 yamt Historically, if the mode of the editor changed (ex to vi or vice versa),
13 1.1.4.2 yamt any queued input was silently discarded. I don't see any reason to either
14 1.1.4.2 yamt support or not support this semantic. I intend to retain the queued input,
15 1.1.4.2 yamt mostly because it's simpler than throwing it away.
16 1.1.4.2 yamt
17 1.1.4.2 yamt Historically, neither the initial command on the command line (the + flag)
18 1.1.4.2 yamt or the +cmd associated with the ex and edit commands was subject to mapping.
19 1.1.4.2 yamt Also, while the +cmd appears to be subject to "@buffer" expansion, once
20 1.1.4.2 yamt expanded it doesn't appear to work correctly. I don't see any reason to
21 1.1.4.2 yamt either support or not support these semantics, so, for consistency, I intend
22 1.1.4.2 yamt to pass both the initial command and the command associated with ex and edit
23 1.1.4.2 yamt commands through the standard mapping and @ buffer expansion.
24 1.1.4.2 yamt
25 1.1.4.2 yamt One other difference between the historic ex/vi and nex/nvi is that nex
26 1.1.4.2 yamt displays the executed buffers as it executes them. This means that if
27 1.1.4.2 yamt the file is:
28 1.1.4.2 yamt
29 1.1.4.2 yamt set term=xterm
30 1.1.4.2 yamt set term=yterm
31 1.1.4.2 yamt set term=yterm
32 1.1.4.2 yamt
33 1.1.4.2 yamt the user will see the following during a typical edit session:
34 1.1.4.2 yamt
35 1.1.4.2 yamt nex testfile
36 1.1.4.2 yamt testfile: unmodified: line 3
37 1.1.4.2 yamt :1,$yank a
38 1.1.4.2 yamt :@a
39 1.1.4.2 yamt :set term=zterm
40 1.1.4.2 yamt :set term=yterm
41 1.1.4.2 yamt :set term=xterm
42 1.1.4.2 yamt :q!
43 1.1.4.2 yamt
44 1.1.4.2 yamt This seems like a feature and unlikely to break anything, so I don't
45 1.1.4.2 yamt intend to match historic practice in this area.
46 1.1.4.2 yamt
47 1.1.4.2 yamt The rest of this document is a set of conclusions as to how I believe
48 1.1.4.2 yamt the historic maps and @ buffers work. The summary is as follows:
49 1.1.4.2 yamt
50 1.1.4.2 yamt 1: For buffers that are cut in "line mode", or buffers that are not cut
51 1.1.4.2 yamt in line mode but which contain portions of more than a single line, a
52 1.1.4.2 yamt trailing <newline> character appears in the input for each line in the
53 1.1.4.2 yamt buffer when it is executed. For buffers not cut in line mode and which
54 1.1.4.2 yamt contain portions of only a single line, no additional characters
55 1.1.4.2 yamt appear in the input.
56 1.1.4.2 yamt 2: Executable buffers that execute other buffers don't load their
57 1.1.4.2 yamt contents until they execute them.
58 1.1.4.2 yamt 3: Maps and executable buffers are copied when they are executed --
59 1.1.4.2 yamt they can be modified by the command but that does not change their
60 1.1.4.2 yamt actions.
61 1.1.4.2 yamt 4: Historically, executable buffers are discarded if the editor
62 1.1.4.2 yamt switches between ex and vi modes.
63 1.1.4.2 yamt 5: Executable buffers inside of map commands are expanded normally.
64 1.1.4.2 yamt Maps inside of executable buffers are expanded normally.
65 1.1.4.2 yamt 6: If an error is encountered while executing a mapped command or buffer,
66 1.1.4.2 yamt the rest of the mapped command/buffer is discarded. No user input
67 1.1.4.2 yamt characters are discarded.
68 1.1.4.2 yamt 7: Characters in executable buffers are remapped.
69 1.1.4.2 yamt 8: Characters in executable buffers are not quoted.
70 1.1.4.2 yamt
71 1.1.4.2 yamt Individual test cases follow. Note, in the test cases, control characters
72 1.1.4.2 yamt are not literal and will have to be replaced to make the test cases work.
73 1.1.4.2 yamt
74 1.1.4.2 yamt =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
75 1.1.4.2 yamt 1: For buffers that are cut in "line mode", or buffers that are not cut
76 1.1.4.2 yamt in line mode but which contain portions of more than a single line, a
77 1.1.4.2 yamt trailing <newline> character appears in the input for each line in the
78 1.1.4.2 yamt buffer when it is executed. For buffers not cut in line mode and which
79 1.1.4.2 yamt contain portions of only a single line, no additional characters
80 1.1.4.2 yamt appear in the input.
81 1.1.4.2 yamt
82 1.1.4.2 yamt === test file ===
83 1.1.4.2 yamt 3Gw
84 1.1.4.2 yamt w
85 1.1.4.2 yamt line 1 foo bar baz
86 1.1.4.2 yamt line 2 foo bar baz
87 1.1.4.2 yamt line 3 foo bar baz
88 1.1.4.2 yamt === end test file ===
89 1.1.4.2 yamt
90 1.1.4.2 yamt If the first line is loaded into 'a' and executed:
91 1.1.4.2 yamt
92 1.1.4.2 yamt 1G"ayy@a
93 1.1.4.2 yamt
94 1.1.4.2 yamt The cursor ends up on the '2', a result of pushing "3Gw^J" onto
95 1.1.4.2 yamt the stack.
96 1.1.4.2 yamt
97 1.1.4.2 yamt If the first two lines are loaded into 'a' and executed:
98 1.1.4.2 yamt
99 1.1.4.2 yamt 1G2"ayy@a
100 1.1.4.2 yamt
101 1.1.4.2 yamt The cursor ends up on the 'f' in "foo" in the fifth line of the
102 1.1.4.2 yamt file, a result of pushing "3Gw^Jw^J" onto the stack.
103 1.1.4.2 yamt
104 1.1.4.2 yamt If the first line is loaded into 'a', but not using line mode,
105 1.1.4.2 yamt and executed:
106 1.1.4.2 yamt
107 1.1.4.2 yamt 1G"ay$@a
108 1.1.4.2 yamt
109 1.1.4.2 yamt The cursor ends up on the '1', a result of pushing "3Gw" onto
110 1.1.4.2 yamt the stack
111 1.1.4.2 yamt
112 1.1.4.2 yamt If the first two lines are loaded into 'a', but not using line mode,
113 1.1.4.2 yamt and executed:
114 1.1.4.2 yamt
115 1.1.4.2 yamt 1G2"ay$@a
116 1.1.4.2 yamt
117 1.1.4.2 yamt The cursor ends up on the 'f' in "foo" in the fifth line of the
118 1.1.4.2 yamt file, a result of pushing "3Gw^Jw^J" onto the stack.
119 1.1.4.2 yamt
120 1.1.4.2 yamt =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
121 1.1.4.2 yamt 2: Executable buffers that execute other buffers don't load their
122 1.1.4.2 yamt contents until they execute them.
123 1.1.4.2 yamt
124 1.1.4.2 yamt === test file ===
125 1.1.4.2 yamt cwLOAD B^[
126 1.1.4.2 yamt line 1 foo bar baz
127 1.1.4.2 yamt line 2 foo bar baz
128 1.1.4.2 yamt line 3 foo bar baz
129 1.1.4.2 yamt @a@b
130 1.1.4.2 yamt "byy
131 1.1.4.2 yamt === end test file ===
132 1.1.4.2 yamt
133 1.1.4.2 yamt The command is loaded into 'e', and then executed. 'e' executes
134 1.1.4.2 yamt 'a', which loads 'b', then 'e' executes 'b'.
135 1.1.4.2 yamt
136 1.1.4.2 yamt 5G"eyy6G"ayy1G@e
137 1.1.4.2 yamt
138 1.1.4.2 yamt The output should be:
139 1.1.4.2 yamt
140 1.1.4.2 yamt === output file ===
141 1.1.4.2 yamt cwLOAD B^[
142 1.1.4.2 yamt LOAD B 1 foo bar baz
143 1.1.4.2 yamt line 2 foo bar baz
144 1.1.4.2 yamt line 3 foo bar baz
145 1.1.4.2 yamt @a@b
146 1.1.4.2 yamt "byy
147 1.1.4.2 yamt === end output file ===
148 1.1.4.2 yamt
149 1.1.4.2 yamt =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
150 1.1.4.2 yamt 3: Maps and executable buffers are copied when they are executed --
151 1.1.4.2 yamt they can be modified by the command but that does not change their
152 1.1.4.2 yamt actions.
153 1.1.4.2 yamt
154 1.1.4.2 yamt Executable buffers:
155 1.1.4.2 yamt
156 1.1.4.2 yamt === test file ===
157 1.1.4.2 yamt line 1 foo bar baz
158 1.1.4.2 yamt line 2 foo bar baz
159 1.1.4.2 yamt line 3 foo bar baz
160 1.1.4.2 yamt @a@b
161 1.1.4.2 yamt "eyy
162 1.1.4.2 yamt cwEXECUTE B^[
163 1.1.4.2 yamt === end test file ===
164 1.1.4.2 yamt
165 1.1.4.2 yamt 4G"eyy5G"ayy6G"byy1G@eG"ep
166 1.1.4.2 yamt
167 1.1.4.2 yamt The command is loaded into 'e', and then executed. 'e' executes
168 1.1.4.2 yamt 'a', which loads 'e', then 'e' executes 'b' anyway.
169 1.1.4.2 yamt
170 1.1.4.2 yamt The output should be:
171 1.1.4.2 yamt
172 1.1.4.2 yamt === output file ===
173 1.1.4.2 yamt line 1 foo bar baz
174 1.1.4.2 yamt EXECUTE B 2 foo bar baz
175 1.1.4.2 yamt line 3 foo bar baz
176 1.1.4.2 yamt @a@b
177 1.1.4.2 yamt "eyy
178 1.1.4.2 yamt cwEXECUTE B^[
179 1.1.4.2 yamt line 1 foo bar baz
180 1.1.4.2 yamt === end output file ===
181 1.1.4.2 yamt
182 1.1.4.2 yamt Maps:
183 1.1.4.2 yamt
184 1.1.4.2 yamt === test file ===
185 1.1.4.2 yamt Cine 1 foo bar baz
186 1.1.4.2 yamt line 2 foo bar baz
187 1.1.4.2 yamt line 3 foo bar baz
188 1.1.4.2 yamt === end test file ===
189 1.1.4.2 yamt
190 1.1.4.2 yamt Entering the command ':map = :map = rB^V^MrA^M1G==' shows that
191 1.1.4.2 yamt the first time the '=' is entered the '=' map is set and the
192 1.1.4.2 yamt character is changed to 'A', the second time the character is
193 1.1.4.2 yamt changed to 'B'.
194 1.1.4.2 yamt
195 1.1.4.2 yamt =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
196 1.1.4.2 yamt 4: Historically, executable buffers are discarded if the editor
197 1.1.4.2 yamt switches between ex and vi modes.
198 1.1.4.2 yamt
199 1.1.4.2 yamt === test file ===
200 1.1.4.2 yamt line 1 foo bar baz
201 1.1.4.2 yamt line 2 foo bar baz
202 1.1.4.2 yamt line 3 foo bar baz
203 1.1.4.2 yamt cwCHANGE^[Q:set
204 1.1.4.2 yamt set|visual|1Gwww
205 1.1.4.2 yamt === end test file ===
206 1.1.4.2 yamt
207 1.1.4.2 yamt vi testfile
208 1.1.4.2 yamt 4G"ayy@a
209 1.1.4.2 yamt
210 1.1.4.2 yamt ex testfile
211 1.1.4.2 yamt $p
212 1.1.4.2 yamt yank a
213 1.1.4.2 yamt @a
214 1.1.4.2 yamt
215 1.1.4.2 yamt In vi, the command is loaded into 'a' and then executed. The command
216 1.1.4.2 yamt subsequent to the 'Q' is (historically, silently) discarded.
217 1.1.4.2 yamt
218 1.1.4.2 yamt In ex, the command is loaded into 'a' and then executed. The command
219 1.1.4.2 yamt subsequent to the 'visual' is (historically, silently) discarded. The
220 1.1.4.2 yamt first set command is output by ex, although refreshing the screen usually
221 1.1.4.2 yamt causes it not to be seen.
222 1.1.4.2 yamt
223 1.1.4.2 yamt =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
224 1.1.4.2 yamt 5: Executable buffers inside of map commands are expanded normally.
225 1.1.4.2 yamt Maps inside of executable buffers are expanded normally.
226 1.1.4.2 yamt
227 1.1.4.2 yamt Buffers inside of map commands:
228 1.1.4.2 yamt
229 1.1.4.2 yamt === test file ===
230 1.1.4.2 yamt line 1 foo bar baz
231 1.1.4.2 yamt line 2 foo bar baz
232 1.1.4.2 yamt line 3 foo bar baz
233 1.1.4.2 yamt cwREPLACE BY A^[
234 1.1.4.2 yamt === end test file ===
235 1.1.4.2 yamt
236 1.1.4.2 yamt 4G"ay$:map x @a
237 1.1.4.2 yamt 1Gx
238 1.1.4.2 yamt
239 1.1.4.2 yamt The output should be:
240 1.1.4.2 yamt
241 1.1.4.2 yamt === output file ===
242 1.1.4.2 yamt REPLACE BY A 1 foo bar baz
243 1.1.4.2 yamt line 2 foo bar baz
244 1.1.4.2 yamt line 3 foo bar baz
245 1.1.4.2 yamt cwREPLACE BY A^[
246 1.1.4.2 yamt === end output file ===
247 1.1.4.2 yamt
248 1.1.4.2 yamt Maps commands inside of executable buffers:
249 1.1.4.2 yamt
250 1.1.4.2 yamt === test file ===
251 1.1.4.2 yamt line 1 foo bar baz
252 1.1.4.2 yamt line 2 foo bar baz
253 1.1.4.2 yamt line 3 foo bar baz
254 1.1.4.2 yamt X
255 1.1.4.2 yamt === end test file ===
256 1.1.4.2 yamt
257 1.1.4.2 yamt :map X cwREPLACE BY XMAP^[
258 1.1.4.2 yamt 4G"ay$1G@a
259 1.1.4.2 yamt
260 1.1.4.2 yamt The output should be:
261 1.1.4.2 yamt
262 1.1.4.2 yamt === output file ===
263 1.1.4.2 yamt REPLACE BY XMAP 1 foo bar baz
264 1.1.4.2 yamt line 2 foo bar baz
265 1.1.4.2 yamt line 3 foo bar baz
266 1.1.4.2 yamt X
267 1.1.4.2 yamt === end output file ===
268 1.1.4.2 yamt
269 1.1.4.2 yamt Here's a test that does both, repeatedly.
270 1.1.4.2 yamt
271 1.1.4.2 yamt === test file ===
272 1.1.4.2 yamt line 1 foo bar baz
273 1.1.4.2 yamt line 2 foo bar baz
274 1.1.4.2 yamt line 3 foo bar baz
275 1.1.4.2 yamt X
276 1.1.4.2 yamt Y
277 1.1.4.2 yamt cwREPLACED BY C^[
278 1.1.4.2 yamt blank line
279 1.1.4.2 yamt === end test file ===
280 1.1.4.2 yamt
281 1.1.4.2 yamt :map x @a
282 1.1.4.2 yamt 4G"ay$
283 1.1.4.2 yamt :map X @b
284 1.1.4.2 yamt 5G"by$
285 1.1.4.2 yamt :map Y @c
286 1.1.4.2 yamt 6G"cy$
287 1.1.4.2 yamt 1Gx
288 1.1.4.2 yamt
289 1.1.4.2 yamt The output should be:
290 1.1.4.2 yamt
291 1.1.4.2 yamt === output file ===
292 1.1.4.2 yamt REPLACED BY C 1 foo bar baz
293 1.1.4.2 yamt line 2 foo bar baz
294 1.1.4.2 yamt line 3 foo bar baz
295 1.1.4.2 yamt X
296 1.1.4.2 yamt Y
297 1.1.4.2 yamt cwREPLACED BY C^[
298 1.1.4.2 yamt blank line
299 1.1.4.2 yamt === end output file ===
300 1.1.4.2 yamt
301 1.1.4.2 yamt =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
302 1.1.4.2 yamt 6: If an error is encountered while executing a mapped command or
303 1.1.4.2 yamt a buffer, the rest of the mapped command/buffer is discarded. No
304 1.1.4.2 yamt user input characters are discarded.
305 1.1.4.2 yamt
306 1.1.4.2 yamt === test file ===
307 1.1.4.2 yamt line 1 foo bar baz
308 1.1.4.2 yamt line 2 foo bar baz
309 1.1.4.2 yamt line 3 foo bar baz
310 1.1.4.2 yamt :map = 10GcwREPLACMENT^V^[^[
311 1.1.4.2 yamt === end test file ===
312 1.1.4.2 yamt
313 1.1.4.2 yamt The above mapping fails, however, if the 10G is changed to 1, 2,
314 1.1.4.2 yamt or 3G, it will succeed.
315 1.1.4.2 yamt
316 1.1.4.2 yamt =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
317 1.1.4.2 yamt 7: Characters in executable buffers are remapped.
318 1.1.4.2 yamt
319 1.1.4.2 yamt === test file ===
320 1.1.4.2 yamt abcdefghijklmnnop
321 1.1.4.2 yamt ggg
322 1.1.4.2 yamt === end test file ===
323 1.1.4.2 yamt
324 1.1.4.2 yamt :map g x
325 1.1.4.2 yamt 2G"ay$1G@a
326 1.1.4.2 yamt
327 1.1.4.2 yamt The output should be:
328 1.1.4.2 yamt
329 1.1.4.2 yamt === output file ===
330 1.1.4.2 yamt defghijklmnnop
331 1.1.4.2 yamt ggg
332 1.1.4.2 yamt === end output file ===
333 1.1.4.2 yamt
334 1.1.4.2 yamt =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
335 1.1.4.2 yamt 8: Characters in executable buffers are not quoted.
336 1.1.4.2 yamt
337 1.1.4.2 yamt === test file ===
338 1.1.4.2 yamt iFOO^[
339 1.1.4.2 yamt
340 1.1.4.2 yamt === end test file ===
341 1.1.4.2 yamt
342 1.1.4.2 yamt 1G"ay$2G@a
343 1.1.4.2 yamt
344 1.1.4.2 yamt The output should be:
345 1.1.4.2 yamt
346 1.1.4.2 yamt === output file ===
347 1.1.4.2 yamt iFOO^[
348 1.1.4.2 yamt FOO
349 1.1.4.2 yamt === end output file ===
350 1.1.4.2 yamt =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
351