Commit | Line | Data |
---|---|---|
8340f87c BJ |
1 | .NH |
2 | LINE ADDRESSING IN THE EDITOR | |
3 | .PP | |
4 | The next general area we will discuss is that of | |
5 | line addressing in | |
6 | .UL ed , | |
7 | that is, how you specify what lines are to be | |
8 | affected by editing commands. | |
9 | We have already used constructions like | |
10 | .P1 | |
11 | 1,$s/x/y/ | |
12 | .P2 | |
13 | to specify a change on all lines. | |
14 | And most users are long since familiar with | |
15 | using a single newline (or return) to print the next line, | |
16 | and with | |
17 | .P1 | |
18 | /thing/ | |
19 | .P2 | |
20 | to find a line that contains `thing'. | |
21 | Less familiar, surprisingly enough, is the | |
22 | use of | |
23 | .P1 | |
24 | ?thing? | |
25 | .P2 | |
26 | to scan | |
27 | .ul | |
28 | backwards | |
29 | for the previous occurrence of `thing'. | |
30 | This is especially handy when you realize that the thing | |
31 | you want to operate on is back up the page from | |
32 | where you are currently editing. | |
33 | .PP | |
34 | The slash and question mark are the only characters you can | |
35 | use to delimit a context search, though you can use | |
36 | essentially any character in a substitute command. | |
37 | .SH | |
38 | Address Arithmetic | |
39 | .PP | |
40 | The next step is to combine the line numbers | |
41 | like `\*.', `$', `/.../' and `?...?' | |
42 | with `+' and `\-'. | |
43 | Thus | |
44 | .P1 | |
45 | $-1 | |
46 | .P2 | |
47 | is a command to print the next to last line of | |
48 | the current file (that is, one line before line `$'). | |
49 | For example, to recall how far you got in a previous editing session, | |
50 | .P1 | |
51 | $-5,$p | |
52 | .P2 | |
53 | prints the last six lines. | |
54 | (Be sure you understand why it's six, not five.) | |
55 | If there aren't six, of course, you'll get an error message. | |
56 | .PP | |
57 | As another example, | |
58 | .P1 | |
59 | \&\*.-3,\*.+3p | |
60 | .P2 | |
61 | prints from three lines before where you are now | |
62 | (at line dot) | |
63 | to three lines after, | |
64 | thus giving you a bit of context. | |
65 | By the way, the `+' can be omitted: | |
66 | .P1 | |
67 | \&\*.-3,\*.3p | |
68 | .P2 | |
69 | is absolutely identical in meaning. | |
70 | .PP | |
71 | Another area in which you can save typing effort | |
72 | in specifying lines is to use `\-' and `+' as line numbers | |
73 | by themselves. | |
74 | .P1 | |
75 | - | |
76 | .P2 | |
77 | by itself is a command to move back up one line in the file. | |
78 | In fact, you can string several minus signs together to move | |
79 | back up that many lines: | |
80 | .P1 | |
81 | --- | |
82 | .P2 | |
83 | moves up three lines, as does `\-3'. | |
84 | Thus | |
85 | .P1 | |
86 | -3,+3p | |
87 | .P2 | |
88 | is also identical to the examples above. | |
89 | .PP | |
90 | Since `\-' is shorter than `\*.\-1', | |
91 | constructions like | |
92 | .P1 | |
93 | -,\*.s/bad/good/ | |
94 | .P2 | |
95 | are useful. This changes `bad' to `good' on the previous line and | |
96 | on the current line. | |
97 | .PP | |
98 | `+' and `\-' can be used in combination with searches using `/.../' and `?...?', | |
99 | and with `$'. | |
100 | The search | |
101 | .P1 | |
102 | /thing/-- | |
103 | .P2 | |
104 | finds the line containing `thing', and positions you | |
105 | two lines before it. | |
106 | .SH | |
107 | Repeated Searches | |
108 | .PP | |
109 | Suppose you ask for the search | |
110 | .P1 | |
111 | /horrible thing/ | |
112 | .P2 | |
113 | and when the line is printed you discover that it | |
114 | isn't the horrible thing that you wanted, | |
115 | so it is necessary to repeat the search again. | |
116 | You don't have to re-type the search, | |
117 | for the construction | |
118 | .P1 | |
119 | // | |
120 | .P2 | |
121 | is a shorthand for `the previous thing that was searched for', | |
122 | whatever it was. | |
123 | This can be repeated as many times as necessary. | |
124 | You can also go backwards: | |
125 | .P1 | |
126 | ?? | |
127 | .P2 | |
128 | searches for the same thing, | |
129 | but in the reverse direction. | |
130 | .PP | |
131 | Not only can you repeat the search, but you can | |
132 | use `//' as the left side of a substitute command, | |
133 | to mean | |
134 | `the most recent pattern'. | |
135 | .P1 | |
136 | /horrible thing/ | |
137 | .ft I | |
138 | .... ed prints line with `horrible thing' ... | |
139 | .ft R | |
140 | s//good/p | |
141 | .P2 | |
142 | To go backwards and change a line, say | |
143 | .P1 | |
144 | ??s//good/ | |
145 | .P2 | |
146 | Of course, you can still use the `&' on the right hand side of a substitute to stand for | |
147 | whatever got matched: | |
148 | .P1 | |
149 | //s//&\*B&/p | |
150 | .P2 | |
151 | finds the next occurrence of whatever you searched for last, | |
152 | replaces it by two copies of itself, | |
153 | then prints the line just to verify that it worked. | |
154 | .SH | |
155 | Default Line Numbers and the Value of Dot | |
156 | .PP | |
157 | One of the most effective ways to speed up your editing | |
158 | is always to know what lines will be affected | |
159 | by a command if you don't specify the lines it is to act on, | |
160 | and on what line you will be positioned (i.e., the value of dot) when a command finishes. | |
161 | If you can edit without specifying unnecessary | |
162 | line numbers, you can save a lot of typing. | |
163 | .PP | |
164 | As the most obvious example, if you issue a search command | |
165 | like | |
166 | .P1 | |
167 | /thing/ | |
168 | .P2 | |
169 | you are left pointing at the next line that contains `thing'. | |
170 | Then no address is required with commands like | |
171 | .UL s | |
172 | to make a substitution on that line, | |
173 | or | |
174 | .UL p | |
175 | to print it, | |
176 | or | |
177 | .UL l | |
178 | to list it, | |
179 | or | |
180 | .UL d | |
181 | to delete it, | |
182 | or | |
183 | .UL a | |
184 | to append text after it, | |
185 | or | |
186 | .UL c | |
187 | to change it, | |
188 | or | |
189 | .UL i | |
190 | to insert text before it. | |
191 | .PP | |
192 | What happens if there was no `thing'? | |
193 | Then you are left right where you were _ | |
194 | dot is unchanged. | |
195 | This is also true if you were sitting | |
196 | on the only `thing' when you issued the command. | |
197 | The same rules hold for searches that use | |
198 | `?...?'; the only difference is the direction | |
199 | in which you search. | |
200 | .PP | |
201 | The delete command | |
202 | .UL d | |
203 | leaves dot pointing | |
204 | at the line that followed the last deleted line. | |
205 | When line `$' gets deleted, | |
206 | however, | |
207 | dot points at the | |
208 | .ul | |
209 | new | |
210 | line `$'. | |
211 | .PP | |
212 | The line-changing commands | |
213 | .UL a , | |
214 | .UL c | |
215 | and | |
216 | .UL i | |
217 | by default all affect the current line _ | |
218 | if you give no line number with them, | |
219 | .UL a | |
220 | appends text after the current line, | |
221 | .UL c | |
222 | changes the current line, | |
223 | and | |
224 | .UL i | |
225 | inserts text before the current line. | |
226 | .PP | |
227 | .UL a , | |
228 | .UL c , | |
229 | and | |
230 | .UL i | |
231 | behave identically in one respect _ | |
232 | when you stop appending, changing or inserting, | |
233 | dot points at the last line entered. | |
234 | This is exactly what you want for typing and editing on the fly. | |
235 | For example, you can say | |
236 | .P1 | |
237 | .ta 1.5i | |
238 | a | |
239 | ... text ... | |
240 | ... botch ... (minor error) | |
241 | \&\*. | |
242 | s/botch/correct/ (fix botched line) | |
243 | a | |
244 | ... more text ... | |
245 | .P2 | |
246 | without specifying any line number for the substitute command or for | |
247 | the second append command. | |
248 | Or you can say | |
249 | .P1 2 | |
250 | .ta 1.5i | |
251 | a | |
252 | ... text ... | |
253 | ... horrible botch ... (major error) | |
254 | \&\*. | |
255 | c (replace entire line) | |
256 | ... fixed up line ... | |
257 | .P2 | |
258 | .PP | |
259 | You should experiment to determine what happens if you add | |
260 | .ul | |
261 | no | |
262 | lines with | |
263 | .UL a , | |
264 | .UL c | |
265 | or | |
266 | .UL i . | |
267 | .PP | |
268 | The | |
269 | .UL r | |
270 | command will read a file into the text being edited, | |
271 | either at the end if you give no address, | |
272 | or after the specified line if you do. | |
273 | In either case, dot points at the last line read in. | |
274 | Remember that you can even say | |
275 | .UL 0r | |
276 | to read a file in at the beginning of the text. | |
277 | (You can also say | |
278 | .UL 0a | |
279 | or | |
280 | .UL 1i | |
281 | to start adding text at the beginning.) | |
282 | .PP | |
283 | The | |
284 | .UL w | |
285 | command writes out the entire file. | |
286 | If you precede the command by one line number, | |
287 | that line is written, | |
288 | while if you precede it by two line numbers, | |
289 | that range of lines is written. | |
290 | The | |
291 | .UL w | |
292 | command does | |
293 | .ul | |
294 | not | |
295 | change dot: | |
296 | the current line remains the same, | |
297 | regardless of what lines are written. | |
298 | This is true even if you say something like | |
299 | .P1 | |
300 | /^\*e\*.AB/,/^\*e\*.AE/w abstract | |
301 | .P2 | |
302 | which involves a context search. | |
303 | .PP | |
304 | Since the | |
305 | .UL w | |
306 | command is so easy to use, | |
307 | you should save what you are editing regularly | |
308 | as you go along | |
309 | just in case the system crashes, or in case you do something foolish, | |
310 | like clobbering what you're editing. | |
311 | .PP | |
312 | The least intuitive behavior, in a sense, is that of the | |
313 | .UL s | |
314 | command. | |
315 | The rule is simple _ | |
316 | you are left sitting on the last line that got changed. | |
317 | If there were no changes, then dot is unchanged. | |
318 | .PP | |
319 | To illustrate, | |
320 | suppose that there are three lines in the buffer, and you are sitting on | |
321 | the middle one: | |
322 | .P1 | |
323 | x1 | |
324 | x2 | |
325 | x3 | |
326 | .P2 | |
327 | Then the command | |
328 | .P1 | |
329 | \&-,+s/x/y/p | |
330 | .P2 | |
331 | prints the third line, which is the last one changed. | |
332 | But if the three lines had been | |
333 | .P1 | |
334 | x1 | |
335 | y2 | |
336 | y3 | |
337 | .P2 | |
338 | and the same command had been issued while | |
339 | dot pointed | |
340 | at the second line, then the result | |
341 | would be to change and print only the first line, | |
342 | and that is where dot would be set. | |
343 | .SH | |
344 | Semicolon `;' | |
345 | .PP | |
346 | Searches with `/.../' and `?...?' start | |
347 | at the current line and move | |
348 | forward or backward respectively | |
349 | until they either find the pattern or get back to the current line. | |
350 | Sometimes this is not what is wanted. | |
351 | Suppose, for example, that the buffer contains lines like this: | |
352 | .P1 | |
353 | \*. | |
354 | \*. | |
355 | \*. | |
356 | ab | |
357 | \*. | |
358 | \*. | |
359 | \*. | |
360 | bc | |
361 | \*. | |
362 | \*. | |
363 | .P2 | |
364 | Starting at line 1, one would expect that the command | |
365 | .P1 | |
366 | /a/,/b/p | |
367 | .P2 | |
368 | prints all the lines from the `ab' to the `bc' inclusive. | |
369 | Actually this is not what happens. | |
370 | .ul | |
371 | Both | |
372 | searches | |
373 | (for `a' and for `b') | |
374 | start from the same point, and thus they both find the line | |
375 | that contains `ab'. | |
376 | The result is to print a single line. | |
377 | Worse, if there had been a line with a `b' in it | |
378 | before the `ab' line, then the print command | |
379 | would be in error, since the second line number | |
380 | would be less than the first, and it is illegal to | |
381 | try to print lines in reverse order. | |
382 | .PP | |
383 | This is because the comma separator | |
384 | for line numbers doesn't set dot as each address is processed; | |
385 | each search starts from the same place. | |
386 | In | |
387 | .UL ed , | |
388 | the semicolon `;' can be used just like comma, | |
389 | with the single difference that use of a semicolon | |
390 | forces dot to be set at that point | |
391 | as the line numbers are being evaluated. | |
392 | In effect, the semicolon `moves' dot. | |
393 | Thus in our example above, the command | |
394 | .P1 | |
395 | /a/;/b/p | |
396 | .P2 | |
397 | prints the range of lines from `ab' to `bc', | |
398 | because after the `a' is found, dot is set to that line, | |
399 | and then `b' is searched for, starting beyond that line. | |
400 | .PP | |
401 | This property is most often useful in a very simple situation. | |
402 | Suppose you want to find the | |
403 | .ul | |
404 | second | |
405 | occurrence of `thing'. | |
406 | You could say | |
407 | .P1 | |
408 | /thing/ | |
409 | // | |
410 | .P2 | |
411 | but this prints the first occurrence as well as the second, | |
412 | and is a nuisance when you know very well that it is only | |
413 | the second one you're interested in. | |
414 | The solution is to say | |
415 | .P1 | |
416 | /thing/;// | |
417 | .P2 | |
418 | This says to find the first occurrence of `thing', set dot to that line, then find the second | |
419 | and print only that. | |
420 | .PP | |
421 | Closely related is searching for the second previous | |
422 | occurrence of something, as in | |
423 | .P1 | |
424 | ?something?;?? | |
425 | .P2 | |
426 | Printing the third or fourth or ... | |
427 | in either direction is left as an exercise. | |
428 | .PP | |
429 | Finally, bear in mind that if you want to find the first occurrence of | |
430 | something in a file, starting at an arbitrary place within the file, | |
431 | it is not sufficient to say | |
432 | .P1 | |
433 | 1;/thing/ | |
434 | .P2 | |
435 | because this fails if `thing' occurs on line 1. | |
436 | But it is possible to say | |
437 | .P1 | |
438 | 0;/thing/ | |
439 | .P2 | |
440 | (one of the few places where 0 is a legal line number), | |
441 | for this starts the search at line 1. | |
442 | .SH | |
443 | Interrupting the Editor | |
444 | .PP | |
445 | As a final note on what dot gets set to, | |
446 | you should be aware that if you hit the interrupt or delete | |
447 | or rubout or break key | |
448 | while | |
449 | .UL ed | |
450 | is doing a command, things are put back together again and your state | |
451 | is restored as much as possible to what it was before the command | |
452 | began. | |
453 | Naturally, some changes are irrevocable _ | |
454 | if you are reading or writing a file or making substitutions or deleting lines, these will be stopped | |
455 | in some clean but unpredictable state in the middle | |
456 | (which is why it is not usually wise to stop them). | |
457 | Dot may or may not be changed. | |
458 | .PP | |
459 | Printing is more clear cut. | |
460 | Dot is not changed until the printing is done. | |
461 | Thus if you print until you see an interesting line, | |
462 | then hit delete, you are | |
463 | .ul | |
464 | not | |
465 | sitting on that line or even near it. | |
466 | Dot is left where it was when the | |
467 | .UL p | |
468 | command was started. |