1 # @(#)input 5.4 (Berkeley) 8/26/93
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.
69 Individual test cases follow. Note, in the test cases, control characters
70 are not literal and will have to be replaced to make the test cases work.
72 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
73 1: For buffers that are cut in "line mode", or buffers that are not cut
74 in line mode but which contain portions of more than a single line, a
75 trailing <newline> character appears in the input for each line in the
76 buffer when it is executed. For buffers not cut in line mode and which
77 contain portions of only a single line, no additional characters
88 If the first line is loaded into 'a' and executed:
92 The cursor ends up on the '2', a result of pushing "3Gw^J" onto
95 If the first two lines are loaded into 'a' and executed:
99 The cursor ends up on the 'f' in "foo" in the fifth line of the
100 file, a result of pushing "3Gw^Jw^J" onto the stack.
102 If the first line is loaded into 'a', but not using line mode,
107 The cursor ends up on the '1', a result of pushing "3Gw" onto
110 If the first two lines are loaded into 'a', but not using line mode,
115 The cursor ends up on the 'f' in "foo" in the fifth line of the
116 file, a result of pushing "3Gw^Jw^J" onto the stack.
118 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
119 2: Executable buffers that execute other buffers don't load their
120 contents until they execute them.
129 === end test file ===
131 The command is loaded into 'e', and then executed. 'e' executes
132 'a', which loads 'b', then 'e' executes 'b'.
136 The output should be:
145 === end output file ===
147 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
148 3: Maps and executable buffers are copied when they are executed --
149 they can be modified by the command but that does not change their
161 === end test file ===
163 4G"eyy5G"ayy6G"byy1G@eG"ep
165 The command is loaded into 'e', and then executed. 'e' executes
166 'a', which loads 'e', then 'e' executes 'b' anyway.
168 The output should be:
172 EXECUTE B 2 foo bar baz
178 === end output file ===
186 === end test file ===
188 Entering the command ':map = :map = rB^V^MrA^M1G==' shows that
189 the first time the '=' is entered the '=' map is set and the
190 character is changed to 'A', the second time the character is
193 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
194 4: Historically, executable buffers are discarded if the editor
195 switches between ex and vi modes.
203 === end test file ===
213 In vi, the command is loaded into 'a' and then executed. The command
214 subsequent to the 'Q' is (historically, silently) discarded.
216 In ex, the command is loaded into 'a' and then executed. The command
217 subsequent to the 'visual' is (historically, silently) discarded. The
218 first set command is output by ex, although refreshing the screen usually
219 causes it not to be seen.
221 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
222 5: Executable buffers inside of map commands are expanded normally.
223 Maps inside of executable buffers are expanded normally.
225 Buffers inside of map commands:
232 === end test file ===
237 The output should be:
240 REPLACE BY A 1 foo bar baz
244 === end output file ===
246 Maps commands inside of executable buffers:
253 === end test file ===
255 :map X cwREPLACE BY XMAP^[
258 The output should be:
261 REPLACE BY XMAP 1 foo bar baz
265 === end output file ===
267 Here's a test that does both, repeatedly.
277 === end test file ===
287 The output should be:
290 REPLACED BY C 1 foo bar baz
297 === end output file ===
299 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
300 6: If an error is encountered while executing a mapped command or
301 a buffer, the rest of the mapped command/buffer is discarded. No
302 user input characters are discarded.
308 :map = 10GcwREPLACMENT^V^[^[
309 === end test file ===
311 The above mapping fails, however, if the 10G is changed to 1, 2,
312 or 3G, it will succeed.
314 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=