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