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