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