1 # @(#)input 5.5 (Berkeley) 7/2/94
3 MAPS, EXECUTABLE BUFFERS AND INPUT IN EX/VI:
5 The basic rule is that input in ex/vi is a stack. Every time a key which
6 gets expanded is encountered, it is expanded and the expansion is treated
7 as if it were input from the user. So, maps and executable buffers are
8 simply pushed onto the stack from which keys are returned. The exception
9 is that if the "remap" option is turned off, only a single map expansion
10 is done. I intend to be fully backward compatible with this.
12 Historically, if the mode of the editor changed (ex to vi or vice versa),
13 any queued input was silently discarded. I don't see any reason to either
14 support or not support this semantic. I intend to retain the queued input,
15 mostly because it's simpler than throwing it away.
17 Historically, neither the initial command on the command line (the + flag)
18 or the +cmd associated with the ex and edit commands was subject to mapping.
19 Also, while the +cmd appears to be subject to "@buffer" expansion, once
20 expanded it doesn't appear to work correctly. I don't see any reason to
21 either support or not support these semantics, so, for consistency, I intend
22 to pass both the initial command and the command associated with ex and edit
23 commands through the standard mapping and @ buffer expansion.
25 One other difference between the historic ex/vi and nex/nvi is that nex
26 displays the executed buffers as it executes them. This means that if
33 the user will see the following during a typical edit session:
36 testfile: unmodified: line 3
44 This seems like a feature and unlikely to break anything, so I don't
45 intend to match historic practice in this area.
47 The rest of this document is a set of conclusions as to how I believe
48 the historic maps and @ buffers work. The summary is as follows:
50 1: For buffers that are cut in "line mode", or buffers that are not cut
51 in line mode but which contain portions of more than a single line, a
52 trailing <newline> character appears in the input for each line in the
53 buffer when it is executed. For buffers not cut in line mode and which
54 contain portions of only a single line, no additional characters
56 2: Executable buffers that execute other buffers don't load their
57 contents until they execute them.
58 3: Maps and executable buffers are copied when they are executed --
59 they can be modified by the command but that does not change their
61 4: Historically, executable buffers are discarded if the editor
62 switches between ex and vi modes.
63 5: Executable buffers inside of map commands are expanded normally.
64 Maps inside of executable buffers are expanded normally.
65 6: If an error is encountered while executing a mapped command or buffer,
66 the rest of the mapped command/buffer is discarded. No user input
67 characters are discarded.
68 7: Characters in executable buffers are remapped.
69 8: Characters in executable buffers are not quoted.
71 Individual test cases follow. Note, in the test cases, control characters
72 are not literal and will have to be replaced to make the test cases work.
74 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
75 1: For buffers that are cut in "line mode", or buffers that are not cut
76 in line mode but which contain portions of more than a single line, a
77 trailing <newline> character appears in the input for each line in the
78 buffer when it is executed. For buffers not cut in line mode and which
79 contain portions of only a single line, no additional characters
90 If the first line is loaded into 'a' and executed:
94 The cursor ends up on the '2', a result of pushing "3Gw^J" onto
97 If the first two lines are loaded into 'a' and executed:
101 The cursor ends up on the 'f' in "foo" in the fifth line of the
102 file, a result of pushing "3Gw^Jw^J" onto the stack.
104 If the first line is loaded into 'a', but not using line mode,
109 The cursor ends up on the '1', a result of pushing "3Gw" onto
112 If the first two lines are loaded into 'a', but not using line mode,
117 The cursor ends up on the 'f' in "foo" in the fifth line of the
118 file, a result of pushing "3Gw^Jw^J" onto the stack.
120 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
121 2: Executable buffers that execute other buffers don't load their
122 contents until they execute them.
131 === end test file ===
133 The command is loaded into 'e', and then executed. 'e' executes
134 'a', which loads 'b', then 'e' executes 'b'.
138 The output should be:
147 === end output file ===
149 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
150 3: Maps and executable buffers are copied when they are executed --
151 they can be modified by the command but that does not change their
163 === end test file ===
165 4G"eyy5G"ayy6G"byy1G@eG"ep
167 The command is loaded into 'e', and then executed. 'e' executes
168 'a', which loads 'e', then 'e' executes 'b' anyway.
170 The output should be:
174 EXECUTE B 2 foo bar baz
180 === end output file ===
188 === end test file ===
190 Entering the command ':map = :map = rB^V^MrA^M1G==' shows that
191 the first time the '=' is entered the '=' map is set and the
192 character is changed to 'A', the second time the character is
195 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
196 4: Historically, executable buffers are discarded if the editor
197 switches between ex and vi modes.
205 === end test file ===
215 In vi, the command is loaded into 'a' and then executed. The command
216 subsequent to the 'Q' is (historically, silently) discarded.
218 In ex, the command is loaded into 'a' and then executed. The command
219 subsequent to the 'visual' is (historically, silently) discarded. The
220 first set command is output by ex, although refreshing the screen usually
221 causes it not to be seen.
223 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
224 5: Executable buffers inside of map commands are expanded normally.
225 Maps inside of executable buffers are expanded normally.
227 Buffers inside of map commands:
234 === end test file ===
239 The output should be:
242 REPLACE BY A 1 foo bar baz
246 === end output file ===
248 Maps commands inside of executable buffers:
255 === end test file ===
257 :map X cwREPLACE BY XMAP^[
260 The output should be:
263 REPLACE BY XMAP 1 foo bar baz
267 === end output file ===
269 Here's a test that does both, repeatedly.
279 === end test file ===
289 The output should be:
292 REPLACED BY C 1 foo bar baz
299 === end output file ===
301 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
302 6: If an error is encountered while executing a mapped command or
303 a buffer, the rest of the mapped command/buffer is discarded. No
304 user input characters are discarded.
310 :map = 10GcwREPLACMENT^V^[^[
311 === end test file ===
313 The above mapping fails, however, if the 10G is changed to 1, 2,
314 or 3G, it will succeed.
316 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
317 7: Characters in executable buffers are remapped.
322 === end test file ===
327 The output should be:
332 === end output file ===
334 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
335 8: Characters in executable buffers are not quoted.
340 === end test file ===
344 The output should be:
349 === end output file ===
350 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=